diff options
author | brian <brian@FreeBSD.org> | 1997-05-23 04:54:03 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 1997-05-23 04:54:03 +0000 |
commit | 6d0cdc4cfb3fa176c7652dec4a5d653682c90b2a (patch) | |
tree | 4297fb56b0856242cee4124a73b083023e9ef542 | |
parent | 68e0b00a5914f21f0856d21dcbefb44edf0d7138 (diff) | |
download | FreeBSD-src-6d0cdc4cfb3fa176c7652dec4a5d653682c90b2a.zip FreeBSD-src-6d0cdc4cfb3fa176c7652dec4a5d653682c90b2a.tar.gz |
Use the latest alias engine - now in libalias.
Submitted by: Charles Mott <cmott@srv.net>
-rw-r--r-- | usr.sbin/ppp/Makefile | 15 | ||||
-rw-r--r-- | usr.sbin/ppp/README.alias | 428 | ||||
-rw-r--r-- | usr.sbin/ppp/README.nat | 428 | ||||
-rw-r--r-- | usr.sbin/ppp/alias.c | 838 | ||||
-rw-r--r-- | usr.sbin/ppp/alias.h | 21 | ||||
-rw-r--r-- | usr.sbin/ppp/alias.p | 94 | ||||
-rw-r--r-- | usr.sbin/ppp/alias_db.c | 1146 | ||||
-rw-r--r-- | usr.sbin/ppp/alias_ftp.c | 198 | ||||
-rw-r--r-- | usr.sbin/ppp/alias_util.c | 104 | ||||
-rw-r--r-- | usr.sbin/ppp/command.c | 103 | ||||
-rw-r--r-- | usr.sbin/ppp/ip.c | 76 | ||||
-rw-r--r-- | usr.sbin/ppp/ipcp.c | 6 | ||||
-rw-r--r-- | usr.sbin/ppp/main.c | 10 |
13 files changed, 841 insertions, 2626 deletions
diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile index 4a2e2ba..94e0c7f 100644 --- a/usr.sbin/ppp/Makefile +++ b/usr.sbin/ppp/Makefile @@ -1,15 +1,14 @@ -# $Id: Makefile,v 1.17 1997/03/30 12:12:20 brian Exp $ +# $Id: Makefile,v 1.18 1997/03/31 22:50:59 brian Exp $ PROG= ppp -SRCS= async.c auth.c ccp.c chap.c chat.c command.c filter.c fsm.c hdlc.c \ - ip.c ipcp.c lcp.c lqr.c log.c main.c mbuf.c modem.c os.c \ - pap.c pred.c route.c slcompress.c timer.c systems.c vars.c \ - vjcomp.c arp.c alias.c alias_db.c alias_ftp.c alias_util.c \ - passwdauth.c sig.c +SRCS= alias_cmd.c arp.c async.c auth.c ccp.c chap.c chat.c command.c \ + filter.c fsm.c hdlc.c ip.c ipcp.c lcp.c log.c lqr.c main.c mbuf.c \ + modem.c os.c pap.c passwdauth.c pred.c route.c sig.c slcompress.c \ + systems.c timer.c vars.c vjcomp.c #CFLAGS+= -DHAVE_SHELL_CMD_WITH_ANY_MODE CFLAGS += -Wall -DMSEXT -DPASSWDAUTH -LDADD += -lmd -lcrypt -lutil -DPADD += ${LIBMD} ${LIBCRYPT} ${LIBUTIL} +LDADD += -lmd -lcrypt -lutil -lalias +DPADD += ${LIBMD} ${LIBCRYPT} ${LIBUTIL} ${LIBALIAS} MAN8= ppp.8 BINMODE=4555 BINOWN= root diff --git a/usr.sbin/ppp/README.alias b/usr.sbin/ppp/README.alias index 51465f8..de5b3c9 100644 --- a/usr.sbin/ppp/README.alias +++ b/usr.sbin/ppp/README.alias @@ -1,112 +1,352 @@ User PPP Packet Aliasing + + 0. Contents 1. Background 2. Setup - 3. Future Development + 3. New commands in ppp + 4. Future Work + 5. Authors / Acknowledgments + 6. Revision History for Aliasing Code + 1. Background -User ppp has embedded packet aliasing (IP masquerading) code. -When this capability is enabled by the "-alias" command line -option, the ppp host will automatically alias IP packets forwarded -from a local network so that they appear to come from the ppp -host machine. Incoming packets from the outside world are then -appropriately de-aliased. +User mode ppp has embedded packet aliasing (IP masquerading) code. +Enabling this, either by the "-alias" command line option or the +"alias enable yes" command in a ppp.conf file, makes the ppp host +automatically alias IP packets forwarded from a local network, making +them appear to come from the ppp host machine. Incoming packets +from the outside world are then appropriately de-aliased. -The process of aliasing involves both the IP address as well as -TCP and UDP port numbers. ICMP packets can be aliased by either -their id or sequence numbers. +The process of aliasing involves both the IP address and the TCP or UDP +port numbers. ICMP echo and timestamp packets are aliased by their id +numbers. ICMP error messages can be properly directed by examining the +fragment of the offending packet which is contained in the body of the +message. This software was specifically meant to support users who have -unregistered, private address IP networks (e.g. 192.168.0.x or -10.0.0.x addresses). The ppp host can act as a gateway for these -networks, and computers on the local area net will have some -degree of internet access without the need for a registered IP -address. Additionally, there will be no need for an internet -service provider to maintain routing tables for the local area -network. - -A disadvantage of packet aliasing is that machines on the local -network, behind the ppp host, can establish tcp connections and -make udp inqiries (such as domain name service requests), but these -machines, other than the ppp host itself, are not visible from -the outside world. There is, in effect, a partial firewall. - -A second disadvantage is that "IP encoding" protocols, which send -IP address or port information within the data stream, are not -supported unless exception code has been put in place. A workaround -for ftp, which is the most well known of the IP encoding protocols, -has been developed in this implementation, so users do not have -to depend on using the ftp passive mode, as is sometimes the case -with other masquerading solutions. - -All standard, non-encoding TCP and UDP protocals are supported, -Examples of these protocols are http, gopher and telnet. The -standard UDP mode of RealAudio is not presently supported, -but the TCP mode does work correctly. IRC is reported by users -to work in some, but not all, modes. - -The packet aliasing code also handle many ICMP messages. In -particular, ping and traceroute are supported. +unregistered, private address IP networks (e.g. 192.168.0.x or 10.0.0.x +addresses). The ppp host can act as a gateway for these networks, and +computers on the local area net will have some degree of Internet access +without the need for a registered IP address. Additionally, there will +be no need for an Internet service provider to maintain routing tables +for the local area network. + +A disadvantage of packet aliasing is that machines on the local network, +behind the ppp host, are not visible from the outside world. They can +establish TCP connections and make UDP inquiries (such as domain name +service requests) but the connections seem to come from the ppp host +itself. There is, in effect, a partial firewall. Of course, if this is +what you want, the disadvantage becomes an advantage. + +A second disadvantage is that "IP encoding" protocols, which send IP +address or port information within the data stream, are not supported +for the cases where exception code exists. This implementation has +workarounds for FTP and IRC DCC, the most well known of the IP encoding +protocols. This frees users from depending on using the ftp passive +mode and avoiding IRC DCC sends, as is sometimes the case with other +masquerading solutions. + +The implementation supports all standard, non-encoding TCP and UDP protocols. +Examples of these protocols are http, gopher and telnet. The standard UDP +mode of RealAudio is not presently supported, but the TCP mode does work +correctly. + +The packet aliasing code also handle many ICMP messages. In particular, +ping and traceroute are supported. 2. Packet Aliasing Setup -It is recommended that correct ppp operation first be verified -without packet aliasing enabled. Then ppp can be started with -the "-alias" option in the command line. Correct network operation -of the ppp host in packet aliasing mode should then be verified. -Finally, machines on the private network should be checked to see -whether they can access the internet. - -Since the masquerading software aliases all packets, whether -they come from the host or another computer on the local area -network, a correctly operating ppp host will indicate that the -software should work properly for other computers on the private -network. - -If the ppp host can access the internet, but other computers on -the local network cannot do this, then it should be checked that -IP forwarding is enabled on the ppp host and that the other -computers use this machine as a gateway. Of course, proper -communications between machines within the local area network -should also be verified (do they use consistent subnet addresses -and masks?). - - - -3. Future Development - -What is called packet aliasing here has been variously called -masquerading, network address translation (NAT) and transparent -proxying by others. It is an extremely useful function to -many users, but it is also necessarily imperfect. Workarounds -(hacks) are always needed for the occasional IP-encoding -protocols. - -The specific solution implemented here does not block off or -reserve any segment of TCP or UDP ports on the ppp host for use -by the masquerading function. No communication to the kernel -is needed in this matter. All packets are aliased, whether -they originate from the ppp host or other computers on the -local network. This is a central issue, and some programmers -may wish to handle this differently. - -The packet aliasing engine (alias.c, alias_db.c, alias_ftp.c -and alias_util.c) runs in user space, and is intended to be -both portable and reusable for interfaces other than ppp. The -basic engine is accessed by four simple function calls -(initialization, communication of host address, outgoing -aliasing and incoming de-aliasing). - -Limited IP fragment handling exists. Once the packet aliasing -software sees the header fragment of a packet, all other fragments -will be correctly forwarded. However, if the header fragment -does not come first, then some fragments will be lost. - -Charles Mott (cmott@srv.net) -December 4, 1996 +It is recommended that users first verify correct ppp operation without +packet aliasing enabled. This will confirm that the ppp.conf file is +properly set up and that there are no ppp problems. Then start ppp with +the "-alias" option on the command line. The user should verify that +the ppp host can correctly connect to the Internet in packet aliasing +mode. Finally, check that machines on the private network can access +the Internet. + +The masquerading software aliases all packets, whether they come from +the host or another computer on the local area network. Thus, a correctly +operating ppp host indicates that the software should work properly for +other computers on the private network. + +If the ppp host can access the Internet, but other computers on the local +network cannot, check that IP forwarding is enabled on the ppp host. Also, +verify that the other computers use this machine as a gateway. Of course, +you should also verify that machines within the local area network +communicate properly. A common error is inconsistent subnet addresses +and masks. + + + +3. New commands in ppp + +In order to control aliasing behavior in a simple manner (no need for +recompilation), a new command has been added to iij-ppp: alias. This +is in addition to the -alias command line option. System managers and +more experienced users may prefer to use the iij-ppp command syntax +within the ppp.conf file. The alias command also allows packet aliasing +behavior to be more precisely specified. + +The decision to add a command instead of extending 'set' or 'option' was +to make obvious that these options only work when aliasing is enabled. + +The syntax for 'alias' is + + ppp> alias option [yes|no] + +where option is given by one of the following templates. + + + - alias enable [yes|no] (default no) + +Enable packet aliasing functionality. If disabled, no other alias +options will have any effect. You should usually enable aliasing +before routing any packets over the link; good points are in the +initial script or right before adding a route. If you do not always +want aliasing, consider using the -alias option to ppp instead of this +command. + + + - alias deny_incoming [yes|no] (default yes) + +Set to "yes" to disable all incoming connections. This just drops +connections to, for example, ftp, telnet or web servers. The aliasing +mechanism prevents these connections. Technically, this option denies +all incoming TCP and UDP requests, making the aliasing software a +fairly efficient one-way firewall. The default is no, which will +all incoming connections to telnetd, ftpd, etc. + + + - alias log [yes|no] + +Controls logging of alias link creation to "/var/log/alias.log" - this +is usually only useful if debugging a setup, to see if the bug is in +the PPP aliasing. The debugging information is fairly limited, listing +the number of aliasing links open for different prototocols. + + + - alias same_ports [yes|no] (default yes) + +When a connection is being established going through the aliasing +routines, it will normally have its port number changed to allow the +aliasing code to track it. If same_ports is enabled, the alias +software attempts to keep the connection's source port unchanged. +This will allow rsh, RPC and other specialized protocols to work +_most of the time_, at least on the host machine. Please, do not +report this being unstable as a bug - it is a result of the way +aliasing has to work. TCP/IP was intended to have one IP address +per machine. + + + - alias use_sockets [yes|no] (default yes) + +This is a fairly obscure option. For the most part, the packet aliasing +software does not have to allocate system sockets when it chooses an +aliasing port number. Under very specific circumstances, FTP data +connections (which don't know the remote port nubmer, though it is +usually 20) and IRC DCC send (which doesn't know either the address or +the port from which the connection will come), there can potentially be +some interference with an open server socket having the same port number +on the ppp host machine. This possibility for interferience only exists +until the TCP connection has been acknowledged on both sides. The safe +option is yes, though fewer system resources are consumed by specifying +no. + + + - alias unregistered_only [yes|no] (default no) + +Packet aliasing normally remaps all packets coming from the local area +network to the ppp host machine address. Set this option to only map +addresses from the following standard ranges for private, unregistered +addresses: + + 10.0.0.0 -> 10.255.255.255 + 172.16.0.0 -> 172.31.255.255 + 192.168.0.0 -> 192.168.255.255 */ + +In the instance that there is a subnet of public addresses and another +subnet of private addresses being routed by the ppp host, then only the +packets on the private subnet will be aliased. + + +- alias port <proto> <local addr>:<port> <alias port> + +This command allows incoming traffic to <alias port> on the host +machine to be redirected to a specific machine and port on the +local area network. One example of this would be: + + alias port tcp 192.168.0.4:telnet 8066 + +All traffic to port 8066 fthe ppp host would then be sent to +the telnet port (23) of machine 192.168.0.4. Port numbers +can either be designated numerically or by symbolic names +listed in /etc/services. Similarly, addresses can be either +in dotted quad notation or in /etc/hosts. + + +- alias addr <local addr> <public addr> + +This command allows traffic for a public IP address to be +redirected to a machine on the local network. This function +is known as "static NAT". An address assignment of 0 refers +to the default address of the ppp host. Normally static +NAT is useful if your ISP has allocated a small block of +IP addresses to the user, but it can even be used in the +case of a single, dynamically allocated IP address: + + alias addr 10.0.0.8 0 + +The above command would redirect all incoming traffic to +machine 10.0.0.8. + +If several address aliases specifiy the same public addres +as follows + + alias addr 192.168.0.2 public_addr + alias addr 192.168.0.3 public_addr + alias addr 192.168.0.4 public_addr + +then incoming traffice 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 the specified public address. + + + +4. Future Work + +What is called packet aliasing here has been variously called masquerading, +network address translation (NAT) and transparent proxying by others. It +is an extremely useful function to many users, but it is also necessarily +imperfect. The occasional IP-encoding protocols always need workarounds +(hacks). Users who are interested in supporting new IP-encoding protocols +can follow the examples of alias_ftp.c and alias_irc.c. + +ICMP error messages are currently handled only in the incoming direction. +A handler needs to be added to correctly alias outgoing error messages. + +IRC and FTP exception handling make reasonable, though not strictly correct +assumptions, about how IP encoded messages will appear in the control +stream. Programmers may wish to consider how to make this process more +robust. + +The packet aliasing engine (alias.c, alias_db.c, alias_ftp.c, alias_irc.c +and alias_util.c) runs in user space, and is intended to be both portable +and reusable for interfaces other than ppp. To access the basic engine +only requires four simple function calls (initialization, communication of +host address, outgoing aliasing and incoming de-aliasing). + + + +5. Authors / Acknowledgments + +Charles Mott (cmott@srv.net) <versions 1.0 - 1.8, 2.0, 2.1> +Eivind Eklund (perhaps@yes.no) <versions 1.8b - 1.9, new ppp commands> + +Listed below, in chronological order, are individuals who have provided +valuable comments and/or debugging assistance. + + Gary Roberts + Tom Torrance + Reto Burkhalter + Martin Renters + Brian Somers + Paul Traina + Ari Suutari + J. Fortes + Andrzej Bialeki + + + +6. Revision History for Aliasing Code + +Version 1.0: August 11, 1996 (cjm) + +Version 1.1: August 20, 1996 (cjm) + PPP host accepts incoming connections for ports 0 to 1023. + +Version 1.2: September 7, 1996 (cjm) + Fragment handling error in alias_db.c corrected. + +Version 1.3: September 15, 1996 (cjm) + - Generalized mechanism for handling incoming connections + (no more 0 to 1023 restriction). + - Increased ICMP support (will handle traceroute now). + - Improved TCP close connection logic. + +Version 1.4: September 16, 1996 + Can't remember (this version only lasted a day -- cjm). + +Version 1.5: September 17, 1996 (cjm) + Corrected error in handling incoming UDP packets + with zero checksum. + +Version 1.6: September 18, 1996 + Simplified ICMP data storage. Will now handle + tracert from Win95 as well as FreeBSD traceroute. + +Verstion 1.7: January 9, 1997 (cjm) + - Reduced malloc() activity for ICMP echo and + timestamp requests. + - Added handling for out-of-order IP fragments. + - Switched to differential checksum computation + for IP headers (TCP, UDP and ICMP checksums + were already differential). + - Accepts FTP data connections from other than + port 20. This allows one ftp connections + from two hosts which are both running packet + aliasing. + +Verstion 1.8: January 14, 1997 (cjm) + - Fixed data type error in function StartPoint() + in alias_db.c (this bug did not exist before v1.7) + +Version 1.8b: January 16, 1997 (Eivind Eklund <perhaps@yes.no>) + - Upgraded base PPP version to be the sourcecode from + FreeBSD 2.1.6, with additional security patches. This + version should still be possible to run on 2.1.5, though - + I've run it with a 2.1.5 kernel without problems. + (Update done with the permission of cjm) + +Version 1.9: February 1, 1997 (Eivind Eklund <perhaps@yes.no>) + - Added support for IRC DCC (ee) + - Changed the aliasing routines to use ANSI style throughout - + minor API changes for integration with other programs than PPP (ee) + - Changed the build process, making all options switchable + from the Makefile (ee) + - Fixed minor security hole in alias_ftp.c for other applications + of the aliasing software. Hole could _not_ manifest in + PPP+pktAlias, but could potentially manifest in other + applications of the aliasing. (ee) + - Connections initiated from packet aliasing host machine will + not have their port number aliased unless it conflicts with + an aliasing port already being used. (There is an option to + disable this for debugging) (cjm) + - Sockets will be allocated in cases where there might be + port interference with the host machine. This can be disabled + in cases where the ppp host will be acting purely as a + masquerading router and not generate any traffic of its own. + (cjm) + +Version 2.0: March, 1997 (cjm) + - Incoming packets which are not recognized by the packet + aliasing engine are now completely dropped in ip.c. + - Aliasing links are cleared when a host interface address + changes (due to re-dial and dynamic address allocatioa). + - PacketAliasPermanentLink() API added. + - Option for only aliasing private, unregistered IP addresses + added. + - Substantial rework to the aliasing lookup engine. + +Version 2.1: May, 1997 (cjm) + - Continuing rework to the aliasing lookup engine to support + multiple incoming addresses and static NAT. + - Now supports outgoing as well as incoming ICMP error messges/ + - PPP commands to support address and port redirection. diff --git a/usr.sbin/ppp/README.nat b/usr.sbin/ppp/README.nat index 51465f8..de5b3c9 100644 --- a/usr.sbin/ppp/README.nat +++ b/usr.sbin/ppp/README.nat @@ -1,112 +1,352 @@ User PPP Packet Aliasing + + 0. Contents 1. Background 2. Setup - 3. Future Development + 3. New commands in ppp + 4. Future Work + 5. Authors / Acknowledgments + 6. Revision History for Aliasing Code + 1. Background -User ppp has embedded packet aliasing (IP masquerading) code. -When this capability is enabled by the "-alias" command line -option, the ppp host will automatically alias IP packets forwarded -from a local network so that they appear to come from the ppp -host machine. Incoming packets from the outside world are then -appropriately de-aliased. +User mode ppp has embedded packet aliasing (IP masquerading) code. +Enabling this, either by the "-alias" command line option or the +"alias enable yes" command in a ppp.conf file, makes the ppp host +automatically alias IP packets forwarded from a local network, making +them appear to come from the ppp host machine. Incoming packets +from the outside world are then appropriately de-aliased. -The process of aliasing involves both the IP address as well as -TCP and UDP port numbers. ICMP packets can be aliased by either -their id or sequence numbers. +The process of aliasing involves both the IP address and the TCP or UDP +port numbers. ICMP echo and timestamp packets are aliased by their id +numbers. ICMP error messages can be properly directed by examining the +fragment of the offending packet which is contained in the body of the +message. This software was specifically meant to support users who have -unregistered, private address IP networks (e.g. 192.168.0.x or -10.0.0.x addresses). The ppp host can act as a gateway for these -networks, and computers on the local area net will have some -degree of internet access without the need for a registered IP -address. Additionally, there will be no need for an internet -service provider to maintain routing tables for the local area -network. - -A disadvantage of packet aliasing is that machines on the local -network, behind the ppp host, can establish tcp connections and -make udp inqiries (such as domain name service requests), but these -machines, other than the ppp host itself, are not visible from -the outside world. There is, in effect, a partial firewall. - -A second disadvantage is that "IP encoding" protocols, which send -IP address or port information within the data stream, are not -supported unless exception code has been put in place. A workaround -for ftp, which is the most well known of the IP encoding protocols, -has been developed in this implementation, so users do not have -to depend on using the ftp passive mode, as is sometimes the case -with other masquerading solutions. - -All standard, non-encoding TCP and UDP protocals are supported, -Examples of these protocols are http, gopher and telnet. The -standard UDP mode of RealAudio is not presently supported, -but the TCP mode does work correctly. IRC is reported by users -to work in some, but not all, modes. - -The packet aliasing code also handle many ICMP messages. In -particular, ping and traceroute are supported. +unregistered, private address IP networks (e.g. 192.168.0.x or 10.0.0.x +addresses). The ppp host can act as a gateway for these networks, and +computers on the local area net will have some degree of Internet access +without the need for a registered IP address. Additionally, there will +be no need for an Internet service provider to maintain routing tables +for the local area network. + +A disadvantage of packet aliasing is that machines on the local network, +behind the ppp host, are not visible from the outside world. They can +establish TCP connections and make UDP inquiries (such as domain name +service requests) but the connections seem to come from the ppp host +itself. There is, in effect, a partial firewall. Of course, if this is +what you want, the disadvantage becomes an advantage. + +A second disadvantage is that "IP encoding" protocols, which send IP +address or port information within the data stream, are not supported +for the cases where exception code exists. This implementation has +workarounds for FTP and IRC DCC, the most well known of the IP encoding +protocols. This frees users from depending on using the ftp passive +mode and avoiding IRC DCC sends, as is sometimes the case with other +masquerading solutions. + +The implementation supports all standard, non-encoding TCP and UDP protocols. +Examples of these protocols are http, gopher and telnet. The standard UDP +mode of RealAudio is not presently supported, but the TCP mode does work +correctly. + +The packet aliasing code also handle many ICMP messages. In particular, +ping and traceroute are supported. 2. Packet Aliasing Setup -It is recommended that correct ppp operation first be verified -without packet aliasing enabled. Then ppp can be started with -the "-alias" option in the command line. Correct network operation -of the ppp host in packet aliasing mode should then be verified. -Finally, machines on the private network should be checked to see -whether they can access the internet. - -Since the masquerading software aliases all packets, whether -they come from the host or another computer on the local area -network, a correctly operating ppp host will indicate that the -software should work properly for other computers on the private -network. - -If the ppp host can access the internet, but other computers on -the local network cannot do this, then it should be checked that -IP forwarding is enabled on the ppp host and that the other -computers use this machine as a gateway. Of course, proper -communications between machines within the local area network -should also be verified (do they use consistent subnet addresses -and masks?). - - - -3. Future Development - -What is called packet aliasing here has been variously called -masquerading, network address translation (NAT) and transparent -proxying by others. It is an extremely useful function to -many users, but it is also necessarily imperfect. Workarounds -(hacks) are always needed for the occasional IP-encoding -protocols. - -The specific solution implemented here does not block off or -reserve any segment of TCP or UDP ports on the ppp host for use -by the masquerading function. No communication to the kernel -is needed in this matter. All packets are aliased, whether -they originate from the ppp host or other computers on the -local network. This is a central issue, and some programmers -may wish to handle this differently. - -The packet aliasing engine (alias.c, alias_db.c, alias_ftp.c -and alias_util.c) runs in user space, and is intended to be -both portable and reusable for interfaces other than ppp. The -basic engine is accessed by four simple function calls -(initialization, communication of host address, outgoing -aliasing and incoming de-aliasing). - -Limited IP fragment handling exists. Once the packet aliasing -software sees the header fragment of a packet, all other fragments -will be correctly forwarded. However, if the header fragment -does not come first, then some fragments will be lost. - -Charles Mott (cmott@srv.net) -December 4, 1996 +It is recommended that users first verify correct ppp operation without +packet aliasing enabled. This will confirm that the ppp.conf file is +properly set up and that there are no ppp problems. Then start ppp with +the "-alias" option on the command line. The user should verify that +the ppp host can correctly connect to the Internet in packet aliasing +mode. Finally, check that machines on the private network can access +the Internet. + +The masquerading software aliases all packets, whether they come from +the host or another computer on the local area network. Thus, a correctly +operating ppp host indicates that the software should work properly for +other computers on the private network. + +If the ppp host can access the Internet, but other computers on the local +network cannot, check that IP forwarding is enabled on the ppp host. Also, +verify that the other computers use this machine as a gateway. Of course, +you should also verify that machines within the local area network +communicate properly. A common error is inconsistent subnet addresses +and masks. + + + +3. New commands in ppp + +In order to control aliasing behavior in a simple manner (no need for +recompilation), a new command has been added to iij-ppp: alias. This +is in addition to the -alias command line option. System managers and +more experienced users may prefer to use the iij-ppp command syntax +within the ppp.conf file. The alias command also allows packet aliasing +behavior to be more precisely specified. + +The decision to add a command instead of extending 'set' or 'option' was +to make obvious that these options only work when aliasing is enabled. + +The syntax for 'alias' is + + ppp> alias option [yes|no] + +where option is given by one of the following templates. + + + - alias enable [yes|no] (default no) + +Enable packet aliasing functionality. If disabled, no other alias +options will have any effect. You should usually enable aliasing +before routing any packets over the link; good points are in the +initial script or right before adding a route. If you do not always +want aliasing, consider using the -alias option to ppp instead of this +command. + + + - alias deny_incoming [yes|no] (default yes) + +Set to "yes" to disable all incoming connections. This just drops +connections to, for example, ftp, telnet or web servers. The aliasing +mechanism prevents these connections. Technically, this option denies +all incoming TCP and UDP requests, making the aliasing software a +fairly efficient one-way firewall. The default is no, which will +all incoming connections to telnetd, ftpd, etc. + + + - alias log [yes|no] + +Controls logging of alias link creation to "/var/log/alias.log" - this +is usually only useful if debugging a setup, to see if the bug is in +the PPP aliasing. The debugging information is fairly limited, listing +the number of aliasing links open for different prototocols. + + + - alias same_ports [yes|no] (default yes) + +When a connection is being established going through the aliasing +routines, it will normally have its port number changed to allow the +aliasing code to track it. If same_ports is enabled, the alias +software attempts to keep the connection's source port unchanged. +This will allow rsh, RPC and other specialized protocols to work +_most of the time_, at least on the host machine. Please, do not +report this being unstable as a bug - it is a result of the way +aliasing has to work. TCP/IP was intended to have one IP address +per machine. + + + - alias use_sockets [yes|no] (default yes) + +This is a fairly obscure option. For the most part, the packet aliasing +software does not have to allocate system sockets when it chooses an +aliasing port number. Under very specific circumstances, FTP data +connections (which don't know the remote port nubmer, though it is +usually 20) and IRC DCC send (which doesn't know either the address or +the port from which the connection will come), there can potentially be +some interference with an open server socket having the same port number +on the ppp host machine. This possibility for interferience only exists +until the TCP connection has been acknowledged on both sides. The safe +option is yes, though fewer system resources are consumed by specifying +no. + + + - alias unregistered_only [yes|no] (default no) + +Packet aliasing normally remaps all packets coming from the local area +network to the ppp host machine address. Set this option to only map +addresses from the following standard ranges for private, unregistered +addresses: + + 10.0.0.0 -> 10.255.255.255 + 172.16.0.0 -> 172.31.255.255 + 192.168.0.0 -> 192.168.255.255 */ + +In the instance that there is a subnet of public addresses and another +subnet of private addresses being routed by the ppp host, then only the +packets on the private subnet will be aliased. + + +- alias port <proto> <local addr>:<port> <alias port> + +This command allows incoming traffic to <alias port> on the host +machine to be redirected to a specific machine and port on the +local area network. One example of this would be: + + alias port tcp 192.168.0.4:telnet 8066 + +All traffic to port 8066 fthe ppp host would then be sent to +the telnet port (23) of machine 192.168.0.4. Port numbers +can either be designated numerically or by symbolic names +listed in /etc/services. Similarly, addresses can be either +in dotted quad notation or in /etc/hosts. + + +- alias addr <local addr> <public addr> + +This command allows traffic for a public IP address to be +redirected to a machine on the local network. This function +is known as "static NAT". An address assignment of 0 refers +to the default address of the ppp host. Normally static +NAT is useful if your ISP has allocated a small block of +IP addresses to the user, but it can even be used in the +case of a single, dynamically allocated IP address: + + alias addr 10.0.0.8 0 + +The above command would redirect all incoming traffic to +machine 10.0.0.8. + +If several address aliases specifiy the same public addres +as follows + + alias addr 192.168.0.2 public_addr + alias addr 192.168.0.3 public_addr + alias addr 192.168.0.4 public_addr + +then incoming traffice 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 the specified public address. + + + +4. Future Work + +What is called packet aliasing here has been variously called masquerading, +network address translation (NAT) and transparent proxying by others. It +is an extremely useful function to many users, but it is also necessarily +imperfect. The occasional IP-encoding protocols always need workarounds +(hacks). Users who are interested in supporting new IP-encoding protocols +can follow the examples of alias_ftp.c and alias_irc.c. + +ICMP error messages are currently handled only in the incoming direction. +A handler needs to be added to correctly alias outgoing error messages. + +IRC and FTP exception handling make reasonable, though not strictly correct +assumptions, about how IP encoded messages will appear in the control +stream. Programmers may wish to consider how to make this process more +robust. + +The packet aliasing engine (alias.c, alias_db.c, alias_ftp.c, alias_irc.c +and alias_util.c) runs in user space, and is intended to be both portable +and reusable for interfaces other than ppp. To access the basic engine +only requires four simple function calls (initialization, communication of +host address, outgoing aliasing and incoming de-aliasing). + + + +5. Authors / Acknowledgments + +Charles Mott (cmott@srv.net) <versions 1.0 - 1.8, 2.0, 2.1> +Eivind Eklund (perhaps@yes.no) <versions 1.8b - 1.9, new ppp commands> + +Listed below, in chronological order, are individuals who have provided +valuable comments and/or debugging assistance. + + Gary Roberts + Tom Torrance + Reto Burkhalter + Martin Renters + Brian Somers + Paul Traina + Ari Suutari + J. Fortes + Andrzej Bialeki + + + +6. Revision History for Aliasing Code + +Version 1.0: August 11, 1996 (cjm) + +Version 1.1: August 20, 1996 (cjm) + PPP host accepts incoming connections for ports 0 to 1023. + +Version 1.2: September 7, 1996 (cjm) + Fragment handling error in alias_db.c corrected. + +Version 1.3: September 15, 1996 (cjm) + - Generalized mechanism for handling incoming connections + (no more 0 to 1023 restriction). + - Increased ICMP support (will handle traceroute now). + - Improved TCP close connection logic. + +Version 1.4: September 16, 1996 + Can't remember (this version only lasted a day -- cjm). + +Version 1.5: September 17, 1996 (cjm) + Corrected error in handling incoming UDP packets + with zero checksum. + +Version 1.6: September 18, 1996 + Simplified ICMP data storage. Will now handle + tracert from Win95 as well as FreeBSD traceroute. + +Verstion 1.7: January 9, 1997 (cjm) + - Reduced malloc() activity for ICMP echo and + timestamp requests. + - Added handling for out-of-order IP fragments. + - Switched to differential checksum computation + for IP headers (TCP, UDP and ICMP checksums + were already differential). + - Accepts FTP data connections from other than + port 20. This allows one ftp connections + from two hosts which are both running packet + aliasing. + +Verstion 1.8: January 14, 1997 (cjm) + - Fixed data type error in function StartPoint() + in alias_db.c (this bug did not exist before v1.7) + +Version 1.8b: January 16, 1997 (Eivind Eklund <perhaps@yes.no>) + - Upgraded base PPP version to be the sourcecode from + FreeBSD 2.1.6, with additional security patches. This + version should still be possible to run on 2.1.5, though - + I've run it with a 2.1.5 kernel without problems. + (Update done with the permission of cjm) + +Version 1.9: February 1, 1997 (Eivind Eklund <perhaps@yes.no>) + - Added support for IRC DCC (ee) + - Changed the aliasing routines to use ANSI style throughout - + minor API changes for integration with other programs than PPP (ee) + - Changed the build process, making all options switchable + from the Makefile (ee) + - Fixed minor security hole in alias_ftp.c for other applications + of the aliasing software. Hole could _not_ manifest in + PPP+pktAlias, but could potentially manifest in other + applications of the aliasing. (ee) + - Connections initiated from packet aliasing host machine will + not have their port number aliased unless it conflicts with + an aliasing port already being used. (There is an option to + disable this for debugging) (cjm) + - Sockets will be allocated in cases where there might be + port interference with the host machine. This can be disabled + in cases where the ppp host will be acting purely as a + masquerading router and not generate any traffic of its own. + (cjm) + +Version 2.0: March, 1997 (cjm) + - Incoming packets which are not recognized by the packet + aliasing engine are now completely dropped in ip.c. + - Aliasing links are cleared when a host interface address + changes (due to re-dial and dynamic address allocatioa). + - PacketAliasPermanentLink() API added. + - Option for only aliasing private, unregistered IP addresses + added. + - Substantial rework to the aliasing lookup engine. + +Version 2.1: May, 1997 (cjm) + - Continuing rework to the aliasing lookup engine to support + multiple incoming addresses and static NAT. + - Now supports outgoing as well as incoming ICMP error messges/ + - PPP commands to support address and port redirection. diff --git a/usr.sbin/ppp/alias.c b/usr.sbin/ppp/alias.c deleted file mode 100644 index 5a99fb9..0000000 --- a/usr.sbin/ppp/alias.c +++ /dev/null @@ -1,838 +0,0 @@ -/* - Alias.c provides supervisory control for the functions of the - packet aliasing software. It consists of routines to monitor - TCP connection state, protocol-specific aliasing routines, - limited fragment handling and the two primary outside world - functional interfaces: PacketAliasIn and PacketAliasOut. - - The other C program files are briefly described. The data - structure framework which holds information needed to translate - packets is encapsulated in alias_db.c. Data is accessed by - function calls, so other segments of the program need not - know about the underlying data structures. Alias_ftp.c contains - special code for modifying the ftp PORT command used to establish - data connections. Alias_util.c contains a few utility routines. - - This software is placed into the public domain with no restrictions - on its distribution. - - Version 1.0 August, 1996 (cjm) - - Version 1.1 August 20, 1996 (cjm) - PPP host accepts incoming connections for ports 0 to 1023. - - Version 1.2 September 7, 1996 (cjm) - Fragment handling error in alias_db.c corrected. - - Version 1.4 September 16, 1996 (cjm) - - A more generalized method for handling incoming - connections, without the 0-1023 restriction, is - implemented in alias_db.c - - Improved ICMP support in alias.c. Traceroute - packet streams can now be correctly aliased. - - TCP connection closing logic simplified in - alias.c and now allows for additional 1 minute - "grace period" after FIN or RST is observed. - Version 1.5 September 17, 1996 (cjm) - Corrected error in handling incoming UDP packets with 0 checksum. - Version 1.6 September 18, 1996 (cjm) - Simplified ICMP aliasing scheme. Should now support - traceroute from Win95 as well as FreeBSD. - -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/param.h> -#include <sys/types.h> -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/ip_icmp.h> -#include <netinet/tcp.h> -#include <netinet/udp.h> -#include <arpa/inet.h> - -#include "alias.p" - -#define FTP_CONTROL_PORT_NUMBER 21 - - - - -/* TCP Handling Routines - - TcpMonitorIn() -- These routines monitor TCP connections, and - TcpMonitorOut() -- delete a link node when a connection is closed. - -These routines look for SYN, ACK and RST flags to determine when TCP -connections open and close. When a TCP connection closes, the data -structure containing packet aliasing information is deleted after -a timeout period. -*/ - -void -TcpMonitorIn(pip, link) -struct ip *pip; -char *link; -{ - struct tcphdr *tc; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - switch (GetStateIn(link)) - { - case 0: - if (tc->th_flags & TH_SYN) SetStateIn(link, 1); - break; - case 1: - if (tc->th_flags & TH_FIN - || tc->th_flags & TH_RST) SetStateIn(link, 2); - } -} - -void -TcpMonitorOut(pip, link) -struct ip *pip; -char *link; -{ - struct tcphdr *tc; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - switch (GetStateOut(link)) - { - case 0: - if (tc->th_flags & TH_SYN) SetStateOut(link, 1); - break; - case 1: - if (tc->th_flags & TH_FIN - || tc->th_flags & TH_RST) SetStateOut(link, 2); - } -} - - - - - -/* Protocol Specific Packet Aliasing Routines - - IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2 - IcmpAliasOut(), IcmpAliasOut1() - UdpAliasIn(), UdpAliasOut() - TcpAliasIn(), TcpAliasOut() - -These routines handle protocol specific details of packet aliasing. -One may observe a certain amount of repetitive arithmetic in these -functions, the purpose of which is to compute a revised checksum -without actually summing over the entire data packet, which could be -unnecessarily time consuming. - -The purpose of the packet aliasing routines is to replace the source -address of the outgoing packet and then correctly put it back for -any incoming packets. For TCP and UDP, ports are also re-mapped. - -For ICMP echo/timestamp requests and replies, the following scheme -is used: the sequence number is replaced by an alias for the outgoing -packet and this sequence number, plus the id and remote address are -used to find the packet on the return path. - -ICMP error messages are handled by looking at the IP fragment -in the data section of the message. - -For TCP and UDP protocols, a port number is chosen for an outgoing -packet, and then incoming packets are identified by IP address and -port number. For TCP packets, there is additional logic in the event -that sequence and ack numbers have been altered (as is the case for -FTP data port commands). - -The port numbers used by the packet aliasing module are not true -ports in the Unix sense. No sockets are actually bound to ports. -They are more correctly placeholders. - -All packets are aliased, whether they come from the gateway machine -or other machines on a local area network. -*/ - -void -IcmpAliasIn1(pip) -struct ip *pip; -{ -/* - Un-alias incoming echo and timestamp replies -*/ - char *link; - struct icmp *ic; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - -/* Get source address from ICMP data field and restore original data */ - link = FindIcmpIn(pip->ip_src, ic->icmp_id, ic->icmp_seq); - if (link != NULL_PTR) - { - u_short original_seq; - int accumulate; - - original_seq = GetOriginalPort(link); - -/* Adjust ICMP checksum */ - accumulate = ic->icmp_cksum; - accumulate += ic->icmp_seq; - accumulate -= original_seq; - - if (accumulate < 0) - { - accumulate = -accumulate; - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ic->icmp_cksum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ic->icmp_cksum = (u_short) accumulate; - } - -/* Put original sequence number back in */ - ic->icmp_seq = original_seq; - -/* Put original address back into IP header */ - pip->ip_dst = GetOriginalAddress(link); - -/* Delete unneeded data structure */ - DeleteLink(link); - } -} - -void -IcmpAliasIn2(pip) -struct ip *pip; -{ -/* - Alias incoming ICMP error messages containing - IP header and first 64 bits of datagram. -*/ - struct ip *ip; - struct icmp *ic, *ic2; - struct udphdr *ud; - struct tcphdr *tc; - char *link; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - ip = (struct ip *) ic->icmp_data; - - ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2)); - tc = (struct tcphdr *) ud; - ic2 = (struct icmp *) ud; - - if (ip->ip_p == IPPROTO_UDP) - link = FindUdpIn(ip->ip_dst, ud->uh_dport, ud->uh_sport); - else if (ip->ip_p == IPPROTO_TCP) - link = FindTcpIn(ip->ip_dst, tc->th_dport, tc->th_sport); - else if (ip->ip_p == IPPROTO_ICMP) - if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP) - link = FindIcmpIn(ip->ip_dst, ic2->icmp_id, ic2->icmp_seq); - else - link = NULL_PTR; - else - link = NULL_PTR; - - if (link != NULL_PTR) - { - if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) - { - u_short *sptr; - int accumulate; - struct in_addr original_address; - u_short original_port; - - original_address = GetOriginalAddress(link); - original_port = GetOriginalPort(link); - -/* Adjust ICMP checksum */ - accumulate = ic->icmp_cksum; - sptr = (u_short *) &(ip->ip_src); - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &original_address; - accumulate -= *sptr++; - accumulate -= *sptr; - accumulate += ud->uh_sport; - accumulate -= original_port; - - if (accumulate < 0) - { - accumulate = -accumulate; - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ic->icmp_cksum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ic->icmp_cksum = (u_short) accumulate; - } - -/* Un-alias address in IP header */ - pip->ip_dst = original_address; - -/* Un-alias address and port number of original IP packet -fragment contained in ICMP data section */ - ip->ip_src = original_address; - ud->uh_sport = original_port; - } - else if (pip->ip_p == IPPROTO_ICMP) - { - u_short *sptr; - int accumulate; - struct in_addr original_address; - u_short original_seq; - - original_address = GetOriginalAddress(link); - original_seq = GetOriginalPort(link); - -/* Adjust ICMP checksum */ - accumulate = ic->icmp_cksum; - sptr = (u_short *) &(ip->ip_src); - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &original_address; - accumulate -= *sptr++; - accumulate -= *sptr; - accumulate += ic2->icmp_seq; - accumulate -= original_seq; - - if (accumulate < 0) - { - accumulate = -accumulate; - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ic->icmp_cksum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ic->icmp_cksum = (u_short) accumulate; - } - -/* Un-alias address in IP header */ - pip->ip_dst = original_address; - -/* Un-alias address of original IP packet and seqence number of - embedded icmp datagram */ - ip->ip_src = original_address; - ic2->icmp_seq = original_seq; - } - } -} - -void -IcmpAliasIn(pip) -struct ip *pip; -{ - struct icmp *ic; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - - switch (ic->icmp_type) - { - case ICMP_ECHOREPLY: - case ICMP_TSTAMPREPLY: - if (ic->icmp_code == 0) - { - IcmpAliasIn1(pip); - } - break; - case ICMP_UNREACH: - case ICMP_SOURCEQUENCH: - case ICMP_TIMXCEED: - case ICMP_PARAMPROB: - IcmpAliasIn2(pip); - break; - } -} - - -void -IcmpAliasOut1(pip) -struct ip *pip; -{ -/* - Alias ICMP echo and timestamp packets -*/ - char *link; - struct icmp *ic; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - -/* Save overwritten data for when echo packet returns */ - link = FindIcmpOut(pip->ip_src, pip->ip_dst, ic->icmp_id, ic->icmp_seq); - if (link != NULL_PTR) - { - u_short alias_seq; - int accumulate; - - alias_seq = GetAliasPort(link); - -/* Since data field is being modified, adjust ICMP checksum */ - accumulate = ic->icmp_cksum; - accumulate += ic->icmp_seq; - accumulate -= alias_seq; - - if (accumulate < 0) - { - accumulate = -accumulate; - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ic->icmp_cksum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ic->icmp_cksum = (u_short) accumulate; - } - -/* Alias sequence number */ - ic->icmp_seq = alias_seq; - -/* Change source address */ - pip->ip_src = GetAliasAddress(); - } -} - -void -IcmpAliasOut(pip) -struct ip *pip; -{ - struct icmp *ic; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - - switch (ic->icmp_type) - { - case ICMP_ECHO: - case ICMP_TSTAMP: - if (ic->icmp_code == 0) - { - IcmpAliasOut1(pip); - } - break; - } -} - -void -UdpAliasIn(pip) -struct ip *pip; -{ - struct udphdr *ud; - char *link; - - ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); - - link = FindUdpIn(pip->ip_src, ud->uh_sport, ud->uh_dport); - if (link != NULL_PTR) - { - struct in_addr alias_address; - u_short alias_port; - int accumulate; - u_short *sptr; - - alias_address = GetAliasAddress(); - pip->ip_dst = GetOriginalAddress(link); - alias_port = ud->uh_dport; - ud->uh_dport = GetOriginalPort(link); - -/* If UDP checksum is not zero, then adjust since destination port */ -/* is being unaliased and destination port is being altered. */ - if (ud->uh_sum != 0) - { - accumulate = ud->uh_sum; - accumulate += alias_port; - accumulate -= ud->uh_dport; - sptr = (u_short *) &alias_address; - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &(pip->ip_dst); - accumulate -= *sptr++; - accumulate -= *sptr; - - if (accumulate < 0) - { - accumulate = -accumulate; - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ud->uh_sum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ud->uh_sum = (u_short) accumulate; - } - } - } -} - -void -UdpAliasOut(pip) -struct ip *pip; -{ - struct udphdr *ud; - char *link; - - ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); - - link = FindUdpOut(pip->ip_src, pip->ip_dst, ud->uh_sport, ud->uh_dport); - if (link != NULL_PTR) - { - u_short alias_port; - - alias_port = GetAliasPort(link); - -/* If UDP checksum is not zero, adjust since source port is */ -/* being aliased and source address is being altered */ - if (ud->uh_sum != 0) - { - struct in_addr alias_address; - int accumulate; - u_short *sptr; - - alias_address = GetAliasAddress(); - - accumulate = ud->uh_sum; - accumulate += ud->uh_sport; - accumulate -= alias_port; - sptr = (u_short *) &(pip->ip_src); - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &alias_address; - accumulate -= *sptr++; - accumulate -= *sptr; - - if (accumulate < 0) - { - accumulate = -accumulate; - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ud->uh_sum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - ud->uh_sum = (u_short) accumulate; - } - } - -/* Put alias port in TCP header */ - ud->uh_sport = alias_port; - -/* Change source address */ - pip->ip_src = GetAliasAddress(); - } -} - - - -void -TcpAliasIn(pip) -struct ip *pip; -{ - struct tcphdr *tc; - char *link; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - link = FindTcpIn(pip->ip_src, tc->th_sport, tc->th_dport); - if (link != NULL_PTR) - { - struct in_addr alias_address; - u_short alias_port; - int accumulate; - u_short *sptr; - - alias_address = GetAliasAddress(); - pip->ip_dst = GetOriginalAddress(link); - alias_port = tc->th_dport; - tc->th_dport = GetOriginalPort(link); - -/* Adjust TCP checksum since destination port is being unaliased */ -/* and destination port is being altered. */ - accumulate = tc->th_sum; - accumulate += alias_port; - accumulate -= tc->th_dport; - sptr = (u_short *) &alias_address; - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &(pip->ip_dst); - accumulate -= *sptr++; - accumulate -= *sptr; - -/* See if ack number needs to be modified */ - if (GetAckModified(link) == 1) - { - int delta; - - delta = GetDeltaAckIn(pip, link); - if (delta != 0) - { - sptr = (u_short *) &tc->th_ack; - accumulate += *sptr++; - accumulate += *sptr; - tc->th_ack = htonl(ntohl(tc->th_ack) - delta); - sptr = (u_short *) &tc->th_ack; - accumulate -= *sptr++; - accumulate -= *sptr; - } - } - -/* Finish checksum modification */ - if (accumulate < 0) - { - accumulate = -accumulate; - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - tc->th_sum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - tc->th_sum = (u_short) accumulate; - } - -/* Monitor TCP connection state */ - TcpMonitorIn(pip, link); - } -} - -void -TcpAliasOut(pip) -struct ip *pip; -{ - struct tcphdr *tc; - char *link; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - link = FindTcpOut(pip->ip_src, pip->ip_dst, tc->th_sport, tc->th_dport); - if (link !=NULL_PTR) - { - struct in_addr alias_address; - u_short alias_port; - int accumulate; - u_short *sptr; - - alias_address = GetAliasAddress(); - alias_port = GetAliasPort(link); - -/* Monitor tcp connection state */ - TcpMonitorOut(pip, link); - -/* Special processing for ftp connection */ - if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER - || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER) - HandleFtpOut(pip, link); - -/* Adjust TCP checksum since source port is being aliased */ -/* and source address is being altered */ - accumulate = tc->th_sum; - accumulate += tc->th_sport; - accumulate -= alias_port; - sptr = (u_short *) &(pip->ip_src); - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &alias_address; - accumulate -= *sptr++; - accumulate -= *sptr; - -/* Modify sequence number if necessary */ - if (GetAckModified(link) == 1) - { - int delta; - - delta = GetDeltaSeqOut(pip, link); - if (delta != 0) - { - sptr = (u_short *) &tc->th_seq; - accumulate += *sptr++; - accumulate += *sptr; - tc->th_seq = htonl(ntohl(tc->th_seq) + delta); - sptr = (u_short *) &tc->th_seq; - accumulate -= *sptr++; - accumulate -= *sptr; - } - } - -/* Finish up checksum calculation */ - if (accumulate < 0) - { - accumulate = -accumulate; - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - tc->th_sum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - tc->th_sum = (u_short) accumulate; - } - -/* Put alias address in TCP header */ - tc->th_sport = alias_port; - -/* Change source address */ - pip->ip_src = GetAliasAddress(); - } -} - - - - -/* Fragment Handling - - FragmentIn() - FragmentOut() - -The packet aliasing module has a limited ability for handling IP -fragments. If the ICMP, TCP or UDP header is in the first fragment -received, then the id number of the IP packet is saved, and other -fragments are identified according to their ID number and IP address -they were sent from. - -In general, fragments seem few and far between these days. One way -to generate them is with a ping request specifying a large data segment. -This is how the software here was tested. - -In principle, out-of-order IP fragments could also be handled by saving -fragments until the header fragment came in and then sending them on -their way. However, this violates a basic interface rule of the -aliasing module in which individual packets are sent for remapping, -and nothing is actually known about how to write these packets to a -device interface. -*/ - -void -FragmentIn(pip) -struct ip *pip; -{ - char *link; - - link = FindFragmentIn2(pip->ip_src); - if (link != NULL_PTR) - GetFragmentAddr(link, pip->ip_id, pip->ip_p, &(pip->ip_dst) ); -} - -void -FragmentOut(pip) -struct ip *pip; -{ - pip->ip_src = GetAliasAddress(); -} - - - - - - - - -/* Outside World Access - - PacketAliasIn() - PacketAliasOut() -*/ - -void -PacketAliasIn(pip) -struct ip *pip; -{ - int checksum_ok; - -/* Verify initial checksum */ - if (IpChecksum(pip) == 0) - checksum_ok = 1; - else - checksum_ok = 0; - - if ( (ntohs(pip->ip_off) & IP_OFFMASK) == 0 ) - { - switch (pip->ip_p) - { - case IPPROTO_ICMP: - IcmpAliasIn(pip); - break; - case IPPROTO_UDP: - UdpAliasIn(pip); - break; - case IPPROTO_TCP: - TcpAliasIn(pip); - break; - } - if (ntohs(pip->ip_off) & IP_MF) - { - char *link; - - link = FindFragmentIn1(pip->ip_src); - if (link != NULL_PTR) - SetFragmentData(link, pip->ip_id, pip->ip_p, pip->ip_dst); - } - } - else - { - FragmentIn(pip); - } - -/* adjust IP checksum, if original is correct */ - if (checksum_ok == 1) - { - pip->ip_sum = 0; - pip->ip_sum = IpChecksum(pip); - } -} - -void -PacketAliasOut(pip) -struct ip *pip; -{ - int checksum_ok; - - if (IpChecksum(pip) == 0) - checksum_ok = 1; - else - checksum_ok = 0; - - if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) - { - switch (pip->ip_p) - { - case IPPROTO_ICMP: - IcmpAliasOut(pip); - break; - case IPPROTO_UDP: - UdpAliasOut(pip); - break; - case IPPROTO_TCP: - TcpAliasOut(pip); - break; - } - } - else - { - FragmentOut(pip); - } - -/* Adjust IP checksum, if original is correct */ - if (checksum_ok == 1) - { - pip->ip_sum = 0; - pip->ip_sum = IpChecksum(pip); - } -} diff --git a/usr.sbin/ppp/alias.h b/usr.sbin/ppp/alias.h deleted file mode 100644 index 4075822..0000000 --- a/usr.sbin/ppp/alias.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - Alias.h defines the outside world interfaces for the packet - aliasing software. - - This software is placed into the public domain with no restrictions - on its distribution. - - Initial version: August, 1996 (cjm) -*/ - - -#ifndef _ALIAS_H_ -#define _ALIAS_H_ - -extern void PacketAliasIn __P((struct ip *)); -extern void PacketAliasOut __P((struct ip *)); -extern void SetAliasAddress __P((struct in_addr)); -extern void InitAlias(); -extern void InitAliasLog(); - -#endif diff --git a/usr.sbin/ppp/alias.p b/usr.sbin/ppp/alias.p deleted file mode 100644 index 5d33f12..0000000 --- a/usr.sbin/ppp/alias.p +++ /dev/null @@ -1,94 +0,0 @@ -/* - Alias.p contains the function prototypes for alias.c, alias_db.c, - alias_util.c and alias_ftp.c (as well as any future add-ons). It - is intended to be used only within the aliasing software. Outside - world interfaces are defined in alias.h - - - This software is placed into the public domain with no restrictions - on its distribution. - - Initial version: August, 1996 (cjm) -*/ - -#define NULL_PTR 0 - -/* General utilities */ -u_short InternetChecksum(u_short *, int); -u_short IpChecksum(struct ip *); -u_short TcpChecksum(struct ip *); - -/* Data access utilities */ -int StartPoint(struct in_addr, u_short, int); -u_short GetNewPort(); -int SeqDiff(u_long, u_long); -void ShowAliasStats(); - -/* Internal data access */ -void CleanupAliasData(); -void IncrementalCleanup(); -char * FindLink1(struct in_addr, struct in_addr, u_short, u_short, int); -char * FindLink2(struct in_addr, u_short, u_short, int); -void DeleteLink(char *); -char * AddLink(struct in_addr, struct in_addr, u_short, u_short, - u_short, int); - -/* External data search */ -char * FindIcmpIn(struct in_addr, u_short, u_short); -char * FindIcmpOut(struct in_addr, struct in_addr, u_short, u_short); -char * FindFragmentIn1(struct in_addr); -char * FindFragmentIn2(struct in_addr); -char * FindUdpIn(struct in_addr, u_short, u_short); -char * FindUdpOut(struct in_addr, struct in_addr, u_short, u_short); -char * FindTcpIn(struct in_addr, u_short, u_short); -char * FindTcpOut(struct in_addr, struct in_addr, u_short, u_short); - -/* External data access/modification */ -void GetIcmpData(char *, u_short, u_short, u_long *); -void SetIcmpData(char *, u_short, u_short, u_long); -void GetFragmentAddr(char *, u_short, u_char, struct in_addr *); -void SetFragmentData(char *, u_short, u_char, struct in_addr); -void SetStateIn(char *, int); -void SetStateOut(char *, int); -int GetStateIn(char *); -int GetStateOut(char *); -struct in_addr GetOriginalAddress(char *); -struct in_addr GetDestAddress(char *); -struct in_addr GetAliasAddress(); -u_short GetOriginalPort(char *); -u_short GetDestPort(char *); -u_short GetAliasPort(char *); -void SetAckModified(char *); -int GetAckModified(char *); -int GetDeltaAckIn(struct ip *, char *); -int GetDeltaSeqOut(struct ip *, char *); -void AddSeq(struct ip *, char *, int); - -/* Tcp specfic routines */ -void TcpMonitorIn(struct ip *, char *); -void TcpMonitorOut(struct ip *, char *); -void HandleFtpOut(struct ip *, char *); -void NewFtpPortCommand(struct ip *, char *, struct in_addr, u_short); - -/* Protocal specific packet aliasing routines */ -void IcmpAliasIn1(struct ip *); -void IcmpAliasIn2(struct ip *); -void IcmpAliasIn(struct ip *); -void IcmpAliasOut(struct ip *); -void IcmpAliasOut1(struct ip *); -void UdpAliasIn(struct ip *); -void UdpAliasOut(struct ip *); -void TcpAliasIn(struct ip *); -void TcpAliasOut(struct ip *); - -/* Fragment handling */ -void FragmentIn(struct ip *); -void FragmentOut(struct ip *); - -/* Outside world interfaces */ -void PacketAliasIn(struct ip *); -void PacketAliasOut(struct ip *); -void SetAliasAddress(struct in_addr); -void InitAlias(); -void InitAliasLog(); - diff --git a/usr.sbin/ppp/alias_db.c b/usr.sbin/ppp/alias_db.c deleted file mode 100644 index f144c0b..0000000 --- a/usr.sbin/ppp/alias_db.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* - Alias_db.c encapsulates all data structures used for storing - packet aliasing data. Other parts of the aliasing software - access data through functions provided in this file. - - Data storage is based on the notion of a "link", which is - established for ICMP echo/reply packets, UDP datagrams and - TCP stream connections. A link stores the original source - and destination addresses. For UDP and TCP, it also stores - source and destination port numbers, as well as an alias - port number. - - There is a facility for sweeping through and deleting old - links as new packets are sent through. A simple timeout is - used for ICMP and UDP links. TCP links are left alone unless - there is an incomplete connection, in which case the link - can be deleted after a certain amount of time. TCP links which - properly close are deleted by a function call to DeleteLink() - from alias.c. - - - This software is placed into the public domain with no restrictions - on its distribution. - - Initial version: August, 1996 (cjm) - - Version 1.4: September 16, 1996 (cjm) - Facility for handling incoming links added. - - Version 1.6: September 18, 1996 (cjm) - ICMP data handling simplified. -*/ - - -/* Include files */ - -#include <stdio.h> -#include <stdlib.h> -#include <sys/time.h> -#include <sys/types.h> -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include "defs.h" - - -/* Constants */ - -#define FTP_CONTROL_PORT_NUMBER 21 -#define LINK_TABLE_SIZE 101 -#define LINK_ICMP 1 -#define LINK_UDP 2 -#define LINK_TCP 3 -#define LINK_FRAGMENT_ID 4 -#define N_LINK_ICMP_DATA 20 -#define N_LINK_ID_DATA 20 -#define N_LINK_TCP_DATA 20 - -#define ICMP_EXPIRE_TIME 60 -#define UDP_EXPIRE_TIME 60 -#define TCP_EXPIRE_TIME 60 -#define FRAGMENT_EXPIRE_TIME 60 - -#define ALIAS_PORT_BASE 30000 -#define ALIAS_PORT_MASK 0x7fff -#define ALIAS_PORT_TABLE_SIZE 0x8000 - - -/* If MONITOR_ALIAS is defined, a message will be printed to -/var/log/alias.log every time a link is created or deleted. This -is useful for debugging -*/ - -/* #define MONITOR_ALIAS */ - - -/* If ALLOW_INCOMING is defined, then incoming connections (e.g. -to ftp, telnet or web servers will be handled. Otherwise, these -types of connections will be prevented by the aliasing mechanism. -*/ - -#define ALLOW_INCOMING - - - -/* Data Structures - - The fundamental data structure used in this program is - "struct link_record". Whenever a TCP connection is made, - a UDP datagram is sent out, or an ICMP echo request is made, - a link record is made (if it has not already been created). - - The link record is identified by the source address/port - and the destination address/port. In the case of an ICMP - echo request, which has no port numbers, these fields are - set to zero. - - The link record also can store some auxiliary data. For ICMP - echo requests, there is space allocated to save id and sequence - numbers. For tcp connections that have had sequence and - acknowledgment modifications, data space is available to - track these changes. A state field is used to keep track in - changes to the tcp connection state. Id numbers of fragments - can also be stored in the auxiliary space. - - The link records are chained together and initially referenced - from a table in order to shorten lookup time. -*/ - -struct id_data_record /* used to save data about ip fragments */ -{ - u_short id; - u_char protocol; - struct in_addr src_addr; - int active; -}; - -struct id_dat -{ - int index; - struct id_data_record data[N_LINK_ID_DATA]; -}; - -struct ack_data_record /* used to save changes to ack/seq numbers */ -{ - u_long ack_old; - u_long ack_new; - int delta; - int active; -}; - -struct tcp_state /* Information about tcp connection */ -{ - int in; /* State for outside -> inside */ - int out; /* State for inside -> outside */ - int index; /* Index to ack data array */ - int ack_modified; /* Indicates whether ack and seq numbers have - been modified */ -}; - -struct tcp_dat -{ - struct tcp_state state; - struct ack_data_record ack[N_LINK_TCP_DATA]; -}; - -struct link_record /* Main data structure */ -{ - struct in_addr src_addr; - struct in_addr dst_addr; - u_short src_port; - u_short dst_port; - u_short alias_port; - long timestamp; - int passthrough; /* set to 1 if non-aliasing link */ - int link_type; /* Type of link: tcp, udp, icmp, frag */ - int table_index; /* Index number in lookup table */ - int socket; /* Socket used to bind alias port */ - struct link_record *next; /* Pointer to next data structure */ - struct link_record *last; /* Pointer to previous data structure */ - union /* Auxiliary data */ - { - struct id_dat *id; - struct tcp_dat *tcp; - } data; -}; - - - -/* Function Prototypes */ -#include "alias.p" - - - -/* Global Variables - - The global variables listed here are only accessed from - within alias_db.c. -*/ - -struct in_addr aliasAddress; /* Address written onto source */ - /* field of IP packet. */ -struct link_record - *linkTable[LINK_TABLE_SIZE]; /* Lookup table of pointers to */ - /* chains of link records. */ - - -char portTable[ALIAS_PORT_TABLE_SIZE]; /* Table showing which ports */ - /* are in use (no distinction */ - /* is made between TCP and UDP */ -u_short alias_sequence; /* used for aliasing sequence numbers of */ - /* ICMP packets */ - -int icmpLinkCount; /* Storage for link statistics */ -int udpLinkCount; -int tcpLinkCount; -int fragmentLinkCount; - -int cleanupIndex; /* Index to chain of link table being */ - /* inspected for old links */ - -int monitorAlias; /* Debug variable (set to 1 when active) */ -FILE *monitorFile; - - - -/* Internal utility routines (used only in alias_db.c) - - StartPoint -- find lookup table start point - GetNewPort -- find and reserve new alias port number - SetTimestamp -- save last access time - SeqDiff -- difference between two TCP sequences -*/ - -int -StartPoint(dst_addr, dst_port, link_type) -struct in_addr dst_addr; -u_short dst_port; -int link_type; -{ - u_long n; - - n = dst_addr.s_addr; - n += dst_port; - n += link_type; - return(n % LINK_TABLE_SIZE); -} - -u_short -GetNewPort() -{ - int i; - - for (i=0; i<20; i++) - { - int port_offset; - - port_offset = (int) (random() & ALIAS_PORT_MASK); - if (portTable[port_offset] == 0) - { - portTable[port_offset] = 1; - return( htons(ALIAS_PORT_BASE + port_offset) ); - } - } - - fprintf(stderr, - "PacketAlias/GetNewPort: Can't allocate port number.\n"); - return(0); -} - -void -SetTimestamp(clink) -char *clink; -{ - struct link_record *link; - struct timezone tz; - struct timeval tv; - - if (clink != NULL_PTR) - { - link = (struct link_record *) clink; - gettimeofday(&tv, &tz); - link->timestamp = tv.tv_sec; - } -} - -int -SeqDiff(x, y) -u_long x; -u_long y; -{ -/* Return the difference between two TCP sequence numbers */ - -/* - This function is encapsulated in case there are any unusual - arithmetic conditions that need to be considered. -*/ - - return (ntohl(y) - ntohl(x)); -} - -void ShowAliasStats() -{ -/* Used for debugging */ - - fprintf(monitorFile, - "ShowAliasStats: icmp=%d, udp=%d, tcp=%d, frag=%d / tot=%d\n", - icmpLinkCount, udpLinkCount, tcpLinkCount, fragmentLinkCount, - icmpLinkCount+udpLinkCount+tcpLinkCount+fragmentLinkCount); - fflush(monitorFile); -} - - - - -/* Internal routines for finding, deleting and adding links - - CleanupAliasData() - remove all link chains from lookup table - IncrementalCleanup() - look for stale links in a single chain - FindLink1() - find link based on original ports - FindLink2() - find link based on alias port - DeleteLink() - remove link - AddLink() - add link -*/ - -void CleanupAliasData() -{ - struct link_record *link; - int i, icount; - - icount = 0; - for (i=0; i<LINK_TABLE_SIZE; i++) - { - link = linkTable[i]; - linkTable[i] = NULL_PTR; - while (link != NULL_PTR) - { - struct link_record *link_next; - link_next = link->next; icount++; - DeleteLink((char *)link); - link = link_next; - } - } - - icmpLinkCount = 0; - udpLinkCount = 0; - tcpLinkCount = 0; - fragmentLinkCount = 0; - - cleanupIndex =0; -} - -void IncrementalCleanup() -{ - int icount; - long secs; - struct timeval tv; - struct timezone tz; - struct link_record *link; - - gettimeofday(&tv, &tz); - secs = tv.tv_sec; - - icount = 0; - link = linkTable[cleanupIndex++]; - while (link != NULL_PTR) - { - long idelta; - struct link_record *link_next; - - link_next = link->next; - idelta = secs - link->timestamp; - switch (link->link_type) - { - case LINK_ICMP: - if (idelta > ICMP_EXPIRE_TIME) - { - DeleteLink((char *) link); - icount++; - } - break; - case LINK_UDP: - if (idelta > UDP_EXPIRE_TIME) - { - DeleteLink((char *) link); - icount++; - } - break; - case LINK_TCP: - if (idelta > TCP_EXPIRE_TIME) - { - struct tcp_dat *tcp_aux; - - tcp_aux = link->data.tcp; - if (tcp_aux->state.in != 1 - || tcp_aux->state.out != 1) - { - DeleteLink((char *) link); - icount++; - } - } - break; - case LINK_FRAGMENT_ID: - if (idelta > FRAGMENT_EXPIRE_TIME) - { - DeleteLink((char *) link); - icount++; - } - break; - } - link = link_next; - } - - if (cleanupIndex == LINK_TABLE_SIZE) - cleanupIndex = 0; -} - -char * -FindLink1(src_addr, dst_addr, src_port, dst_port, link_type) -struct in_addr src_addr, dst_addr; -u_short src_port, dst_port; -int link_type; -{ - int i; - struct link_record *link; - - i = StartPoint(dst_addr, dst_port, link_type); - link = linkTable[i]; - while (link != NULL_PTR) - { - if (link->src_addr.s_addr == src_addr.s_addr - && link->dst_addr.s_addr == dst_addr.s_addr - && link->dst_port == dst_port - && link->src_port == src_port - && link->link_type == link_type) - { - break; - } - link = link->next; - } - SetTimestamp((char *) link); - IncrementalCleanup(); - return((char *) link); -} - -char * -FindLink2(dst_addr, dst_port, alias_port, link_type) -struct in_addr dst_addr; -u_short dst_port, alias_port; -int link_type; -{ - int i; - struct link_record *link; - - i = StartPoint(dst_addr, dst_port, link_type); - link = linkTable[i]; - while (link != NULL_PTR) - { - if (link->dst_addr.s_addr == dst_addr.s_addr - && link->dst_port == dst_port - && link->alias_port == alias_port - && link->link_type == link_type) - { - break; - } - link = link->next; - } - SetTimestamp((char *) link); - IncrementalCleanup(); - return((char *) link); -} - -void -DeleteLink(clink) -char *clink; -{ - struct link_record *link; - struct link_record *link_last; - struct link_record *link_next; - - link = (struct link_record *) clink; - - link_last = link->last; - link_next = link->next; - - if (link_last != NULL_PTR) - link_last->next = link_next; - else - linkTable[link->table_index] = link->next; - - if (link_next != NULL_PTR) - link_next->last = link_last; - - switch(link->link_type) - { - int port; - - case LINK_ICMP: - icmpLinkCount--; - break; - case LINK_UDP: - udpLinkCount--; - port = ntohs(link->alias_port); - if (port != 0 && link->passthrough == 0) - portTable[port - ALIAS_PORT_BASE] = 0; - break; - case LINK_TCP: - tcpLinkCount--; - port = ntohs(link->alias_port); - if (port != 0 && link->passthrough == 0) - portTable[port - ALIAS_PORT_BASE] = 0; - free(link->data.tcp); - break; - case LINK_FRAGMENT_ID: - fragmentLinkCount--; - free(link->data.id); - break; - } - - free(link); - - if (monitorAlias == 1) - { - ShowAliasStats(); - } -} - -char * -AddLink(src_addr, dst_addr, src_port, dst_port, alias_port, link_type) -struct in_addr src_addr, dst_addr; -u_short src_port, dst_port, alias_port; -int link_type; -{ - int i; - struct link_record *link, *last_link; - - i = StartPoint(dst_addr, dst_port, link_type); - last_link = NULL_PTR; - link = linkTable[i]; - while (link != NULL_PTR) - { - last_link = link; - link = link->next; - } - - link = malloc( sizeof(struct link_record) ); - if (link != NULL_PTR) - { - if (last_link != NULL_PTR) - last_link->next = link; - else - linkTable[i] = link; - link->next = NULL_PTR; - link->table_index = i; - link->last = last_link; - link->src_addr = src_addr; - link->dst_addr = dst_addr; - link->src_port = src_port; - link->dst_port = dst_port; - link->alias_port = 0; - link->link_type = link_type; - link->passthrough = 0; - - switch(link_type) - { - struct id_dat *aux_id; - struct tcp_dat *aux_tcp; - - case LINK_ICMP: - icmpLinkCount++; - link->alias_port = alias_port; - break; - case LINK_UDP: - udpLinkCount++; - link->alias_port = alias_port; - break; - case LINK_TCP: - link->alias_port = alias_port; - aux_tcp = malloc( sizeof(struct tcp_dat) ); - link->data.tcp = aux_tcp; - if (aux_tcp != NULL_PTR) - { - tcpLinkCount++; - aux_tcp->state.in = 0; - aux_tcp->state.out = 0; - aux_tcp->state.index = 0; - aux_tcp->state.ack_modified = 0; - for (i=0; i<N_LINK_TCP_DATA; i++) - aux_tcp->ack[i].active = 0; - } - else - { - fprintf(stderr, - "PacketAlias/AddLink:Cannot allocate auxiliary TCP data" - ); - } - break; - case LINK_FRAGMENT_ID: - aux_id = malloc( sizeof(struct id_dat) ); - link->data.id = aux_id; - if (aux_id != NULL_PTR) - { - fragmentLinkCount++; - aux_id->index = 0; - for (i=0; i<N_LINK_ID_DATA; i++) - aux_id->data[i].active = 0; - } - else - { - fprintf(stderr, - "PacketAlias/AddLink:Cannot allocate auxiliary id data" - ); - } - break; - } - } - else - { - fprintf(stderr, - "PacketAlias/AddLink: Cannot dynamically allocate memory.\n"); - } - - SetTimestamp((char *) link); - IncrementalCleanup(); - - if (monitorAlias == 1) - { - ShowAliasStats(); - } - - return((char *) link); -} - - - -/* External routines for finding/adding links - - FindIcmpIn(), FindIcmpOut() - FindFragmentIn1(), FindFragmentIn2() - FindUdpIn(), FindUdpOut() - FindTcpIn(), FindTcpOut() -*/ - -char * -FindIcmpIn(dst_addr, id, seq_alias) -struct in_addr dst_addr; -u_short id, seq_alias; -{ - return(FindLink2(dst_addr, id, seq_alias, LINK_ICMP)); -} - -char * -FindIcmpOut(src_addr, dst_addr, id, seq) -struct in_addr src_addr, dst_addr; -u_short id, seq; -{ - char *link; - - link = FindLink1(src_addr, dst_addr, seq, id, LINK_ICMP); - if (link == NULL_PTR) - link = AddLink(src_addr, dst_addr, seq, id, - alias_sequence++, LINK_ICMP); - return((char *) link); -} - -char * -FindFragmentIn1(dst_addr) -struct in_addr dst_addr; -{ - char *link; - - link = FindLink2(dst_addr, 0, 0, LINK_FRAGMENT_ID); - if (link == NULL_PTR) - link = AddLink(aliasAddress, dst_addr, 0, 0, 0, LINK_FRAGMENT_ID); - return(link); -} - -char * -FindFragmentIn2(dst_addr) -struct in_addr dst_addr; -{ - return(FindLink2(dst_addr, 0, 0, LINK_FRAGMENT_ID)); -} - -char * -FindUdpIn(dst_addr, dst_port, alias_port) -struct in_addr dst_addr; -u_short dst_port, alias_port; -{ - char *link; - - link = FindLink2(dst_addr, dst_port, alias_port, LINK_UDP); - -#ifdef ALLOW_INCOMING - if (link == NULL_PTR) { - link = AddLink(GetAliasAddress(), dst_addr, - alias_port, dst_port, alias_port, - LINK_UDP); - if (link != NULL_PTR) - ((struct link_record *) link)->passthrough = 1; - } -#endif - - return(link); -} - -char * -FindUdpOut(src_addr, dst_addr, src_port, dst_port) -struct in_addr src_addr, dst_addr; -u_short src_port, dst_port; -{ - char *link; - - link = FindLink1(src_addr, dst_addr, src_port, dst_port, LINK_UDP); - if (link == NULL_PTR) - link = AddLink(src_addr, dst_addr, - src_port, dst_port, GetNewPort(), - LINK_UDP); - return(link); -} - -char * -FindTcpIn(dst_addr, dst_port, alias_port) -struct in_addr dst_addr; -u_short dst_port, alias_port; -{ - char *link; - - link = FindLink2(dst_addr, dst_port, alias_port, LINK_TCP); - -#ifdef ALLOW_INCOMING - if (link == NULL_PTR) - link = AddLink(GetAliasAddress(), dst_addr, - alias_port, dst_port, alias_port, - LINK_TCP); - if (link != NULL_PTR) - ((struct link_record *) link)->passthrough = 1; -#endif - - return(link); -} - -char * -FindTcpOut(src_addr, dst_addr, src_port, dst_port) -struct in_addr src_addr, dst_addr; -u_short src_port, dst_port; -{ - char *link; - - link = FindLink1(src_addr, dst_addr, src_port, dst_port, LINK_TCP); - if (link == NULL_PTR) - link = AddLink(src_addr, dst_addr, - src_port, dst_port, GetNewPort(), - LINK_TCP); - return(link); -} - - - - -/* External routines for getting or changing link data - - SetFragmentData(), GetFragmentData() - SetStateIn(), SetStateOut(), GetStateIn(), GetStateOut() - GetOriginalAddress(), GetDestAddress(), GetAliasAddress() - GetOriginalPort(), GetDestPort(), GetAliasPort() - SetAckModified(), GetAckModified() - GetDeltaAckIn(), GetDeltaSeqOut(), AddSeq() -*/ - -void -SetFragmentData(clink, idnum, protocol, src_addr) -char *clink; -u_short idnum; -u_char protocol; -struct in_addr src_addr; -{ - struct link_record *link; - struct id_dat *idx; - int i; - link = (struct link_record *) clink; - - idx = link->data.id; - if (idx != NULL_PTR) - { - i = idx->index; - idx->data[i].id = idnum; - idx->data[i].protocol = protocol; - idx->data[i].src_addr = src_addr; - idx->data[i].active = 1; - i++; - if (i == N_LINK_ID_DATA) - idx->index = 0; - else - idx->index = i; - } -} - -void -GetFragmentAddr(clink, idnum, protocol, src_addr) -char *clink; -u_short idnum; -u_char protocol; -struct in_addr *src_addr; -{ - struct link_record *link; - int i; - - link = (struct link_record *) clink; - - for (i=0; i<N_LINK_ID_DATA; i++) - { - struct id_dat *idx; - - idx = link->data.id; - - if (idx->data[i].active == 1) - { - if (idx->data[i].id == idnum - && idx->data[i].protocol == protocol) - { - *src_addr = idx->data[i].src_addr; - break; - } - } - } -} - -void -SetStateIn(clink, state) -char *clink; -int state; -{ - struct link_record *link; - -/* TCP input state */ - link = (struct link_record *) clink; - (link->data.tcp)->state.in = state; -} - -void -SetStateOut(clink, state) -char *clink; -int state; -{ - struct link_record *link; - -/* TCP output state */ - link = (struct link_record *) clink; - (link->data.tcp)->state.out = state; -} - -int -GetStateIn(clink) -char *clink; -{ - struct link_record *link; - -/* TCP input state */ - link = (struct link_record *) clink; - return( (link->data.tcp)->state.in); -} - -int -GetStateOut(clink) -char *clink; -{ - struct link_record *link; - -/* TCP output state */ - link = (struct link_record *) clink; - return( (link->data.tcp)->state.out); -} - -struct in_addr -GetOriginalAddress(clink) -char *clink; -{ - struct link_record *link; - - link = (struct link_record *) clink; - return(link->src_addr); -} - -struct in_addr -GetDestAddress(clink) -char *clink; -{ - struct link_record *link; - - link = (struct link_record *) clink; - return(link->dst_addr); -} - -struct in_addr -GetAliasAddress() -{ - return(aliasAddress); -} - -u_short -GetOriginalPort(clink) -char *clink; -{ - struct link_record *link; - - link = (struct link_record *) clink; - return(link->src_port); -} - -u_short -GetDestPort(clink) -char *clink; -{ - struct link_record *link; - - link = (struct link_record *) clink; - return(link->dst_port); -} - -u_short -GetAliasPort(clink) -char *clink; -{ - struct link_record *link; - - link = (struct link_record *) clink; - return(link->alias_port); -} - -void -SetAckModified(clink) -char *clink; -{ - struct link_record *link; - -/* Indicate that ack numbers have been modified in a TCP connection */ - link = (struct link_record *) clink; - (link->data.tcp)->state.ack_modified = 1; -} - -int -GetAckModified(clink) -char *clink; -{ - struct link_record *link; - -/* See if ack numbers have been modified */ - link = (struct link_record *) clink; - return( (link->data.tcp)->state.ack_modified ); -} - -int -GetDeltaAckIn(pip, clink) -struct ip *pip; -char *clink; -{ -/* -Find out how much the ack number has been altered for an incoming -TCP packet. To do this, a circular list is ack numbers where the TCP -packet size was altered is searched. -*/ - - int i; - struct link_record *link; - struct tcphdr *tc; - int delta, ack_diff_min; - u_long ack; - - link = (struct link_record *) clink; - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - ack = tc->th_ack; - - delta = 0; - ack_diff_min = -1; - for (i=0; i<N_LINK_TCP_DATA; i++) - { - struct ack_data_record x; - - x = (link->data.tcp)->ack[i]; - if (x.active == 1) - { - int ack_diff; - - ack_diff = SeqDiff(x.ack_new, ack); - if (ack_diff >= 0) - { - if (ack_diff_min >= 0) - { - if (ack_diff < ack_diff_min) - { - delta = x.delta; - ack_diff_min = ack_diff; - } - } - else - { - delta = x.delta; - ack_diff_min = ack_diff; - } - } - } - } - return (delta); -} - -int -GetDeltaSeqOut(pip, clink) -struct ip *pip; -char *clink; -{ -/* -Find out how much the seq number has been altered for an outgoing -TCP packet. To do this, a circular list is ack numbers where the TCP -packet size was altered is searched. -*/ - - int i; - struct link_record *link; - struct tcphdr *tc; - int delta, seq_diff_min; - u_long seq; - - link = (struct link_record *) clink; - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - seq = tc->th_seq; - - delta = 0; - seq_diff_min = -1; - for (i=0; i<N_LINK_TCP_DATA; i++) - { - struct ack_data_record x; - - x = (link->data.tcp)->ack[i]; - if (x.active == 1) - { - int seq_diff; - - seq_diff = SeqDiff(x.ack_old, seq); - if (seq_diff >= 0) - { - if (seq_diff_min >= 0) - { - if (seq_diff < seq_diff_min) - { - delta = x.delta; - seq_diff_min = seq_diff; - } - } - else - { - delta = x.delta; - seq_diff_min = seq_diff; - } - } - } - } - return (delta); -} - - -void -AddSeq(pip, clink, delta) -struct ip *pip; -char *clink; -int delta; -{ -/* -When a TCP packet has been altered in length, save this -information in a circular list. If enough packets have -been altered, then this list will begin to overwrite itself. -*/ - - struct tcphdr *tc; - struct link_record *link; - struct ack_data_record x; - int hlen, tlen, dlen; - int i; - - link = (struct link_record *) clink; - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - hlen = (pip->ip_hl + tc->th_off) << 2; - tlen = ntohs(pip->ip_len); - dlen = tlen - hlen; - - x.ack_old = htonl(ntohl(tc->th_seq) + dlen); - x.ack_new = htonl(ntohl(tc->th_seq) + dlen + delta); - x.delta = delta; - x.active = 1; - - i = (link->data.tcp)->state.index; - (link->data.tcp)->ack[i] = x; - - i++; - if (i == N_LINK_TCP_DATA) - (link->data.tcp)->state.index = 0; - else - (link->data.tcp)->state.index = i; -} - - - - - - - - -/* Outside world interfaces - - SetAliasAddress() - InitAliasLog() - InitAlias() -*/ - -void -SetAliasAddress(addr) -struct in_addr addr; -{ - aliasAddress = addr; - CleanupAliasData(); - if (monitorAlias == 1) - { - fprintf(monitorFile, - "SetAliasAddress: %s\n", inet_ntoa(aliasAddress)); - fflush(monitorFile); - } -} - -void -InitAliasLog() -{ - monitorAlias = 1; - monitorFile = fopen("/var/log/alias.log", "a"); - printf("Alias log file opened.\n"); -} - -void -InitAlias() -{ - int i; - - for (i=0; i<LINK_TABLE_SIZE; i++) - linkTable[i] = NULL_PTR; - - for (i=0; i<ALIAS_PORT_TABLE_SIZE; i++) - portTable[i] = 0; - - alias_sequence = 0; - - icmpLinkCount = 0; - udpLinkCount = 0; - tcpLinkCount = 0; - fragmentLinkCount = 0; - cleanupIndex =0; - monitorAlias = 0; - - if (mode & MODE_ALIAS) - printf("Packet aliasing enabled.\n"); - -#ifdef MONITOR_ALIAS - InitAliasLog(); -#endif -} diff --git a/usr.sbin/ppp/alias_ftp.c b/usr.sbin/ppp/alias_ftp.c deleted file mode 100644 index 6a682bc..0000000 --- a/usr.sbin/ppp/alias_ftp.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - Alias_ftp.c performs special processing for FTP sessions under - TCP. Specifically, when a PORT command from the client side - is sent, it is intercepted and modified. The address is changed - to the gateway machine and an aliasing port is used. - - For this routine to work, the PORT command must fit entirely - into a single TCP packet. This is typically the case, but exceptions - can easily be envisioned under the actual specifications. - - Probably the most troubling aspect of the approach taken here is - that the new PORT command will typically be a different length, and - this causes a certain amount of bookkeeping to keep track of the - changes of sequence and acknowledgment numbers, since the client - machine is totally unaware of the modification to the TCP stream. - - - This software is placed into the public domain with no restrictions - on its distribution. - - Initial version: August, 1996 (cjm) -*/ - -/* Includes */ -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> - -/* Constants */ -#define FTP_DATA_PORT_NUMBER 20 - -/* Prototypes */ -#include "alias.p" - - -void -HandleFtpOut(pip, link) -struct ip *pip; -char *link; -{ - int hlen, tlen, dlen; - struct in_addr true_addr; - u_short true_port; - char *sptr; - struct tcphdr *tc; - -/* Calculate data length of TCP packet */ - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - hlen = (pip->ip_hl + tc->th_off) << 2; - tlen = ntohs(pip->ip_len); - dlen = tlen - hlen; - -/* Return is data length is too long or too short */ - if (dlen<10 || dlen>80) - return; - -/* Place string pointer and beginning of data */ - sptr = (char *) pip; - sptr += hlen; - -/* Parse through string using state diagram method */ - { - char ch, zero; - int i, state; - u_long a1, a2, a3, a4; - u_short p1, p2; - - a1=0; a2=0; a3=0; a4=0; p1=0; p2=0; - zero = '0'; - state=-4; - for (i=0; i<dlen; i++) - { - ch = sptr[i]; - switch (state) - { - case -4: if (ch == 'P') state=-3; else return; break; - case -3: if (ch == 'O') state=-2; else return; break; - case -2: if (ch == 'R') state=-1; else return; break; - case -1: if (ch == 'T') state= 0; else return; break; - - case 0 : - if (isdigit(ch)) {a1=ch-zero; state=1 ;} break; - case 1 : - if (isdigit(ch)) a1=10*a1+ch-zero; else state=2 ; break; - case 2 : - if (isdigit(ch)) {a2=ch-zero; state=3 ;} break; - case 3 : - if (isdigit(ch)) a2=10*a2+ch-zero; else state=4 ; break; - case 4 : - if (isdigit(ch)) {a3=ch-zero; state=5 ;} break; - case 5 : - if (isdigit(ch)) a3=10*a3+ch-zero; else state=6 ; break; - case 6 : - if (isdigit(ch)) {a4=ch-zero; state=7 ;} break; - case 7 : - if (isdigit(ch)) a4=10*a4+ch-zero; else state=8 ; break; - case 8 : - if (isdigit(ch)) {p1=ch-zero; state=9 ;} break; - case 9 : - if (isdigit(ch)) p1=10*p1+ch-zero; else state=10; break; - case 10: - if (isdigit(ch)) {p2=ch-zero; state=11;} break; - case 11: - if (isdigit(ch)) p2=10*p2+ch-zero; break; - } - } - - if (state == 11) - { - true_port = htons((p1<<8) + p2); - true_addr.s_addr = htonl((a1<<24) + (a2<<16) +(a3<<8) + a4); - NewFtpPortCommand(pip, link, true_addr, true_port); - } - } -} - -void -NewFtpPortCommand(pip, link, true_addr, true_port) -struct ip *pip; -char *link; -struct in_addr true_addr; -u_short true_port; -{ - char *ftp_link; - -/* Establish link to address and port found in PORT command */ - ftp_link = FindTcpOut (true_addr, - GetDestAddress(link), - true_port, - htons(FTP_DATA_PORT_NUMBER)); - - if (ftp_link != NULL_PTR) - { - int slen, hlen, tlen, dlen; - struct tcphdr *tc; - -/* Calculate data length of TCP packet */ - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - hlen = (pip->ip_hl + tc->th_off) << 2; - tlen = ntohs(pip->ip_len); - dlen = tlen - hlen; - -/* Create new PORT command */ - { - char stemp[80]; - char *sptr; - u_short alias_port; - u_char *ptr; - int a1, a2, a3, a4, p1, p2; - struct in_addr aliasAddress; - -/* Decompose alias address into quad format */ - aliasAddress = GetAliasAddress(); - ptr = (char *) &aliasAddress; - a1 = *ptr++; a2=*ptr++; a3=*ptr++; a4=*ptr; - -/* Decompose alias port into pair format */ - alias_port = GetAliasPort(ftp_link); - ptr = (char *) &alias_port; - p1 = *ptr++; p2=*ptr; - -/* Generate command string */ - snprintf(stemp, sizeof(stemp), "PORT %d,%d,%d,%d,%d,%d\r\n", - a1,a2,a3,a4,p1,p2); - -/* Save string length for IP header modification */ - slen = strlen(stemp); - -/* Copy into IP packet */ - sptr = (char *) pip; sptr += hlen; - strcpy(sptr, stemp); - } - -/* Save information regarding modified seq and ack numbers */ - { - int delta; - - SetAckModified(link); - delta = GetDeltaSeqOut(pip, link); - AddSeq(pip, link, delta+slen-dlen); - pip->ip_len = ntohs(hlen + slen); - } - -/* Compute TCP checksum for revised packet */ - tc->th_sum = 0; - tc->th_sum = TcpChecksum(pip); - } - else - { - fprintf(stderr, - "PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n"); - } -} diff --git a/usr.sbin/ppp/alias_util.c b/usr.sbin/ppp/alias_util.c deleted file mode 100644 index a8a5240..0000000 --- a/usr.sbin/ppp/alias_util.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - Alias_util.h contains general utilities used by other functions - in the packet aliasing module. At the moment, there are functions - for computing IP header and TCP packet checksums. - - The checksum routines are based upon example code in a Unix networking - text written by Stevens (sorry, I can't remember the title -- but - at least this is a good author). - - Initial Version: August, 1996 (cjm) -*/ - -/* -Note: the checksum routines assume that the actual checksum word has -been zeroed out. If the checksum workd is filled with the proper value, -then these routines will give a result of zero (useful for testing -purposes); -*/ - -#include <sys/types.h> -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> - -u_short -InternetChecksum(ptr, nbytes) -u_short *ptr; -int nbytes; -{ - int sum, oddbyte; - - sum = 0; - while (nbytes > 1) - { - sum += *ptr++; - nbytes -= 2; - } - if (nbytes == 1) - { - oddbyte = 0; - *((u_char *) &oddbyte) = *(u_char *) ptr; - sum += oddbyte; - } - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - return(~sum); -} - -u_short -IpChecksum(pip) -struct ip *pip; -{ - return( InternetChecksum((u_short *) pip, (pip->ip_hl << 2)) ); - -} - -u_short -TcpChecksum(pip) -struct ip *pip; -{ - u_short *ptr; - struct tcphdr *tc; - int nhdr, ntcp, nbytes; - int sum, oddbyte; - - nhdr = pip->ip_hl << 2; - ntcp = ntohs(pip->ip_len) - nhdr; - - tc = (struct tcphdr *) ((char *) pip + nhdr); - ptr = (u_short *) tc; - -/* Add up TCP header and data */ - nbytes = ntcp; - sum = 0; - while (nbytes > 1) - { - sum += *ptr++; - nbytes -= 2; - } - if (nbytes == 1) - { - oddbyte = 0; - *((u_char *) &oddbyte) = *(u_char *) ptr; - sum += oddbyte; - } - -/* "Pseudo-header" data */ - ptr = (u_short *) &(pip->ip_dst); - sum += *ptr++; - sum += *ptr; - ptr = (u_short *) &(pip->ip_src); - sum += *ptr++; - sum += *ptr; - sum += htons((u_short) ntcp); - sum += htons((u_short) pip->ip_p); - -/* Roll over carry bits */ - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - -/* Return checksum */ - return((u_short) ~sum); -} diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index be5b140..8e0a216 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.c,v 1.46 1997/05/14 01:18:50 brian Exp $ + * $Id: command.c,v 1.47 1997/05/19 01:59:59 brian Exp $ * */ #include <sys/types.h> @@ -25,6 +25,13 @@ #include <termios.h> #include <sys/wait.h> #include <time.h> +#include <netdb.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/route.h> +#include <paths.h> +#include <alias.h> #include "fsm.h" #include "phase.h" #include "lcp.h" @@ -32,21 +39,18 @@ #include "modem.h" #include "filter.h" #include "command.h" +#include "alias_cmd.h" #include "hdlc.h" #include "vars.h" #include "systems.h" #include "chat.h" -#include <netdb.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <net/route.h> #include "os.h" -#include <paths.h> #include "chat.h" extern void Cleanup(), TtyTermMode(), PacketMode(); extern int EnableCommand(), DisableCommand(), DisplayCommand(); extern int AcceptCommand(), DenyCommand(); +static int AliasCommand(); extern int LocalAuthCommand(); extern int LoadCommand(), SaveCommand(); extern int ChangeParity(char *); @@ -283,6 +287,8 @@ struct cmdtab const Commands[] = { "Show status and statictics", "var"}, { "term", NULL, TerminalCommand,LOCAL_AUTH, "Enter to terminal mode", StrNull}, + { "alias", NULL, AliasCommand, LOCAL_AUTH, + "alias control", "option [yes|no]"}, { "quit", "bye", QuitCommand, LOCAL_AUTH | LOCAL_NO_AUTH, "Quit PPP program", "[all]"}, { "help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, @@ -1208,3 +1214,88 @@ char **argv; return(1); } + +static int AliasEnable(); +static int AliasOption(); + + +static struct cmdtab const AliasCommands[] = +{ + { "enable", NULL, AliasEnable, LOCAL_AUTH, + "enable IP aliasing", "[yes|no]"}, + { "port", NULL, AliasRedirectPort, LOCAL_AUTH, + "port redirection", "[proto addr_local:port_local port_alias]"}, + { "addr", NULL, AliasRedirectAddr, LOCAL_AUTH, + "static address translation", "[addr_local addr_alias]"}, + { "deny_incoming", NULL, AliasOption, LOCAL_AUTH, + "stop incoming connections", "[yes|no]", + (void*)PKT_ALIAS_DENY_INCOMING}, + { "log", NULL, AliasOption, LOCAL_AUTH, + "log aliasing link creation", "[yes|no]", + (void*)PKT_ALIAS_LOG}, + { "same_ports", NULL, AliasOption, LOCAL_AUTH, + "try to leave port numbers unchanged", "[yes|no]", + (void*)PKT_ALIAS_SAME_PORTS}, + { "use_sockets", NULL, AliasOption, LOCAL_AUTH, + "allocate host sockets", "[yes|no]", + (void*)PKT_ALIAS_USE_SOCKETS }, + { "unregistered_only", NULL, AliasOption, LOCAL_AUTH, + "alias unregistered (private) IP address space only", "[yes|no]", + (void*)PKT_ALIAS_UNREGISTERED_ONLY}, + { "help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, + "Display this message", StrNull, + (void *)AliasCommands}, + { NULL, NULL, NULL }, +}; + + +static int +AliasCommand(list, argc, argv) +struct cmdtab *list; +int argc; +char **argv; +{ + int val = 1; + + if (argc > 0) + val = FindExec(AliasCommands, argc, argv); + else + printf("Use `alias help' to get a list or `alias help <option>' for syntax h +elp.\n"); + return(val); +} + + +static int +AliasEnable(list, argc, argv) +struct cmdtab *list; +int argc; +char **argv; +{ + if (argc == 1 && strcmp(argv[0], "yes") == 0) { + mode |= MODE_ALIAS; + } else if (argc == 1 && strcmp(argv[0], "no") == 0) { + mode &= ~MODE_ALIAS; + } else { + printf("Usage: alias %s %s\n", list->name, list->syntax); + } + return(1); +} + + +static int +AliasOption(list, argc, argv, param) +struct cmdtab *list; +int argc; +char **argv; +void* param; +{ + if (argc == 1 && strcmp(argv[0], "yes") == 0) { + SetPacketAliasMode((unsigned)param, (unsigned)param); + } else if (argc == 1 && strcmp(argv[0], "no") == 0) { + SetPacketAliasMode(0, (unsigned)param); + } else { + printf("Usage: alias %s %s\n", list->name, list->syntax); + } + return(1); +} diff --git a/usr.sbin/ppp/ip.c b/usr.sbin/ppp/ip.c index ee1fb27..7248fc7 100644 --- a/usr.sbin/ppp/ip.c +++ b/usr.sbin/ppp/ip.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ip.c,v 1.16 1997/05/10 01:22:11 brian Exp $ + * $Id: ip.c,v 1.17 1997/05/19 02:00:00 brian Exp $ * * TODO: * o Return ICMP message for filterd packet @@ -32,9 +32,9 @@ #include <netinet/udp.h> #include <netinet/tcp.h> #include <arpa/inet.h> +#include <alias.h> #include "vars.h" #include "filter.h" -#include "alias.h" extern void SendPppFrame(); extern void LcpClose(); @@ -334,22 +334,68 @@ struct mbuf *bp; /* IN: Pointer to IP pakcet */ } if (mode & MODE_ALIAS) { - PacketAliasIn((struct ip *)tunbuff); - nb = ntohs(((struct ip *)tunbuff)->ip_len); - } + int iresult; + char *fptr; - if ( PacketCheck(tunbuff, nb, FL_IN ) < 0) { - pfree(bp); - return; + iresult = PacketAliasIn(tunbuff, sizeof tunbuff); + nb = ntohs(((struct ip *) tunbuff)->ip_len); + + if (nb > MAX_MRU) { + fprintf(stderr, "Problem with IP header length\n"); + pfree(bp); + return; + } + + if (iresult == PKT_ALIAS_OK + || iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) { + if ( PacketCheck(tunbuff, nb, FL_IN ) < 0) { + pfree(bp); + return; + } + + ipInOctets += nb; + + nb = ntohs(((struct ip *) tunbuff)->ip_len); + nw = write(tun_out, tunbuff, nb); + if (nw != nb) + fprintf(stderr, "wrote %d, got %d\r\n", nb, nw); + + if (iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) { + while ((fptr = GetNextFragmentPtr(tunbuff)) != NULL) { + FragmentAliasIn(tunbuff, fptr); + nb = ntohs(((struct ip *) fptr)->ip_len); + nw = write(tun_out, fptr, nb); + if (nw != nb) + fprintf(stderr, "wrote %d, got %d\r\n", nb, nw); + free(fptr); + } + } + } + else if (iresult == PKT_ALIAS_UNRESOLVED_FRAGMENT) { + nb = ntohs(((struct ip *) tunbuff)->ip_len); + fptr = malloc(nb); + if (fptr == NULL) { + fprintf(stderr, "Cannot allocate memory for fragment\n"); + } + else { + memcpy(fptr, tunbuff, nb); + SaveFragmentPtr(fptr); + } + } } + else + { /* no aliasing */ + if ( PacketCheck(tunbuff, nb, FL_IN ) < 0) + { + pfree(bp); + return; + } - ipInOctets += nb; - /* - * Pass it to tunnel device - */ - nw = write(tun_out, tunbuff, nb); - if (nw != nb) - fprintf(stderr, "wrote %d, got %d\r\n", nb, nw); + ipInOctets += nb; + nw = write(tun_out, tunbuff, nb); + if (nw != nb) + fprintf(stderr, "wrote %d, got %d\r\n", nb, nw); + } pfree(bp); RestartIdleTimer(); diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c index 8ef0f49..5cfc6f7 100644 --- a/usr.sbin/ppp/ipcp.c +++ b/usr.sbin/ppp/ipcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.c,v 1.16 1997/05/10 23:46:29 ache Exp $ + * $Id: ipcp.c,v 1.17 1997/05/19 02:00:02 brian Exp $ * * TODO: * o More RFC1772 backwoard compatibility @@ -31,11 +31,11 @@ #include <netinet/ip.h> #include <arpa/inet.h> #include <sys/socket.h> +#include <alias.h> #include "slcompress.h" #include "os.h" #include "phase.h" #include "vars.h" -#include "alias.h" extern void PutConfValue(); extern void Prompt(); @@ -282,7 +282,7 @@ struct fsm *fp; IpcpStartReport(); StartIdleTimer(); if (mode & MODE_ALIAS) - SetAliasAddress(IpcpInfo.want_ipaddr); + SetPacketAliasAddress(IpcpInfo.want_ipaddr); } void diff --git a/usr.sbin/ppp/main.c b/usr.sbin/ppp/main.c index 40bbbb7..06e5042 100644 --- a/usr.sbin/ppp/main.c +++ b/usr.sbin/ppp/main.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: main.c,v 1.52 1997/05/19 02:00:06 brian Exp $ + * $Id: main.c,v 1.53 1997/05/19 03:02:36 brian Exp $ * * TODO: * o Add commands for traffic summary, version display, etc. @@ -37,6 +37,7 @@ #include <arpa/inet.h> #include <netinet/in_systm.h> #include <netinet/ip.h> +#include <alias.h> #include "modem.h" #include "os.h" #include "hdlc.h" @@ -48,7 +49,6 @@ #include "filter.h" #include "systems.h" #include "ip.h" -#include "alias.h" #include "sig.h" #define LAUTH_M1 "Warning: No password entry for this host in ppp.secret\n" @@ -330,7 +330,7 @@ char **argv; Greetings(); GetUid(); IpcpDefAddress(); - InitAlias(); + InitPacketAlias(); if (SelectSystem("default", CONFFILE) < 0) { fprintf(stderr, "Warning: No default entry is given in config file.\n"); @@ -1022,7 +1022,7 @@ DoLoop() pri = PacketCheck(rbuff, n, FL_DIAL); if (pri >= 0) { if (mode & MODE_ALIAS) { - PacketAliasOut((struct ip *)rbuff); + PacketAliasOut(rbuff, sizeof rbuff); n = ntohs(((struct ip *)rbuff)->ip_len); } IpEnqueue(pri, rbuff, n); @@ -1033,7 +1033,7 @@ DoLoop() pri = PacketCheck(rbuff, n, FL_OUT); if (pri >= 0) { if (mode & MODE_ALIAS) { - PacketAliasOut((struct ip *)rbuff); + PacketAliasOut(rbuff, sizeof rbuff); n = ntohs(((struct ip *)rbuff)->ip_len); } IpEnqueue(pri, rbuff, n); |