- Buffer space problem found by Sergio Lenzi <lenzi@bsi.com.br>

fixed. Natd now waits with select(2) for buffer space
  to become available if write fails.
- Packet aliasing library upgraded to 2.2.

Submitted by:	Ari Suutari <suutari@iki.fi>
This commit is contained in:
Brian Somers 1997-08-10 21:55:52 +00:00
parent a5e8237d2a
commit fb994b078f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=28045
10 changed files with 608 additions and 198 deletions

113
sbin/natd/HISTORY Normal file
View File

@ -0,0 +1,113 @@
* Version 0.1
Initial version of natd.
* Version 0.2
- Alias address can now be set by giving interface name with
new (-n) command-line option.
- New Makefile based on bsd.prog.mk.
- Error messages are written to syslog
after natd has become a daemon.
* Version 1.0
- Support for using only single socket (-p option)
* Version 1.1
- -a option now understands a hostname also.
- -a option no longer dumps core.
- Packet aliasing software upgraded to v. 1.9
- added long option names (like -address)
* Version 1.2
- Fixed core dump with -port option.
- Added -Wall to CFLAGS and some headers added to natd.c
to get clean compile by Brian Somers [brian@awfulhak.org].
* Version 1.3
- Aliasing address initialization is delayed until first
packet arrives. This allows natd to start up before
interface address is set.
- SIGTERM is now catched to allow kernel to close
existing connections when system is shutting down.
- SIGHUP is now catched to allow natd to refresh aliasing
address from interface, which might be useful to tun devices.
* Version 1.4
- Changed command line options to be compatible with
command names used in ppp+packetAlias package (which is the
original application using aliasing routines).
The options which map directly to packet aliasing options are:
-unregistered_only [yes|no]
-log [yes|no]
-deny_incoming [yes|no]
-use_sockets [yes|no]
-same_ports [yes|no]
The short option names are the same as in previous
releases.
- Command line parser rewritten to provide more flexible
way to support new packet aliasing options.
- Support for natd.cf configuration file has been added.
- SIGHUP no longer causes problems when running without
interface name option.
- When using -interface command line option, routing socket
is optionally listened for interface address changes. This
mode is activated by -dynamic option.
- Directory tree reorganized, alias package is now a library.
- Manual page written by Brian Somers <brian@awfulhak.org> added.
- README file updated.
* Version 1.5
- Support for sending ICMP 'need fragmentation' messages
when packet size exceeds mtu size of outgoing network interface.
- ipfw rule example in manual page fixed.
* Version 1.6
- Upgrade to new packet aliasing engine (2.1)
- redirect_port and redirect_address configuration
parameters added.
- It is no longer necessary to quote complex parameter values
in command line.
- Manual page fixed (same_port -> same_ports).
* Version 1.7
- A bug in command-line parsing fixed (it appeared due
to changes made in 1.6).
* Version 1.8
- Fixed problems with -dynamic option.
- Added /var/run/natd.pid
* Version 1.9
- Changes to manual page by
Brian Somers <brian@awfulhak.org> integrated.
- Checksum for incoming packets is always recalculated
for FreeBSD 2.2 and never recalculated for newer
versions. This should fix the problem with wrong
checksum of fragmented packets.
- Buffer space problem found by Sergio Lenzi <lenzi@bsi.com.br>
fixed. Natd now waits with select(2) for buffer space
to become available if write fails.
- Packet aliasing library upgraded to 2.2.

53
sbin/natd/README Normal file
View File

@ -0,0 +1,53 @@
A Network Address Translation Daemon for FreeBSD
1. WHAT IS NATD ?
This is a simple daemon based on FreeBSD divert sockets
which performs network address translation (or masquerading)
for IP packets (see related RFCs 1631 and 1918).
It is based on packet aliasing package (see README.alias)
written by Charles Mott (cmott@srv.net).
This package works with any network interface (doesn't have
to be ppp). I run it on a computer having two ethernet cards,
one connected to internet and the other one to local network.
2. GETTING IT RUNNING
1) Get FreeBSD 2.2 - I think the divert sockets are
not available on earlier versions,
2) Compile this software by executing "make".
3) Install the software by executing "make install".
4) See man natd for further instructions.
3. FTP SITES FOR NATD
This package is available at ftp://ftp.suutari.iki.fi/pub/natd.
4. AUTHORS
This program is the result of the efforts of many people
at different times:
Archie Cobbs <archie@whistle.com> Divert sockets
Charles Mott <cmott@srv.net> Packet aliasing engine
Eivind Eklund <eivind@dimaga.com> Packet aliasing engine
Ari Suutari <suutari@iki.fi> Natd
Brian Somers <brian@awfulhak.org> Manual page, glue and
bunch of good ideas.
The original package written by Charles Mott
is available at http://www.srv.net/~cmott.
It is described in README.alias.
Happy Networking - comments and fixes are welcome!
Ari S. (suutari@iki.fi)

