summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1997-08-10 21:55:52 +0000
committerbrian <brian@FreeBSD.org>1997-08-10 21:55:52 +0000
commit69210a76930cd9f8b1cd7b25f62b62feacb73c43 (patch)
tree65326d3024b1606d6fc19b37cf6da72801dc4bb1 /sbin
parentd89f54f7a31493ef7ab830f3ea3911c80ba43f2e (diff)
downloadFreeBSD-src-69210a76930cd9f8b1cd7b25f62b62feacb73c43.zip
FreeBSD-src-69210a76930cd9f8b1cd7b25f62b62feacb73c43.tar.gz
- 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>
Diffstat (limited to 'sbin')
-rw-r--r--sbin/natd/HISTORY113
-rw-r--r--sbin/natd/README53
-rw-r--r--sbin/natd/icmp.c3
-rw-r--r--sbin/natd/natd.82
-rw-r--r--sbin/natd/natd.c218
5 files changed, 297 insertions, 92 deletions
diff --git a/sbin/natd/HISTORY b/sbin/natd/HISTORY
new file mode 100644
index 0000000..404be4b
--- /dev/null
+++ b/sbin/natd/HISTORY
@@ -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.
diff --git a/sbin/natd/README b/sbin/natd/README
new file mode 100644
index 0000000..6c158d5
--- /dev/null
+++ b/sbin/natd/README
@@ -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)
+
+
+
diff --git a/sbin/natd/icmp.c b/sbin/natd/icmp.c
index 40464ff..2018f66 100644
--- a/sbin/natd/icmp.c
+++ b/sbin/natd/icmp.c
@@ -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.
*/
diff --git a/sbin/natd/natd.8 b/sbin/natd/natd.8
index dbda1c5c1..c38887c 100644
--- a/sbin/natd/natd.8
+++ b/sbin/natd/natd.8
@@ -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>
diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c
index f166765..13cf6ab 100644
--- a/sbin/natd/natd.c
+++ b/sbin/natd/natd.c
@@ -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);
+ }
+/*
+ * Routing info is processed always.
+ */
+ if (routeSock != -1)
+ FD_SET (routeSock, &readMask);
- if (routeSock != -1)
- FD_SET (routeSock, &readMask);
+ if (select (fdMax + 1,
+ &readMask,
+ &writeMask,
+ NULL,
+ NULL) == -1) {
- if (select (fdMax + 1,
- &readMask,
- NULL,
- NULL,
- NULL) == -1) {
+ if (errno == EINTR)
+ continue;
- if (errno == EINTR)
- continue;
+ Quit ("Select failed.");
+ }
- Quit ("Select failed.");
- }
+ if (packetSock != -1)
+ if (FD_ISSET (packetSock, &writeMask))
+ FlushPacketBuffer (packetSock);
- if (divertIn != -1)
- if (FD_ISSET (divertIn, &readMask))
- DoAliasing (divertIn);
+ if (divertIn != -1)
+ if (FD_ISSET (divertIn, &readMask))
+ DoAliasing (divertIn);
- if (divertOut != -1)
- if (FD_ISSET (divertOut, &readMask))
- DoAliasing (divertOut);
+ if (divertOut != -1)
+ if (FD_ISSET (divertOut, &readMask))
+ DoAliasing (divertOut);
- if (divertInOut != -1)
- if (FD_ISSET (divertInOut, &readMask))
- DoAliasing (divertInOut);
+ if (divertInOut != -1)
+ if (FD_ISSET (divertInOut, &readMask))
+ DoAliasing (divertInOut);
- if (routeSock != -1)
- if (FD_ISSET (routeSock, &readMask))
- HandleRoutingInfo (routeSock);
- }
+ 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:
OpenPOWER on IntegriCloud