diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/Makefile | 3 | ||||
-rw-r--r-- | usr.sbin/natd/HISTORY | 146 | ||||
-rw-r--r-- | usr.sbin/natd/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/natd/README | 53 | ||||
-rw-r--r-- | usr.sbin/natd/icmp.c | 127 | ||||
-rw-r--r-- | usr.sbin/natd/natd.8 | 426 | ||||
-rw-r--r-- | usr.sbin/natd/natd.c | 1477 | ||||
-rw-r--r-- | usr.sbin/natd/natd.h | 24 | ||||
-rw-r--r-- | usr.sbin/natd/samples/natd.cf.sample | 94 | ||||
-rw-r--r-- | usr.sbin/natd/samples/natd.test | 14 |
10 files changed, 1 insertions, 2371 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index e071446..afe09bd 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -1,5 +1,5 @@ # From: @(#)Makefile 5.20 (Berkeley) 6/12/93 -# $Id: Makefile,v 1.147 1999/01/11 18:03:54 msmith Exp $ +# $Id: Makefile,v 1.148 1999/02/21 21:30:13 rnordier Exp $ # XXX MISSING: mkproto SUBDIR= IPXrouted \ @@ -46,7 +46,6 @@ SUBDIR= IPXrouted \ named \ named.reload \ named.restart \ - natd \ ndc \ newsyslog \ nslookup \ diff --git a/usr.sbin/natd/HISTORY b/usr.sbin/natd/HISTORY deleted file mode 100644 index f929e80..0000000 --- a/usr.sbin/natd/HISTORY +++ /dev/null @@ -1,146 +0,0 @@ -* 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. - -* Version 1.10 - - - Ignored incoming packets are now dropped when - deny_incoming option is set to yes. - - Packet aliasing library upgraded to 2.4. - -* Version 1.11 - - - Code cleanup work done in FreeBSD-current development merged. - - Port numbers are now unsigned as they should always have been. - -* Version 1.12 - - - Typos in comment fixed. Copyright message added to - source & header files that were missing it. - - A small patch to libalias to make static NAT work correctly. - -* Version 2.0 - - - Upgrade to libalias 3.0 which gives: - - Transparent proxy support. - - permanent_link is now obsolete, use redirect_port instead. - - Drop support for early FreeBSD 2.2 versions - - If separate input & output sockets are being used - use them to find out packet direction instead of - normal mechanism. This can be handy in complex environments - with multiple interfaces. - - libalias is no longer part of this distribution. - - New sample configuration file - from Ted Mittelstaedt <tedm@portsoft.com>. - - PPTP redirect support by Dru Nelson <dnelson@redwoodsoft.com> added. - - Logging enhancements from Martin Machacek <mm@i.cz> added. diff --git a/usr.sbin/natd/Makefile b/usr.sbin/natd/Makefile deleted file mode 100644 index b947158..0000000 --- a/usr.sbin/natd/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG = natd -SRCS = natd.c icmp.c -CFLAGS += -Wall -LDADD = -lalias -DPADD = ${LIBALIAS} -MAN8 = natd.8 - -.include <bsd.prog.mk> diff --git a/usr.sbin/natd/README b/usr.sbin/natd/README deleted file mode 100644 index 6c158d5..0000000 --- a/usr.sbin/natd/README +++ /dev/null @@ -1,53 +0,0 @@ - - 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/usr.sbin/natd/icmp.c b/usr.sbin/natd/icmp.c deleted file mode 100644 index 1a144c2..0000000 --- a/usr.sbin/natd/icmp.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * natd - Network Address Translation Daemon for FreeBSD. - * - * This software is provided free of charge, with no - * warranty of any kind, either expressed or implied. - * Use at your own risk. - * - * You may copy, modify and distribute this software (icmp.c) freely. - * - * Ari Suutari <suutari@iki.fi> - * - * $Id:$ - */ - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <errno.h> -#include <signal.h> - -#include <netdb.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/ip_icmp.h> -#include <machine/in_cksum.h> - -#include <alias.h> - -#include "natd.h" - -int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu) -{ - char icmpBuf[IP_MAXPACKET]; - struct ip* ip; - struct icmp* icmp; - int icmpLen; - int failBytes; - int failHdrLen; - struct sockaddr_in addr; - int wrote; - struct in_addr swap; -/* - * Don't send error if packet is - * not the first fragment. - */ - if (ntohs (failedDgram->ip_off) & ~(IP_MF | IP_DF)) - return 0; -/* - * Dont respond if failed datagram is ICMP. - */ - if (failedDgram->ip_p == IPPROTO_ICMP) - return 0; -/* - * Start building the message. - */ - ip = (struct ip*) icmpBuf; - icmp = (struct icmp*) (icmpBuf + sizeof (struct ip)); -/* - * Complete ICMP part. - */ - icmp->icmp_type = ICMP_UNREACH; - icmp->icmp_code = ICMP_UNREACH_NEEDFRAG; - icmp->icmp_cksum = 0; - icmp->icmp_void = 0; - icmp->icmp_nextmtu = htons (mtu); -/* - * Copy header + 64 bits of original datagram. - */ - failHdrLen = (failedDgram->ip_hl << 2); - failBytes = failedDgram->ip_len - failHdrLen; - if (failBytes > 8) - failBytes = 8; - - failBytes += failHdrLen; - icmpLen = ICMP_MINLEN + failBytes; - - memcpy (&icmp->icmp_ip, failedDgram, failBytes); -/* - * Calculate checksum. - */ - icmp->icmp_cksum = PacketAliasInternetChecksum ((u_short*) icmp, - icmpLen); -/* - * Add IP header using old IP header as template. - */ - memcpy (ip, failedDgram, sizeof (struct ip)); - - ip->ip_v = 4; - ip->ip_hl = 5; - ip->ip_len = htons (sizeof (struct ip) + icmpLen); - ip->ip_p = IPPROTO_ICMP; - ip->ip_tos = 0; - - swap = ip->ip_dst; - ip->ip_dst = ip->ip_src; - ip->ip_src = swap; - - PacketAliasIn ((char*) ip, IP_MAXPACKET); - - addr.sin_family = AF_INET; - addr.sin_addr = ip->ip_dst; - addr.sin_port = 0; -/* - * Put packet into processing queue. - */ - wrote = sendto (sock, - icmp, - icmpLen, - 0, - (struct sockaddr*) &addr, - sizeof addr); - - if (wrote != icmpLen) - Warn ("Cannot send ICMP message."); - - return 1; -} - - diff --git a/usr.sbin/natd/natd.8 b/usr.sbin/natd/natd.8 deleted file mode 100644 index 6202a94..0000000 --- a/usr.sbin/natd/natd.8 +++ /dev/null @@ -1,426 +0,0 @@ -.\" manual page [] for natd 1.4 -.\" $Id:$ -.Dd 15 April 1997 -.Os FreeBSD -.Dt NATD 8 -.Sh NAME -.Nm natd -.Nd -Network Address Translation Daemon -.Sh SYNOPSIS -.Nm -.Op Fl ldsmvu -.Op Fl dynamic -.Op Fl i Ar inport -.Op Fl o Ar outport -.Op Fl p Ar port -.Op Fl a Ar address -.Op Fl n Ar interface -.Op Fl f Ar configfile - -.Nm -.Op Fl log -.Op Fl deny_incoming -.Op Fl log_denied -.Op Fl use_sockets -.Op Fl same_ports -.Op Fl verbose -.Op Fl log_facility Ar facility_name -.Op Fl unregistered_only -.Op Fl dynamic -.Op Fl inport Ar inport -.Op Fl outport Ar outport -.Op Fl port Ar port -.Op Fl alias_address Ar address -.Op Fl interface Ar interface -.Op Fl config Ar configfile -.Op Fl redirect_port Ar linkspec -.Op Fl redirect_address Ar localIP publicIP -.Op Fl reverse -.Op Fl proxy_only -.Op Fl proxy_rule Ar proxyspec -.Op Fl pptpalias Ar localIP - -.Sh DESCRIPTION -This program provides a Network Address Translation facility for use -with -.Xr divert 4 -sockets under FreeBSD. Most of the command line options are available -in a single character short form or in a long form. Use of the long -form is encouraged as it makes things clearer to the casual observer. - -.Pp -.Nm Natd -normally runs in the background as a daemon. It is passed raw IP packets -as they travel into and out of the machine, and will possibly change these -before re-injecting them back into the IP packet stream. - -.Pp -.Nm Natd -changes all packets destined for another host so that their source -IP number is that of the current machine. For each packet changed -in this manner, an internal table entry is created to record this -fact. The source port number is also changed to indicate the -table entry applying to the packet. Packets that are received with -a target IP of the current host are checked against this internal -table. If an entry is found, it is used to determine the correct -target IP number and port to place in the packet. - -.Pp -The following command line options are available. -.Bl -tag -width Fl - -.It Fl log | l -Log various aliasing statistics and information to the file -.Pa /var/log/alias.log . -This file is truncated each time natd is started. - -.It Fl deny_incoming | d -Reject packets destined for the current IP number that have no entry -in the internal translation table. - -.It Fl log_denied -Log denied incoming packets via syslog (see also log_facility) - -.It Fl log_facility Ar facility_name -Use specified log facility when logging information via syslog. -Facility names are as in -.Xr syslog.conf 5 - -.It Fl use_sockets | s -Allocate a -.Xr socket 2 -in order to establish an FTP data or IRC DCC send connection. This -option uses more system resources, but guarantees successful connections -when port numbers conflict. - -.It Fl same_ports | m -Try to keep the same port number when altering outgoing packets. -With this option, protocols such as RPC will have a better chance -of working. If it is not possible to maintain the port number, it -will be silently changed as per normal. - -.It Fl verbose | v -Don't call -.Xr fork 2 -or -.Xr daemon 3 -on startup. Instead, stay attached to the controling terminal and -display all packet alterations to the standard output. This option -should only be used for debugging purposes. - -.It Fl unregistered_only | u -Only alter outgoing packets with an unregistered source address. -According to rfc 1918, unregistered source addresses are 10.0.0.0/8, -172.16.0.0/12 and 192.168.0.0/16. - -.It Fl redirect_port Ar proto targetIP:targetPORT [aliasIP:]aliasPORT [remoteIP[:remotePORT]] -Redirect incoming connections arriving to given port to another host and port. -Proto is either tcp or udp, targetIP is the desired target IP -number, targetPORT is the desired target PORT number, aliasPORT -is the requested PORT number and aliasIP is the aliasing address. -RemoteIP and remotePORT can be used to specify the connection -more accurately if necessary. -For example, the argument - -.Ar tcp inside1:telnet 6666 - -means that tcp packets destined for port 6666 on this machine will -be sent to the telnet port on the inside1 machine. - -.It Fl redirect_address Ar localIP publicIP -Redirect traffic for public IP address to a machine on the local -network. This function is known as "static NAT". Normally static NAT -is useful if your ISP has allocated a small block of IP addresses to you, -but it can even be used in the case of single address: - - redirect_address 10.0.0.8 0.0.0.0 - -The above command would redirect all incoming traffic -to machine 10.0.0.8. - -If several address aliases specify the same public address -as follows - - redirect_address 192.168.0.2 public_addr - redirect_address 192.168.0.3 public_addr - redirect_address 192.168.0.4 public_addr - -the incoming traffic will be directed to the last -translated local address (192.168.0.4), but outgoing -traffic to the first two addresses will still be aliased -to specified public address. - -.It Fl dynamic -If the -.Fl n -or -.Fl interface -option is used, -.Nm -will monitor the routing socket for alterations to the -.Ar interface -passed. If the interfaces IP number is changed, -.Nm -will dynamically alter its concept of the alias address. - -.It Fl i | inport Ar inport -Read from and write to -.Ar inport , -treating all packets as packets coming into the machine. - -.It Fl o | outport Ar outport -Read from and write to -.Ar outport , -treating all packets as packets going out of the machine. - -.It Fl p | port Ar port -Read from and write to -.Ar port , -distinguishing packets as incoming our outgoing using the rules specified in -.Xr divert 4 . -If -.Ar port -is not numeric, it is searched for in the -.Pa /etc/services -database using the -.Xr getservbyname 3 -function. If this flag is not specified, the divert port named natd will -be used as a default. An example entry in the -.Pa /etc/services -database would be: - - natd 8668/divert # Network Address Translation socket - -Refer to -.Xr services 5 -for further details. - -.It Fl a | alias_address Ar address -Use -.Ar address -as the alias address. If this option is not specified, the -.Fl n -or -.Fl interface -option must be used. The specified address should be the address assigned -to the public network interface. -.Pp -All data passing out through this addresses interface will be rewritten -with a source address equal to -.Ar address . -All data arriving at the interface from outside will be checked to -see if it matches any already-aliased outgoing connection. If it does, -the packet is altered accordingly. If not, all -.Fl redirect_port -and -.Fl redirect_address -assignments are checked and actioned. If no other action can be made, -and if -.Fl deny_incoming -is not specified, the packet is delivered to the local machine and port -as specified in the packet. - -.It Fl n | interface Ar interface -Use -.Ar interface -to determine the alias address. If there is a possibility that the -IP number associated with -.Ar interface -may change, the -.Fl dynamic -flag should also be used. If this option is not specified, the -.Fl a -or -.Fl alias_address -flag must be used. -.Pp -The specified -.Ar interface -must be the public network interface. -.It Fl f | config Ar configfile -Read configuration from -.Ar configfile . -.Ar Configfile -contains a list of options, one per line in the same form as the -long form of the above command line flags. For example, the line - - alias_address 158.152.17.1 - -would specify an alias address of 158.152.17.1. Options that don't -take an argument are specified with an option of -.Ar yes -or -.Ar no -in the configuration file. For example, the line - - log yes - -is synonomous with -.Fl log . -Empty lines and lines beginning with '#' are ignored. - -.It Fl reverse -Reverse operation of natd. This can be useful in some -transparent proxying situations when outgoing traffic -is redirected to the local machine and natd is running on the -incoming interface (it usually runs on the outgoing interface). - -.It Fl proxy_only -Force natd to perform transparent proxying -only. Normal address translation is not performed. - -.It Fl proxy_rule Ar [type encode_ip_hdr|encode_tcp_stream] port xxxx server a.b.c.d:yyyy -Enable transparent proxying. Packets with the given port going through this -host to any other host are redirected to the given server and port. -Optionally, the original target address can be encoded into the packet. Use -.Dq encode_ip_hdr -to put this information into the IP option field or -.Dq encode_tcp_stream -to inject the data into the beginning of the TCP stream. - -.It Fl pptpalias Ar localIP -Allow PPTP packets to go to the defined localIP address. PPTP is a VPN or secure -IP tunneling technology being developed primarily by Microsoft. For its encrypted traffic, -it uses an old IP encapsulation protocol called GRE (47). This -natd option will translate any traffic of this protocol to a -single, specified IP address. This would allow either one client or one server -to be serviced with natd. If you are setting up a server, don't forget to allow the TCP traffic -for the PPTP setup. For a client or server, you must allow GRE (protocol 47) if you have firewall lists active. - -.El - -.Sh RUNNING NATD -The following steps are necessary before attempting to run -.Nm natd : - -.Bl -enum -.It -Get FreeBSD version 2.2 or higher. Versions before this do not support -.Xr divert 4 -sockets. - -.It -Build a custom kernel with the following options: - - options IPFIREWALL - options IPDIVERT - -Refer to the handbook for detailed instructions on building a custom -kernel. - -.It -Ensure that your machine is acting as a gateway. This can be done by -specifying the line - - gateway_enable=YES - -in -.Pa /etc/rc.conf , -or using the command - - sysctl -w net.inet.ip.forwarding=1 - -.It -If you wish to use the -.Fl n -or -.Fl interface -flags, make sure that your interface is already configured. If, for -example, you wish to specify tun0 as your -.Ar interface , -and you're using -.Xr ppp 8 -on that interface, you must make sure that you start -.Nm ppp -prior to starting -.Nm natd . - -.It -Create an entry in -.Pa /etc/services : - - natd 8668/divert # Network Address Translation socket - -This gives a default for the -.Fl p -or -.Fl port -flag. - -.El -.Pp -Running -.Nm -is fairly straight forward. The line - - natd -interface ed0 - -should suffice in most cases (substituting the correct interface name). Once -.Nm -is running, you must ensure that traffic is diverted to natd: - -.Bl -enum -.It -You will need to adjust the -.Pa /etc/rc.firewall -script to taste. If you're not interested in having a firewall, the -following lines will do: - - /sbin/ipfw -f flush - /sbin/ipfw add divert natd all from any to any via ed0 - /sbin/ipfw add pass all from any to any - -The second line depends on your interface (change ed0 as appropriate) -and assumes that you've updated -.Pa /etc/services -with the natd entry as above. If you specify real firewall rules, it's -best to specify line 2 at the start of the script so that -.Nm -sees all packets before they are dropped by the firewall. The firewall -rules will be run again on each packet after translation by -.Nm natd , -minus any divert rules. - -.It -Enable your firewall by setting - - firewall_enable=YES - -in -.Pa /etc/rc.conf . -This tells the system startup scripts to run the -.Pa /etc/rc.firewall -script. If you don't wish to reboot now, just run this by hand from the -console. NEVER run this from a virtual session unless you put it into -the background. If you do, you'll lock yourself out after the flush -takes place, and execution of -.Pa /etc/rc.firewall -will stop at this point - blocking all accesses permanently. Running -the script in the background should be enough to prevent this disaster. - -.El - -.Sh SEE ALSO -.Xr getservbyname 2 , -.Xr socket 2 , -.Xr divert 4 , -.Xr services 5 , -.Xr ipfw 8 - -.Sh AUTHORS -This program is the result of the efforts of many people at different -times: - -.An Archie Cobbs Aq archie@whistle.com -(divert sockets) -.An Charles Mott Aq cmott@srv.net -(packet aliasing) -.An Eivind Eklund Aq perhaps@yes.no -(IRC support & misc additions) -.An Ari Suutari Aq suutari@iki.fi -(natd) -.An Dru Nelson Aq dnelson@redwoodsoft.com -(PPTP support) -.An Brian Somers Aq brian@awfulhak.org -(glue) diff --git a/usr.sbin/natd/natd.c b/usr.sbin/natd/natd.c deleted file mode 100644 index 5dab03e..0000000 --- a/usr.sbin/natd/natd.c +++ /dev/null @@ -1,1477 +0,0 @@ -/* - * natd - Network Address Translation Daemon for FreeBSD. - * - * This software is provided free of charge, with no - * warranty of any kind, either expressed or implied. - * Use at your own risk. - * - * You may copy, modify and distribute this software (natd.c) freely. - * - * Ari Suutari <suutari@iki.fi> - * - * $Id: natd.c,v 1.10 1999/03/07 18:23:56 brian Exp $ - */ - -#define SYSLOG_NAMES - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <machine/in_cksum.h> -#include <netinet/tcp.h> -#include <netinet/udp.h> -#include <netinet/ip_icmp.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include <net/route.h> -#include <arpa/inet.h> - -#include <alias.h> -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <netdb.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> - -#include "natd.h" - -/* - * Default values for input and output - * divert socket ports. - */ - -#define DEFAULT_SERVICE "natd" - -/* - * Function prototypes. - */ - -static void DoAliasing (int fd, int direction); -static void DaemonMode (); -static void HandleRoutingInfo (int fd); -static void Usage (); -static char* FormatPacket (struct ip*); -static void PrintPacket (struct ip*); -static void SyslogPacket (struct ip*, int priority, char *label); -static void SetAliasAddressFromIfName (char* ifName); -static void InitiateShutdown (); -static void Shutdown (); -static void RefreshAddr (); -static void ParseOption (char* option, char* parms, int cmdLine); -static void ReadConfigFile (char* fileName); -static void SetupPortRedirect (char* parms); -static void SetupAddressRedirect (char* parms); -static void SetupPptpAlias (char* parms); -static void StrToAddr (char* str, struct in_addr* addr); -static u_short StrToPort (char* str, char* proto); -static int StrToProto (char* str); -static u_short 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 u_short inPort; -static u_short outPort; -static u_short 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; -static int packetDirection; -static int dropIgnoredIncoming; -static int logDropped; -static int logFacility; - -int main (int argc, char** argv) -{ - int divertIn; - int divertOut; - int divertInOut; - 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. - */ - PacketAliasInit (); -/* - * Parse options. - */ - inPort = 0; - outPort = 0; - verbose = 0; - inOutPort = 0; - ifName = NULL; - ifMTU = -1; - background = 0; - running = 1; - assignAliasAddr = 0; - aliasAddr.s_addr = INADDR_NONE; - aliasOverhead = 12; - dynamicMode = 0; - logDropped = 0; - logFacility = LOG_DAEMON; -/* - * Mark packet buffer empty. - */ - packetSock = -1; - packetDirection = DONT_KNOW; - - ParseArgs (argc, argv); -/* - * Open syslog channel. - */ - openlog ("natd", LOG_CONS | LOG_PID, logFacility); -/* - * Check that valid aliasing address has been given. - */ - if (aliasAddr.s_addr == INADDR_NONE && ifName == NULL) - errx (1, "aliasing address not given"); - - if (aliasAddr.s_addr != INADDR_NONE && ifName != NULL) - errx (1, "both alias address and interface " - "name are not allowed"); -/* - * Check that valid port number is known. - */ - if (inPort != 0 || outPort != 0) - if (inPort == 0 || outPort == 0) - errx (1, "both input and output ports are required"); - - if (inPort == 0 && outPort == 0 && inOutPort == 0) - ParseOption ("port", DEFAULT_SERVICE, 0); - -/* - * Check if ignored packets should be dropped. - */ - dropIgnoredIncoming = PacketAliasSetMode (0, 0); - dropIgnoredIncoming &= PKT_ALIAS_DENY_INCOMING; -/* - * Create divert sockets. Use only one socket if -p was specified - * on command line. Otherwise, create separate sockets for - * outgoing and incoming connnections. - */ - if (inOutPort) { - - divertInOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); - if (divertInOut == -1) - Quit ("Unable to create divert socket."); - - divertIn = -1; - divertOut = -1; -/* - * Bind socket. - */ - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = inOutPort; - - if (bind (divertInOut, - (struct sockaddr*) &addr, - sizeof addr) == -1) - Quit ("Unable to bind divert socket."); - } - else { - - divertIn = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); - if (divertIn == -1) - Quit ("Unable to create incoming divert socket."); - - divertOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); - if (divertOut == -1) - Quit ("Unable to create outgoing divert socket."); - - divertInOut = -1; - -/* - * Bind divert sockets. - */ - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = inPort; - - if (bind (divertIn, - (struct sockaddr*) &addr, - sizeof addr) == -1) - Quit ("Unable to bind incoming divert socket."); - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = outPort; - - if (bind (divertOut, - (struct sockaddr*) &addr, - sizeof addr) == -1) - Quit ("Unable to bind outgoing divert socket."); - } -/* - * Create routing socket if interface name specified. - */ - if (ifName && dynamicMode) { - - routeSock = socket (PF_ROUTE, SOCK_RAW, 0); - if (routeSock == -1) - Quit ("Unable to create routing info socket."); - } - else - routeSock = -1; -/* - * Create socket for sending ICMP messages. - */ - icmpSock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (icmpSock == -1) - Quit ("Unable to create ICMP socket."); -/* - * Become a daemon unless verbose mode was requested. - */ - if (!verbose) - DaemonMode (); -/* - * Catch signals to manage shutdown and - * refresh of interface address. - */ - signal (SIGTERM, InitiateShutdown); - signal (SIGHUP, RefreshAddr); -/* - * Set alias address if it has been given. - */ - if (aliasAddr.s_addr != INADDR_NONE) - PacketAliasSetAddress (aliasAddr); -/* - * We need largest descriptor number for select. - */ - - fdMax = -1; - - if (divertIn > fdMax) - fdMax = divertIn; - - if (divertOut > fdMax) - fdMax = divertOut; - - if (divertInOut > fdMax) - fdMax = divertInOut; - - if (routeSock > fdMax) - fdMax = routeSock; - - while (running) { - - if (divertInOut != -1 && !ifName && packetSock == -1) { -/* - * When using only one socket, just call - * DoAliasing repeatedly to process packets. - */ - DoAliasing (divertInOut, DONT_KNOW); - continue; - } -/* - * Build read mask from socket descriptors to select. - */ - 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); - - if (divertOut != -1) - FD_SET (divertOut, &readMask); - - if (divertInOut != -1) - FD_SET (divertInOut, &readMask); - } -/* - * 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, INPUT); - - if (divertOut != -1) - if (FD_ISSET (divertOut, &readMask)) - DoAliasing (divertOut, OUTPUT); - - if (divertInOut != -1) - if (FD_ISSET (divertInOut, &readMask)) - DoAliasing (divertInOut, DONT_KNOW); - - if (routeSock != -1) - if (FD_ISSET (routeSock, &readMask)) - HandleRoutingInfo (routeSock); - } - - if (background) - unlink (PIDFILE); - - return 0; -} - -static void DaemonMode () -{ - FILE* pidFile; - - daemon (0, 0); - background = 1; - - pidFile = fopen (PIDFILE, "w"); - if (pidFile) { - - fprintf (pidFile, "%d\n", getpid ()); - fclose (pidFile); - } -} - -static void ParseArgs (int argc, char** argv) -{ - int arg; - char* parm; - char* opt; - char parmBuf[256]; - - for (arg = 1; arg < argc; arg++) { - - opt = argv[arg]; - if (*opt != '-') { - - warnx ("invalid option %s", opt); - Usage (); - } - - parm = NULL; - parmBuf[0] = '\0'; - - while (arg < argc - 1) { - - if (argv[arg + 1][0] == '-') - break; - - if (parm) - strcat (parmBuf, " "); - - ++arg; - parm = parmBuf; - strcat (parmBuf, argv[arg]); - } - - ParseOption (opt + 1, parm, 1); - } -} - -static void DoAliasing (int fd, int direction) -{ - int bytes; - int origBytes; - int status; - int addrSize; - struct ip* ip; - - if (assignAliasAddr) { - - SetAliasAddressFromIfName (ifName); - assignAliasAddr = 0; - } -/* - * Get packet from socket. - */ - addrSize = sizeof packetAddr; - origBytes = recvfrom (fd, - packetBuf, - sizeof packetBuf, - 0, - (struct sockaddr*) &packetAddr, - &addrSize); - - if (origBytes == -1) { - - if (errno != EINTR) - Warn ("read from divert socket failed"); - - return; - } -/* - * This is a IP packet. - */ - ip = (struct ip*) packetBuf; - if (direction == DONT_KNOW) - if (packetAddr.sin_addr.s_addr == INADDR_ANY) - direction = OUTPUT; - else - direction = INPUT; - - if (verbose) { - -/* - * Print packet direction and protocol type. - */ - printf (direction == OUTPUT ? "Out " : "In "); - - switch (ip->ip_p) { - case IPPROTO_TCP: - printf ("[TCP] "); - break; - - case IPPROTO_UDP: - printf ("[UDP] "); - break; - - case IPPROTO_ICMP: - printf ("[ICMP] "); - break; - - default: - printf ("[%d] ", ip->ip_p); - break; - } -/* - * Print addresses. - */ - PrintPacket (ip); - } - - if (direction == OUTPUT) { -/* - * Outgoing packets. Do aliasing. - */ - PacketAliasOut (packetBuf, IP_MAXPACKET); - } - else { - -/* - * Do aliasing. - */ - status = PacketAliasIn (packetBuf, IP_MAXPACKET); - if (status == PKT_ALIAS_IGNORED && - dropIgnoredIncoming) { - - if (verbose) - printf (" dropped.\n"); - - if (logDropped) - SyslogPacket (ip, LOG_WARNING, "denied"); - - return; - } - } -/* - * Length might have changed during aliasing. - */ - bytes = ntohs (ip->ip_len); -/* - * Update alias overhead size for outgoing packets. - */ - if (direction == OUTPUT && - bytes - origBytes > aliasOverhead) - aliasOverhead = bytes - origBytes; - - if (verbose) { - -/* - * Print addresses after aliasing. - */ - printf (" aliased to\n"); - printf (" "); - PrintPacket (ip); - printf ("\n"); - } - - packetLen = bytes; - packetSock = fd; - packetDirection = direction; - - FlushPacketBuffer (fd); -} - -static void FlushPacketBuffer (int fd) -{ - int wrote; - char msgBuf[80]; -/* - * Put packet back for processing. - */ - wrote = sendto (fd, - packetBuf, - packetLen, - 0, - (struct sockaddr*) &packetAddr, - sizeof packetAddr); - - 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 (packetDirection == OUTPUT && - ifMTU != -1) - SendNeedFragIcmp (icmpSock, - (struct ip*) packetBuf, - ifMTU - aliasOverhead); - } - else { - - sprintf (msgBuf, "failed to write packet back"); - Warn (msgBuf); - } - } - - packetSock = -1; -} - -static void HandleRoutingInfo (int fd) -{ - int bytes; - struct if_msghdr ifMsg; -/* - * Get packet from socket. - */ - bytes = read (fd, &ifMsg, sizeof ifMsg); - if (bytes == -1) { - - Warn ("read from routing socket failed"); - return; - } - - if (ifMsg.ifm_version != RTM_VERSION) { - - Warn ("unexpected packet read from routing socket"); - return; - } - - if (verbose) - printf ("Routing message %X received.\n", ifMsg.ifm_type); - - if (ifMsg.ifm_type != RTM_NEWADDR) - return; - - if (verbose && ifMsg.ifm_index == ifIndex) - printf ("Interface address has changed.\n"); - - if (ifMsg.ifm_index == ifIndex) - assignAliasAddr = 1; -} - -static void PrintPacket (struct ip* ip) -{ - printf ("%s", FormatPacket (ip)); -} - -static void SyslogPacket (struct ip* ip, int priority, char *label) -{ - syslog (priority, "%s %s", label, FormatPacket (ip)); -} - -static char* FormatPacket (struct ip* ip) -{ - static char buf[256]; - struct tcphdr* tcphdr; - struct udphdr* udphdr; - struct icmp* icmphdr; - char src[20]; - char dst[20]; - - strcpy (src, inet_ntoa (ip->ip_src)); - strcpy (dst, inet_ntoa (ip->ip_dst)); - - switch (ip->ip_p) { - case IPPROTO_TCP: - tcphdr = (struct tcphdr*) ((char*) ip + (ip->ip_hl << 2)); - sprintf (buf, "[TCP] %s:%d -> %s:%d", - src, - ntohs (tcphdr->th_sport), - dst, - ntohs (tcphdr->th_dport)); - break; - - case IPPROTO_UDP: - udphdr = (struct udphdr*) ((char*) ip + (ip->ip_hl << 2)); - sprintf (buf, "[UDP] %s:%d -> %s:%d", - src, - ntohs (udphdr->uh_sport), - dst, - ntohs (udphdr->uh_dport)); - break; - - case IPPROTO_ICMP: - icmphdr = (struct icmp*) ((char*) ip + (ip->ip_hl << 2)); - sprintf (buf, "[ICMP] %s -> %s %u(%u)", - src, - dst, - icmphdr->icmp_type, - icmphdr->icmp_code); - break; - - default: - sprintf (buf, "[%d] %s -> %s ", ip->ip_p, src, dst); - break; - } - - return buf; -} - -static void SetAliasAddressFromIfName (char* ifName) -{ - struct ifconf cf; - struct ifreq buf[32]; - char msg[80]; - struct ifreq* ifPtr; - int extra; - int helperSock; - int bytes; - struct sockaddr_in* addr; - int found; - struct ifreq req; - char last[10]; -/* - * Create a dummy socket to access interface information. - */ - helperSock = socket (AF_INET, SOCK_DGRAM, 0); - if (helperSock == -1) { - - Quit ("Failed to create helper socket."); - exit (1); - } - - cf.ifc_len = sizeof (buf); - cf.ifc_req = buf; -/* - * Get interface data. - */ - if (ioctl (helperSock, SIOCGIFCONF, &cf) == -1) { - - Quit ("Ioctl SIOCGIFCONF failed."); - exit (1); - } - - ifIndex = 0; - ifPtr = buf; - bytes = cf.ifc_len; - found = 0; - last[0] = '\0'; -/* - * Loop through interfaces until one with - * given name is found. This is done to - * find correct interface index for routing - * message processing. - */ - while (bytes) { - - if (ifPtr->ifr_addr.sa_family == AF_INET && - !strcmp (ifPtr->ifr_name, ifName)) { - - found = 1; - break; - } - - if (strcmp (last, ifPtr->ifr_name)) { - - strcpy (last, ifPtr->ifr_name); - ++ifIndex; - } - - extra = ifPtr->ifr_addr.sa_len - sizeof (struct sockaddr); - - ifPtr++; - ifPtr = (struct ifreq*) ((char*) ifPtr + extra); - bytes -= sizeof (struct ifreq) + extra; - } - - if (!found) { - - close (helperSock); - sprintf (msg, "Unknown interface name %s.\n", ifName); - Quit (msg); - } -/* - * Get MTU size. - */ - strcpy (req.ifr_name, ifName); - - if (ioctl (helperSock, SIOCGIFMTU, &req) == -1) - Quit ("Cannot get interface mtu size."); - - ifMTU = req.ifr_mtu; -/* - * Get interface address. - */ - if (ioctl (helperSock, SIOCGIFADDR, &req) == -1) - Quit ("Cannot get interface address."); - - addr = (struct sockaddr_in*) &req.ifr_addr; - PacketAliasSetAddress (addr->sin_addr); - syslog (LOG_INFO, "Aliasing to %s, mtu %d bytes", - inet_ntoa (addr->sin_addr), - ifMTU); - - close (helperSock); -} - -void Quit (char* msg) -{ - Warn (msg); - exit (1); -} - -void Warn (char* msg) -{ - if (background) - syslog (LOG_ALERT, "%s (%m)", msg); - else - warn (msg); -} - -static void RefreshAddr () -{ - signal (SIGHUP, RefreshAddr); - if (ifName) - assignAliasAddr = 1; -} - -static void InitiateShutdown () -{ -/* - * Start timer to allow kernel gracefully - * shutdown existing connections when system - * is shut down. - */ - signal (SIGALRM, Shutdown); - alarm (10); -} - -static void Shutdown () -{ - running = 0; -} - -/* - * Different options recognized by this program. - */ - -enum Option { - - PacketAliasOption, - Verbose, - InPort, - OutPort, - Port, - AliasAddress, - InterfaceName, - RedirectPort, - RedirectAddress, - ConfigFile, - DynamicMode, - PptpAlias, - ProxyRule, - LogDenied, - LogFacility -}; - -enum Param { - - YesNo, - Numeric, - String, - None, - Address, - Service -}; - -/* - * Option information structure (used by ParseOption). - */ - -struct OptionInfo { - - enum Option type; - int packetAliasOpt; - enum Param parm; - char* parmDescription; - char* description; - char* name; - char* shortName; -}; - -/* - * Table of known options. - */ - -static struct OptionInfo optionTable[] = { - - { PacketAliasOption, - PKT_ALIAS_UNREGISTERED_ONLY, - YesNo, - "[yes|no]", - "alias only unregistered addresses", - "unregistered_only", - "u" }, - - { PacketAliasOption, - PKT_ALIAS_LOG, - YesNo, - "[yes|no]", - "enable logging", - "log", - "l" }, - - { PacketAliasOption, - PKT_ALIAS_PROXY_ONLY, - YesNo, - "[yes|no]", - "proxy only", - "proxy_only", - NULL }, - - { PacketAliasOption, - PKT_ALIAS_REVERSE, - YesNo, - "[yes|no]", - "operate in reverse mode", - "reverse", - NULL }, - - { PacketAliasOption, - PKT_ALIAS_DENY_INCOMING, - YesNo, - "[yes|no]", - "allow incoming connections", - "deny_incoming", - "d" }, - - { PacketAliasOption, - PKT_ALIAS_USE_SOCKETS, - YesNo, - "[yes|no]", - "use sockets to inhibit port conflict", - "use_sockets", - "s" }, - - { PacketAliasOption, - PKT_ALIAS_SAME_PORTS, - YesNo, - "[yes|no]", - "try to keep original port numbers for connections", - "same_ports", - "m" }, - - { Verbose, - 0, - YesNo, - "[yes|no]", - "verbose mode, dump packet information", - "verbose", - "v" }, - - { DynamicMode, - 0, - YesNo, - "[yes|no]", - "dynamic mode, automatically detect interface address changes", - "dynamic", - NULL }, - - { InPort, - 0, - Service, - "number|service_name", - "set port for incoming packets", - "in_port", - "i" }, - - { OutPort, - 0, - Service, - "number|service_name", - "set port for outgoing packets", - "out_port", - "o" }, - - { Port, - 0, - Service, - "number|service_name", - "set port (defaults to natd/divert)", - "port", - "p" }, - - { AliasAddress, - 0, - Address, - "x.x.x.x", - "address to use for aliasing", - "alias_address", - "a" }, - - { InterfaceName, - 0, - String, - "network_if_name", - "take aliasing address from interface", - "interface", - "n" }, - - { ProxyRule, - 0, - String, - "[type encode_ip_hdr|encode_tcp_stream] port xxxx server " - "a.b.c.d:yyyy", - "add transparent proxying / destination NAT", - "proxy_rule", - NULL }, - - { RedirectPort, - 0, - String, - "tcp|udp local_addr:local_port [public_addr:]public_port" - " [remote_addr[:remote_port]]", - "redirect a port for incoming traffic", - "redirect_port", - NULL }, - - { RedirectAddress, - 0, - String, - "local_addr public_addr", - "define mapping between local and public addresses", - "redirect_address", - NULL }, - - { PptpAlias, - 0, - String, - "src", - "define inside machine for PPTP traffic", - "pptpalias", - NULL }, - - { ConfigFile, - 0, - String, - "file_name", - "read options from configuration file", - "config", - "f" }, - - { LogDenied, - 0, - YesNo, - "[yes|no]", - "enable logging of denied incoming packets", - "log_denied", - NULL }, - - { LogFacility, - 0, - String, - "facility", - "name of syslog facility to use for logging", - "log_facility", - NULL } - -}; - -static void ParseOption (char* option, char* parms, int cmdLine) -{ - int i; - struct OptionInfo* info; - int yesNoValue; - int aliasValue; - int numValue; - u_short uNumValue; - char* strValue; - struct in_addr addrValue; - int max; - char* end; - CODE* fac_record = NULL; -/* - * Find option from table. - */ - max = sizeof (optionTable) / sizeof (struct OptionInfo); - for (i = 0, info = optionTable; i < max; i++, info++) { - - if (!strcmp (info->name, option)) - break; - - if (info->shortName) - if (!strcmp (info->shortName, option)) - break; - } - - if (i >= max) { - - warnx ("unknown option %s", option); - Usage (); - } - - uNumValue = 0; - yesNoValue = 0; - numValue = 0; - strValue = NULL; -/* - * Check parameters. - */ - switch (info->parm) { - case YesNo: - if (!parms) - parms = "yes"; - - if (!strcmp (parms, "yes")) - yesNoValue = 1; - else - if (!strcmp (parms, "no")) - yesNoValue = 0; - else - errx (1, "%s needs yes/no parameter", option); - break; - - case Service: - if (!parms) - errx (1, "%s needs service name or " - "port number parameter", - option); - - uNumValue = StrToPort (parms, "divert"); - break; - - case Numeric: - if (parms) - numValue = strtol (parms, &end, 10); - else - end = parms; - - if (end == parms) - errx (1, "%s needs numeric parameter", option); - break; - - case String: - strValue = parms; - if (!strValue) - errx (1, "%s needs parameter", option); - break; - - case None: - if (parms) - errx (1, "%s does not take parameters", option); - break; - - case Address: - if (!parms) - errx (1, "%s needs address/host parameter", option); - - StrToAddr (parms, &addrValue); - break; - } - - switch (info->type) { - case PacketAliasOption: - - aliasValue = yesNoValue ? info->packetAliasOpt : 0; - PacketAliasSetMode (aliasValue, info->packetAliasOpt); - break; - - case Verbose: - verbose = yesNoValue; - break; - - case DynamicMode: - dynamicMode = yesNoValue; - break; - - case InPort: - inPort = uNumValue; - break; - - case OutPort: - outPort = uNumValue; - break; - - case Port: - inOutPort = uNumValue; - break; - - case AliasAddress: - memcpy (&aliasAddr, &addrValue, sizeof (struct in_addr)); - break; - - case RedirectPort: - SetupPortRedirect (strValue); - break; - - case RedirectAddress: - SetupAddressRedirect (strValue); - break; - - case PptpAlias: - SetupPptpAlias (strValue); - break; - - case ProxyRule: - PacketAliasProxyRule (strValue); - break; - - case InterfaceName: - if (ifName) - free (ifName); - - ifName = strdup (strValue); - assignAliasAddr = 1; - break; - - case ConfigFile: - ReadConfigFile (strValue); - break; - - case LogDenied: - logDropped = 1; - break; - - case LogFacility: - - fac_record = facilitynames; - while (fac_record->c_name != NULL) { - - if (!strcmp (fac_record->c_name, strValue)) { - - logFacility = fac_record->c_val; - break; - - } - else - fac_record++; - } - - if(fac_record->c_name == NULL) - errx(1, "Unknown log facility name: %s", strValue); - - break; - } -} - -void ReadConfigFile (char* fileName) -{ - FILE* file; - char buf[128]; - char* ptr; - char* option; - - file = fopen (fileName, "r"); - if (!file) { - - sprintf (buf, "Cannot open config file %s.\n", fileName); - Quit (buf); - } - - while (fgets (buf, sizeof (buf), file)) { - - ptr = strchr (buf, '\n'); - if (!ptr) - errx (1, "config line too long: %s", buf); - - *ptr = '\0'; - if (buf[0] == '#') - continue; - - ptr = buf; -/* - * Skip white space at beginning of line. - */ - while (*ptr && isspace (*ptr)) - ++ptr; - - if (*ptr == '\0') - continue; -/* - * Extract option name. - */ - option = ptr; - while (*ptr && !isspace (*ptr)) - ++ptr; - - if (*ptr != '\0') { - - *ptr = '\0'; - ++ptr; - } -/* - * Skip white space between name and parms. - */ - while (*ptr && isspace (*ptr)) - ++ptr; - - ParseOption (option, *ptr ? ptr : NULL, 0); - } - - fclose (file); -} - -static void Usage () -{ - int i; - int max; - struct OptionInfo* info; - - fprintf (stderr, "Recognized options:\n\n"); - - max = sizeof (optionTable) / sizeof (struct OptionInfo); - for (i = 0, info = optionTable; i < max; i++, info++) { - - fprintf (stderr, "-%-20s %s\n", info->name, - info->parmDescription); - - if (info->shortName) - fprintf (stderr, "-%-20s %s\n", info->shortName, - info->parmDescription); - - fprintf (stderr, " %s\n\n", info->description); - } - - exit (1); -} - -void SetupPptpAlias (char* parms) -{ - char buf[128]; - char* ptr; - struct in_addr srcAddr; - - strcpy (buf, parms); - -/* - * Extract source address. - */ - ptr = strtok (buf, " \t"); - if (!ptr) - errx(1, "pptpalias: missing src address"); - - StrToAddr (ptr, &srcAddr); - PacketAliasPptp (srcAddr); -} - -void SetupPortRedirect (char* parms) -{ - char buf[128]; - char* ptr; - struct in_addr localAddr; - struct in_addr publicAddr; - struct in_addr remoteAddr; - u_short localPort; - u_short publicPort; - u_short remotePort; - int proto; - char* protoName; - char* separator; - - strcpy (buf, parms); -/* - * Extract protocol. - */ - protoName = strtok (buf, " \t"); - if (!protoName) - errx (1, "redirect_port: missing protocol"); - - proto = StrToProto (protoName); -/* - * Extract local address. - */ - ptr = strtok (NULL, " \t"); - if (!ptr) - errx (1, "redirect_port: missing local address"); - - localPort = StrToAddrAndPort (ptr, &localAddr, protoName); -/* - * Extract public port and optinally address. - */ - ptr = strtok (NULL, " \t"); - if (!ptr) - errx (1, "redirect_port: missing public port"); - - separator = strchr (ptr, ':'); - if (separator) - publicPort = StrToAddrAndPort (ptr, &publicAddr, protoName); - else { - - publicAddr.s_addr = INADDR_ANY; - publicPort = StrToPort (ptr, protoName); - } - -/* - * Extract remote address and optionally port. - */ - ptr = strtok (NULL, " \t"); - if (ptr) { - - - separator = strchr (ptr, ':'); - if (separator) - remotePort = StrToAddrAndPort (ptr, - &remoteAddr, - protoName); - else { - - remotePort = 0; - StrToAddr (ptr, &remoteAddr); - } - } - else { - - remotePort = 0; - remoteAddr.s_addr = INADDR_ANY; - } - - PacketAliasRedirectPort (localAddr, - localPort, - remoteAddr, - remotePort, - publicAddr, - publicPort, - proto); -} - -void SetupAddressRedirect (char* parms) -{ - char buf[128]; - char* ptr; - struct in_addr localAddr; - struct in_addr publicAddr; - - strcpy (buf, parms); -/* - * Extract local address. - */ - ptr = strtok (buf, " \t"); - if (!ptr) - errx (1, "redirect_address: missing local address"); - - StrToAddr (ptr, &localAddr); -/* - * Extract public address. - */ - ptr = strtok (NULL, " \t"); - if (!ptr) - errx (1, "redirect_address: missing public address"); - - StrToAddr (ptr, &publicAddr); - PacketAliasRedirectAddr (localAddr, publicAddr); -} - -void StrToAddr (char* str, struct in_addr* addr) -{ - struct hostent* hp; - - if (inet_aton (str, addr)) - return; - - hp = gethostbyname (str); - if (!hp) - errx (1, "unknown host %s", str); - - memcpy (addr, hp->h_addr, sizeof (struct in_addr)); -} - -u_short StrToPort (char* str, char* proto) -{ - u_short port; - struct servent* sp; - char* end; - - port = strtol (str, &end, 10); - if (end != str) - return htons (port); - - sp = getservbyname (str, proto); - if (!sp) - errx (1, "unknown service %s/%s", str, proto); - - return sp->s_port; -} - -int StrToProto (char* str) -{ - if (!strcmp (str, "tcp")) - return IPPROTO_TCP; - - if (!strcmp (str, "udp")) - return IPPROTO_UDP; - - errx (1, "unknown protocol %s. Expected tcp or udp", str); -} - -u_short StrToAddrAndPort (char* str, struct in_addr* addr, char* proto) -{ - char* ptr; - - ptr = strchr (str, ':'); - if (!ptr) - errx (1, "%s is missing port number", str); - - *ptr = '\0'; - ++ptr; - - StrToAddr (str, addr); - return StrToPort (ptr, proto); -} - diff --git a/usr.sbin/natd/natd.h b/usr.sbin/natd/natd.h deleted file mode 100644 index b45048e..0000000 --- a/usr.sbin/natd/natd.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * natd - Network Address Translation Daemon for FreeBSD. - * - * This software is provided free of charge, with no - * warranty of any kind, either expressed or implied. - * Use at your own risk. - * - * You may copy, modify and distribute this software (natd.h) freely. - * - * Ari Suutari <suutari@iki.fi> - * - * $Id:$ - */ - -#define PIDFILE "/var/run/natd.pid" -#define INPUT 1 -#define OUTPUT 2 -#define DONT_KNOW 3 - -extern void Quit (char* msg); -extern void Warn (char* msg); -extern int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu); - - diff --git a/usr.sbin/natd/samples/natd.cf.sample b/usr.sbin/natd/samples/natd.cf.sample deleted file mode 100644 index df1018b..0000000 --- a/usr.sbin/natd/samples/natd.cf.sample +++ /dev/null @@ -1,94 +0,0 @@ -# -# $Id:$ -# -# -# Configuration file for natd. -# -# -# Enable logging to file /var/log/alias.log -# -log no -# -# Incoming connections. Should NEVER be set to "yes" if redirect_port, -# redirect_address, or permanent_link statements are activated in this file! -# -# Setting to yes provides additional anti-crack protection -# -deny_incoming no -# -# Use sockets to avoid port clashes. Uses additional system resources, but -# guarantees successful connections when port numbers conflict -# -use_sockets no -# -# Avoid port changes if possible when altering outbound packets. Makes rlogin -# work in most cases. -# -same_port yes -# -# Verbose mode. Enables dumping of packets and disables -# forking to background. Only set to yes for debugging. -# -verbose no -# -# Divert port. Can be a name in /etc/services or numeric value. -# -port 32000 -# -# Interface name or address being aliased. Either one, -# not both is required. -# -# Obtain interface name from the command output of "ifconfig -a" -# -# alias_address 192.168.0.1 -interface ep0 -# -# Alias unregistered addresses or all addresses. Set this to yes if -# the inside network is all RFC1918 addresses. -# -unregistered_only no -# -# Configure permanent links. If you use host names instead -# of addresses here, be sure that name server works BEFORE -# natd is up - this is usually not the case. So either use -# numeric addresses or hosts that are in /etc/hosts. -# -# Note: Current versions of FreeBSD all call /etc/rc.firewall -# BEFORE running named, so if the DNS server and NAT are on the same -# machine, the nameserver won't be up if natd is called from /etc/rc.firewall -# -# Map connections coming to port 30000 to telnet in my_private_host. -# Remember to allow the connection /etc/rc.firewall also. -# -# The following permanent_link and redirect_port statements are equivalent -#permanent_link tcp my_private_host:telnet 0.0.0.0:0 30000 -#redirect_port tcp my_private_host:telnet 30000 -# -# Map connections coming from host.xyz.com to port 30001 to -# telnet in another_host. -#permanent_link tcp another_host:telnet host.xyz.com:0 30001 -# -# Static NAT address mapping: -# -# ipconfig must apply any legal IP numbers that inside hosts -# will be known by to the outside interface. These are sometimes known as -# virtual IP numbers. It's suggested to use the "interface" directive -# instead of the "alias_address" directive to make it more clear what is -# going on. (although both will work) -# -# DNS in this situation can get hairy. For example, an inside host -# named aweb.company.com is located at 192.168.1.56, and needs to be -# accessible through a legal IP number like 198.105.232.1. If both -# 192.168.1.56 and 198.105.232.1 are set up as address records in the DNS -# for aweb.company.com, then external hosts attempting to access -# aweb.company.com may use address 192.168.1.56 which is inaccessible to them. -# -# The obvious solution is to use only a single address for the name, the -# outside address. However, this creates needless traffic through the -# NAT, because inside hosts will go through the NAT to get to the legal -# number, even when the inside number is on the same subnet as they are! -# -# It's probably not a good idea to use DNS names in redirect_address statements -# -#The following mapping points outside address 198.105.232.1 to 192.168.1.56 -#redirect_address 192.168.1.56 198.105.232.1 diff --git a/usr.sbin/natd/samples/natd.test b/usr.sbin/natd/samples/natd.test deleted file mode 100644 index cfdbd15..0000000 --- a/usr.sbin/natd/samples/natd.test +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - - if [ $# != 1 ] - then - echo "usage: natd.test ifname" - exit 1 - fi - - ipfw flush - ipfw add divert 32000 ip from any to any via $1 - ipfw add pass ip from any to any - - ./natd -port 32000 -interface $1 -verbose - |