View File

@ -72,7 +72,8 @@ int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu)
/*
* Calculate checksum.
*/
icmp->icmp_cksum = InternetChecksum ((u_short*) icmp, icmpLen);
icmp->icmp_cksum = PacketAliasInternetChecksum ((u_short*) icmp,
icmpLen);
/*
* Add IP header using old IP header as template.
*/

View File

@ -377,5 +377,5 @@ times:
Divert sockets: Archie Cobbs <archie@whistle.com>
Packet aliasing: Charles Mott <cmott@srv.net>
IRC support & misc additions: Eivind Eklund <eivind@dimaga.com>
Natd: Ari Suutari <ari.suutari@ps.carel.fi>
Natd: Ari Suutari <suutari@iki.fi>
Glue: Brian Somers <brian@awfulhak.org>

View File

@ -7,7 +7,7 @@
*
* You may copy, modify and distribute this software (natd.c) freely.
*
* Ari Suutari (ari@kn6-045.ktvlpr.inet.fi, ari@ps.carel.fi)
* Ari Suutari <suutari@iki.fi>
*
*/
@ -70,25 +70,30 @@ static int StrToPort (char* str, char* proto);
static int StrToProto (char* str);
static int StrToAddrAndPort (char* str, struct in_addr* addr, char* proto);
static void ParseArgs (int argc, char** argv);
static void FlushPacketBuffer (int fd);
/*
* Globals.
*/
static int verbose;
static int background;
static int running;
static int assignAliasAddr;
static char* ifName;
static int ifIndex;
static int inPort;
static int outPort;
static int inOutPort;
static struct in_addr aliasAddr;
static int dynamicMode;
static int ifMTU;
static int aliasOverhead;
static int icmpSock;
static int verbose;
static int background;
static int running;
static int assignAliasAddr;
static char* ifName;
static int ifIndex;
static int inPort;
static int outPort;
static int inOutPort;
static struct in_addr aliasAddr;
static int dynamicMode;
static int ifMTU;
static int aliasOverhead;
static int icmpSock;
static char packetBuf[IP_MAXPACKET];
static int packetLen;
static struct sockaddr_in packetAddr;
static int packetSock;
int main (int argc, char** argv)
{
@ -98,13 +103,14 @@ int main (int argc, char** argv)
int routeSock;
struct sockaddr_in addr;
fd_set readMask;
fd_set writeMask;
int fdMax;
/*
* Initialize packet aliasing software.
* Done already here to be able to alter option bits
* during command line and configuration file processing.
*/
InitPacketAlias ();
PacketAliasInit ();
/*
* Parse options.
*/
@ -120,6 +126,10 @@ int main (int argc, char** argv)
aliasAddr.s_addr = INADDR_NONE;
aliasOverhead = 12;
dynamicMode = 0;
/*
* Mark packet buffer empty.
*/
packetSock = -1;
ParseArgs (argc, argv);
/*
@ -243,42 +253,55 @@ int main (int argc, char** argv)
* Set alias address if it has been given.
*/
if (aliasAddr.s_addr != INADDR_NONE)
SetPacketAliasAddress (aliasAddr);
PacketAliasSetAddress (aliasAddr);
if (divertInOut != -1 && !ifName) {
/*
* When using only one socket, just call
* DoAliasing repeatedly to process packets.
*/
while (running)
DoAliasing (divertInOut);
}
else {
/*
* We need largest descriptor number for select.
*/
fdMax = -1;
fdMax = -1;
if (divertIn > fdMax)
fdMax = divertIn;
if (divertIn > fdMax)
fdMax = divertIn;
if (divertOut > fdMax)
fdMax = divertOut;
if (divertOut > fdMax)
fdMax = divertOut;
if (divertInOut > fdMax)
fdMax = divertInOut;
if (divertInOut > fdMax)
fdMax = divertInOut;
if (routeSock > fdMax)
fdMax = routeSock;
if (routeSock > fdMax)
fdMax = routeSock;
while (running) {
while (running) {
if (divertInOut != -1 && !ifName && packetSock == -1) {
/*
* When using only one socket, just call
* DoAliasing repeatedly to process packets.
*/
DoAliasing (divertInOut);
continue;
}
/*
* Build read mask from socket descriptors to select.
*/
FD_ZERO (&readMask);
FD_ZERO (&readMask);
FD_ZERO (&writeMask);
/*
* If there is unsent packet in buffer, use select
* to check when socket comes writable again.
*/
if (packetSock != -1) {
FD_SET (packetSock, &writeMask);
}
else {
/*
* No unsent packet exists - safe to check if
* new ones are available.
*/
if (divertIn != -1)
FD_SET (divertIn, &readMask);
@ -287,38 +310,44 @@ int main (int argc, char** argv)
if (divertInOut != -1)
FD_SET (divertInOut, &readMask);
if (routeSock != -1)
FD_SET (routeSock, &readMask);
if (select (fdMax + 1,
&readMask,
NULL,
NULL,
NULL) == -1) {
if (errno == EINTR)
continue;
Quit ("Select failed.");
}
if (divertIn != -1)
if (FD_ISSET (divertIn, &readMask))
DoAliasing (divertIn);
if (divertOut != -1)
if (FD_ISSET (divertOut, &readMask))
DoAliasing (divertOut);
if (divertInOut != -1)
if (FD_ISSET (divertInOut, &readMask))
DoAliasing (divertInOut);
if (routeSock != -1)
if (FD_ISSET (routeSock, &readMask))
HandleRoutingInfo (routeSock);
}
/*
* Routing info is processed always.
*/
if (routeSock != -1)
FD_SET (routeSock, &readMask);
if (select (fdMax + 1,
&readMask,
&writeMask,
NULL,
NULL) == -1) {
if (errno == EINTR)
continue;
Quit ("Select failed.");
}
if (packetSock != -1)
if (FD_ISSET (packetSock, &writeMask))
FlushPacketBuffer (packetSock);
if (divertIn != -1)
if (FD_ISSET (divertIn, &readMask))
DoAliasing (divertIn);
if (divertOut != -1)
if (FD_ISSET (divertOut, &readMask))
DoAliasing (divertOut);
if (divertInOut != -1)
if (FD_ISSET (divertInOut, &readMask))
DoAliasing (divertInOut);
if (routeSock != -1)
if (FD_ISSET (routeSock, &readMask))
HandleRoutingInfo (routeSock);
}
if (background)
@ -382,12 +411,8 @@ static void DoAliasing (int fd)
{
int bytes;
int origBytes;
char buf[IP_MAXPACKET];
struct sockaddr_in addr;
int wrote;
int addrSize;
struct ip* ip;
char msgBuf[80];
if (assignAliasAddr) {
@ -397,12 +422,12 @@ static void DoAliasing (int fd)
/*
* Get packet from socket.
*/
addrSize = sizeof addr;
addrSize = sizeof packetAddr;
origBytes = recvfrom (fd,
buf,
sizeof buf,
packetBuf,
sizeof packetBuf,
0,
(struct sockaddr*) &addr,
(struct sockaddr*) &packetAddr,
&addrSize);
if (origBytes == -1) {
@ -415,7 +440,7 @@ static void DoAliasing (int fd)
/*
* This is a IP packet.
*/
ip = (struct ip*) buf;
ip = (struct ip*) packetBuf;
if (verbose) {
@ -423,7 +448,7 @@ static void DoAliasing (int fd)
* Print packet direction and protocol type.
*/
if (addr.sin_addr.s_addr == INADDR_ANY)
if (packetAddr.sin_addr.s_addr == INADDR_ANY)
printf ("Out ");
else
printf ("In ");
@ -451,23 +476,17 @@ static void DoAliasing (int fd)
PrintPacket (ip);
}
if (addr.sin_addr.s_addr == INADDR_ANY) {
if (packetAddr.sin_addr.s_addr == INADDR_ANY) {
/*
* Outgoing packets. Do aliasing.
*/
PacketAliasOut (buf, IP_MAXPACKET);
PacketAliasOut (packetBuf, IP_MAXPACKET);
}
else {
/*
* Incoming packets may have ip checksum zeroed
* when read from divert socket. Re-calculate it.
*/
if (ip->ip_sum == 0)
ip->ip_sum = in_cksum_hdr (ip);
/*
* Do aliasing.
*/
PacketAliasIn (buf, IP_MAXPACKET);
PacketAliasIn (packetBuf, IP_MAXPACKET);
}
/*
* Length might have changed during aliasing.
@ -476,7 +495,7 @@ static void DoAliasing (int fd)
/*
* Update alias overhead size for outgoing packets.
*/
if (addr.sin_addr.s_addr == INADDR_ANY &&
if (packetAddr.sin_addr.s_addr == INADDR_ANY &&
bytes - origBytes > aliasOverhead)
aliasOverhead = bytes - origBytes;
@ -490,24 +509,41 @@ static void DoAliasing (int fd)
PrintPacket (ip);
printf ("\n");
}
packetLen = bytes;
packetSock = fd;
FlushPacketBuffer (fd);
}
static void FlushPacketBuffer (int fd)
{
int wrote;
char msgBuf[80];
/*
* Put packet back for processing.
*/
wrote = sendto (fd,
buf,
bytes,
packetBuf,
packetLen,
0,
(struct sockaddr*) &addr,
sizeof addr);
(struct sockaddr*) &packetAddr,
sizeof packetAddr);
if (wrote != bytes) {
if (wrote != packetLen) {
/*
* If buffer space is not available,
* just return. Main loop will take care of
* retrying send when space becomes available.
*/
if (errno == ENOBUFS)
return;
if (errno == EMSGSIZE) {
if (addr.sin_addr.s_addr == INADDR_ANY &&
if (packetAddr.sin_addr.s_addr == INADDR_ANY &&
ifMTU != -1)
SendNeedFragIcmp (icmpSock,
(struct ip*) buf,
(struct ip*) packetBuf,
ifMTU - aliasOverhead);
}
else {
@ -516,6 +552,8 @@ static void DoAliasing (int fd)
Warn (msgBuf);
}
}
packetSock = -1;
}
static void HandleRoutingInfo (int fd)
@ -1001,7 +1039,7 @@ static void ParseOption (char* option, char* parms, int cmdLine)
case PacketAliasOption:
aliasValue = yesNoValue ? info->packetAliasOpt : 0;
SetPacketAliasMode (aliasValue, info->packetAliasOpt);
PacketAliasSetMode (aliasValue, info->packetAliasOpt);
break;
case Verbose:

113
usr.sbin/natd/HISTORY Normal file
View File

@ -0,0 +1,113 @@
* Version 0.1
Initial version of natd.
* Version 0.2
- Alias address can now be set by giving interface name with
new (-n) command-line option.
- New Makefile based on bsd.prog.mk.
- Error messages are written to syslog
after natd has become a daemon.
* Version 1.0
- Support for using only single socket (-p option)
* Version 1.1
- -a option now understands a hostname also.
- -a option no longer dumps core.
- Packet aliasing software upgraded to v. 1.9
- added long option names (like -address)
* Version 1.2
- Fixed core dump with -port option.
- Added -Wall to CFLAGS and some headers added to natd.c
to get clean compile by Brian Somers [brian@awfulhak.org].
* Version 1.3
- Aliasing address initialization is delayed until first
packet arrives. This allows natd to start up before
interface address is set.
- SIGTERM is now catched to allow kernel to close
existing connections when system is shutting down.
- SIGHUP is now catched to allow natd to refresh aliasing
address from interface, which might be useful to tun devices.
* Version 1.4
- Changed command line options to be compatible with
command names used in ppp+packetAlias package (which is the
original application using aliasing routines).
The options which map directly to packet aliasing options are:
-unregistered_only [yes|no]
-log [yes|no]
-deny_incoming [yes|no]
-use_sockets [yes|no]
-same_ports [yes|no]
The short option names are the same as in previous
releases.
- Command line parser rewritten to provide more flexible
way to support new packet aliasing options.
- Support for natd.cf configuration file has been added.
- SIGHUP no longer causes problems when running without
interface name option.
- When using -interface command line option, routing socket
is optionally listened for interface address changes. This
mode is activated by -dynamic option.
- Directory tree reorganized, alias package is now a library.
- Manual page written by Brian Somers <brian@awfulhak.org> added.
- README file updated.
* Version 1.5
- Support for sending ICMP 'need fragmentation' messages
when packet size exceeds mtu size of outgoing network interface.
- ipfw rule example in manual page fixed.
* Version 1.6
- Upgrade to new packet aliasing engine (2.1)
- redirect_port and redirect_address configuration
parameters added.
- It is no longer necessary to quote complex parameter values
in command line.
- Manual page fixed (same_port -> same_ports).
* Version 1.7
- A bug in command-line parsing fixed (it appeared due
to changes made in 1.6).
* Version 1.8
- Fixed problems with -dynamic option.
- Added /var/run/natd.pid
* Version 1.9
- Changes to manual page by
Brian Somers <brian@awfulhak.org> integrated.
- Checksum for incoming packets is always recalculated
for FreeBSD 2.2 and never recalculated for newer
versions. This should fix the problem with wrong
checksum of fragmented packets.
- Buffer space problem found by Sergio Lenzi <lenzi@bsi.com.br>
fixed. Natd now waits with select(2) for buffer space
to become available if write fails.
- Packet aliasing library upgraded to 2.2.

53
usr.sbin/natd/README Normal file
View File

@ -0,0 +1,53 @@
A Network Address Translation Daemon for FreeBSD
1. WHAT IS NATD ?
This is a simple daemon based on FreeBSD divert sockets
which performs network address translation (or masquerading)
for IP packets (see related RFCs 1631 and 1918).
It is based on packet aliasing package (see README.alias)
written by Charles Mott (cmott@srv.net).
This package works with any network interface (doesn't have
to be ppp). I run it on a computer having two ethernet cards,
one connected to internet and the other one to local network.
2. GETTING IT RUNNING
1) Get FreeBSD 2.2 - I think the divert sockets are
not available on earlier versions,
2) Compile this software by executing "make".
3) Install the software by executing "make install".
4) See man natd for further instructions.
3. FTP SITES FOR NATD
This package is available at ftp://ftp.suutari.iki.fi/pub/natd.
4. AUTHORS
This program is the result of the efforts of many people
at different times:
Archie Cobbs <archie@whistle.com> Divert sockets
Charles Mott <cmott@srv.net> Packet aliasing engine
Eivind Eklund <eivind@dimaga.com> Packet aliasing engine
Ari Suutari <suutari@iki.fi> Natd
Brian Somers <brian@awfulhak.org> Manual page, glue and
bunch of good ideas.
The original package written by Charles Mott
is available at http://www.srv.net/~cmott.
It is described in README.alias.
Happy Networking - comments and fixes are welcome!
Ari S. (suutari@iki.fi)

View File

@ -72,7 +72,8 @@ int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu)
/*
* Calculate checksum.
*/
icmp->icmp_cksum = InternetChecksum ((u_short*) icmp, icmpLen);
icmp->icmp_cksum = PacketAliasInternetChecksum ((u_short*) icmp,
icmpLen);
/*
* Add IP header using old IP header as template.
*/

View File

@ -377,5 +377,5 @@ times:
Divert sockets: Archie Cobbs <archie@whistle.com>
Packet aliasing: Charles Mott <cmott@srv.net>
IRC support & misc additions: Eivind Eklund <eivind@dimaga.com>
Natd: Ari Suutari <ari.suutari@ps.carel.fi>
Natd: Ari Suutari <suutari@iki.fi>
Glue: Brian Somers <brian@awfulhak.org>

View File

@ -7,7 +7,7 @@
*
* You may copy, modify and distribute this software (natd.c) freely.
*
* Ari Suutari (ari@kn6-045.ktvlpr.inet.fi, ari@ps.carel.fi)
* Ari Suutari <suutari@iki.fi>
*
*/
@ -70,25 +70,30 @@ static int StrToPort (char* str, char* proto);
static int StrToProto (char* str);
static int StrToAddrAndPort (char* str, struct in_addr* addr, char* proto);
static void ParseArgs (int argc, char** argv);
static void FlushPacketBuffer (int fd);
/*
* Globals.
*/
static int verbose;
static int background;
static int running;
static int assignAliasAddr;
static char* ifName;
static int ifIndex;
static int inPort;
static int outPort;
static int inOutPort;
static struct in_addr aliasAddr;
static int dynamicMode;
static int ifMTU;
static int aliasOverhead;
static int icmpSock;
static int verbose;
static int background;
static int running;
static int assignAliasAddr;
static char* ifName;
static int ifIndex;
static int inPort;
static int outPort;
static int inOutPort;
static struct in_addr aliasAddr;
static int dynamicMode;
static int ifMTU;
static int aliasOverhead;
static int icmpSock;
static char packetBuf[IP_MAXPACKET];
static int packetLen;
static struct sockaddr_in packetAddr;
static int packetSock;
int main (int argc, char** argv)
{
@ -98,13 +103,14 @@ int main (int argc, char** argv)
int routeSock;
struct sockaddr_in addr;
fd_set readMask;
fd_set writeMask;
int fdMax;
/*
* Initialize packet aliasing software.
* Done already here to be able to alter option bits
* during command line and configuration file processing.
*/
InitPacketAlias ();
PacketAliasInit ();
/*
* Parse options.
*/
@ -120,6 +126,10 @@ int main (int argc, char** argv)
aliasAddr.s_addr = INADDR_NONE;
aliasOverhead = 12;
dynamicMode = 0;
/*
* Mark packet buffer empty.
*/
packetSock = -1;
ParseArgs (argc, argv);
/*
@ -243,42 +253,55 @@ int main (int argc, char** argv)
* Set alias address if it has been given.
*/
if (aliasAddr.s_addr != INADDR_NONE)
SetPacketAliasAddress (aliasAddr);
PacketAliasSetAddress (aliasAddr);
if (divertInOut != -1 && !ifName) {
/*
* When using only one socket, just call
* DoAliasing repeatedly to process packets.
*/
while (running)
DoAliasing (divertInOut);
}
else {
/*
* We need largest descriptor number for select.
*/
fdMax = -1;
fdMax = -1;
if (divertIn > fdMax)
fdMax = divertIn;
if (divertIn > fdMax)
fdMax = divertIn;
if (divertOut > fdMax)
fdMax = divertOut;
if (divertOut > fdMax)
fdMax = divertOut;
if (divertInOut > fdMax)
fdMax = divertInOut;
if (divertInOut > fdMax)
fdMax = divertInOut;
if (routeSock > fdMax)
fdMax = routeSock;
if (routeSock > fdMax)
fdMax = routeSock;
while (running) {
while (running) {
if (divertInOut != -1 && !ifName && packetSock == -1) {
/*
* When using only one socket, just call
* DoAliasing repeatedly to process packets.
*/
DoAliasing (divertInOut);
continue;
}
/*
* Build read mask from socket descriptors to select.
*/
FD_ZERO (&readMask);
FD_ZERO (&readMask);
FD_ZERO (&writeMask);
/*
* If there is unsent packet in buffer, use select
* to check when socket comes writable again.
*/
if (packetSock != -1) {
FD_SET (packetSock, &writeMask);
}
else {
/*
* No unsent packet exists - safe to check if
* new ones are available.
*/
if (divertIn != -1)
FD_SET (divertIn, &readMask);
@ -287,38 +310,44 @@ int main (int argc, char** argv)
if (divertInOut != -1)
FD_SET (divertInOut, &readMask);
if (routeSock != -1)
FD_SET (routeSock, &readMask);
if (select (fdMax + 1,
&readMask,
NULL,
NULL,
NULL) == -1) {
if (errno == EINTR)
continue;
Quit ("Select failed.");
}
if (divertIn != -1)
if (FD_ISSET (divertIn, &readMask))
DoAliasing (divertIn);
if (divertOut != -1)
if (FD_ISSET (divertOut, &readMask))
DoAliasing (divertOut);
if (divertInOut != -1)
if (FD_ISSET (divertInOut, &readMask))
DoAliasing (divertInOut);
if (routeSock != -1)
if (FD_ISSET (routeSock, &readMask))
HandleRoutingInfo (routeSock);
}
/*
* Routing info is processed always.
*/
if (routeSock != -1)
FD_SET (routeSock, &readMask);
if (select (fdMax + 1,
&readMask,
&writeMask,
NULL,
NULL) == -1) {
if (errno == EINTR)
continue;
Quit ("Select failed.");
}
if (packetSock != -1)
if (FD_ISSET (packetSock, &writeMask))
FlushPacketBuffer (packetSock);
if (divertIn != -1)
if (FD_ISSET (divertIn, &readMask))
DoAliasing (divertIn);
if (divertOut != -1)
if (FD_ISSET (divertOut, &readMask))
DoAliasing (divertOut);
if (divertInOut != -1)
if (FD_ISSET (divertInOut, &readMask))
DoAliasing (divertInOut);
if (routeSock != -1)
if (FD_ISSET (routeSock, &readMask))
HandleRoutingInfo (routeSock);
}
if (background)
@ -382,12 +411,8 @@ static void DoAliasing (int fd)
{
int bytes;
int origBytes;
char buf[IP_MAXPACKET];
struct sockaddr_in addr;
int wrote;
int addrSize;
struct ip* ip;
char msgBuf[80];
if (assignAliasAddr) {
@ -397,12 +422,12 @@ static void DoAliasing (int fd)
/*
* Get packet from socket.
*/
addrSize = sizeof addr;
addrSize = sizeof packetAddr;
origBytes = recvfrom (fd,
buf,
sizeof buf,
packetBuf,
sizeof packetBuf,
0,
(struct sockaddr*) &addr,
(struct sockaddr*) &packetAddr,
&addrSize);
if (origBytes == -1) {
@ -415,7 +440,7 @@ static void DoAliasing (int fd)
/*
* This is a IP packet.
*/
ip = (struct ip*) buf;
ip = (struct ip*) packetBuf;
if (verbose) {
@ -423,7 +448,7 @@ static void DoAliasing (int fd)
* Print packet direction and protocol type.
*/
if (addr.sin_addr.s_addr == INADDR_ANY)
if (packetAddr.sin_addr.s_addr == INADDR_ANY)
printf ("Out ");
else
printf ("In ");
@ -451,23 +476,17 @@ static void DoAliasing (int fd)
PrintPacket (ip);
}
if (addr.sin_addr.s_addr == INADDR_ANY) {
if (packetAddr.sin_addr.s_addr == INADDR_ANY) {
/*
* Outgoing packets. Do aliasing.
*/
PacketAliasOut (buf, IP_MAXPACKET);
PacketAliasOut (packetBuf, IP_MAXPACKET);
}
else {
/*
* Incoming packets may have ip checksum zeroed
* when read from divert socket. Re-calculate it.
*/
if (ip->ip_sum == 0)
ip->ip_sum = in_cksum_hdr (ip);
/*
* Do aliasing.
*/
PacketAliasIn (buf, IP_MAXPACKET);
PacketAliasIn (packetBuf, IP_MAXPACKET);
}
/*
* Length might have changed during aliasing.
@ -476,7 +495,7 @@ static void DoAliasing (int fd)
/*
* Update alias overhead size for outgoing packets.
*/
if (addr.sin_addr.s_addr == INADDR_ANY &&
if (packetAddr.sin_addr.s_addr == INADDR_ANY &&
bytes - origBytes > aliasOverhead)
aliasOverhead = bytes - origBytes;
@ -490,24 +509,41 @@ static void DoAliasing (int fd)
PrintPacket (ip);
printf ("\n");
}
packetLen = bytes;
packetSock = fd;
FlushPacketBuffer (fd);
}
static void FlushPacketBuffer (int fd)
{
int wrote;
char msgBuf[80];
/*
* Put packet back for processing.
*/
wrote = sendto (fd,
buf,
bytes,
packetBuf,
packetLen,
0,
(struct sockaddr*) &addr,
sizeof addr);
(struct sockaddr*) &packetAddr,
sizeof packetAddr);
if (wrote != bytes) {
if (wrote != packetLen) {
/*
* If buffer space is not available,
* just return. Main loop will take care of
* retrying send when space becomes available.
*/
if (errno == ENOBUFS)
return;
if (errno == EMSGSIZE) {
if (addr.sin_addr.s_addr == INADDR_ANY &&
if (packetAddr.sin_addr.s_addr == INADDR_ANY &&
ifMTU != -1)
SendNeedFragIcmp (icmpSock,
(struct ip*) buf,
(struct ip*) packetBuf,
ifMTU - aliasOverhead);
}
else {
@ -516,6 +552,8 @@ static void DoAliasing (int fd)
Warn (msgBuf);
}
}
packetSock = -1;
}
static void HandleRoutingInfo (int fd)
@ -1001,7 +1039,7 @@ static void ParseOption (char* option, char* parms, int cmdLine)
case PacketAliasOption:
aliasValue = yesNoValue ? info->packetAliasOpt : 0;
SetPacketAliasMode (aliasValue, info->packetAliasOpt);
PacketAliasSetMode (aliasValue, info->packetAliasOpt);
break;
case Verbose: