From d9520f62e711f9e90f2db3a98bd16ef30eb26a13 Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 12 Jun 2017 18:59:04 +0000 Subject: [PATCH 1/1] network_cmds-543.tar.gz --- .gitignore | 3 + alias/HISTORY | 145 -- alias/alias.c | 1661 ------------- alias/alias.h | 219 -- alias/alias_cuseeme.c | 142 -- alias/alias_db.c | 3096 ------------------------ alias/alias_ftp.c | 606 ----- alias/alias_irc.c | 368 --- alias/alias_local.h | 251 -- alias/alias_nbt.c | 732 ------ alias/alias_pptp.c | 390 --- alias/alias_proxy.c | 865 ------- alias/alias_smedia.c | 501 ---- alias/alias_util.c | 189 -- alias/libalias.3 | 987 -------- ifconfig.tproj/ifconfig.c | 24 +- ifconfig.tproj/iffake.c | 138 ++ ifconfig.tproj/nexus.c | 98 + mptcp_client/conn_lib.c | 60 +- mptcp_client/mptcp_client.1 | 2 - mptcp_client/mptcp_client.c | 345 +-- natd.tproj/HISTORY | 146 -- natd.tproj/README | 50 - natd.tproj/icmp.c | 148 -- natd.tproj/natd.8 | 11 - natd.tproj/natd.c | 2407 ------------------ natd.tproj/natd.cf.sample | 92 - natd.tproj/natd.h | 46 - natd.tproj/natd.test | 14 - netstat.tproj/if.c | 233 +- netstat.tproj/inet.c | 11 + netstat.tproj/inet6.c | 8 +- netstat.tproj/main.c | 10 + netstat.tproj/misc.c | 122 + netstat.tproj/mptcp.c | 5 +- netstat.tproj/netstat.h | 2 + netstat.tproj/route.c | 4 +- network_cmds.xcodeproj/project.pbxproj | 496 +--- ping.tproj/ping.8 | 6 +- ping6.tproj/ping6.8 | 4 +- ping6.tproj/ping6.c | 443 ++-- rtadvd.tproj/rtadvd.c | 3 +- 42 files changed, 801 insertions(+), 14282 deletions(-) delete mode 100644 alias/HISTORY delete mode 100644 alias/alias.c delete mode 100644 alias/alias.h delete mode 100644 alias/alias_cuseeme.c delete mode 100644 alias/alias_db.c delete mode 100644 alias/alias_ftp.c delete mode 100644 alias/alias_irc.c delete mode 100644 alias/alias_local.h delete mode 100644 alias/alias_nbt.c delete mode 100644 alias/alias_pptp.c delete mode 100644 alias/alias_proxy.c delete mode 100644 alias/alias_smedia.c delete mode 100644 alias/alias_util.c delete mode 100644 alias/libalias.3 create mode 100644 ifconfig.tproj/iffake.c create mode 100644 ifconfig.tproj/nexus.c delete mode 100644 natd.tproj/HISTORY delete mode 100644 natd.tproj/README delete mode 100644 natd.tproj/icmp.c delete mode 100644 natd.tproj/natd.8 delete mode 100644 natd.tproj/natd.c delete mode 100644 natd.tproj/natd.cf.sample delete mode 100644 natd.tproj/natd.h delete mode 100644 natd.tproj/natd.test create mode 100644 netstat.tproj/misc.c diff --git a/.gitignore b/.gitignore index 009fb98..919696e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ build *~.m *~.c *~.h +cscope.* +tags +TAGS diff --git a/alias/HISTORY b/alias/HISTORY deleted file mode 100644 index a660135..0000000 --- a/alias/HISTORY +++ /dev/null @@ -1,145 +0,0 @@ -$FreeBSD: src/lib/libalias/HISTORY,v 1.6.2.2 2000/08/18 20:00:00 jhb Exp $ - -Version 1.0: August 11, 1996 (cjm) - -Version 1.1: August 20, 1996 (cjm) - - 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 (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 and NT as well as FreeBSD - traceroute, which uses UDP packets to non-existent - ports. - -Version 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. - - - Checksum error on FTP transfers. Problem - in code located by Martin Renters and - Brian Somers. - -Version 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) - Problem in code located by Ari Suutari. - -Version 1.9: February 1, 1997 (Eivind Eklund ) - - Added support for IRC DCC (ee) - - - Changed the aliasing routines to use ANSI style - throughout (ee) - - - Minor API changes for integration with other - programs than PPP (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) - - Aliasing links are cleared only when a host interface address - changes. - - - 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. PacketAliasRedirectPort() and - PacketAliasRedirectAddr() added to API. - - - Now supports outgoing as well as incoming ICMP - error messages. - -Version 2.2: July, 1997 (cjm) - - Rationalized API function names to all begin with - "PacketAlias..." Old function names are retained - for backwards compatibility. - - - Packet aliasing engine will now free memory of - fragments which are never resolved after a timeout - period. Once a fragment is resolved, it becomes - the users responsibility to free the memory. - -Version 2.3: August 11, 1997 (cjm) - - Problem associated with socket file descriptor - accumulation in alias_db.c corrected. The sockets - had to be closed when a binding failed. Problem - in code located by Gordon Burditt. - -Version 2.4: September 1, 1997 (cjm) - - PKT_ALIAS_UNREGISTERED_ONLY option repaired. - This part of the code was incorrectly re-implemented - in version 2.1. - -Version 2.5: December, 1997 (ee) - - Added PKT_ALIAS_PUNCH_FW mode for firewall - bypass of FTP/IRC DCC data connections. Also added - improved TCP connection monitoring. - -Version 2.6: May, 1998 (amurai) - - Added supporting routine for NetBios over TCP/IP. - -Version 3.0: January 1, 1999 - - Transparent proxying support added. - - PPTP redirecting support added based on patches - contributed by Dru Nelson . - -Version 3.1: May, 2000 (Erik Salander, erik@whistle.com) - - Added support to alias 227 replies, allows aliasing for - FTP servers in passive mode. - - Added support for PPTP aliasing. - -Version 3.2: July, 2000 (Erik Salander, erik@whistle.com and - Junichi Satoh, junichi@junichi.org) - - Added support for streaming media (RTSP and PNA) aliasing. diff --git a/alias/alias.c b/alias/alias.c deleted file mode 100644 index 668dbe1..0000000 --- a/alias/alias.c +++ /dev/null @@ -1,1661 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 2001 Charles Mott - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias.c,v 1.16.2.7 2001/08/21 03:50:25 brian Exp $ - */ - -/* - 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, - fragment handling and the following outside world functional - interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn, - 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, while alias_irc.c does the same for IRC - DCC. Alias_util.c contains a few utility routines. - - Version 1.0 August, 1996 (cjm) - - Version 1.1 August 20, 1996 (cjm) - PPP host accepts incoming connections for ports 0 to 1023. - (Gary Roberts pointed out the need to handle incoming - connections.) - - Version 1.2 September 7, 1996 (cjm) - Fragment handling error in alias_db.c corrected. - (Tom Torrance helped fix this problem.) - - 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. - (Tom Torrance helped fix this problem.) - - Version 1.6 September 18, 1996 (cjm) - Simplified ICMP aliasing scheme. Should now support - traceroute from Win95 as well as FreeBSD. - - Version 1.7 January 9, 1997 (cjm) - - Out-of-order fragment handling. - - IP checksum error fixed for ftp transfers - from aliasing host. - - Integer return codes added to all - aliasing/de-aliasing functions. - - Some obsolete comments cleaned up. - - Differential checksum computations for - IP header (TCP, UDP and ICMP were already - differential). - - Version 2.1 May 1997 (cjm) - - Added support for outgoing ICMP error - messages. - - Added two functions PacketAliasIn2() - and PacketAliasOut2() for dynamic address - control (e.g. round-robin allocation of - incoming packets). - - Version 2.2 July 1997 (cjm) - - Rationalized API function names to begin - with "PacketAlias..." - - Eliminated PacketAliasIn2() and - PacketAliasOut2() as poorly conceived. - - Version 2.3 Dec 1998 (dillon) - - Major bounds checking additions, see FreeBSD/CVS - - Version 3.1 May, 2000 (salander) - - Added hooks to handle PPTP. - - Version 3.2 July, 2000 (salander and satoh) - - Added PacketUnaliasOut routine. - - Added hooks to handle RTSP/RTP. - - See HISTORY file for additional revisions. -*/ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "alias_local.h" -#include "alias.h" - -#define NETBIOS_NS_PORT_NUMBER 137 -#define NETBIOS_DGM_PORT_NUMBER 138 -#define FTP_CONTROL_PORT_NUMBER 21 -#define IRC_CONTROL_PORT_NUMBER_1 6667 -#define IRC_CONTROL_PORT_NUMBER_2 6668 -#define CUSEEME_PORT_NUMBER 7648 -#define RTSP_CONTROL_PORT_NUMBER_1 554 -#define RTSP_CONTROL_PORT_NUMBER_2 7070 -#define PPTP_CONTROL_PORT_NUMBER 1723 - - - - -/* TCP Handling Routines - - TcpMonitorIn() -- These routines monitor TCP connections, and - TcpMonitorOut() delete a link when a connection is closed. - - DoMSSClamp() -- Clamps the MSS of the given TCP header to the - value in packetAliasMSS. - -These routines look for SYN, FIN 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. -*/ - -/* Local prototypes */ -static void TcpMonitorIn(struct ip *, struct alias_link *); - -static void TcpMonitorOut(struct ip *, struct alias_link *); - - -static u_short packetAliasMSS; - -void PacketAliasClampMSS(u_short mss) -{ - packetAliasMSS = mss; -} - -static void DoMSSClamp(struct tcphdr *tc) -{ - u_char *option = (u_char *) tc + sizeof(*tc); - u_char *optionEnd = option + ((tc->th_off << 2) - sizeof(*tc)); - -#define TEST_5618045 0 -#if TEST_5618045 - if ((ntohs(tc->th_dport) == 8080 || ntohs(tc->th_sport) == 8080) && tc->th_off > 5) { - option[0] = 0xF4; - option[1] = 0; - } -#endif - - while (optionEnd > option) - { - /* Bounds checking to avoid infinite loops */ - if (option[0] == TCPOPT_EOL) - break; - - if (option[0] == TCPOPT_NOP) { - ++option; - continue; - } else { - if (optionEnd - option < 2) - break; - if (option[1] < 2 || option + option[1] >= optionEnd) - break; - } - - switch (option[0]) - { - case TCPOPT_MAXSEG: - if (option[1] == 4) - { - u_short *mssPtr = (u_short *) option + 1; - u_short mssVal = ntohs(*mssPtr); - - if (packetAliasMSS < mssVal) - { - int accumulate = mssVal; - int accnetorder = 0 ; - - accumulate -= packetAliasMSS; - *mssPtr = htons(packetAliasMSS); - accnetorder = htons(accumulate); - ADJUST_CHECKSUM(accnetorder, tc->th_sum); - } - - option = optionEnd; - } - break; - - default: - option += option[1]; - break; - } - } -} - -static void -TcpMonitorIn(struct ip *pip, struct alias_link *link) -{ - struct tcphdr *tc; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - switch (GetStateIn(link)) - { - case ALIAS_TCP_STATE_NOT_CONNECTED: - if (tc->th_flags & TH_RST) - SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED); - else if (tc->th_flags & TH_SYN) - { - SetStateIn(link, ALIAS_TCP_STATE_CONNECTED); - - if (packetAliasMSS) - DoMSSClamp(tc); - } - break; - case ALIAS_TCP_STATE_CONNECTED: - if (tc->th_flags & (TH_FIN | TH_RST)) - SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED); - break; - } -} - -static void -TcpMonitorOut(struct ip *pip, struct alias_link *link) -{ - struct tcphdr *tc; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - switch (GetStateOut(link)) - { - case ALIAS_TCP_STATE_NOT_CONNECTED: - if (tc->th_flags & TH_RST) - SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED); - else if (tc->th_flags & TH_SYN) - { - SetStateOut(link, ALIAS_TCP_STATE_CONNECTED); - - if (packetAliasMSS) - DoMSSClamp(tc); - } - break; - case ALIAS_TCP_STATE_CONNECTED: - if (tc->th_flags & (TH_FIN | TH_RST)) - SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED); - break; - } -} - - - - - -/* Protocol Specific Packet Aliasing Routines - - IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2() - IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2() - ProtoAliasIn(), ProtoAliasOut() - 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 ID number is replaced by an alias for the outgoing -packet. - -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 numbers. For TCP packets, there is additional logic in the event -that sequence and ACK numbers have been altered (as in 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 thought of as placeholders. - -All packets go through the aliasing mechanism, whether they come from -the gateway machine or other machines on a local area network. -*/ - - -/* Local prototypes */ -static int IcmpAliasIn1(struct ip *); -static int IcmpAliasIn2(struct ip *); -static int IcmpAliasIn (struct ip *); - -static int IcmpAliasOut1(struct ip *); -static int IcmpAliasOut2(struct ip *); -static int IcmpAliasOut (struct ip *); - -static int ProtoAliasIn(struct ip *); -static int ProtoAliasOut(struct ip *); - -static int UdpAliasOut(struct ip *); -static int UdpAliasIn (struct ip *); - -static int TcpAliasOut(struct ip *, int); -static int TcpAliasIn (struct ip *); - - -static int -IcmpAliasIn1(struct ip *pip) -{ -/* - De-alias incoming echo and timestamp replies. - Alias incoming echo and timestamp requests. -*/ - struct alias_link *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, pip->ip_dst, ic->icmp_id, 1); - if (link != NULL) - { - u_short original_id; - int accumulate; - - original_id = GetOriginalPort(link); - -/* Adjust ICMP checksum */ - accumulate = ic->icmp_id; - accumulate -= original_id; - ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); - -/* Put original sequence number back in */ - ic->icmp_id = original_id; - -/* Put original address back into IP header */ - { - struct in_addr original_address; - - original_address = GetOriginalAddress(link); - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); - pip->ip_dst = original_address; - } - - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - -static int -IcmpAliasIn2(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; - struct alias_link *link; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - ip = &ic->icmp_ip; - - ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2)); - tc = (struct tcphdr *) ud; - ic2 = (struct icmp *) ud; - - if (ip->ip_p == IPPROTO_UDP) - link = FindUdpTcpIn(ip->ip_dst, ip->ip_src, - ud->uh_dport, ud->uh_sport, - IPPROTO_UDP, 0); - else if (ip->ip_p == IPPROTO_TCP) - link = FindUdpTcpIn(ip->ip_dst, ip->ip_src, - tc->th_dport, tc->th_sport, - IPPROTO_TCP, 0); - else if (ip->ip_p == IPPROTO_ICMP) { - if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP) - link = FindIcmpIn(ip->ip_dst, ip->ip_src, ic2->icmp_id, 0); - else - link = NULL; - } else - link = NULL; - - if (link != NULL) - { - 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 */ - 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; - ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); - -/* Un-alias address in IP header */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); - 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 (ip->ip_p == IPPROTO_ICMP) - { - u_short *sptr; - int accumulate; - struct in_addr original_address; - u_short original_id; - - original_address = GetOriginalAddress(link); - original_id = GetOriginalPort(link); - -/* Adjust ICMP checksum */ - sptr = (u_short *) &(ip->ip_src); - accumulate = *sptr++; - accumulate += *sptr; - sptr = (u_short *) &original_address; - accumulate -= *sptr++; - accumulate -= *sptr; - accumulate += ic2->icmp_id; - accumulate -= original_id; - ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); - -/* Un-alias address in IP header */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); - pip->ip_dst = original_address; - -/* Un-alias address of original IP packet and sequence number of - embedded ICMP datagram */ - ip->ip_src = original_address; - ic2->icmp_id = original_id; - } - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - - -static int -IcmpAliasIn(struct ip *pip) -{ - int iresult; - struct icmp *ic; - -/* Return if proxy-only mode is enabled */ - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) - return PKT_ALIAS_OK; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - - iresult = PKT_ALIAS_IGNORED; - switch (ic->icmp_type) - { - case ICMP_ECHOREPLY: - case ICMP_TSTAMPREPLY: - if (ic->icmp_code == 0) - { - iresult = IcmpAliasIn1(pip); - } - break; - case ICMP_UNREACH: - case ICMP_SOURCEQUENCH: - case ICMP_TIMXCEED: - case ICMP_PARAMPROB: - iresult = IcmpAliasIn2(pip); - break; - case ICMP_ECHO: - case ICMP_TSTAMP: - iresult = IcmpAliasIn1(pip); - break; - } - return(iresult); -} - - -static int -IcmpAliasOut1(struct ip *pip) -{ -/* - Alias outgoing echo and timestamp requests. - De-alias outgoing echo and timestamp replies. -*/ - struct alias_link *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, 1); - if (link != NULL) - { - u_short alias_id; - int accumulate; - - alias_id = GetAliasPort(link); - -/* Since data field is being modified, adjust ICMP checksum */ - accumulate = ic->icmp_id; - accumulate -= alias_id; - ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); - -/* Alias sequence number */ - ic->icmp_id = alias_id; - -/* Change source address */ - { - struct in_addr alias_address; - - alias_address = GetAliasAddress(link); - DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, - (u_short *) &pip->ip_src, - 2); - pip->ip_src = alias_address; - } - - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - - -static int -IcmpAliasOut2(struct ip *pip) -{ -/* - Alias outgoing 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; - struct alias_link *link; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - ip = &ic->icmp_ip; - - ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2)); - tc = (struct tcphdr *) ud; - ic2 = (struct icmp *) ud; - - if (ip->ip_p == IPPROTO_UDP) - link = FindUdpTcpOut(ip->ip_dst, ip->ip_src, - ud->uh_dport, ud->uh_sport, - IPPROTO_UDP, 0); - else if (ip->ip_p == IPPROTO_TCP) - link = FindUdpTcpOut(ip->ip_dst, ip->ip_src, - tc->th_dport, tc->th_sport, - IPPROTO_TCP, 0); - else if (ip->ip_p == IPPROTO_ICMP) { - if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP) - link = FindIcmpOut(ip->ip_dst, ip->ip_src, ic2->icmp_id, 0); - else - link = NULL; - } else - link = NULL; - - if (link != NULL) - { - if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) - { - u_short *sptr; - int accumulate; - struct in_addr alias_address; - u_short alias_port; - - alias_address = GetAliasAddress(link); - alias_port = GetAliasPort(link); - -/* Adjust ICMP checksum */ - sptr = (u_short *) &(ip->ip_dst); - accumulate = *sptr++; - accumulate += *sptr; - sptr = (u_short *) &alias_address; - accumulate -= *sptr++; - accumulate -= *sptr; - accumulate += ud->uh_dport; - accumulate -= alias_port; - ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); - -/* - * Alias address in IP header if it comes from the host - * the original TCP/UDP packet was destined for. - */ - if (pip->ip_src.s_addr == ip->ip_dst.s_addr) { - DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, - (u_short *) &pip->ip_src, - 2); - pip->ip_src = alias_address; - } - -/* Alias address and port number of original IP packet -fragment contained in ICMP data section */ - ip->ip_dst = alias_address; - ud->uh_dport = alias_port; - } - else if (ip->ip_p == IPPROTO_ICMP) - { - u_short *sptr; - int accumulate; - struct in_addr alias_address; - u_short alias_id; - - alias_address = GetAliasAddress(link); - alias_id = GetAliasPort(link); - -/* Adjust ICMP checksum */ - sptr = (u_short *) &(ip->ip_dst); - accumulate = *sptr++; - accumulate += *sptr; - sptr = (u_short *) &alias_address; - accumulate -= *sptr++; - accumulate -= *sptr; - accumulate += ic2->icmp_id; - accumulate -= alias_id; - ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); - -/* - * Alias address in IP header if it comes from the host - * the original ICMP message was destined for. - */ - if (pip->ip_src.s_addr == ip->ip_dst.s_addr) { - DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, - (u_short *) &pip->ip_src, - 2); - pip->ip_src = alias_address; - } - -/* Alias address of original IP packet and sequence number of - embedded ICMP datagram */ - ip->ip_dst = alias_address; - ic2->icmp_id = alias_id; - } - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - - -static int -IcmpAliasOut(struct ip *pip) -{ - int iresult; - struct icmp *ic; - -/* Return if proxy-only mode is enabled */ - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) - return PKT_ALIAS_OK; - - ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); - - iresult = PKT_ALIAS_IGNORED; - switch (ic->icmp_type) - { - case ICMP_ECHO: - case ICMP_TSTAMP: - if (ic->icmp_code == 0) - { - iresult = IcmpAliasOut1(pip); - } - break; - case ICMP_UNREACH: - case ICMP_SOURCEQUENCH: - case ICMP_TIMXCEED: - case ICMP_PARAMPROB: - iresult = IcmpAliasOut2(pip); - break; - case ICMP_ECHOREPLY: - case ICMP_TSTAMPREPLY: - iresult = IcmpAliasOut1(pip); - } - return(iresult); -} - - - -static int -ProtoAliasIn(struct ip *pip) -{ -/* - Handle incoming IP packets. The - only thing which is done in this case is to alias - the dest IP address of the packet to our inside - machine. -*/ - struct alias_link *link; - -/* Return if proxy-only mode is enabled */ - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) - return PKT_ALIAS_OK; - - link = FindProtoIn(pip->ip_src, pip->ip_dst, pip->ip_p); - if (link != NULL) - { - struct in_addr original_address; - - original_address = GetOriginalAddress(link); - -/* Restore original IP address */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); - pip->ip_dst = original_address; - - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - - -static int -ProtoAliasOut(struct ip *pip) -{ -/* - Handle outgoing IP packets. The - only thing which is done in this case is to alias - the source IP address of the packet. -*/ - struct alias_link *link; - -/* Return if proxy-only mode is enabled */ - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) - return PKT_ALIAS_OK; - - link = FindProtoOut(pip->ip_src, pip->ip_dst, pip->ip_p); - if (link != NULL) - { - struct in_addr alias_address; - - alias_address = GetAliasAddress(link); - -/* Change source address */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, - (u_short *) &pip->ip_src, - 2); - pip->ip_src = alias_address; - - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - - -static int -UdpAliasIn(struct ip *pip) -{ - struct udphdr *ud; - struct alias_link *link; - -/* Return if proxy-only mode is enabled */ - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) - return PKT_ALIAS_OK; - - ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); - - link = FindUdpTcpIn(pip->ip_src, pip->ip_dst, - ud->uh_sport, ud->uh_dport, - IPPROTO_UDP, 1); - if (link != NULL) - { - struct in_addr alias_address; - struct in_addr original_address; - u_short alias_port; - int accumulate; - u_short *sptr; - int r = 0; - - alias_address = GetAliasAddress(link); - original_address = GetOriginalAddress(link); - alias_port = ud->uh_dport; - ud->uh_dport = GetOriginalPort(link); - -/* Special processing for IP encoding protocols */ - if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) - AliasHandleCUSeeMeIn(pip, original_address); -/* If NETBIOS Datagram, It should be alias address in UDP Data, too */ - else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER - || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) - r = AliasHandleUdpNbt(pip, link, &original_address, ud->uh_dport); - else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER - || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) - r = AliasHandleUdpNbtNS(pip, link, &alias_address, &alias_port, - &original_address, &ud->uh_dport); - -/* If UDP checksum is not zero, then adjust since destination port */ -/* is being unaliased and destination address is being altered. */ - if (ud->uh_sum != 0) - { - accumulate = alias_port; - accumulate -= ud->uh_dport; - sptr = (u_short *) &alias_address; - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &original_address; - accumulate -= *sptr++; - accumulate -= *sptr; - ADJUST_CHECKSUM(accumulate, ud->uh_sum); - } - -/* Restore original IP address */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); - pip->ip_dst = original_address; - - /* - * If we cannot figure out the packet, ignore it. - */ - if (r < 0) - return(PKT_ALIAS_IGNORED); - else - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - -static int -UdpAliasOut(struct ip *pip) -{ - struct udphdr *ud; - struct alias_link *link; - -/* Return if proxy-only mode is enabled */ - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) - return PKT_ALIAS_OK; - - ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); - - link = FindUdpTcpOut(pip->ip_src, pip->ip_dst, - ud->uh_sport, ud->uh_dport, - IPPROTO_UDP, 1); - if (link != NULL) - { - u_short alias_port; - struct in_addr alias_address; - - alias_address = GetAliasAddress(link); - alias_port = GetAliasPort(link); - -/* Special processing for IP encoding protocols */ - if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) - AliasHandleCUSeeMeOut(pip, link); -/* If NETBIOS Datagram, It should be alias address in UDP Data, too */ - else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER - || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) - AliasHandleUdpNbt(pip, link, &alias_address, alias_port); - else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER - || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) - AliasHandleUdpNbtNS(pip, link, &pip->ip_src, &ud->uh_sport, - &alias_address, &alias_port); - -/* If UDP checksum is not zero, adjust since source port is */ -/* being aliased and source address is being altered */ - if (ud->uh_sum != 0) - { - int accumulate; - u_short *sptr; - - 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; - ADJUST_CHECKSUM(accumulate, ud->uh_sum); - } - -/* Put alias port in UDP header */ - ud->uh_sport = alias_port; - -/* Change source address */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, - (u_short *) &pip->ip_src, - 2); - pip->ip_src = alias_address; - - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - - - -static int -TcpAliasIn(struct ip *pip) -{ - struct tcphdr *tc; - struct alias_link *link; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - link = FindUdpTcpIn(pip->ip_src, pip->ip_dst, - tc->th_sport, tc->th_dport, - IPPROTO_TCP, - !(packetAliasMode & PKT_ALIAS_PROXY_ONLY)); - if (link != NULL) - { - struct in_addr alias_address; - struct in_addr original_address; - struct in_addr proxy_address; - u_short alias_port; - u_short proxy_port; - int accumulate; - u_short *sptr; - -/* Special processing for IP encoding protocols */ - if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER - || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) - AliasHandlePptpIn(pip, link); - - alias_address = GetAliasAddress(link); - original_address = GetOriginalAddress(link); - proxy_address = GetProxyAddress(link); - alias_port = tc->th_dport; - tc->th_dport = GetOriginalPort(link); - proxy_port = GetProxyPort(link); - -/* Adjust TCP checksum since destination port is being unaliased */ -/* and destination port is being altered. */ - accumulate = alias_port; - accumulate -= tc->th_dport; - sptr = (u_short *) &alias_address; - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &original_address; - accumulate -= *sptr++; - accumulate -= *sptr; - -/* If this is a proxy, then modify the TCP source port and - checksum accumulation */ - if (proxy_port != 0) - { - accumulate += tc->th_sport; - tc->th_sport = proxy_port; - accumulate -= tc->th_sport; - - sptr = (u_short *) &pip->ip_src; - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &proxy_address; - 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; - } - } - - ADJUST_CHECKSUM(accumulate, tc->th_sum); - -/* Restore original IP address */ - sptr = (u_short *) &pip->ip_dst; - accumulate = *sptr++; - accumulate += *sptr; - pip->ip_dst = original_address; - sptr = (u_short *) &pip->ip_dst; - accumulate -= *sptr++; - accumulate -= *sptr; - -/* If this is a transparent proxy packet, then modify the source - address */ - if (proxy_address.s_addr != 0) - { - sptr = (u_short *) &pip->ip_src; - accumulate += *sptr++; - accumulate += *sptr; - pip->ip_src = proxy_address; - sptr = (u_short *) &pip->ip_src; - accumulate -= *sptr++; - accumulate -= *sptr; - } - - ADJUST_CHECKSUM(accumulate, pip->ip_sum); - -/* Monitor TCP connection state */ - TcpMonitorIn(pip, link); - - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - -static int -TcpAliasOut(struct ip *pip, int maxpacketsize) -{ - int proxy_type; - u_short dest_port; - u_short proxy_server_port; - struct in_addr dest_address; - struct in_addr proxy_server_address; - struct tcphdr *tc; - struct alias_link *link; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - - proxy_type = ProxyCheck(pip, &proxy_server_address, &proxy_server_port); - - if (proxy_type == 0 && (packetAliasMode & PKT_ALIAS_PROXY_ONLY)) - return PKT_ALIAS_OK; - -/* If this is a transparent proxy, save original destination, - then alter the destination and adjust checksums */ - dest_port = tc->th_dport; - dest_address = pip->ip_dst; - if (proxy_type != 0) - { - int accumulate; - u_short *sptr; - - accumulate = tc->th_dport; - tc->th_dport = proxy_server_port; - accumulate -= tc->th_dport; - - sptr = (u_short *) &(pip->ip_dst); - accumulate += *sptr++; - accumulate += *sptr; - sptr = (u_short *) &proxy_server_address; - accumulate -= *sptr++; - accumulate -= *sptr; - - ADJUST_CHECKSUM(accumulate, tc->th_sum); - - sptr = (u_short *) &(pip->ip_dst); - accumulate = *sptr++; - accumulate += *sptr; - pip->ip_dst = proxy_server_address; - sptr = (u_short *) &(pip->ip_dst); - accumulate -= *sptr++; - accumulate -= *sptr; - - ADJUST_CHECKSUM(accumulate, pip->ip_sum); - } - - link = FindUdpTcpOut(pip->ip_src, pip->ip_dst, - tc->th_sport, tc->th_dport, - IPPROTO_TCP, 1); - if (link !=NULL) - { - u_short alias_port; - struct in_addr alias_address; - int accumulate; - u_short *sptr; - -/* Save original destination address, if this is a proxy packet. - Also modify packet to include destination encoding. */ - if (proxy_type != 0) - { - SetProxyPort(link, dest_port); - SetProxyAddress(link, dest_address); - ProxyModify(link, pip, maxpacketsize, proxy_type); - } - -/* Get alias address and port */ - alias_port = GetAliasPort(link); - alias_address = GetAliasAddress(link); - -/* Monitor TCP connection state */ - TcpMonitorOut(pip, link); - -/* Special processing for IP encoding protocols */ - if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER - || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER) - AliasHandleFtpOut(pip, link, maxpacketsize); - else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1 - || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2) - AliasHandleIrcOut(pip, link, maxpacketsize); - else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1 - || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1 - || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2 - || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2) - AliasHandleRtspOut(pip, link, maxpacketsize); - else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER - || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) - AliasHandlePptpOut(pip, link); - -/* Adjust TCP checksum since source port is being aliased */ -/* and source address is being altered */ - accumulate = tc->th_sport; - tc->th_sport = alias_port; - accumulate -= tc->th_sport; - - 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; - } - } - - ADJUST_CHECKSUM(accumulate, tc->th_sum); - -/* Change source address */ - sptr = (u_short *) &(pip->ip_src); - accumulate = *sptr++; - accumulate += *sptr; - pip->ip_src = alias_address; - sptr = (u_short *) &(pip->ip_src); - accumulate -= *sptr++; - accumulate -= *sptr; - - ADJUST_CHECKSUM(accumulate, pip->ip_sum); - - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_IGNORED); -} - - - - -/* 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. Pointers to unresolved fragments can also be -saved and recalled when a header fragment is seen. -*/ - -/* Local prototypes */ -static int FragmentIn(struct ip *); -static int FragmentOut(struct ip *); - - -static int -FragmentIn(struct ip *pip) -{ - struct alias_link *link; - - link = FindFragmentIn2(pip->ip_src, pip->ip_dst, pip->ip_id); - if (link != NULL) - { - struct in_addr original_address; - - GetFragmentAddr(link, &original_address); - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); - pip->ip_dst = original_address; - - return(PKT_ALIAS_OK); - } - return(PKT_ALIAS_UNRESOLVED_FRAGMENT); -} - - -static int -FragmentOut(struct ip *pip) -{ - struct in_addr alias_address; - - alias_address = FindAliasAddress(pip->ip_src); - DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, - (u_short *) &pip->ip_src, - 2); - pip->ip_src = alias_address; - - return(PKT_ALIAS_OK); -} - - - - - - -/* Outside World Access - - PacketAliasSaveFragment() - PacketAliasGetFragment() - PacketAliasFragmentIn() - PacketAliasIn() - PacketAliasOut() - PacketUnaliasOut() - -(prototypes in alias.h) -*/ - - -int -PacketAliasSaveFragment(char *ptr) -{ - int iresult; - struct alias_link *link; - struct ip *pip; - - pip = (struct ip *) ptr; - link = AddFragmentPtrLink(pip->ip_src, pip->ip_id); - iresult = PKT_ALIAS_ERROR; - if (link != NULL) - { - SetFragmentPtr(link, ptr); - iresult = PKT_ALIAS_OK; - } - return(iresult); -} - - -char * -PacketAliasGetFragment(char *ptr) -{ - struct alias_link *link; - char *fptr; - struct ip *pip; - - pip = (struct ip *) ptr; - link = FindFragmentPtr(pip->ip_src, pip->ip_id); - if (link != NULL) - { - GetFragmentPtr(link, &fptr); - SetFragmentPtr(link, NULL); - SetExpire(link, 0); /* Deletes link */ - - return(fptr); - } - else - { - return(NULL); - } -} - - -void -PacketAliasFragmentIn(char *ptr, /* Points to correctly de-aliased - header fragment */ - char *ptr_fragment /* Points to fragment which must - be de-aliased */ - ) -{ - struct ip *pip; - struct ip *fpip; - - pip = (struct ip *) ptr; - fpip = (struct ip *) ptr_fragment; - - DifferentialChecksum(&fpip->ip_sum, - (u_short *) &pip->ip_dst, - (u_short *) &fpip->ip_dst, - 2); - fpip->ip_dst = pip->ip_dst; -} - - -int -PacketAliasIn(char *ptr, int maxpacketsize) -{ - struct in_addr alias_addr; - struct ip *pip; - int iresult; - - if (packetAliasMode & PKT_ALIAS_REVERSE) { - packetAliasMode &= ~PKT_ALIAS_REVERSE; - iresult = PacketAliasOut(ptr, maxpacketsize); - packetAliasMode |= PKT_ALIAS_REVERSE; - return iresult; - } - - HouseKeeping(); - ClearCheckNewLink(); - pip = (struct ip *) ptr; - alias_addr = pip->ip_dst; - - /* Defense against mangled packets */ - if (ntohs(pip->ip_len) > maxpacketsize - || (pip->ip_hl<<2) > maxpacketsize) - return PKT_ALIAS_IGNORED; - - iresult = PKT_ALIAS_IGNORED; - if ( (ntohs(pip->ip_off) & IP_OFFMASK) == 0 ) - { - switch (pip->ip_p) - { - case IPPROTO_ICMP: - iresult = IcmpAliasIn(pip); - break; - case IPPROTO_UDP: - iresult = UdpAliasIn(pip); - break; - case IPPROTO_TCP: - iresult = TcpAliasIn(pip); - break; - case IPPROTO_GRE: - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY || - AliasHandlePptpGreIn(pip) == 0) - iresult = PKT_ALIAS_OK; - else - iresult = ProtoAliasIn(pip); - break; - default: - iresult = ProtoAliasIn(pip); - break; - } - - if (ntohs(pip->ip_off) & IP_MF) - { - struct alias_link *link; - - link = FindFragmentIn1(pip->ip_src, alias_addr, pip->ip_id); - if (link != NULL) - { - iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT; - SetFragmentAddr(link, pip->ip_dst); - } - else - { - iresult = PKT_ALIAS_ERROR; - } - } - } - else - { - iresult = FragmentIn(pip); - } - - return(iresult); -} - - - -/* Unregistered address ranges */ - -/* 10.0.0.0 -> 10.255.255.255 */ -#define UNREG_ADDR_A_LOWER 0x0a000000 -#define UNREG_ADDR_A_UPPER 0x0affffff - -/* 172.16.0.0 -> 172.31.255.255 */ -#define UNREG_ADDR_B_LOWER 0xac100000 -#define UNREG_ADDR_B_UPPER 0xac1fffff - -/* 192.168.0.0 -> 192.168.255.255 */ -#define UNREG_ADDR_C_LOWER 0xc0a80000 -#define UNREG_ADDR_C_UPPER 0xc0a8ffff - -int -PacketAliasOut(char *ptr, /* valid IP packet */ - int maxpacketsize /* How much the packet data may grow - (FTP and IRC inline changes) */ - ) -{ - int iresult; - struct in_addr addr_save; - struct ip *pip; - - if (packetAliasMode & PKT_ALIAS_REVERSE) { - packetAliasMode &= ~PKT_ALIAS_REVERSE; - iresult = PacketAliasIn(ptr, maxpacketsize); - packetAliasMode |= PKT_ALIAS_REVERSE; - return iresult; - } - - HouseKeeping(); - ClearCheckNewLink(); - pip = (struct ip *) ptr; - - /* Defense against mangled packets */ - if (ntohs(pip->ip_len) > maxpacketsize - || (pip->ip_hl<<2) > maxpacketsize) - return PKT_ALIAS_IGNORED; - - addr_save = GetDefaultAliasAddress(); - if (packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY) - { - in_addr_t addr; - int iclass; - - iclass = 0; - addr = ntohl(pip->ip_src.s_addr); - if (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER) - iclass = 3; - else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER) - iclass = 2; - else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER) - iclass = 1; - - if (iclass == 0) - { - SetDefaultAliasAddress(pip->ip_src); - } - } - - iresult = PKT_ALIAS_IGNORED; - if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) - { - switch (pip->ip_p) - { - case IPPROTO_ICMP: - iresult = IcmpAliasOut(pip); - break; - case IPPROTO_UDP: - iresult = UdpAliasOut(pip); - break; - case IPPROTO_TCP: - iresult = TcpAliasOut(pip, maxpacketsize); - break; - case IPPROTO_GRE: - if (AliasHandlePptpGreOut(pip) == 0) - iresult = PKT_ALIAS_OK; - else - iresult = ProtoAliasOut(pip); - break; - default: - iresult = ProtoAliasOut(pip); - break; - } - } - else - { - iresult = FragmentOut(pip); - } - - SetDefaultAliasAddress(addr_save); - return(iresult); -} - -int -PacketUnaliasOut(char *ptr, /* valid IP packet */ - int maxpacketsize /* for error checking */ - ) -{ - struct ip *pip; - struct icmp *ic; - struct udphdr *ud; - struct tcphdr *tc; - struct alias_link *link; - int iresult = PKT_ALIAS_IGNORED; - - pip = (struct ip *) ptr; - - /* Defense against mangled packets */ - if (ntohs(pip->ip_len) > maxpacketsize - || (pip->ip_hl<<2) > maxpacketsize) - return(iresult); - - ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); - tc = (struct tcphdr *) ud; - ic = (struct icmp *) ud; - - /* Find a link */ - if (pip->ip_p == IPPROTO_UDP) - link = FindUdpTcpIn(pip->ip_dst, pip->ip_src, - ud->uh_dport, ud->uh_sport, - IPPROTO_UDP, 0); - else if (pip->ip_p == IPPROTO_TCP) - link = FindUdpTcpIn(pip->ip_dst, pip->ip_src, - tc->th_dport, tc->th_sport, - IPPROTO_TCP, 0); - else if (pip->ip_p == IPPROTO_ICMP) - link = FindIcmpIn(pip->ip_dst, pip->ip_src, ic->icmp_id, 0); - else - link = NULL; - - /* Change it from an aliased packet to an unaliased packet */ - if (link != NULL) - { - if (pip->ip_p == IPPROTO_UDP || pip->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 TCP/UDP checksum */ - sptr = (u_short *) &(pip->ip_src); - accumulate = *sptr++; - accumulate += *sptr; - sptr = (u_short *) &original_address; - accumulate -= *sptr++; - accumulate -= *sptr; - - if (pip->ip_p == IPPROTO_UDP) { - accumulate += ud->uh_sport; - accumulate -= original_port; - ADJUST_CHECKSUM(accumulate, ud->uh_sum); - } else { - accumulate += tc->th_sport; - accumulate -= original_port; - ADJUST_CHECKSUM(accumulate, tc->th_sum); - } - - /* Adjust IP checksum */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_src, - 2); - - /* Un-alias source address and port number */ - pip->ip_src = original_address; - if (pip->ip_p == IPPROTO_UDP) - ud->uh_sport = original_port; - else - tc->th_sport = original_port; - - iresult = PKT_ALIAS_OK; - - } else if (pip->ip_p == IPPROTO_ICMP) { - - u_short *sptr; - int accumulate; - struct in_addr original_address; - u_short original_id; - - original_address = GetOriginalAddress(link); - original_id = GetOriginalPort(link); - - /* Adjust ICMP checksum */ - sptr = (u_short *) &(pip->ip_src); - accumulate = *sptr++; - accumulate += *sptr; - sptr = (u_short *) &original_address; - accumulate -= *sptr++; - accumulate -= *sptr; - accumulate += ic->icmp_id; - accumulate -= original_id; - ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); - - /* Adjust IP checksum */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_src, - 2); - - /* Un-alias source address and port number */ - pip->ip_src = original_address; - ic->icmp_id = original_id; - - iresult = PKT_ALIAS_OK; - } - } - return(iresult); - -} diff --git a/alias/alias.h b/alias/alias.h deleted file mode 100644 index a84dd6c..0000000 --- a/alias/alias.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 2001 Charles Mott - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias.h,v 1.12.2.4 2001/08/01 09:36:40 obrien Exp $ - */ - -/*- - * 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. - */ - -#ifndef _ALIAS_H_ -#define _ALIAS_H_ - -/* Alias link representative (incomplete struct) */ -struct alias_link; - -/* External interfaces (API) to packet aliasing engine */ - -/* Initialization and Control */ - extern void - PacketAliasInit(void); - - extern void - PacketAliasUninit(void); - - extern void - PacketAliasSetAddress(struct in_addr); - - extern unsigned int - PacketAliasSetMode(unsigned int, unsigned int); - -#ifndef NO_FW_PUNCH - extern void - PacketAliasSetFWBase(unsigned int, unsigned int); -#endif - - extern void - PacketAliasClampMSS(u_short mss); - -/* Packet Handling */ - extern int - PacketAliasIn(char *, int maxpacketsize); - - extern int - PacketAliasOut(char *, int maxpacketsize); - - extern int - PacketUnaliasOut(char *, int maxpacketsize); - -/* Port and Address Redirection */ - extern struct alias_link * - PacketAliasRedirectPort(struct in_addr, u_short, - struct in_addr, u_short, - struct in_addr, u_short, - u_char); - - extern int - PacketAliasAddServer(struct alias_link *link, - struct in_addr addr, - u_short port); - - extern struct alias_link * - PacketAliasRedirectProto(struct in_addr, - struct in_addr, - struct in_addr, - u_char); - - extern struct alias_link * - PacketAliasRedirectAddr(struct in_addr, - struct in_addr); - - extern void - PacketAliasRedirectDelete(struct alias_link *); - -/* Fragment Handling */ - extern int - PacketAliasSaveFragment(char *); - - extern char * - PacketAliasGetFragment(char *); - - extern void - PacketAliasFragmentIn(char *, char *); - -/* Miscellaneous Functions */ - extern void - PacketAliasSetTarget(struct in_addr addr); - - extern int - PacketAliasCheckNewLink(void); - - extern u_short - PacketAliasInternetChecksum(u_short *, int); - -/* Transparent Proxying */ - extern int - PacketAliasProxyRule(const char *); - - -/********************** Mode flags ********************/ -/* Set these flags using PacketAliasSetMode() */ - -/* If PKT_ALIAS_LOG is set, a message will be printed to - /var/log/alias.log every time a link is created or deleted. This - is useful for debugging */ -#define PKT_ALIAS_LOG 0x01 - -/* If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g. - to ftp, telnet or web servers will be prevented by the aliasing - mechanism. */ -#define PKT_ALIAS_DENY_INCOMING 0x02 - -/* If PKT_ALIAS_SAME_PORTS is set, packets will be attempted sent from - the same port as they originated on. This allows e.g. rsh to work - *99% of the time*, but _not_ 100%. (It will be slightly flakey - instead of not working at all.) This mode bit is set by - PacketAliasInit(), so it is a default mode of operation. */ -#define PKT_ALIAS_SAME_PORTS 0x04 - -/* If PKT_ALIAS_USE_SOCKETS is set, then when partially specified - links (e.g. destination port and/or address is zero), the packet - aliasing engine will attempt to allocate a socket for the aliasing - port it chooses. This will avoid interference with the host - machine. Fully specified links do not require this. This bit - is set after a call to PacketAliasInit(), so it is a default - mode of operation. */ -#define PKT_ALIAS_USE_SOCKETS 0x08 - -/* If PKT_ALIAS_UNREGISTERED_ONLY is set, then only packets with - unregistered source addresses will be aliased. Private - addresses are those in the following ranges: - 10.0.0.0 -> 10.255.255.255 - 172.16.0.0 -> 172.31.255.255 - 192.168.0.0 -> 192.168.255.255 */ -#define PKT_ALIAS_UNREGISTERED_ONLY 0x10 - -/* If PKT_ALIAS_RESET_ON_ADDR_CHANGE is set, then the table of dynamic - aliasing links will be reset whenever PacketAliasSetAddress() - changes the default aliasing address. If the default aliasing - address is left unchanged by this function call, then the - table of dynamic aliasing links will be left intact. This - bit is set after a call to PacketAliasInit(). */ -#define PKT_ALIAS_RESET_ON_ADDR_CHANGE 0x20 - -#ifndef NO_FW_PUNCH -/* If PKT_ALIAS_PUNCH_FW is set, active FTP and IRC DCC connections - will create a 'hole' in the firewall to allow the transfers to - work. Where (IPFW "line-numbers") the hole is created is - controlled by PacketAliasSetFWBase(base, size). The hole will be - attached to that particular alias_link, so when the link goes away - so do the hole. */ -#define PKT_ALIAS_PUNCH_FW 0x100 -#endif - -/* If PKT_ALIAS_PROXY_ONLY is set, then NAT will be disabled and only - transparent proxying performed */ -#define PKT_ALIAS_PROXY_ONLY 0x40 - -/* If PKT_ALIAS_REVERSE is set, the actions of PacketAliasIn() - and PacketAliasOut() are reversed */ -#define PKT_ALIAS_REVERSE 0x80 - -/* Return Codes */ -#define PKT_ALIAS_ERROR -1 -#define PKT_ALIAS_OK 1 -#define PKT_ALIAS_IGNORED 2 -#define PKT_ALIAS_UNRESOLVED_FRAGMENT 3 -#define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4 - -#endif -/* lint -restore */ diff --git a/alias/alias_cuseeme.c b/alias/alias_cuseeme.c deleted file mode 100644 index a19be96..0000000 --- a/alias/alias_cuseeme.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 1998 Brian Somers - * with the aid of code written by - * Junichi SATOH 1996, 1997. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_cuseeme.c,v 1.2.2.2 2000/10/31 08:48:21 ru Exp $ - */ - -#include -#include -#include -#include -#include - -#include "alias_local.h" - -/* CU-SeeMe Data Header */ -struct cu_header { - u_int16_t dest_family; - u_int16_t dest_port; - u_int32_t dest_addr; - int16_t family; - u_int16_t port; - u_int32_t addr; - u_int32_t seq; - u_int16_t msg; - u_int16_t data_type; - u_int16_t packet_len; -}; - -/* Open Continue Header */ -struct oc_header { - u_int16_t client_count; /* Number of client info structs */ - u_int32_t seq_no; - char user_name[20]; - char reserved[4]; /* flags, version stuff, etc */ -}; - -/* client info structures */ -struct client_info { - u_int32_t address; /* Client address */ - char reserved[8]; /* Flags, pruning bitfield, packet counts etc */ -}; - -void -AliasHandleCUSeeMeOut(struct ip *pip, struct alias_link *link) -{ - struct udphdr *ud; - - ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2)); - if (ntohs(ud->uh_ulen) - sizeof(struct udphdr) >= sizeof(struct cu_header)) { - struct cu_header *cu; - struct alias_link *cu_link; - - cu = (struct cu_header *)(ud + 1); - if (cu->addr) - cu->addr = (u_int32_t)GetAliasAddress(link).s_addr; - - cu_link = FindUdpTcpOut(pip->ip_src, GetDestAddress(link), - ud->uh_dport, 0, IPPROTO_UDP, 1); - -#ifndef NO_FW_PUNCH - if (cu_link) - PunchFWHole(cu_link); -#endif - } -} - -void -AliasHandleCUSeeMeIn(struct ip *pip, struct in_addr original_addr) -{ - struct in_addr alias_addr; - struct udphdr *ud; - struct cu_header *cu; - struct oc_header *oc; - struct client_info *ci; - char *end; - int i; - - alias_addr.s_addr = pip->ip_dst.s_addr; - ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2)); - cu = (struct cu_header *)(ud + 1); - oc = (struct oc_header *)(cu + 1); - ci = (struct client_info *)(oc + 1); - end = (char *)ud + ntohs(ud->uh_ulen); - - if ((char *)oc <= end) { - if(cu->dest_addr) - cu->dest_addr = (u_int32_t)original_addr.s_addr; - if(ntohs(cu->data_type) == 101) - /* Find and change our address */ - for(i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++) - if(ci->address == (u_int32_t)alias_addr.s_addr) { - ci->address = (u_int32_t)original_addr.s_addr; - break; - } - } -} diff --git a/alias/alias_db.c b/alias/alias_db.c deleted file mode 100644 index 81dfff9..0000000 --- a/alias/alias_db.c +++ /dev/null @@ -1,3096 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 2001 Charles Mott - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_db.c,v 1.21.2.12 2001/08/21 03:50:25 brian Exp $ - */ - -/* - 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. Links are also used to store information about - fragments. - - 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. - - - 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. - - Version 1.7: January 9, 1997 (cjm) - Fragment handling simplified. - Saves pointers for unresolved fragments. - Permits links for unspecified remote ports - or unspecified remote addresses. - Fixed bug which did not properly zero port - table entries after a link was deleted. - Cleaned up some obsolete comments. - - Version 1.8: January 14, 1997 (cjm) - Fixed data type error in StartPoint(). - (This error did not exist prior to v1.7 - and was discovered and fixed by Ari Suutari) - - Version 1.9: February 1, 1997 - Optionally, connections initiated from packet aliasing host - machine will will not have their port number aliased unless it - conflicts with an aliasing port already being used. (cjm) - - All options earlier being #ifdef'ed are now available through - a new interface, SetPacketAliasMode(). This allows run time - control (which is now available in PPP+pktAlias through the - 'alias' keyword). (ee) - - Added ability to create an alias port without - either destination address or port specified. - port type = ALIAS_PORT_UNKNOWN_DEST_ALL (ee) - - Removed K&R style function headers - and general cleanup. (ee) - - Added packetAliasMode to replace compiler #defines's (ee) - - Allocates sockets for partially specified - ports if ALIAS_USE_SOCKETS defined. (cjm) - - Version 2.0: March, 1997 - SetAliasAddress() will now clean up alias links - if the aliasing address is changed. (cjm) - - PacketAliasPermanentLink() function added to support permanent - links. (J. Fortes suggested the need for this.) - Examples: - - (192.168.0.1, port 23) <-> alias port 6002, unknown dest addr/port - - (192.168.0.2, port 21) <-> alias port 3604, known dest addr - unknown dest port - - These permanent links allow for incoming connections to - machines on the local network. They can be given with a - user-chosen amount of specificity, with increasing specificity - meaning more security. (cjm) - - Quite a bit of rework to the basic engine. The portTable[] - array, which kept track of which ports were in use was replaced - by a table/linked list structure. (cjm) - - SetExpire() function added. (cjm) - - DeleteLink() no longer frees memory association with a pointer - to a fragment (this bug was first recognized by E. Eklund in - v1.9). - - Version 2.1: May, 1997 (cjm) - Packet aliasing engine reworked so that it can handle - multiple external addresses rather than just a single - host address. - - PacketAliasRedirectPort() and PacketAliasRedirectAddr() - added to the API. The first function is a more generalized - version of PacketAliasPermanentLink(). The second function - implements static network address translation. - - Version 3.2: July, 2000 (salander and satoh) - Added FindNewPortGroup to get contiguous range of port values. - - Added QueryUdpTcpIn and QueryUdpTcpOut to look for an aliasing - link but not actually add one. - - Added FindRtspOut, which is closely derived from FindUdpTcpOut, - except that the alias port (from FindNewPortGroup) is provided - as input. - - See HISTORY file for additional revisions. -*/ - - -/* System include files */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* BSD network include files */ -#include -#include -#include -#include -#include - -#include "alias.h" -#include "alias_local.h" - - - -/* - Constants (note: constants are also defined - near relevant functions or structs) -*/ - -/* Sizes of input and output link tables */ -#define LINK_TABLE_OUT_SIZE 101 -#define LINK_TABLE_IN_SIZE 4001 - -/* Parameters used for cleanup of expired links */ -#define ALIAS_CLEANUP_INTERVAL_SECS 60 -#define ALIAS_CLEANUP_MAX_SPOKES 30 - -/* Timeouts (in seconds) for different link types */ -#define ICMP_EXPIRE_TIME 60 -#define UDP_EXPIRE_TIME 60 -#define PROTO_EXPIRE_TIME 60 -#define FRAGMENT_ID_EXPIRE_TIME 10 -#define FRAGMENT_PTR_EXPIRE_TIME 30 - -/* TCP link expire time for different cases */ -/* When the link has been used and closed - minimal grace time to - allow ACKs and potential re-connect in FTP (XXX - is this allowed?) */ -#ifndef TCP_EXPIRE_DEAD -# define TCP_EXPIRE_DEAD 10 -#endif - -/* When the link has been used and closed on one side - the other side - is allowed to still send data */ -#ifndef TCP_EXPIRE_SINGLEDEAD -# define TCP_EXPIRE_SINGLEDEAD 90 -#endif - -/* When the link isn't yet up */ -#ifndef TCP_EXPIRE_INITIAL -# define TCP_EXPIRE_INITIAL 300 -#endif - -/* When the link is up */ -#ifndef TCP_EXPIRE_CONNECTED -# define TCP_EXPIRE_CONNECTED 86400 -#endif - - -static int iChatAVHack = 1; - - -/* Dummy port number codes used for FindLinkIn/Out() and AddLink(). - These constants can be anything except zero, which indicates an - unknown port number. */ - -#define NO_DEST_PORT 1 -#define NO_SRC_PORT 1 - - - -/* Data Structures - - The fundamental data structure used in this program is - "struct alias_link". 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, the source port is treated as being equivalent - with the 16-bit ID number of the ICMP packet. - - The link record also can store some auxiliary data. 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. Pointers to unresolved - fragments can also be stored. - - The link records support two independent chainings. Lookup - tables for input and out tables hold the initial pointers - the link chains. On input, the lookup table indexes on alias - port and link type. On output, the lookup table indexes on - source address, destination address, source port, destination - port and link type. -*/ - -struct ack_data_record /* used to save changes to ACK/sequence numbers */ -{ - __uint32_t ack_old; - __uint32_t 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 sequence numbers */ - /* been modified */ -}; - -#define N_LINK_TCP_DATA 3 /* Number of distinct ACK number changes - saved for a modified TCP stream */ -struct tcp_dat -{ - struct tcp_state state; - struct ack_data_record ack[N_LINK_TCP_DATA]; - int fwhole; /* Which firewall record is used for this hole? */ -}; - -struct server /* LSNAT server pool (circular list) */ -{ - struct in_addr addr; - u_short port; - struct server *next; -}; - -struct alias_link /* Main data structure */ -{ - struct in_addr src_addr; /* Address and port information */ - struct in_addr dst_addr; - struct in_addr alias_addr; - struct in_addr proxy_addr; - u_short src_port; - u_short dst_port; - u_short alias_port; - u_short proxy_port; - struct server *server; - - int link_type; /* Type of link: TCP, UDP, ICMP, proto, frag */ - -/* values for link_type */ -#define LINK_ICMP IPPROTO_ICMP -#define LINK_UDP IPPROTO_UDP -#define LINK_TCP IPPROTO_TCP -#define LINK_FRAGMENT_ID (IPPROTO_MAX + 1) -#define LINK_FRAGMENT_PTR (IPPROTO_MAX + 2) -#define LINK_ADDR (IPPROTO_MAX + 3) -#define LINK_PPTP (IPPROTO_MAX + 4) - - int flags; /* indicates special characteristics */ - -/* flag bits */ -#define LINK_UNKNOWN_DEST_PORT 0x01 -#define LINK_UNKNOWN_DEST_ADDR 0x02 -#define LINK_PERMANENT 0x04 -#define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */ -#define LINK_UNFIREWALLED 0x08 -#define LINK_LAST_LINE_CRLF_TERMED 0x10 -#define LINK_CONE 0x20 - - int timestamp; /* Time link was last accessed */ - int expire_time; /* Expire time for link */ - - int sockfd; /* socket descriptor */ - - LIST_ENTRY(alias_link) list_out; /* Linked list of pointers for */ - LIST_ENTRY(alias_link) list_in; /* input and output lookup tables */ - - union /* Auxiliary data */ - { - char *frag_ptr; - struct in_addr frag_addr; - struct tcp_dat *tcp; - } data; -}; - - - - - -/* Global Variables - - The global variables listed here are only accessed from - within alias_db.c and so are prefixed with the static - designation. -*/ - -int packetAliasMode; /* Mode flags */ - /* - documented in alias.h */ - -static struct in_addr aliasAddress; /* Address written onto source */ - /* field of IP packet. */ - -static struct in_addr targetAddress; /* IP address incoming packets */ - /* are sent to if no aliasing */ - /* link already exists */ - -static struct in_addr nullAddress; /* Used as a dummy parameter for */ - /* some function calls */ -static LIST_HEAD(, alias_link) -linkTableOut[LINK_TABLE_OUT_SIZE]; /* Lookup table of pointers to */ - /* chains of link records. Each */ -static LIST_HEAD(, alias_link) /* link record is doubly indexed */ -linkTableIn[LINK_TABLE_IN_SIZE]; /* into input and output lookup */ - /* tables. */ - -static int icmpLinkCount; /* Link statistics */ -static int udpLinkCount; -static int tcpLinkCount; -static int pptpLinkCount; -static int protoLinkCount; -static int fragmentIdLinkCount; -static int fragmentPtrLinkCount; -static int sockCount; - -static int cleanupIndex; /* Index to chain of link table */ - /* being inspected for old links */ - -static int timeStamp; /* System time in seconds for */ - /* current packet */ - -static int lastCleanupTime; /* Last time IncrementalCleanup() */ - /* was called */ - -static int houseKeepingResidual; /* used by HouseKeeping() */ - -static int deleteAllLinks; /* If equal to zero, DeleteLink() */ - /* will not remove permanent links */ - -static FILE *monitorFile; /* File descriptor for link */ - /* statistics monitoring file */ - -static int newDefaultLink; /* Indicates if a new aliasing */ - /* link has been created after a */ - /* call to PacketAliasIn/Out(). */ - -#ifndef NO_FW_PUNCH -static int fireWallFD = -1; /* File descriptor to be able to */ - /* control firewall. Opened by */ - /* PacketAliasSetMode on first */ - /* setting the PKT_ALIAS_PUNCH_FW */ - /* flag. */ -#endif - - - - - - - -/* Internal utility routines (used only in alias_db.c) - -Lookup table starting points: - StartPointIn() -- link table initial search point for - incoming packets - StartPointOut() -- link table initial search point for - outgoing packets - -Miscellaneous: - SeqDiff() -- difference between two TCP sequences - ShowAliasStats() -- send alias statistics to a monitor file -*/ - - -/* Local prototypes */ -static u_int StartPointIn(struct in_addr, u_short, int); - -static u_int StartPointOut(struct in_addr, struct in_addr, - u_short, u_short, int); - -static int SeqDiff(__uint32_t, __uint32_t); - -#ifndef DEBUG -static void ShowAliasStats(void); -#endif - -#ifndef NO_FW_PUNCH -/* Firewall control */ -static void InitPunchFW(void); -static void UninitPunchFW(void); -static void ClearFWHole(struct alias_link *link); -#endif - -/* Log file control */ -static void InitPacketAliasLog(void); -static void UninitPacketAliasLog(void); - -static u_int -StartPointIn(struct in_addr alias_addr, - u_short alias_port, - int link_type) -{ - u_int n; - - n = alias_addr.s_addr; - if (link_type != LINK_PPTP) - n += alias_port; - n += link_type; - return(n % LINK_TABLE_IN_SIZE); -} - - -static u_int -StartPointOut(struct in_addr src_addr, struct in_addr dst_addr, - u_short src_port, u_short dst_port, int link_type) -{ - u_int n; - - n = src_addr.s_addr; - n += dst_addr.s_addr; - if (link_type != LINK_PPTP) { - n += src_port; - n += dst_port; - } - n += link_type; - - return(n % LINK_TABLE_OUT_SIZE); -} - - -static int -SeqDiff(__uint32_t x, __uint32_t 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)); -} - - -#ifndef DEBUG -static void -ShowAliasStats(void) -{ -/* Used for debugging */ - - if (monitorFile) - { - fprintf(monitorFile, "icmp=%d, udp=%d, tcp=%d, pptp=%d, proto=%d, frag_id=%d frag_ptr=%d", - icmpLinkCount, - udpLinkCount, - tcpLinkCount, - pptpLinkCount, - protoLinkCount, - fragmentIdLinkCount, - fragmentPtrLinkCount); - - fprintf(monitorFile, " / tot=%d (sock=%d)\n", - icmpLinkCount + udpLinkCount - + tcpLinkCount - + pptpLinkCount - + protoLinkCount - + fragmentIdLinkCount - + fragmentPtrLinkCount, - sockCount); - - fflush(monitorFile); - } -} -#endif - - - - - -/* Internal routines for finding, deleting and adding links - -Port Allocation: - GetNewPort() -- find and reserve new alias port number - GetSocket() -- try to allocate a socket for a given port - -Link creation and deletion: - CleanupAliasData() - remove all link chains from lookup table - IncrementalCleanup() - look for stale links in a single chain - DeleteLink() - remove link - AddLink() - add link - ReLink() - change link - -Link search: - FindLinkOut() - find link for outgoing packets - FindLinkIn() - find link for incoming packets - -Port search: - FindNewPortGroup() - find an available group of ports -*/ - -/* Local prototypes */ -static int GetNewPort(struct alias_link *, int); - -static u_short GetSocket(u_short, int *, int); - -static void CleanupAliasData(void); - -static void IncrementalCleanup(void); - -static void DeleteLink(struct alias_link *); - -static struct alias_link * -AddLink(struct in_addr, struct in_addr, struct in_addr, - u_short, u_short, int, int); - -static struct alias_link * -ReLink(struct alias_link *, - struct in_addr, struct in_addr, struct in_addr, - u_short, u_short, int, int); - -static struct alias_link * -FindLinkOut(struct in_addr, struct in_addr, u_short, u_short, int, int); - -static struct alias_link * -FindLinkIn(struct in_addr, struct in_addr, u_short, u_short, int, int); - - -#define ALIAS_PORT_BASE 0x08000 -#define ALIAS_PORT_MASK 0x07fff -#define ALIAS_PORT_MASK_EVEN 0x07ffe -#define GET_NEW_PORT_MAX_ATTEMPTS 20 - -#define GET_ALIAS_PORT -1 -#define GET_ALIAS_EPHEMERAL_PORT -2 -#define GET_ALIAS_ID GET_ALIAS_PORT - -#define FIND_EVEN_ALIAS_BASE 1 - -/* GetNewPort() allocates port numbers. Note that if a port number - is already in use, that does not mean that it cannot be used by - another link concurrently. This is because GetNewPort() looks for - unused triplets: (dest addr, dest port, alias port). */ - -static int -GetEphemeralPort(struct alias_link *link) -{ - int i; - - /* Port number search */ - for (i=0; i < GET_NEW_PORT_MAX_ATTEMPTS; i++) - { - struct sockaddr_in sock_addr; - socklen_t salen; - u_short port_net; - struct alias_link *search_result; - - if (GetSocket(0, &link->sockfd, link->link_type) == 0) - return -1; - salen = sizeof(struct sockaddr_in); - if (getsockname(link->sockfd, (struct sockaddr *)&sock_addr, &salen) == -1) - return -1; - port_net = sock_addr.sin_port; - - search_result = FindLinkIn(link->dst_addr, link->alias_addr, - link->dst_port, port_net, - link->link_type, 0); - - if (search_result == NULL) { - link->alias_port = port_net; - return(0); - } - close(link->sockfd); - link->sockfd = -1; - } - #ifdef DEBUG - fprintf(stderr, "PacketAlias/GetEphemeralPort(): "); - fprintf(stderr, "could not find free port\n"); - #endif - - return(-1); -} - -static int -GetNewPort(struct alias_link *link, int alias_port_param) -{ - int i; - int max_trials; - u_short port_sys; - u_short port_net; - - if (alias_port_param == GET_ALIAS_EPHEMERAL_PORT) - return GetEphemeralPort(link); - -/* - Description of alias_port_param for GetNewPort(). When - this parameter is zero or positive, it precisely specifies - the port number. GetNewPort() will return this number - without check that it is in use. - - When this parameter is GET_ALIAS_PORT, it indicates to get a randomly - selected port number. -*/ - if (alias_port_param == GET_ALIAS_PORT) - { - /* - * The aliasing port is automatically selected - * by one of two methods below: - */ - max_trials = GET_NEW_PORT_MAX_ATTEMPTS; - - if (packetAliasMode & PKT_ALIAS_SAME_PORTS) - { - /* - * When the PKT_ALIAS_SAME_PORTS option is - * chosen, the first try will be the - * actual source port. If this is already - * in use, the remainder of the trials - * will be random. - */ - port_net = link->src_port; - port_sys = ntohs(port_net); - } - else - { - /* First trial and all subsequent are random. */ - port_sys = random() & ALIAS_PORT_MASK; - port_sys += ALIAS_PORT_BASE; - port_net = htons(port_sys); - } - } - else if (alias_port_param >= 0 && alias_port_param < 0x10000) - { - link->alias_port = (u_short) alias_port_param; - return(0); - } - else - { -#ifdef DEBUG - fprintf(stderr, "PacketAlias/GetNewPort(): "); - fprintf(stderr, "input parameter error\n"); -#endif - return(-1); - } - - -/* Port number search */ - for (i=0; idst_addr, link->alias_addr, - link->dst_port, port_net, - link->link_type, 0); - - if (search_result == NULL) - go_ahead = 1; - else if (!(link->flags & LINK_PARTIALLY_SPECIFIED) - && (search_result->flags & LINK_PARTIALLY_SPECIFIED)) - go_ahead = 1; - else - go_ahead = 0; - - if (go_ahead) - { - if ((packetAliasMode & PKT_ALIAS_USE_SOCKETS) - && (link->flags & LINK_PARTIALLY_SPECIFIED) - && ((link->link_type == LINK_TCP) || - (link->link_type == LINK_UDP))) - { - if (GetSocket(port_net, &link->sockfd, link->link_type)) - { - link->alias_port = port_net; - return(0); - } - } - else - { - link->alias_port = port_net; - return(0); - } - } - - port_sys = random() & ALIAS_PORT_MASK; - port_sys += ALIAS_PORT_BASE; - port_net = htons(port_sys); - } -#ifdef DEBUG - fprintf(stderr, "PacketAlias/GetnewPort(): "); - fprintf(stderr, "could not find free port\n"); -#endif - - return(-1); -} - - -static u_short -GetSocket(u_short port_net, int *sockfd, int link_type) -{ - int err; - int sock; - struct sockaddr_in sock_addr; - - if (link_type == LINK_TCP) - sock = socket(AF_INET, SOCK_STREAM, 0); - else if (link_type == LINK_UDP) - sock = socket(AF_INET, SOCK_DGRAM, 0); - else - { -#ifdef DEBUG - fprintf(stderr, "PacketAlias/GetSocket(): "); - fprintf(stderr, "incorrect link type\n"); -#endif - return(0); - } - - if (sock < 0) - { -#ifdef DEBUG - fprintf(stderr, "PacketAlias/GetSocket(): "); - fprintf(stderr, "socket() error %d\n", *sockfd); -#endif - return(0); - } - - sock_addr.sin_family = AF_INET; - sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); - sock_addr.sin_port = port_net; - - err = bind(sock, - (struct sockaddr *) &sock_addr, - sizeof(sock_addr)); - if (err == 0) - { - sockCount++; - *sockfd = sock; - return(1); - } - else - { - close(sock); - return(0); - } -} - - -/* FindNewPortGroup() returns a base port number for an available - range of contiguous port numbers. Note that if a port number - is already in use, that does not mean that it cannot be used by - another link concurrently. This is because FindNewPortGroup() - looks for unused triplets: (dest addr, dest port, alias port). */ - -int -FindNewPortGroup(struct in_addr dst_addr, - struct in_addr alias_addr, - u_short src_port, - u_short dst_port, - u_short port_count, - u_char proto, - u_char align) -{ - int i, j; - int max_trials; - u_short port_sys; - int link_type; - - /* - * Get link_type from protocol - */ - - switch (proto) - { - case IPPROTO_UDP: - link_type = LINK_UDP; - break; - case IPPROTO_TCP: - link_type = LINK_TCP; - break; - default: - return (0); - break; - } - - /* - * The aliasing port is automatically selected - * by one of two methods below: - */ - max_trials = GET_NEW_PORT_MAX_ATTEMPTS; - - if (packetAliasMode & PKT_ALIAS_SAME_PORTS) { - /* - * When the ALIAS_SAME_PORTS option is - * chosen, the first try will be the - * actual source port. If this is already - * in use, the remainder of the trials - * will be random. - */ - port_sys = ntohs(src_port); - - } else { - - /* First trial and all subsequent are random. */ - if (align == FIND_EVEN_ALIAS_BASE) - port_sys = random() & ALIAS_PORT_MASK_EVEN; - else - port_sys = random() & ALIAS_PORT_MASK; - - port_sys += ALIAS_PORT_BASE; - } - -/* Port number search */ - for (i = 0; i < max_trials; i++) { - - struct alias_link *search_result; - - for (j = 0; j < port_count; j++) - if (0 != (search_result = FindLinkIn(dst_addr, alias_addr, - dst_port, htons(port_sys + j), - link_type, 0))) - break; - - /* Found a good range, return base */ - if (j == port_count) - return (htons(port_sys)); - - /* Find a new base to try */ - if (align == FIND_EVEN_ALIAS_BASE) - port_sys = random() & ALIAS_PORT_MASK_EVEN; - else - port_sys = random() & ALIAS_PORT_MASK; - - port_sys += ALIAS_PORT_BASE; - } - -#ifdef DEBUG - fprintf(stderr, "PacketAlias/FindNewPortGroup(): "); - fprintf(stderr, "could not find free port(s)\n"); -#endif - - return(0); -} - -static void -CleanupAliasData(void) -{ - struct alias_link *link; - int i, icount; - - icount = 0; - for (i=0; itimestamp; - switch (link->link_type) - { - case LINK_TCP: - if (idelta > link->expire_time) - { - struct tcp_dat *tcp_aux; - - tcp_aux = link->data.tcp; - if (tcp_aux->state.in != ALIAS_TCP_STATE_CONNECTED - || tcp_aux->state.out != ALIAS_TCP_STATE_CONNECTED) - { - DeleteLink(link); - icount++; - } - } - break; - default: - if (idelta > link->expire_time) - { - DeleteLink(link); - icount++; - } - break; - } - link = link_next; - } - - if (cleanupIndex == LINK_TABLE_OUT_SIZE) - cleanupIndex = 0; -} - -static void -DeleteLink(struct alias_link *link) -{ - -/* Don't do anything if the link is marked permanent */ - if (deleteAllLinks == 0 && link->flags & LINK_PERMANENT) - return; - -#ifndef NO_FW_PUNCH -/* Delete associated firewall hole, if any */ - ClearFWHole(link); -#endif - -/* Free memory allocated for LSNAT server pool */ - if (link->server != NULL) { - struct server *head, *curr, *next; - - head = curr = link->server; - do { - next = curr->next; - free(curr); - } while ((curr = next) != head); - } - -/* Adjust output table pointers */ - LIST_REMOVE(link, list_out); - -/* Adjust input table pointers */ - LIST_REMOVE(link, list_in); - -/* Close socket, if one has been allocated */ - if (link->sockfd != -1) - { - sockCount--; - close(link->sockfd); - } - -/* Link-type dependent cleanup */ - switch(link->link_type) - { - case LINK_ICMP: - icmpLinkCount--; - break; - case LINK_UDP: - udpLinkCount--; - break; - case LINK_TCP: - tcpLinkCount--; - free(link->data.tcp); - break; - case LINK_PPTP: - pptpLinkCount--; - break; - case LINK_FRAGMENT_ID: - fragmentIdLinkCount--; - break; - case LINK_FRAGMENT_PTR: - fragmentPtrLinkCount--; - if (link->data.frag_ptr != NULL) - free(link->data.frag_ptr); - break; - case LINK_ADDR: - break; - default: - protoLinkCount--; - break; - } - -#ifdef DEBUG - if ((packetAliasMode & PKT_ALIAS_LOG) != 0 && - !IN_MULTICAST(link->src_addr.s_addr) && - !IN_MULTICAST(link->dst_addr.s_addr)) - { - char src[16]; - char dst[16]; - char alias[16]; - char *proto; - switch(link->link_type) - { - case LINK_TCP: - proto = " [TCP]"; - break; - case LINK_UDP: - proto = " [UDP]"; - break; - default: - proto = ""; - } - fprintf(monitorFile, "Deleted%s %s:%d<->%s:%d to %s:%d<->%s:%d\n", - proto, - inet_ntop(AF_INET, &link->src_addr, src, sizeof(src)), link->src_port, - inet_ntop(AF_INET, &link->dst_addr, dst, sizeof(dst)), link->dst_port, - inet_ntop(AF_INET, &link->alias_addr, alias, sizeof(alias)), link->alias_port, - dst, link->dst_port); - fflush(monitorFile); - } -#else - if (packetAliasMode & PKT_ALIAS_LOG) - ShowAliasStats(); -#endif - -/* Free memory */ - free(link); -} - - -static struct alias_link * -AddLink(struct in_addr src_addr, - struct in_addr dst_addr, - struct in_addr alias_addr, - u_short src_port, - u_short dst_port, - int alias_port_param, /* if less than zero, alias */ - int link_type) /* port will be automatically */ -{ /* chosen. If greater than */ - u_int start_point; /* zero, equal to alias port */ - struct alias_link *link; - - link = malloc(sizeof(struct alias_link)); - if (link != NULL) - { - /* Basic initialization */ - link->src_addr = src_addr; - link->dst_addr = dst_addr; - link->alias_addr = alias_addr; - link->proxy_addr.s_addr = INADDR_ANY; - link->src_port = src_port; - link->dst_port = dst_port; - link->proxy_port = 0; - link->server = NULL; - link->link_type = link_type; - link->sockfd = -1; - link->flags = 0; - link->timestamp = timeStamp; - - /* Expiration time */ - switch (link_type) - { - case LINK_ICMP: - link->expire_time = ICMP_EXPIRE_TIME; - break; - case LINK_UDP: - if (dst_addr.s_addr == 0 && dst_port == 0) - link->expire_time = UDP_EXPIRE_TIME * 5; - else - link->expire_time = UDP_EXPIRE_TIME; - break; - case LINK_TCP: - link->expire_time = TCP_EXPIRE_INITIAL; - break; - case LINK_PPTP: - link->flags |= LINK_PERMANENT; /* no timeout. */ - break; - case LINK_FRAGMENT_ID: - link->expire_time = FRAGMENT_ID_EXPIRE_TIME; - break; - case LINK_FRAGMENT_PTR: - link->expire_time = FRAGMENT_PTR_EXPIRE_TIME; - break; - case LINK_ADDR: - break; - default: - link->expire_time = PROTO_EXPIRE_TIME; - break; - } - - /* Determine alias flags */ - if (dst_addr.s_addr == INADDR_ANY) - link->flags |= LINK_UNKNOWN_DEST_ADDR; - if (dst_port == 0) - link->flags |= LINK_UNKNOWN_DEST_PORT; - - /* Determine alias port */ - if (GetNewPort(link, alias_port_param) != 0) - { - free(link); - return(NULL); - } - /* Link-type dependent initialization */ - switch(link_type) - { - struct tcp_dat *aux_tcp; - - case LINK_ICMP: - icmpLinkCount++; - break; - case LINK_UDP: - udpLinkCount++; - break; - case LINK_TCP: - aux_tcp = malloc(sizeof(struct tcp_dat)); - if (aux_tcp != NULL) - { - int i; - - tcpLinkCount++; - aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED; - aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED; - aux_tcp->state.index = 0; - aux_tcp->state.ack_modified = 0; - for (i=0; iack[i].active = 0; - aux_tcp->fwhole = -1; - link->data.tcp = aux_tcp; - } - else - { -#ifdef DEBUG - fprintf(stderr, "PacketAlias/AddLink: "); - fprintf(stderr, " cannot allocate auxiliary TCP data\n"); -#endif - free(link); - return (NULL); - } - break; - case LINK_PPTP: - pptpLinkCount++; - break; - case LINK_FRAGMENT_ID: - fragmentIdLinkCount++; - break; - case LINK_FRAGMENT_PTR: - fragmentPtrLinkCount++; - break; - case LINK_ADDR: - break; - default: - protoLinkCount++; - break; - } - - /* Set up pointers for output lookup table */ - start_point = StartPointOut(src_addr, dst_addr, - src_port, dst_port, link_type); - LIST_INSERT_HEAD(&linkTableOut[start_point], link, list_out); - - /* Set up pointers for input lookup table */ - start_point = StartPointIn(alias_addr, link->alias_port, link_type); - LIST_INSERT_HEAD(&linkTableIn[start_point], link, list_in); - } - else - { -#ifdef DEBUG - fprintf(stderr, "PacketAlias/AddLink(): "); - fprintf(stderr, "malloc() call failed.\n"); -#endif - } - -#ifdef DEBUG - if ((packetAliasMode & PKT_ALIAS_LOG) != 0 && - !IN_MULTICAST(link->src_addr.s_addr) && - !IN_MULTICAST(link->dst_addr.s_addr)) - { - char src[16]; - char dst[16]; - char alias[16]; - char *proto; - switch(link->link_type) - { - case LINK_TCP: - proto = " [TCP]"; - break; - case LINK_UDP: - proto = " [UDP]"; - break; - default: - proto = ""; - } - fprintf(monitorFile, "Added %s %s:%d<->%s:%d to %s:%d<->%s:%d\n", - proto, - inet_ntop(AF_INET, &link->src_addr, src, sizeof(src)), link->src_port, - inet_ntop(AF_INET, &link->dst_addr, dst, sizeof(dst)), link->dst_port, - inet_ntop(AF_INET, &link->alias_addr, alias, sizeof(alias)), link->alias_port, - dst, link->dst_port); - } -#else - if (packetAliasMode & PKT_ALIAS_LOG) - ShowAliasStats(); -#endif - - return(link); -} - -static struct alias_link * -ReLink(struct alias_link *old_link, - struct in_addr src_addr, - struct in_addr dst_addr, - struct in_addr alias_addr, - u_short src_port, - u_short dst_port, - int alias_port_param, /* if less than zero, alias */ - int link_type) /* port will be automatically */ -{ /* chosen. If greater than */ - struct alias_link *new_link; /* zero, equal to alias port */ - - new_link = AddLink(src_addr, dst_addr, alias_addr, - src_port, dst_port, alias_port_param, - link_type); -#ifndef NO_FW_PUNCH - if (new_link != NULL && - old_link->link_type == LINK_TCP && - old_link->data.tcp->fwhole > 0) { - PunchFWHole(new_link); - } -#endif - if ((old_link->flags & LINK_CONE) == 0) - DeleteLink(old_link); - return new_link; -} - -static struct alias_link * -_FindLinkOut(struct in_addr src_addr, - struct in_addr dst_addr, - u_short src_port, - u_short dst_port, - int link_type, - int replace_partial_links) -{ - u_int i; - struct alias_link *link; - - i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type); - LIST_FOREACH(link, &linkTableOut[i], list_out) - { - if (link->src_addr.s_addr == src_addr.s_addr - && link->server == NULL - && link->dst_addr.s_addr == dst_addr.s_addr - && link->dst_port == dst_port - && link->src_port == src_port - && link->link_type == link_type) - { - link->timestamp = timeStamp; - break; - } - } - -/* Search for partially specified links. */ - if (link == NULL && replace_partial_links) - { - if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY) - { - link = _FindLinkOut(src_addr, dst_addr, src_port, 0, - link_type, 0); - if (link == NULL) - link = _FindLinkOut(src_addr, nullAddress, src_port, - dst_port, link_type, 0); - } - if (link == NULL && - (dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) - { - link = _FindLinkOut(src_addr, nullAddress, src_port, 0, - link_type, 0); - } - if (link != NULL) - { - link = ReLink(link, - src_addr, dst_addr, link->alias_addr, - src_port, dst_port, link->alias_port, - link_type); - } - } - - return(link); -} - -static struct alias_link * -FindLinkOut(struct in_addr src_addr, - struct in_addr dst_addr, - u_short src_port, - u_short dst_port, - int link_type, - int replace_partial_links) -{ - struct alias_link *link; - - link = _FindLinkOut(src_addr, dst_addr, src_port, dst_port, - link_type, replace_partial_links); - - if (link == NULL) - { - /* The following allows permanent links to be - specified as using the default source address - (i.e. device interface address) without knowing - in advance what that address is. */ - if (aliasAddress.s_addr != 0 && - src_addr.s_addr == aliasAddress.s_addr) - { - link = _FindLinkOut(nullAddress, dst_addr, src_port, dst_port, - link_type, replace_partial_links); - } - } - - return(link); -} - - -static struct alias_link * -_FindLinkIn(struct in_addr dst_addr, - struct in_addr alias_addr, - u_short dst_port, - u_short alias_port, - int link_type, - int replace_partial_links) -{ - int flags_in; - u_int start_point; - struct alias_link *link; - struct alias_link *link_fully_specified; - struct alias_link *link_unknown_all; - struct alias_link *link_unknown_dst_addr; - struct alias_link *link_unknown_dst_port; - -/* Initialize pointers */ - link_fully_specified = NULL; - link_unknown_all = NULL; - link_unknown_dst_addr = NULL; - link_unknown_dst_port = NULL; - -/* If either the dest addr or port is unknown, the search - loop will have to know about this. */ - - flags_in = 0; - if (dst_addr.s_addr == INADDR_ANY) - flags_in |= LINK_UNKNOWN_DEST_ADDR; - if (dst_port == 0) - flags_in |= LINK_UNKNOWN_DEST_PORT; - -/* Search loop */ - start_point = StartPointIn(alias_addr, alias_port, link_type); - LIST_FOREACH(link, &linkTableIn[start_point], list_in) - { - int flags; - - flags = flags_in | link->flags; - if (!(flags & LINK_PARTIALLY_SPECIFIED)) - { - if (link->alias_addr.s_addr == alias_addr.s_addr - && link->alias_port == alias_port - && link->dst_addr.s_addr == dst_addr.s_addr - && link->dst_port == dst_port - && link->link_type == link_type) - { - link_fully_specified = link; - break; - } - } - else if ((flags & LINK_UNKNOWN_DEST_ADDR) - && (flags & LINK_UNKNOWN_DEST_PORT)) - { - if (link->alias_addr.s_addr == alias_addr.s_addr - && link->alias_port == alias_port - && link->link_type == link_type) - { - if (link_unknown_all == NULL) - link_unknown_all = link; - } - } - else if (flags & LINK_UNKNOWN_DEST_ADDR) - { - if (link->alias_addr.s_addr == alias_addr.s_addr - && link->alias_port == alias_port - && link->link_type == link_type - && link->dst_port == dst_port) - { - if (link_unknown_dst_addr == NULL) - link_unknown_dst_addr = link; - } - } - else if (flags & LINK_UNKNOWN_DEST_PORT) - { - if (link->alias_addr.s_addr == alias_addr.s_addr - && link->alias_port == alias_port - && link->link_type == link_type - && link->dst_addr.s_addr == dst_addr.s_addr) - { - if (link_unknown_dst_port == NULL) - link_unknown_dst_port = link; - } - } - } - - - - if (link_fully_specified != NULL) - { - link_fully_specified->timestamp = timeStamp; - link = link_fully_specified; - } - else if (link_unknown_dst_port != NULL) - link = link_unknown_dst_port; - else if (link_unknown_dst_addr != NULL) - link = link_unknown_dst_addr; - else if (link_unknown_all != NULL) - link = link_unknown_all; - else - return (NULL); - - if (replace_partial_links && - (link->flags & LINK_PARTIALLY_SPECIFIED || link->server != NULL)) - { - struct in_addr src_addr; - u_short src_port; - - if (link->server != NULL) { /* LSNAT link */ - src_addr = link->server->addr; - src_port = link->server->port; - link->server = link->server->next; - } else { - src_addr = link->src_addr; - src_port = link->src_port; - } - - link = ReLink(link, - src_addr, dst_addr, alias_addr, - src_port, dst_port, alias_port, - link_type); - } - - return (link); -} - -static struct alias_link * -FindLinkIn(struct in_addr dst_addr, - struct in_addr alias_addr, - u_short dst_port, - u_short alias_port, - int link_type, - int replace_partial_links) -{ - struct alias_link *link; - - link = _FindLinkIn(dst_addr, alias_addr, dst_port, alias_port, - link_type, replace_partial_links); - - if (link == NULL) - { - /* The following allows permanent links to be - specified as using the default aliasing address - (i.e. device interface address) without knowing - in advance what that address is. */ - if (aliasAddress.s_addr != 0 && - alias_addr.s_addr == aliasAddress.s_addr) - { - link = _FindLinkIn(dst_addr, nullAddress, dst_port, alias_port, - link_type, replace_partial_links); - } - } - - return(link); -} - - - - -/* External routines for finding/adding links - --- "external" means outside alias_db.c, but within alias*.c -- - - FindIcmpIn(), FindIcmpOut() - FindFragmentIn1(), FindFragmentIn2() - AddFragmentPtrLink(), FindFragmentPtr() - FindProtoIn(), FindProtoOut() - FindUdpTcpIn(), FindUdpTcpOut() - AddPptp(), FindPptpOutByCallId(), FindPptpInByCallId(), - FindPptpOutByPeerCallId(), FindPptpInByPeerCallId() - FindOriginalAddress(), FindAliasAddress() - -(prototypes in alias_local.h) -*/ - - -struct alias_link * -FindIcmpIn(struct in_addr dst_addr, - struct in_addr alias_addr, - u_short id_alias, - int create) -{ - struct alias_link *link; - - link = FindLinkIn(dst_addr, alias_addr, - NO_DEST_PORT, id_alias, - LINK_ICMP, 0); - if (link == NULL && create && !(packetAliasMode & PKT_ALIAS_DENY_INCOMING)) - { - struct in_addr target_addr; - - target_addr = FindOriginalAddress(alias_addr); - link = AddLink(target_addr, dst_addr, alias_addr, - id_alias, NO_DEST_PORT, id_alias, - LINK_ICMP); - } - - return (link); -} - - -struct alias_link * -FindIcmpOut(struct in_addr src_addr, - struct in_addr dst_addr, - u_short id, - int create) -{ - struct alias_link * link; - - link = FindLinkOut(src_addr, dst_addr, - id, NO_DEST_PORT, - LINK_ICMP, 0); - if (link == NULL && create) - { - struct in_addr alias_addr; - - alias_addr = FindAliasAddress(src_addr); - link = AddLink(src_addr, dst_addr, alias_addr, - id, NO_DEST_PORT, GET_ALIAS_ID, - LINK_ICMP); - } - - return(link); -} - - -struct alias_link * -FindFragmentIn1(struct in_addr dst_addr, - struct in_addr alias_addr, - u_short ip_id) -{ - struct alias_link *link; - - link = FindLinkIn(dst_addr, alias_addr, - NO_DEST_PORT, ip_id, - LINK_FRAGMENT_ID, 0); - - if (link == NULL) - { - link = AddLink(nullAddress, dst_addr, alias_addr, - NO_SRC_PORT, NO_DEST_PORT, ip_id, - LINK_FRAGMENT_ID); - } - - return(link); -} - - -struct alias_link * -FindFragmentIn2(struct in_addr dst_addr, /* Doesn't add a link if one */ - struct in_addr alias_addr, /* is not found. */ - u_short ip_id) -{ - return FindLinkIn(dst_addr, alias_addr, - NO_DEST_PORT, ip_id, - LINK_FRAGMENT_ID, 0); -} - - -struct alias_link * -AddFragmentPtrLink(struct in_addr dst_addr, - u_short ip_id) -{ - return AddLink(nullAddress, dst_addr, nullAddress, - NO_SRC_PORT, NO_DEST_PORT, ip_id, - LINK_FRAGMENT_PTR); -} - - -struct alias_link * -FindFragmentPtr(struct in_addr dst_addr, - u_short ip_id) -{ - return FindLinkIn(dst_addr, nullAddress, - NO_DEST_PORT, ip_id, - LINK_FRAGMENT_PTR, 0); -} - - -struct alias_link * -FindProtoIn(struct in_addr dst_addr, - struct in_addr alias_addr, - u_char proto) -{ - struct alias_link *link; - - link = FindLinkIn(dst_addr, alias_addr, - NO_DEST_PORT, 0, - proto, 1); - - if (link == NULL && !(packetAliasMode & PKT_ALIAS_DENY_INCOMING)) - { - struct in_addr target_addr; - - target_addr = FindOriginalAddress(alias_addr); - link = AddLink(target_addr, dst_addr, alias_addr, - NO_SRC_PORT, NO_DEST_PORT, 0, - proto); - } - - return (link); -} - - -struct alias_link * -FindProtoOut(struct in_addr src_addr, - struct in_addr dst_addr, - u_char proto) -{ - struct alias_link *link; - - link = FindLinkOut(src_addr, dst_addr, - NO_SRC_PORT, NO_DEST_PORT, - proto, 1); - - if (link == NULL) - { - struct in_addr alias_addr; - - alias_addr = FindAliasAddress(src_addr); - link = AddLink(src_addr, dst_addr, alias_addr, - NO_SRC_PORT, NO_DEST_PORT, 0, - proto); - } - - return (link); -} - - -struct alias_link * -FindUdpTcpIn(struct in_addr dst_addr, - struct in_addr alias_addr, - u_short dst_port, - u_short alias_port, - u_char proto, - int create) -{ - int link_type; - struct alias_link *link; - - switch (proto) - { - case IPPROTO_UDP: - link_type = LINK_UDP; - break; - case IPPROTO_TCP: - link_type = LINK_TCP; - break; - default: - return NULL; - break; - } - - link = FindLinkIn(dst_addr, alias_addr, - dst_port, alias_port, - link_type, create); - - if (link == NULL && create && !(packetAliasMode & PKT_ALIAS_DENY_INCOMING)) - { - struct in_addr target_addr; - - target_addr = FindOriginalAddress(alias_addr); - link = AddLink(target_addr, dst_addr, alias_addr, - alias_port, dst_port, alias_port, - link_type); - } - - return(link); -} - - -struct alias_link * -FindUdpTcpOut(struct in_addr src_addr, - struct in_addr dst_addr, - u_short src_port, - u_short dst_port, - u_char proto, - int create) -{ - int link_type; - struct alias_link *link; - - switch (proto) - { - case IPPROTO_UDP: - link_type = LINK_UDP; - break; - case IPPROTO_TCP: - link_type = LINK_TCP; - break; - default: - return NULL; - break; - } - - link = FindLinkOut(src_addr, dst_addr, src_port, dst_port, link_type, create); - - if (link == NULL && create) - { - struct in_addr alias_addr; - struct in_addr dst_addr2 = dst_addr; - u_short dst_port2 = dst_port; - - alias_addr = FindAliasAddress(src_addr); - - if (iChatAVHack && link_type == LINK_UDP && dst_port == htons(5678)) { - dst_addr2.s_addr = 0; - dst_port2 = 0; - } - link = AddLink(src_addr, dst_addr2, alias_addr, - src_port, dst_port2, GET_ALIAS_PORT, - link_type); - if (link != NULL && - (link->flags & (LINK_UNKNOWN_DEST_ADDR | LINK_UNKNOWN_DEST_PORT)) != 0) - { - link->flags |= LINK_CONE; - link = ReLink(link, link->src_addr, dst_addr, link->alias_addr, - link->src_port, dst_port, link->alias_port, link_type); - } - } - - return(link); -} - - -struct alias_link * -AddPptp(struct in_addr src_addr, - struct in_addr dst_addr, - struct in_addr alias_addr, - u_int16_t src_call_id) -{ - struct alias_link *link; - - link = AddLink(src_addr, dst_addr, alias_addr, - src_call_id, 0, GET_ALIAS_PORT, - LINK_PPTP); - - return (link); -} - - -struct alias_link * -FindPptpOutByCallId(struct in_addr src_addr, - struct in_addr dst_addr, - u_int16_t src_call_id) -{ - u_int i; - struct alias_link *link; - - i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP); - LIST_FOREACH(link, &linkTableOut[i], list_out) - if (link->link_type == LINK_PPTP && - link->src_addr.s_addr == src_addr.s_addr && - link->dst_addr.s_addr == dst_addr.s_addr && - link->src_port == src_call_id) - break; - - return (link); -} - - -struct alias_link * -FindPptpOutByPeerCallId(struct in_addr src_addr, - struct in_addr dst_addr, - u_int16_t dst_call_id) -{ - u_int i; - struct alias_link *link; - - i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP); - LIST_FOREACH(link, &linkTableOut[i], list_out) - if (link->link_type == LINK_PPTP && - link->src_addr.s_addr == src_addr.s_addr && - link->dst_addr.s_addr == dst_addr.s_addr && - link->dst_port == dst_call_id) - break; - - return (link); -} - - -struct alias_link * -FindPptpInByCallId(struct in_addr dst_addr, - struct in_addr alias_addr, - u_int16_t dst_call_id) -{ - u_int i; - struct alias_link *link; - - i = StartPointIn(alias_addr, 0, LINK_PPTP); - LIST_FOREACH(link, &linkTableIn[i], list_in) - if (link->link_type == LINK_PPTP && - link->dst_addr.s_addr == dst_addr.s_addr && - link->alias_addr.s_addr == alias_addr.s_addr && - link->dst_port == dst_call_id) - break; - - return (link); -} - - -struct alias_link * -FindPptpInByPeerCallId(struct in_addr dst_addr, - struct in_addr alias_addr, - u_int16_t alias_call_id) -{ - struct alias_link *link; - - link = FindLinkIn(dst_addr, alias_addr, - 0/* any */, alias_call_id, - LINK_PPTP, 0); - - - return (link); -} - - -struct alias_link * -FindRtspOut(struct in_addr src_addr, - struct in_addr dst_addr, - u_short src_port, - u_short alias_port, - u_char proto) -{ - int link_type; - struct alias_link *link; - - switch (proto) - { - case IPPROTO_UDP: - link_type = LINK_UDP; - break; - case IPPROTO_TCP: - link_type = LINK_TCP; - break; - default: - return NULL; - break; - } - - link = FindLinkOut(src_addr, dst_addr, src_port, 0, link_type, 1); - - if (link == NULL) - { - struct in_addr alias_addr; - - alias_addr = FindAliasAddress(src_addr); - link = AddLink(src_addr, dst_addr, alias_addr, - src_port, 0, alias_port, - link_type); - } - - return(link); -} - - -struct in_addr -FindOriginalAddress(struct in_addr alias_addr) -{ - struct alias_link *link; - - link = FindLinkIn(nullAddress, alias_addr, - 0, 0, LINK_ADDR, 0); - if (link == NULL) - { - newDefaultLink = 1; - if (targetAddress.s_addr == INADDR_ANY) - return alias_addr; - else if (targetAddress.s_addr == INADDR_NONE) - return aliasAddress; - else - return targetAddress; - } - else - { - if (link->server != NULL) { /* LSNAT link */ - struct in_addr src_addr; - - src_addr = link->server->addr; - link->server = link->server->next; - return (src_addr); - } else if (link->src_addr.s_addr == INADDR_ANY) - return aliasAddress; - else - return link->src_addr; - } -} - - -struct in_addr -FindAliasAddress(struct in_addr original_addr) -{ - struct alias_link *link; - - link = FindLinkOut(original_addr, nullAddress, - 0, 0, LINK_ADDR, 0); - if (link == NULL) - { - return aliasAddress; - } - else - { - if (link->alias_addr.s_addr == INADDR_ANY) - return aliasAddress; - else - return link->alias_addr; - } -} - -/* FindAliasPortOut */ -/* external routine for NatPortMap */ -/* return alias port for the src_addr,dst_addr,src_port and proto */ -/* if one doesn't existed, create a mapping with providing pub_port if it's not 0 */ -/* delete mapping if addmapping is not true */ -int -FindAliasPortOut(struct in_addr src_addr, struct in_addr dst_addr, u_short src_port, u_short pub_port, u_char proto, int lifetime, char addmapping) -{ - u_int i; - struct alias_link *link; - int link_type; - - switch (proto) - { - case IPPROTO_UDP: - link_type = LINK_UDP; - break; - case IPPROTO_TCP: - link_type = LINK_TCP; - break; - default: - return 0; - break; - } - -#ifdef DEBUG - { - int icount = 0; - - printf("FindAliasPortOut:: srcaddr= %s:%u, ", - inet_ntoa(src_addr), ntohs(src_port)); - printf("dstadd= %s:%u link_type= %d, lifetime= %d\n", - inet_ntoa(dst_addr), ntohs(pub_port), link_type, lifetime); - - for (i=0; isrc_addr), ntohs(link->src_port)); - snprintf(dst_str, sizeof(dst_str), "%s:%u", - inet_ntoa(link->dst_addr), ntohs(link->dst_port)); - snprintf(alias_str, sizeof(alias_str), "%s:%u", - inet_ntoa(link->alias_addr), ntohs(link->alias_port)); - - printf(" linkTableOut[%d:%d] src= %s dst= %s alias= %s flags= 0x%x linktype= %d ts= %d exp= %d fd= %d\n", - i, icount, src_str, dst_str, alias_str, - link->flags, link->link_type, link->timestamp, link->expire_time, link->sockfd); - - link_next = LIST_NEXT(link, list_out); - icount++; - link = link_next; - } - } - - } -#endif - - i = StartPointOut(src_addr, dst_addr, src_port, 0, link_type); -#ifdef DEBUG - printf("PORTMAP::StartPointOut returns %d\n", i); -#endif - LIST_FOREACH(link, &linkTableOut[i], list_out) - { - if (link->src_addr.s_addr == src_addr.s_addr && - link->dst_addr.s_addr == dst_addr.s_addr && - link->src_port == src_port && link->link_type == link_type) - break; - } - - if ( link == NULL && addmapping) - { - struct in_addr alias_addr; -#ifdef DEBUG - printf("PORTMAP:: cannot find mapping, adding mapping private port =%d, public port = %d\n", - src_port, pub_port); -#endif - /* address/port in not in list, create new mapping */ - - alias_addr = FindAliasAddress(src_addr); - /* create new mapping */ - link = AddLink(src_addr, dst_addr, alias_addr, - src_port, 0, GET_ALIAS_EPHEMERAL_PORT, - link_type); - if ( link != NULL ) { - /* link was create, set new lifetime */ - SetExpire(link, lifetime); - /* Prevent link deletion when incoming connection arrive */ - link->flags |= LINK_CONE; - } - } - if ( link ) - { - if ( addmapping ) - return( GetAliasPort(link)); - else - { - SetExpire(link, 0); /* delete mapping */ - return 0; - } - } - - return -1; -} - - -/* External routines for getting or changing link data - (external to alias_db.c, but internal to alias*.c) - - SetFragmentData(), GetFragmentData() - SetFragmentPtr(), GetFragmentPtr() - SetStateIn(), SetStateOut(), GetStateIn(), GetStateOut() - GetOriginalAddress(), GetDestAddress(), GetAliasAddress() - GetOriginalPort(), GetAliasPort() - SetAckModified(), GetAckModified() - GetDeltaAckIn(), GetDeltaSeqOut(), AddSeq() - SetLastLineCrlfTermed(), GetLastLineCrlfTermed() - SetDestCallId() -*/ - - -void -SetFragmentAddr(struct alias_link *link, struct in_addr src_addr) -{ - link->data.frag_addr = src_addr; -} - - -void -GetFragmentAddr(struct alias_link *link, struct in_addr *src_addr) -{ - *src_addr = link->data.frag_addr; -} - - -void -SetFragmentPtr(struct alias_link *link, char *fptr) -{ - link->data.frag_ptr = fptr; -} - - -void -GetFragmentPtr(struct alias_link *link, char **fptr) -{ - *fptr = link->data.frag_ptr; -} - - -void -SetStateIn(struct alias_link *link, int state) -{ - /* TCP input state */ - switch (state) { - case ALIAS_TCP_STATE_DISCONNECTED: - if (link->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED) - link->expire_time = TCP_EXPIRE_DEAD; - else - link->expire_time = TCP_EXPIRE_SINGLEDEAD; - break; - case ALIAS_TCP_STATE_CONNECTED: - if (link->data.tcp->state.out == ALIAS_TCP_STATE_CONNECTED) - link->expire_time = TCP_EXPIRE_CONNECTED; - break; - default: - abort(); - } - link->data.tcp->state.in = state; -} - - -void -SetStateOut(struct alias_link *link, int state) -{ - /* TCP output state */ - switch (state) { - case ALIAS_TCP_STATE_DISCONNECTED: - if (link->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED) - link->expire_time = TCP_EXPIRE_DEAD; - else - link->expire_time = TCP_EXPIRE_SINGLEDEAD; - break; - case ALIAS_TCP_STATE_CONNECTED: - if (link->data.tcp->state.in == ALIAS_TCP_STATE_CONNECTED) - link->expire_time = TCP_EXPIRE_CONNECTED; - break; - default: - abort(); - } - link->data.tcp->state.out = state; -} - - -int -GetStateIn(struct alias_link *link) -{ - /* TCP input state */ - return link->data.tcp->state.in; -} - - -int -GetStateOut(struct alias_link *link) -{ - /* TCP output state */ - return link->data.tcp->state.out; -} - - -struct in_addr -GetOriginalAddress(struct alias_link *link) -{ - if (link->src_addr.s_addr == INADDR_ANY) - return aliasAddress; - else - return(link->src_addr); -} - - -struct in_addr -GetDestAddress(struct alias_link *link) -{ - return(link->dst_addr); -} - - -struct in_addr -GetAliasAddress(struct alias_link *link) -{ - if (link->alias_addr.s_addr == INADDR_ANY) - return aliasAddress; - else - return link->alias_addr; -} - - -struct in_addr -GetDefaultAliasAddress() -{ - return aliasAddress; -} - - -void -SetDefaultAliasAddress(struct in_addr alias_addr) -{ - aliasAddress = alias_addr; -} - - -u_short -GetOriginalPort(struct alias_link *link) -{ - return(link->src_port); -} - - -u_short -GetAliasPort(struct alias_link *link) -{ - return(link->alias_port); -} - -#ifndef NO_FW_PUNCH -static u_short -GetDestPort(struct alias_link *link) -{ - return(link->dst_port); -} -#endif - -void -SetAckModified(struct alias_link *link) -{ -/* Indicate that ACK numbers have been modified in a TCP connection */ - link->data.tcp->state.ack_modified = 1; -} - - -struct in_addr -GetProxyAddress(struct alias_link *link) -{ - return link->proxy_addr; -} - - -void -SetProxyAddress(struct alias_link *link, struct in_addr addr) -{ - link->proxy_addr = addr; -} - - -u_short -GetProxyPort(struct alias_link *link) -{ - return link->proxy_port; -} - - -void -SetProxyPort(struct alias_link *link, u_short port) -{ - link->proxy_port = port; -} - - -int -GetAckModified(struct alias_link *link) -{ -/* See if ACK numbers have been modified */ - return link->data.tcp->state.ack_modified; -} - - -int -GetDeltaAckIn(struct ip *pip, struct alias_link *link) -{ -/* -Find out how much the ACK number has been altered for an incoming -TCP packet. To do this, a circular list of ACK numbers where the TCP -packet size was altered is searched. -*/ - - int i; - struct tcphdr *tc; - int delta, ack_diff_min; - __uint32_t ack; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - ack = tc->th_ack; - - delta = 0; - ack_diff_min = -1; - for (i=0; idata.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(struct ip *pip, struct alias_link *link) -{ -/* -Find out how much the sequence number has been altered for an outgoing -TCP packet. To do this, a circular list of ACK numbers where the TCP -packet size was altered is searched. -*/ - - int i; - struct tcphdr *tc; - int delta, seq_diff_min; - __uint32_t seq; - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - seq = tc->th_seq; - - delta = 0; - seq_diff_min = -1; - for (i=0; idata.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(struct ip *pip, struct alias_link *link, 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 ack_data_record x; - int hlen, tlen, dlen; - int i; - - 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; -} - -void -SetExpire(struct alias_link *link, int expire) -{ - if (expire == 0) - { - link->flags &= ~LINK_PERMANENT; - DeleteLink(link); - } - else if (expire == -1) - { - link->flags |= LINK_PERMANENT; - } - else if (expire > 0) - { - link->expire_time = expire; - } - else - { -#ifdef DEBUG - fprintf(stderr, "PacketAlias/SetExpire(): "); - fprintf(stderr, "error in expire parameter\n"); -#endif - } -} - -void -ClearCheckNewLink(void) -{ - newDefaultLink = 0; -} - -void -SetLastLineCrlfTermed(struct alias_link *link, int yes) -{ - - if (yes) - link->flags |= LINK_LAST_LINE_CRLF_TERMED; - else - link->flags &= ~LINK_LAST_LINE_CRLF_TERMED; -} - -int -GetLastLineCrlfTermed(struct alias_link *link) -{ - - return (link->flags & LINK_LAST_LINE_CRLF_TERMED); -} - -void -SetDestCallId(struct alias_link *link, u_int16_t cid) -{ - - deleteAllLinks = 1; - link = ReLink(link, link->src_addr, link->dst_addr, link->alias_addr, - link->src_port, cid, link->alias_port, link->link_type); - deleteAllLinks = 0; -} - - -/* Miscellaneous Functions - - HouseKeeping() - InitPacketAliasLog() - UninitPacketAliasLog() -*/ - -/* - Whenever an outgoing or incoming packet is handled, HouseKeeping() - is called to find and remove timed-out aliasing links. Logic exists - to sweep through the entire table and linked list structure - every 60 seconds. - - (prototype in alias_local.h) -*/ - -void -HouseKeeping(void) -{ - int i, n, n100; - struct timeval tv; - struct timezone tz; - - /* - * Save system time (seconds) in global variable timeStamp for - * use by other functions. This is done so as not to unnecessarily - * waste timeline by making system calls. - */ - gettimeofday(&tv, &tz); - timeStamp = tv.tv_sec; - - /* Compute number of spokes (output table link chains) to cover */ - n100 = LINK_TABLE_OUT_SIZE * 100 + houseKeepingResidual; - n100 *= timeStamp - lastCleanupTime; - n100 /= ALIAS_CLEANUP_INTERVAL_SECS; - - n = n100/100; - - /* Handle different cases */ - if (n > ALIAS_CLEANUP_MAX_SPOKES) - { - n = ALIAS_CLEANUP_MAX_SPOKES; - lastCleanupTime = timeStamp; - houseKeepingResidual = 0; - - for (i=0; i 0) - { - lastCleanupTime = timeStamp; - houseKeepingResidual = n100 - 100*n; - - for (i=0; iflags |= LINK_PERMANENT; - } -#ifdef DEBUG - else - { - fprintf(stderr, "PacketAliasRedirectPort(): " - "call to AddLink() failed\n"); - } -#endif - - return link; -} - -/* Add server to the pool of servers */ -int -PacketAliasAddServer(struct alias_link *link, struct in_addr addr, u_short port) -{ - struct server *server; - - server = malloc(sizeof(struct server)); - - if (server != NULL) { - struct server *head; - - server->addr = addr; - server->port = port; - - head = link->server; - if (head == NULL) - server->next = server; - else { - struct server *s; - - for (s = head; s->next != head; s = s->next); - s->next = server; - server->next = head; - } - link->server = server; - return (0); - } else - return (-1); -} - -/* Redirect packets of a given IP protocol from a specific - public address to a private address */ -struct alias_link * -PacketAliasRedirectProto(struct in_addr src_addr, - struct in_addr dst_addr, - struct in_addr alias_addr, - u_char proto) -{ - struct alias_link *link; - - link = AddLink(src_addr, dst_addr, alias_addr, - NO_SRC_PORT, NO_DEST_PORT, 0, - proto); - - if (link != NULL) - { - link->flags |= LINK_PERMANENT; - } -#ifdef DEBUG - else - { - fprintf(stderr, "PacketAliasRedirectProto(): " - "call to AddLink() failed\n"); - } -#endif - - return link; -} - -/* Static address translation */ -struct alias_link * -PacketAliasRedirectAddr(struct in_addr src_addr, - struct in_addr alias_addr) -{ - struct alias_link *link; - - link = AddLink(src_addr, nullAddress, alias_addr, - 0, 0, 0, - LINK_ADDR); - - if (link != NULL) - { - link->flags |= LINK_PERMANENT; - } -#ifdef DEBUG - else - { - fprintf(stderr, "PacketAliasRedirectAddr(): " - "call to AddLink() failed\n"); - } -#endif - - return link; -} - - -void -PacketAliasRedirectDelete(struct alias_link *link) -{ -/* This is a dangerous function to put in the API, - because an invalid pointer can crash the program. */ - - deleteAllLinks = 1; - DeleteLink(link); - deleteAllLinks = 0; -} - - -void -PacketAliasSetAddress(struct in_addr addr) -{ - if (packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE - && aliasAddress.s_addr != addr.s_addr) - CleanupAliasData(); - - aliasAddress = addr; -} - - -void -PacketAliasSetTarget(struct in_addr target_addr) -{ - targetAddress = target_addr; -} - - -void -PacketAliasInit(void) -{ - int i; - struct timeval tv; - struct timezone tz; - static int firstCall = 1; - - if (firstCall == 1) - { - gettimeofday(&tv, &tz); - timeStamp = tv.tv_sec; - lastCleanupTime = tv.tv_sec; - houseKeepingResidual = 0; - - for (i=0; i -#include -#include -#include - -static void ClearAllFWHoles(void); - -static int fireWallBaseNum; /* The first firewall entry free for our use */ -static int fireWallNumNums; /* How many entries can we use? */ -static int fireWallActiveNum; /* Which entry did we last use? */ -static char *fireWallField; /* bool array for entries */ - -#define fw_setfield(field, num) \ -do { \ - (field)[(num) - fireWallBaseNum] = 1; \ -} /*lint -save -e717 */ while(0) /*lint -restore */ -#define fw_clrfield(field, num) \ -do { \ - (field)[(num) - fireWallBaseNum] = 0; \ -} /*lint -save -e717 */ while(0) /*lint -restore */ -#define fw_tstfield(field, num) ((field)[(num) - fireWallBaseNum]) - -static void -InitPunchFW(void) { - fireWallField = malloc(fireWallNumNums); - if (fireWallField) { - memset(fireWallField, 0, fireWallNumNums); - if (fireWallFD < 0) { - fireWallFD = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); - } - ClearAllFWHoles(); - fireWallActiveNum = fireWallBaseNum; - } -} - -static void -UninitPunchFW(void) { - ClearAllFWHoles(); - if (fireWallFD >= 0) - close(fireWallFD); - fireWallFD = -1; - if (fireWallField) - free(fireWallField); - fireWallField = NULL; - packetAliasMode &= ~PKT_ALIAS_PUNCH_FW; -} - -/* Make a certain link go through the firewall */ -void -PunchFWHole(struct alias_link *link) { - int r; /* Result code */ - struct ip_fw rule; /* On-the-fly built rule */ - int fwhole; /* Where to punch hole */ - -/* Don't do anything unless we are asked to */ - if ( !(packetAliasMode & PKT_ALIAS_PUNCH_FW) || - fireWallFD < 0 || - link->link_type != LINK_TCP) - return; - - memset(&rule, 0, sizeof rule); - -/** Build rule **/ - - /* Find empty slot */ - for (fwhole = fireWallActiveNum; - fwhole < fireWallBaseNum + fireWallNumNums && - fw_tstfield(fireWallField, fwhole); - fwhole++) - ; - if (fwhole == fireWallBaseNum + fireWallNumNums) { - for (fwhole = fireWallBaseNum; - fwhole < fireWallActiveNum && - fw_tstfield(fireWallField, fwhole); - fwhole++) - ; - if (fwhole == fireWallActiveNum) { - /* No rule point empty - we can't punch more holes. */ - fireWallActiveNum = fireWallBaseNum; -#ifdef DEBUG - fprintf(stderr, "libalias: Unable to create firewall hole!\n"); -#endif - return; - } - } - /* Start next search at next position */ - fireWallActiveNum = fwhole+1; - - /* Build generic part of the two rules */ - rule.fw_number = fwhole; - IP_FW_SETNSRCP(&rule, 1); /* Number of source ports. */ - IP_FW_SETNDSTP(&rule, 1); /* Number of destination ports. */ - rule.fw_flg = IP_FW_F_ACCEPT | IP_FW_F_IN | IP_FW_F_OUT; - rule.fw_prot = IPPROTO_TCP; - rule.fw_smsk.s_addr = INADDR_BROADCAST; - rule.fw_dmsk.s_addr = INADDR_BROADCAST; - - /* Build and apply specific part of the rules */ - rule.fw_src = GetOriginalAddress(link); - rule.fw_dst = GetDestAddress(link); - rule.fw_uar.fw_pts[0] = ntohs(GetOriginalPort(link)); - rule.fw_uar.fw_pts[1] = ntohs(GetDestPort(link)); - - /* Skip non-bound links - XXX should not be strictly necessary, - but seems to leave hole if not done. Leak of non-bound links? - (Code should be left even if the problem is fixed - it is a - clear optimization) */ - if (rule.fw_uar.fw_pts[0] != 0 && rule.fw_uar.fw_pts[1] != 0) { - r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule); -#ifdef DEBUG - if (r) - err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)"); -#endif - rule.fw_src = GetDestAddress(link); - rule.fw_dst = GetOriginalAddress(link); - rule.fw_uar.fw_pts[0] = ntohs(GetDestPort(link)); - rule.fw_uar.fw_pts[1] = ntohs(GetOriginalPort(link)); - r = setsockopt(fireWallFD, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule); -#ifdef DEBUG - if (r) - err(1, "alias punch inbound(2) setsockopt(IP_FW_ADD)"); -#endif - } -/* Indicate hole applied */ - link->data.tcp->fwhole = fwhole; - fw_setfield(fireWallField, fwhole); -} - -/* Remove a hole in a firewall associated with a particular alias - link. Calling this too often is harmless. */ -static void -ClearFWHole(struct alias_link *link) { - if (link->link_type == LINK_TCP) { - int fwhole = link->data.tcp->fwhole; /* Where is the firewall hole? */ - struct ip_fw rule; - - if (fwhole < 0) - return; - - memset(&rule, 0, sizeof rule); - rule.fw_number = fwhole; - while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule)) - ; - fw_clrfield(fireWallField, fwhole); - link->data.tcp->fwhole = -1; - } -} - -/* Clear out the entire range dedicated to firewall holes. */ -static void -ClearAllFWHoles(void) { - struct ip_fw rule; /* On-the-fly built rule */ - int i; - - if (fireWallFD < 0) - return; - - memset(&rule, 0, sizeof rule); - for (i = fireWallBaseNum; i < fireWallBaseNum + fireWallNumNums; i++) { - rule.fw_number = i; - while (!setsockopt(fireWallFD, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule)) - ; - } - memset(fireWallField, 0, fireWallNumNums); -} -#endif - -void -PacketAliasSetFWBase(unsigned int base, unsigned int num) { -#ifndef NO_FW_PUNCH - fireWallBaseNum = base; - fireWallNumNums = num; -#endif -} - -void -DumpInfo(void) -{ - int i, icount = 0; - struct alias_link *link; - - for (i=0; isrc_addr), ntohs(link->src_port)); - snprintf(dst_str, sizeof(dst_str), "%s:%u", - inet_ntoa(link->dst_addr), ntohs(link->dst_port)); - snprintf(alias_str, sizeof(alias_str), "%s:%u", - inet_ntoa(link->alias_addr), ntohs(link->alias_port)); - - syslog(LOG_ERR, " linkTableOut[%d:%d] src= %s dst= %s alias= %s flags= 0x%x linktype= %d ts= %d exp= %d fd= %d", - i, icount, src_str, dst_str, alias_str, - link->flags, link->link_type, link->timestamp, link->expire_time, link->sockfd); - - link_next = LIST_NEXT(link, list_out); - icount++; - link = link_next; - } - } - -} diff --git a/alias/alias_ftp.c b/alias/alias_ftp.c deleted file mode 100644 index d59fbf3..0000000 --- a/alias/alias_ftp.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Copyright (c) 2000-2009 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -/*- - * Copyright (c) 2001 Charles Mott - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_ftp.c,v 1.5.2.4 2001/08/21 03:50:25 brian Exp $ - */ - -/* - Alias_ftp.c performs special processing for FTP sessions under - TCP. Specifically, when a PORT/EPRT command from the client - side or 227/229 reply from the server 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 message 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 message 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. - - - References: RFC 959, RFC 2428. - - Initial version: August, 1996 (cjm) - - Version 1.6 - Brian Somers and Martin Renters identified an IP checksum - error for modified IP packets. - - Version 1.7: January 9, 1996 (cjm) - Differential checksum computation for change - in IP packet length. - - Version 2.1: May, 1997 (cjm) - Very minor changes to conform with - local/global/function naming conventions - within the packet aliasing module. - - Version 3.1: May, 2000 (eds) - Add support for passive mode, alias the 227 replies. - - See HISTORY file for record of revisions. -*/ - -/* Includes */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "alias_local.h" - -#define FTP_CONTROL_PORT_NUMBER 21 -#define MAX_MESSAGE_SIZE 128 - -enum ftp_message_type { - FTP_PORT_COMMAND, - FTP_EPRT_COMMAND, - FTP_227_REPLY, - FTP_229_REPLY, - FTP_UNKNOWN_MESSAGE -}; - -static int ParseFtpPortCommand(char *, int); -static int ParseFtpEprtCommand(char *, int); -static int ParseFtp227Reply(char *, int); -static int ParseFtp229Reply(char *, int); -static void NewFtpMessage(struct ip *, struct alias_link *, int, int); - -static struct in_addr true_addr; /* in network byte order. */ -static u_short true_port; /* in host byte order. */ - -void -AliasHandleFtpOut( -struct ip *pip, /* IP packet to examine/patch */ -struct alias_link *link, /* The link to go through (aliased port) */ -int maxpacketsize /* The maximum size this packet can grow to (including headers) */) -{ - int hlen, tlen, dlen; - char *sptr; - struct tcphdr *tc; - int ftp_message_type; - -/* 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; - -/* Place string pointer and beginning of data */ - sptr = (char *) pip; - sptr += hlen; - -/* - * Check that data length is not too long and previous message was - * properly terminated with CRLF. - */ - if (dlen <= MAX_MESSAGE_SIZE && GetLastLineCrlfTermed(link)) { - ftp_message_type = FTP_UNKNOWN_MESSAGE; - - if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) { -/* - * When aliasing a client, check for the PORT/EPRT command. - */ - if (ParseFtpPortCommand(sptr, dlen)) - ftp_message_type = FTP_PORT_COMMAND; - else if (ParseFtpEprtCommand(sptr, dlen)) - ftp_message_type = FTP_EPRT_COMMAND; - } else { -/* - * When aliasing a server, check for the 227/229 reply. - */ - if (ParseFtp227Reply(sptr, dlen)) - ftp_message_type = FTP_227_REPLY; - else if (ParseFtp229Reply(sptr, dlen)) - ftp_message_type = FTP_229_REPLY; - } - - if (ftp_message_type != FTP_UNKNOWN_MESSAGE) - NewFtpMessage(pip, link, maxpacketsize, ftp_message_type); - } - -/* Track the msgs which are CRLF term'd for PORT/PASV FW breach */ - - if (dlen) { /* only if there's data */ - sptr = (char *) pip; /* start over at beginning */ - tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may have grown */ - SetLastLineCrlfTermed(link, - (sptr[tlen-2] == '\r') && (sptr[tlen-1] == '\n')); - } -} - -static int -ParseFtpPortCommand(char *sptr, int dlen) -{ - char ch; - int i, state; - u_int32_t addr; - u_short port; - u_int8_t octet; - - /* Format: "PORT A,D,D,R,PO,RT". */ - - /* Return if data length is too short. */ - if (dlen < 18) - return 0; - - addr = port = octet = 0; - state = -4; - for (i = 0; i < dlen; i++) { - ch = sptr[i]; - switch (state) { - case -4: if (ch == 'P') state++; else return 0; break; - case -3: if (ch == 'O') state++; else return 0; break; - case -2: if (ch == 'R') state++; else return 0; break; - case -1: if (ch == 'T') state++; else return 0; break; - - case 0: - if (isspace(ch)) - break; - else - state++; - case 1: case 3: case 5: case 7: case 9: case 11: - if (isdigit(ch)) { - octet = ch - '0'; - state++; - } else - return 0; - break; - case 2: case 4: case 6: case 8: - if (isdigit(ch)) - octet = 10 * octet + ch - '0'; - else if (ch == ',') { - addr = (addr << 8) + octet; - state++; - } else - return 0; - break; - case 10: case 12: - if (isdigit(ch)) - octet = 10 * octet + ch - '0'; - else if (ch == ',' || state == 12) { - port = (port << 8) + octet; - state++; - } else - return 0; - break; - } - } - - if (state == 13) { - true_addr.s_addr = htonl(addr); - true_port = port; - return 1; - } else - return 0; -} - -static int -ParseFtpEprtCommand(char *sptr, int dlen) -{ - char ch, delim; - int i, state; - u_int32_t addr; - u_short port; - u_int8_t octet; - - /* Format: "EPRT |1|A.D.D.R|PORT|". */ - - /* Return if data length is too short. */ - if (dlen < 18) - return 0; - - addr = port = octet = 0; - delim = '|'; /* XXX gcc -Wuninitialized */ - state = -4; - for (i = 0; i < dlen; i++) { - ch = sptr[i]; - switch (state) - { - case -4: if (ch == 'E') state++; else return 0; break; - case -3: if (ch == 'P') state++; else return 0; break; - case -2: if (ch == 'R') state++; else return 0; break; - case -1: if (ch == 'T') state++; else return 0; break; - - case 0: - if (!isspace(ch)) { - delim = ch; - state++; - } - break; - case 1: - if (ch == '1') /* IPv4 address */ - state++; - else - return 0; - break; - case 2: - if (ch == delim) - state++; - else - return 0; - break; - case 3: case 5: case 7: case 9: - if (isdigit(ch)) { - octet = ch - '0'; - state++; - } else - return 0; - break; - case 4: case 6: case 8: case 10: - if (isdigit(ch)) - octet = 10 * octet + ch - '0'; - else if (ch == '.' || state == 10) { - addr = (addr << 8) + octet; - state++; - } else - return 0; - break; - case 11: - if (isdigit(ch)) { - port = ch - '0'; - state++; - } else - return 0; - break; - case 12: - if (isdigit(ch)) - port = 10 * port + ch - '0'; - else if (ch == delim) - state++; - else - return 0; - break; - } - } - - if (state == 13) { - true_addr.s_addr = htonl(addr); - true_port = port; - return 1; - } else - return 0; -} - -static int -ParseFtp227Reply(char *sptr, int dlen) -{ - char ch; - int i, state; - u_int32_t addr; - u_short port; - u_int8_t octet; - - /* Format: "227 Entering Passive Mode (A,D,D,R,PO,RT)" */ - - /* Return if data length is too short. */ - if (dlen < 17) - return 0; - - addr = port = octet = 0; - - state = -3; - for (i = 0; i < dlen; i++) { - ch = sptr[i]; - switch (state) - { - case -3: if (ch == '2') state++; else return 0; break; - case -2: if (ch == '2') state++; else return 0; break; - case -1: if (ch == '7') state++; else return 0; break; - - case 0: - if (ch == '(') - state++; - break; - case 1: case 3: case 5: case 7: case 9: case 11: - if (isdigit(ch)) { - octet = ch - '0'; - state++; - } else - return 0; - break; - case 2: case 4: case 6: case 8: - if (isdigit(ch)) - octet = 10 * octet + ch - '0'; - else if (ch == ',') { - addr = (addr << 8) + octet; - state++; - } else - return 0; - break; - case 10: case 12: - if (isdigit(ch)) - octet = 10 * octet + ch - '0'; - else if (ch == ',' || (state == 12 && ch == ')')) { - port = (port << 8) + octet; - state++; - } else - return 0; - break; - } - } - - if (state == 13) { - true_port = port; - true_addr.s_addr = htonl(addr); - return 1; - } else - return 0; -} - -static int -ParseFtp229Reply(char *sptr, int dlen) -{ - char ch, delim; - int i, state; - u_short port; - - /* Format: "229 Entering Extended Passive Mode (|||PORT|)" */ - - /* Return if data length is too short. */ - if (dlen < 11) - return 0; - - port = 0; - delim = '|'; /* XXX gcc -Wuninitialized */ - - state = -3; - for (i = 0; i < dlen; i++) { - ch = sptr[i]; - switch (state) - { - case -3: if (ch == '2') state++; else return 0; break; - case -2: if (ch == '2') state++; else return 0; break; - case -1: if (ch == '9') state++; else return 0; break; - - case 0: - if (ch == '(') - state++; - break; - case 1: - delim = ch; - state++; - break; - case 2: case 3: - if (ch == delim) - state++; - else - return 0; - break; - case 4: - if (isdigit(ch)) { - port = ch - '0'; - state++; - } else - return 0; - break; - case 5: - if (isdigit(ch)) - port = 10 * port + ch - '0'; - else if (ch == delim) - state++; - else - return 0; - break; - case 6: - if (ch == ')') - state++; - else - return 0; - break; - } - } - - if (state == 7) { - true_port = port; - return 1; - } else - return 0; -} - -static void -NewFtpMessage(struct ip *pip, - struct alias_link *link, - int maxpacketsize, - int ftp_message_type) -{ - struct alias_link *ftp_link; - -/* Security checks. */ - if (ftp_message_type != FTP_229_REPLY && - pip->ip_src.s_addr != true_addr.s_addr) - return; - - if (true_port < IPPORT_RESERVED) - return; - -/* Establish link to address and port found in FTP control message. */ - ftp_link = FindUdpTcpOut(true_addr, GetDestAddress(link), - htons(true_port), 0, IPPROTO_TCP, 1); - - if (ftp_link != NULL) - { - int slen, hlen, tlen, dlen; - struct tcphdr *tc; - -#ifndef NO_FW_PUNCH - if (ftp_message_type == FTP_PORT_COMMAND || - ftp_message_type == FTP_EPRT_COMMAND) { - /* Punch hole in firewall */ - PunchFWHole(ftp_link); - } -#endif - -/* 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 FTP message. */ - { - char stemp[MAX_MESSAGE_SIZE + 1]; - char *sptr; - u_short alias_port; - u_char *ptr; - int a1, a2, a3, a4, p1, p2; - struct in_addr alias_address; - -/* Decompose alias address into quad format */ - alias_address = GetAliasAddress(link); - ptr = (u_char *) &alias_address.s_addr; - a1 = *ptr++; a2=*ptr++; a3=*ptr++; a4=*ptr; - - alias_port = GetAliasPort(ftp_link); - - switch (ftp_message_type) - { - case FTP_PORT_COMMAND: - case FTP_227_REPLY: - /* Decompose alias port into pair format. */ - ptr = (u_char *) &alias_port; - p1 = *ptr++; p2=*ptr; - - if (ftp_message_type == FTP_PORT_COMMAND) { - /* Generate PORT command string. */ - snprintf(stemp, sizeof(stemp), "PORT %d,%d,%d,%d,%d,%d\r\n", - a1,a2,a3,a4,p1,p2); - } else { - /* Generate 227 reply string. */ - snprintf(stemp, sizeof(stemp), - "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n", - a1,a2,a3,a4,p1,p2); - } - break; - case FTP_EPRT_COMMAND: - /* Generate EPRT command string. */ - snprintf(stemp, sizeof(stemp), "EPRT |1|%d.%d.%d.%d|%d|\r\n", - a1,a2,a3,a4,ntohs(alias_port)); - break; - case FTP_229_REPLY: - /* Generate 229 reply string. */ - snprintf(stemp, sizeof(stemp), "229 Entering Extended Passive Mode (|||%d|)\r\n", - ntohs(alias_port)); - break; - } - -/* Save string length for IP header modification */ - slen = strlen(stemp); - -/* Copy modified buffer into IP packet. */ - sptr = (char *) pip; sptr += hlen; - strncpy(sptr, stemp, maxpacketsize-hlen); - } - -/* Save information regarding modified seq and ack numbers */ - { - int delta; - - SetAckModified(link); - delta = GetDeltaSeqOut(pip, link); - AddSeq(pip, link, delta+slen-dlen); - } - -/* Revise IP header */ - { - u_short new_len; - - new_len = htons(hlen + slen); - DifferentialChecksum(&pip->ip_sum, - &new_len, - &pip->ip_len, - 1); - pip->ip_len = new_len; - } - -/* Compute TCP checksum for revised packet */ - tc->th_sum = 0; - tc->th_sum = TcpChecksum(pip); - } - else - { -#ifdef DEBUG - fprintf(stderr, - "PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n"); -#endif - } -} diff --git a/alias/alias_irc.c b/alias/alias_irc.c deleted file mode 100644 index 4ecddb9..0000000 --- a/alias/alias_irc.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 2001 Charles Mott - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_irc.c,v 1.5.2.4 2001/08/21 16:42:42 ru Exp $ - */ - -/* Alias_irc.c intercepts packages contain IRC CTCP commands, and - changes DCC commands to export a port on the aliasing host instead - of an aliased host. - - For this routine to work, the DCC command must fit entirely into a - single TCP packet. This will usually happen, but is not - guaranteed. - - The interception is likely to change the length of the packet. - The handling of this is copied more-or-less verbatim from - ftp_alias.c - - Initial version: Eivind Eklund (ee) 97-01-29 - - Version 2.1: May, 1997 (cjm) - Very minor changes to conform with - local/global/function naming conventions - withing the packet alising module. -*/ - -/* Includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "alias_local.h" - -/* Local defines */ -#define DBprintf(a) - - -void -AliasHandleIrcOut(struct ip *pip, /* IP packet to examine */ - struct alias_link *link, /* Which link are we on? */ - int maxsize /* Maximum size of IP packet including headers */ - ) -{ - int hlen, tlen, dlen; - struct in_addr true_addr; - u_short true_port; - char *sptr; - struct tcphdr *tc; - int i; /* Iterator through the source */ - -/* 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 if data length is too short - assume an entire PRIVMSG in each packet. */ - if (dlen= dlen || iCopy >= sizeof(newpacket) ) - goto lPACKET_DONE; - newpacket[iCopy++] = sptr[i++]; /* Copy the CTCP start character */ - /* Start of a CTCP */ - if( i+4 >= dlen ) /* Too short for DCC */ - goto lBAD_CTCP; - if( sptr[i+0] != 'D' ) - goto lBAD_CTCP; - if( sptr[i+1] != 'C' ) - goto lBAD_CTCP; - if( sptr[i+2] != 'C' ) - goto lBAD_CTCP; - if( sptr[i+3] != ' ' ) - goto lBAD_CTCP; - /* We have a DCC command - handle it! */ - i+= 4; /* Skip "DCC " */ - if( iCopy+4 > sizeof(newpacket) ) - goto lPACKET_DONE; - newpacket[iCopy++] = 'D'; - newpacket[iCopy++] = 'C'; - newpacket[iCopy++] = 'C'; - newpacket[iCopy++] = ' '; - - DBprintf(("Found DCC\n")); - /* Skip any extra spaces (should not occur according to - protocol, but DCC breaks CTCP protocol anyway */ - while(sptr[i] == ' ') { - if( ++i >= dlen) { - DBprintf(("DCC packet terminated in just spaces\n")); - goto lPACKET_DONE; - } - } - - DBprintf(("Transferring command...\n")); - while(sptr[i] != ' ') { - newpacket[iCopy++] = sptr[i]; - if( ++i >= dlen || iCopy >= sizeof(newpacket) ) { - DBprintf(("DCC packet terminated during command\n")); - goto lPACKET_DONE; - } - } - /* Copy _one_ space */ - if( i+1 < dlen && iCopy < sizeof(newpacket) ) - newpacket[iCopy++] = sptr[i++]; - - DBprintf(("Done command - removing spaces\n")); - /* Skip any extra spaces (should not occur according to - protocol, but DCC breaks CTCP protocol anyway */ - while(sptr[i] == ' ') { - if( ++i >= dlen ) { - DBprintf(("DCC packet terminated in just spaces (post-command)\n")); - goto lPACKET_DONE; - } - } - - DBprintf(("Transferring filename...\n")); - while(sptr[i] != ' ') { - newpacket[iCopy++] = sptr[i]; - if( ++i >= dlen || iCopy >= sizeof(newpacket) ) { - DBprintf(("DCC packet terminated during filename\n")); - goto lPACKET_DONE; - } - } - /* Copy _one_ space */ - if( i+1 < dlen && iCopy < sizeof(newpacket) ) - newpacket[iCopy++] = sptr[i++]; - - DBprintf(("Done filename - removing spaces\n")); - /* Skip any extra spaces (should not occur according to - protocol, but DCC breaks CTCP protocol anyway */ - while(sptr[i] == ' ') { - if( ++i >= dlen ) { - DBprintf(("DCC packet terminated in just spaces (post-filename)\n")); - goto lPACKET_DONE; - } - } - - DBprintf(("Fetching IP address\n")); - /* Fetch IP address */ - org_addr = 0; - while(i 0xFFFFFFFF/10UL ) { /* Terminate on overflow */ - DBprintf(("DCC Address overflow (org_addr == 0x%08lx, next char %c\n", org_addr, sptr[i])); - goto lBAD_CTCP; - } - org_addr *= 10; - org_addr += sptr[i++]-'0'; - } - DBprintf(("Skipping space\n")); - if( i+1 >= dlen || sptr[i] != ' ' ) { - DBprintf(("Overflow (%d >= %d) or bad character (%02x) terminating IP address\n", i+1, dlen, sptr[i])); - goto lBAD_CTCP; - } - /* Skip any extra spaces (should not occur according to - protocol, but DCC breaks CTCP protocol anyway, so we might - as well play it safe */ - while(sptr[i] == ' ') { - if( ++i >= dlen ) { - DBprintf(("Packet failure - space overflow.\n")); - goto lPACKET_DONE; - } - } - DBprintf(("Fetching port number\n")); - /* Fetch source port */ - org_port = 0; - while(i 6554 ) { /* Terminate on overflow (65536/10 rounded up*/ - DBprintf(("DCC: port number overflow\n")); - goto lBAD_CTCP; - } - org_port *= 10; - org_port += sptr[i++]-'0'; - } - /* Skip illegal addresses (or early termination) */ - if( i >= dlen || (sptr[i] != '\001' && sptr[i] != ' ') ) { - DBprintf(("Bad port termination\n")); - goto lBAD_CTCP; - } - DBprintf(("Got IP %lu and port %u\n", org_addr, (unsigned)org_port)); - - /* We've got the address and port - now alias it */ - { - struct alias_link *dcc_link; - struct in_addr destaddr; - - - true_port = htons(org_port); - true_addr.s_addr = htonl(org_addr); - destaddr.s_addr = 0; - - /* Sanity/Security checking */ - if (!org_addr || !org_port || - pip->ip_src.s_addr != true_addr.s_addr || - org_port < IPPORT_RESERVED) - goto lBAD_CTCP; - - /* Steal the FTP_DATA_PORT - it doesn't really matter, and this - would probably allow it through at least _some_ - firewalls. */ - dcc_link = FindUdpTcpOut(true_addr, destaddr, - true_port, 0, - IPPROTO_TCP, 1); - DBprintf(("Got a DCC link\n")); - if ( dcc_link ) { - struct in_addr alias_address; /* Address from aliasing */ - u_short alias_port; /* Port given by aliasing */ - -#ifndef NO_FW_PUNCH - /* Generate firewall hole as appropriate */ - PunchFWHole(dcc_link); -#endif - - alias_address = GetAliasAddress(link); - iCopy += snprintf(&newpacket[iCopy], - sizeof(newpacket)-iCopy, - "%u ", (in_addr_t)htonl(alias_address.s_addr)); - if( iCopy >= sizeof(newpacket) ) { /* Truncated/fit exactly - bad news */ - DBprintf(("DCC constructed packet overflow.\n")); - goto lBAD_CTCP; - } - alias_port = GetAliasPort(dcc_link); - iCopy += snprintf(&newpacket[iCopy], - sizeof(newpacket)-iCopy, - "%u", htons(alias_port) ); - /* Done - truncated cases will be taken care of by lBAD_CTCP */ - DBprintf(("Aliased IP %lu and port %u\n", alias_address.s_addr, (unsigned)alias_port)); - } - } - /* An uninteresting CTCP - state entered right after '\001' has - been pushed. Also used to copy the rest of a DCC, after IP - address and port has been handled */ - lBAD_CTCP: - for(; i maxsize-copyat ? maxsize-copyat : iCopy; - memcpy(sptr+copyat, newpacket, iCopy); - -/* Save information regarding modified seq and ack numbers */ - { - int delta; - - SetAckModified(link); - delta = GetDeltaSeqOut(pip, link); - AddSeq(pip, link, delta+copyat+iCopy-dlen); - } - - /* Revise IP header */ - { - u_short new_len; - - new_len = htons(hlen + iCopy + copyat); - DifferentialChecksum(&pip->ip_sum, - &new_len, - &pip->ip_len, - 1); - pip->ip_len = new_len; - } - - /* Compute TCP checksum for revised packet */ - tc->th_sum = 0; - tc->th_sum = TcpChecksum(pip); - return; - } -} - -/* Notes: - [Note 1] - The initial search will most often fail; it could be replaced with a 32-bit specific search. - Such a search would be done for 32-bit unsigned value V: - V ^= 0x01010101; (Search is for null bytes) - if( ((V-0x01010101)^V) & 0x80808080 ) { - (found a null bytes which was a 01 byte) - } - To assert that the processor is 32-bits, do - extern int ircdccar[32]; (32 bits) - extern int ircdccar[CHAR_BIT*sizeof(unsigned int)]; - which will generate a type-error on all but 32-bit machines. - - [Note 2] This routine really ought to be replaced with one that - creates a transparent proxy on the aliasing host, to allow arbitary - changes in the TCP stream. This should not be too difficult given - this base; I (ee) will try to do this some time later. - */ diff --git a/alias/alias_local.h b/alias/alias_local.h deleted file mode 100644 index 8aeb983..0000000 --- a/alias/alias_local.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 2001 Charles Mott - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_local.h,v 1.10.2.5 2001/08/01 09:52:26 obrien Exp $ - */ - -/* - * Alias_local.h contains the function prototypes for alias.c, - * alias_db.c, alias_util.c and alias_ftp.c, alias_irc.c (as well - * as any future add-ons). It also includes macros, globals and - * struct definitions shared by more than one alias*.c file. - * - * This include file 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) - * - * - */ - -#ifndef _ALIAS_LOCAL_H_ -#define _ALIAS_LOCAL_H_ - -#ifndef NULL -#define NULL 0 -#endif - -/* Macros */ - -/* - * The following macro is used to update an - * internet checksum. "delta" is a 32-bit - * accumulation of all the changes to the - * checksum (adding in new 16-bit words and - * subtracting out old words), and "cksum" - * is the checksum value to be updated. - */ -#define ADJUST_CHECKSUM(acc, cksum) \ - do { \ - acc += cksum; \ - if (acc < 0) { \ - acc = -acc; \ - acc = (acc >> 16) + (acc & 0xffff); \ - acc += acc >> 16; \ - cksum = (u_short) ~acc; \ - } else { \ - acc = (acc >> 16) + (acc & 0xffff); \ - acc += acc >> 16; \ - cksum = (u_short) acc; \ - } \ - } while (0) - -/* Globals */ - -extern int packetAliasMode; - - -/* Structs */ - -struct alias_link; /* Incomplete structure */ - - -/* Prototypes */ - -/* General utilities */ -u_short IpChecksum(struct ip *); -u_short TcpChecksum(struct ip *); -void DifferentialChecksum(u_short *, u_short *, u_short *, int); - -/* Internal data access */ -struct alias_link * -FindIcmpIn(struct in_addr, struct in_addr, u_short, int); - -struct alias_link * -FindIcmpOut(struct in_addr, struct in_addr, u_short, int); - -struct alias_link * -FindFragmentIn1(struct in_addr, struct in_addr, u_short); - -struct alias_link * -FindFragmentIn2(struct in_addr, struct in_addr, u_short); - -struct alias_link * -AddFragmentPtrLink(struct in_addr, u_short); - -struct alias_link * -FindFragmentPtr(struct in_addr, u_short); - -struct alias_link * -FindProtoIn(struct in_addr, struct in_addr, u_char); - -struct alias_link * -FindProtoOut(struct in_addr, struct in_addr, u_char); - -struct alias_link * -FindUdpTcpIn (struct in_addr, struct in_addr, u_short, u_short, u_char, int); - -struct alias_link * -FindUdpTcpOut(struct in_addr, struct in_addr, u_short, u_short, u_char, int); - -struct alias_link * -AddPptp(struct in_addr, struct in_addr, struct in_addr, u_int16_t); - -struct alias_link * -FindPptpOutByCallId(struct in_addr, struct in_addr, u_int16_t); - -struct alias_link * -FindPptpInByCallId(struct in_addr, struct in_addr, u_int16_t); - -struct alias_link * -FindPptpOutByPeerCallId(struct in_addr, struct in_addr, u_int16_t); - -struct alias_link * -FindPptpInByPeerCallId(struct in_addr, struct in_addr, u_int16_t); - -struct alias_link * -FindRtspOut(struct in_addr, struct in_addr, u_short, u_short, u_char); - -struct in_addr -FindOriginalAddress(struct in_addr); - -struct in_addr -FindAliasAddress(struct in_addr); - -/* External data access/modification */ -int FindNewPortGroup(struct in_addr, struct in_addr, - u_short, u_short, u_short, u_char, u_char); -void GetFragmentAddr(struct alias_link *, struct in_addr *); -void SetFragmentAddr(struct alias_link *, struct in_addr); -void GetFragmentPtr(struct alias_link *, char **); -void SetFragmentPtr(struct alias_link *, char *); -void SetStateIn(struct alias_link *, int); -void SetStateOut(struct alias_link *, int); -int GetStateIn(struct alias_link *); -int GetStateOut(struct alias_link *); -struct in_addr GetOriginalAddress(struct alias_link *); -struct in_addr GetDestAddress(struct alias_link *); -struct in_addr GetAliasAddress(struct alias_link *); -struct in_addr GetDefaultAliasAddress(void); -void SetDefaultAliasAddress(struct in_addr); -u_short GetOriginalPort(struct alias_link *); -u_short GetAliasPort(struct alias_link *); -struct in_addr GetProxyAddress(struct alias_link *); -void SetProxyAddress(struct alias_link *, struct in_addr); -u_short GetProxyPort(struct alias_link *); -void SetProxyPort(struct alias_link *, u_short); -void SetAckModified(struct alias_link *); -int GetAckModified(struct alias_link *); -int GetDeltaAckIn(struct ip *, struct alias_link *); -int GetDeltaSeqOut(struct ip *, struct alias_link *); -void AddSeq(struct ip *, struct alias_link *, int); -void SetExpire(struct alias_link *, int); -void ClearCheckNewLink(void); -void SetLastLineCrlfTermed(struct alias_link *, int); -int GetLastLineCrlfTermed(struct alias_link *); -void SetDestCallId(struct alias_link *, u_int16_t); -#ifndef NO_FW_PUNCH -void PunchFWHole(struct alias_link *); -#endif - - -/* Housekeeping function */ -void HouseKeeping(void); - -/* Tcp specfic routines */ -/*lint -save -library Suppress flexelint warnings */ - -/* FTP routines */ -void AliasHandleFtpOut(struct ip *, struct alias_link *, int); - -/* IRC routines */ -void AliasHandleIrcOut(struct ip *, struct alias_link *, int); - -/* RTSP routines */ -void AliasHandleRtspOut(struct ip *, struct alias_link *, int); - -/* PPTP routines */ -void AliasHandlePptpOut(struct ip *, struct alias_link *); -void AliasHandlePptpIn(struct ip *, struct alias_link *); -int AliasHandlePptpGreOut(struct ip *); -int AliasHandlePptpGreIn(struct ip *); - -/* NetBIOS routines */ -int AliasHandleUdpNbt(struct ip *, struct alias_link *, struct in_addr *, u_short); -int AliasHandleUdpNbtNS(struct ip *, struct alias_link *, struct in_addr *, u_short *, struct in_addr *, u_short *); - -/* CUSeeMe routines */ -void AliasHandleCUSeeMeOut(struct ip *, struct alias_link *); -void AliasHandleCUSeeMeIn(struct ip *, struct in_addr); - -/* Transparent proxy routines */ -int ProxyCheck(struct ip *, struct in_addr *, u_short *); -void ProxyModify(struct alias_link *, struct ip *, int, int); - - -enum alias_tcp_state { - ALIAS_TCP_STATE_NOT_CONNECTED, - ALIAS_TCP_STATE_CONNECTED, - ALIAS_TCP_STATE_DISCONNECTED -}; - -/*lint -restore */ - -#endif /* !_ALIAS_LOCAL_H_ */ diff --git a/alias/alias_nbt.c b/alias/alias_nbt.c deleted file mode 100644 index 4ff5d41..0000000 --- a/alias/alias_nbt.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Written by Atsushi Murai - * Copyright (c) 1998, System Planning and Engineering Co. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_nbt.c,v 1.4.2.3 2001/08/01 09:52:26 obrien Exp $ - * - * TODO: - * oClean up. - * oConsidering for word alignment for other platform. - */ -/* - alias_nbt.c performs special processing for NetBios over TCP/IP - sessions by UDP. - - Initial version: May, 1998 (Atsushi Murai ) - - See HISTORY file for record of revisions. -*/ - -/* Includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "alias_local.h" - -typedef struct { - struct in_addr oldaddr; - u_short oldport; - struct in_addr newaddr; - u_short newport; - u_short *uh_sum; -} NBTArguments; - -typedef struct { - unsigned char type; - unsigned char flags; - u_short id; - struct in_addr source_ip; - u_short source_port; - u_short len; - u_short offset; -} NbtDataHeader; - -#define OpQuery 0 -#define OpUnknown 4 -#define OpRegist 5 -#define OpRelease 6 -#define OpWACK 7 -#define OpRefresh 8 -typedef struct { - u_short nametrid; - u_short dir:1, opcode:4, nmflags:7, rcode:4; - u_short qdcount; - u_short ancount; - u_short nscount; - u_short arcount; -} NbtNSHeader; - -#define FMT_ERR 0x1 -#define SRV_ERR 0x2 -#define IMP_ERR 0x4 -#define RFS_ERR 0x5 -#define ACT_ERR 0x6 -#define CFT_ERR 0x7 - - -#ifdef DEBUG -static void PrintRcode( u_char rcode ) { - - switch (rcode) { - case FMT_ERR: - printf("\n Format Error.\n"); - break; - case SRV_ERR: - printf("\n Server failure.\n"); - break; - case IMP_ERR: - printf("\n Unsupported request error.\n"); - break; - case RFS_ERR: - printf("\n Refused error.\n"); - break; - case ACT_ERR: - printf("\n Active error.\n"); - break; - case CFT_ERR: - printf("\n Name in conflict error.\n"); - break; - default: - printf("\n \?\?\?=%0x\n", rcode ); - break; - } -} -#endif - - -/* Handling Name field */ -static u_char *AliasHandleName ( u_char *p, char *pmax ) { - - u_char *s; - u_char c; - int compress; - - /* Following length field */ - - if (p == NULL || (char *)p >= pmax) - return(NULL); - - if (*p & 0xc0 ) { - p = p + 2; - if ((char *)p > pmax) - return(NULL); - return ((u_char *)p); - } - while ( ( *p & 0x3f) != 0x00 ) { - s = p + 1; - if ( *p == 0x20 ) - compress = 1; - else - compress = 0; - - /* Get next length field */ - p = (u_char *)(p + (*p & 0x3f) + 1); - if ((char *)p > pmax) { - p = NULL; - break; - } -#ifdef DEBUG - printf(":"); -#endif - while (s < p) { - if ( compress == 1 ) { - c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11)); -#ifdef DEBUG - if (isprint( c ) ) - printf("%c", c ); - else - printf("<0x%02x>", c ); -#endif - s +=2; - } else { -#ifdef DEBUG - printf("%c", *s); -#endif - s++; - } - } -#ifdef DEBUG - printf(":"); -#endif - fflush(stdout); - } - - /* Set up to out of Name field */ - if (p == NULL || (char *)p >= pmax) - p = NULL; - else - p++; - return ((u_char *)p); -} - -/* - * NetBios Datagram Handler (IP/UDP) - */ -#define DGM_DIRECT_UNIQ 0x10 -#define DGM_DIRECT_GROUP 0x11 -#define DGM_BROADCAST 0x12 -#define DGM_ERROR 0x13 -#define DGM_QUERY 0x14 -#define DGM_POSITIVE_RES 0x15 -#define DGM_NEGATIVE_RES 0x16 - -int AliasHandleUdpNbt( - struct ip *pip, /* IP packet to examine/patch */ - struct alias_link *link, - struct in_addr *alias_address, - u_short alias_port -) { - struct udphdr * uh; - NbtDataHeader *ndh; - u_char *p = NULL; - char *pmax; - - /* Calculate data length of UDP packet */ - uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); - pmax = (char *)uh + ntohs( uh->uh_ulen ); - - ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr))); - if ((char *)(ndh + 1) > pmax) - return(-1); -#ifdef DEBUG - printf("Type=%02x,", ndh->type ); -#endif - switch ( ndh->type ) { - case DGM_DIRECT_UNIQ: - case DGM_DIRECT_GROUP: - case DGM_BROADCAST: - p = (u_char *)ndh + 14; - p = AliasHandleName ( p, pmax ); /* Source Name */ - p = AliasHandleName ( p, pmax ); /* Destination Name */ - break; - case DGM_ERROR: - p = (u_char *)ndh + 11; - break; - case DGM_QUERY: - case DGM_POSITIVE_RES: - case DGM_NEGATIVE_RES: - p = (u_char *)ndh + 10; - p = AliasHandleName ( p, pmax ); /* Destination Name */ - break; - } - if (p == NULL || (char *)p > pmax) - p = NULL; -#ifdef DEBUG - printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); -#endif - /* Doing a IP address and Port number Translation */ - if ( uh->uh_sum != 0 ) { - int acc; - u_short *sptr; - acc = ndh->source_port; - acc -= alias_port; - sptr = (u_short *) &(ndh->source_ip); - acc += *sptr++; - acc += *sptr; - sptr = (u_short *) alias_address; - acc -= *sptr++; - acc -= *sptr; - ADJUST_CHECKSUM(acc, uh->uh_sum); - } - ndh->source_ip = *alias_address; - ndh->source_port = alias_port; -#ifdef DEBUG - printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); - fflush(stdout); -#endif - return((p == NULL) ? -1 : 0); -} -/* Question Section */ -#define QS_TYPE_NB 0x0020 -#define QS_TYPE_NBSTAT 0x0021 -#define QS_CLAS_IN 0x0001 -typedef struct { - u_short type; /* The type of Request */ - u_short class; /* The class of Request */ -} NBTNsQuestion; - -static u_char * -AliasHandleQuestion( - u_short count, - NBTNsQuestion *q, - char *pmax, - NBTArguments *nbtarg) -{ - - while ( count != 0 ) { - /* Name Filed */ - q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax); - - if (q == NULL || (char *)(q + 1) > pmax) { - q = NULL; - break; - } - - /* Type and Class filed */ - switch ( ntohs(q->type) ) { - case QS_TYPE_NB: - case QS_TYPE_NBSTAT: - q= q+1; - break; - default: -#ifdef DEBUG - printf("\nUnknown Type on Question %0x\n", ntohs(q->type) ); -#endif - break; - } - count--; - } - - /* Set up to out of Question Section */ - return ((u_char *)q); -} - -/* Resource Record */ -#define RR_TYPE_A 0x0001 -#define RR_TYPE_NS 0x0002 -#define RR_TYPE_NULL 0x000a -#define RR_TYPE_NB 0x0020 -#define RR_TYPE_NBSTAT 0x0021 -#define RR_CLAS_IN 0x0001 -#define SizeOfNsResource 8 -typedef struct { - u_short type; - u_short class; - unsigned int ttl; - u_short rdlen; -} NBTNsResource; - -#define SizeOfNsRNB 6 -typedef struct { - u_short g:1, ont:2, resv:13; - struct in_addr addr; -} NBTNsRNB; - -static u_char * -AliasHandleResourceNB( - NBTNsResource *q, - char *pmax, - NBTArguments *nbtarg) -{ - NBTNsRNB *nb; - u_short bcount; - - if (q == NULL || (char *)(q + 1) > pmax) - return(NULL); - /* Check out a length */ - bcount = ntohs(q->rdlen); - - /* Forward to Resource NB position */ - nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource); - - /* Processing all in_addr array */ -#ifdef DEBUG - printf(" NB rec[%s", inet_ntoa(nbtarg->oldaddr)); - printf("->%s, %d bytes] ",inet_ntoa(nbtarg->newaddr ), bcount); -#endif - while ( nb != NULL && bcount != 0 ) { - if ((char *)(nb + 1) > pmax) { - nb = NULL; - break; - } -#ifdef DEBUG - printf("<%s>", inet_ntoa(nb->addr) ); -#endif - if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) { - if ( *nbtarg->uh_sum != 0 ) { - int acc; - u_short *sptr; - - sptr = (u_short *) &(nb->addr); - acc = *sptr++; - acc += *sptr; - sptr = (u_short *) &(nbtarg->newaddr); - acc -= *sptr++; - acc -= *sptr; - ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); - } - - nb->addr = nbtarg->newaddr; -#ifdef DEBUG - printf("O"); -#endif - } -#ifdef DEBUG - else { - printf("."); - } -#endif - nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB); - bcount -= SizeOfNsRNB; - } - if (nb == NULL || (char *)(nb + 1) > pmax) { - nb = NULL; - } - - return ((u_char *)nb); -} - -#define SizeOfResourceA 6 -typedef struct { - struct in_addr addr; -} NBTNsResourceA; - -static u_char * -AliasHandleResourceA( - NBTNsResource *q, - char *pmax, - NBTArguments *nbtarg) -{ - NBTNsResourceA *a; - u_short bcount; - - if (q == NULL || (char *)(q + 1) > pmax) - return(NULL); - - /* Forward to Resource A position */ - a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) ); - - /* Check out of length */ - bcount = ntohs(q->rdlen); - - /* Processing all in_addr array */ -#ifdef DEBUG - printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); - printf("->%s]",inet_ntoa(nbtarg->newaddr )); -#endif - while ( bcount != 0 ) { - if (a == NULL || (char *)(a + 1) > pmax) - return(NULL); -#ifdef DEBUG - printf("..%s", inet_ntoa(a->addr) ); -#endif - if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) { - if ( *nbtarg->uh_sum != 0 ) { - int acc; - u_short *sptr; - - sptr = (u_short *) &(a->addr); /* Old */ - acc = *sptr++; - acc += *sptr; - sptr = (u_short *) &nbtarg->newaddr; /* New */ - acc -= *sptr++; - acc -= *sptr; - ADJUST_CHECKSUM(acc, *nbtarg->uh_sum); - } - - a->addr = nbtarg->newaddr; - } - a++; /*XXXX*/ - bcount -= SizeOfResourceA; - } - if (a == NULL || (char *)(a + 1) > pmax) - a = NULL; - return ((u_char *)a); -} - -typedef struct { - u_short opcode:4, flags:8, resv:4; -} NBTNsResourceNULL; - -static u_char * -AliasHandleResourceNULL( - NBTNsResource *q, - char *pmax, - NBTArguments *nbtarg) -{ - NBTNsResourceNULL *n; - u_short bcount; - - if (q == NULL || (char *)(q + 1) > pmax) - return(NULL); - - /* Forward to Resource NULL position */ - n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); - - /* Check out of length */ - bcount = ntohs(q->rdlen); - - /* Processing all in_addr array */ - while ( bcount != 0 ) { - if ((char *)(n + 1) > pmax) { - n = NULL; - break; - } - n++; - bcount -= sizeof(NBTNsResourceNULL); - } - if ((char *)(n + 1) > pmax) - n = NULL; - - return ((u_char *)n); -} - -static u_char * -AliasHandleResourceNS( - NBTNsResource *q, - char *pmax, - NBTArguments *nbtarg) -{ - NBTNsResourceNULL *n; - u_short bcount; - - if (q == NULL || (char *)(q + 1) > pmax) - return(NULL); - - /* Forward to Resource NULL position */ - n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); - - /* Check out of length */ - bcount = ntohs(q->rdlen); - - /* Resource Record Name Filed */ - q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */ - - if (q == NULL || (char *)((u_char *)n + bcount) > pmax) - return(NULL); - else - return ((u_char *)n + bcount); -} - -typedef struct { - u_short numnames; -} NBTNsResourceNBSTAT; - -static u_char * -AliasHandleResourceNBSTAT( - NBTNsResource *q, - char *pmax, - NBTArguments *nbtarg) -{ - NBTNsResourceNBSTAT *n; - u_short bcount; - - if (q == NULL || (char *)(q + 1) > pmax) - return(NULL); - - /* Forward to Resource NBSTAT position */ - n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) ); - - /* Check out of length */ - bcount = ntohs(q->rdlen); - - if (q == NULL || (char *)((u_char *)n + bcount) > pmax) - return(NULL); - else - return ((u_char *)n + bcount); -} - -static u_char * -AliasHandleResource( - u_short count, - NBTNsResource *q, - char *pmax, - NBTArguments - *nbtarg) -{ - while ( count != 0 ) { - /* Resource Record Name Filed */ - q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax ); - - if (q == NULL || (char *)(q + 1) > pmax) - break; -#ifdef DEBUG - printf("\n type=%02x, count=%d\n", ntohs(q->type), count ); -#endif - - /* Type and Class filed */ - switch ( ntohs(q->type) ) { - case RR_TYPE_NB: - q = (NBTNsResource *)AliasHandleResourceNB( - q, - pmax, - nbtarg - ); - break; - case RR_TYPE_A: - q = (NBTNsResource *)AliasHandleResourceA( - q, - pmax, - nbtarg - ); - break; - case RR_TYPE_NS: - q = (NBTNsResource *)AliasHandleResourceNS( - q, - pmax, - nbtarg - ); - break; - case RR_TYPE_NULL: - q = (NBTNsResource *)AliasHandleResourceNULL( - q, - pmax, - nbtarg - ); - break; - case RR_TYPE_NBSTAT: - q = (NBTNsResource *)AliasHandleResourceNBSTAT( - q, - pmax, - nbtarg - ); - break; - default: -#ifdef DEBUG - printf( - "\nUnknown Type of Resource %0x\n", - ntohs(q->type) - ); -#endif - break; - } - count--; - } - fflush(stdout); - return ((u_char *)q); -} - -int AliasHandleUdpNbtNS( - struct ip *pip, /* IP packet to examine/patch */ - struct alias_link *link, - struct in_addr *alias_address, - u_short *alias_port, - struct in_addr *original_address, - u_short *original_port ) -{ - struct udphdr * uh; - NbtNSHeader * nsh; - u_char * p; - char *pmax; - NBTArguments nbtarg; - - /* Set up Common Parameter */ - nbtarg.oldaddr = *alias_address; - nbtarg.oldport = *alias_port; - nbtarg.newaddr = *original_address; - nbtarg.newport = *original_port; - - /* Calculate data length of UDP packet */ - uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); - nbtarg.uh_sum = &(uh->uh_sum); - nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr))); - p = (u_char *)(nsh + 1); - pmax = (char *)uh + ntohs( uh->uh_ulen ); - - if ((char *)(nsh + 1) > pmax) - return(-1); - -#ifdef DEBUG - printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x" - ", an=%04x, ns=%04x, ar=%04x, [%d]-->", - nsh->dir ? "Response": "Request", - nsh->nametrid, - nsh->opcode, - nsh->nmflags, - nsh->rcode, - ntohs(nsh->qdcount), - ntohs(nsh->ancount), - ntohs(nsh->nscount), - ntohs(nsh->arcount), - (int)((u_char *)p -(u_char *)nsh) - ); -#endif - - /* Question Entries */ - if (ntohs(nsh->qdcount) !=0 ) { - p = AliasHandleQuestion( - ntohs(nsh->qdcount), - (NBTNsQuestion *)p, - pmax, - &nbtarg - ); - } - - /* Answer Resource Records */ - if (ntohs(nsh->ancount) !=0 ) { - p = AliasHandleResource( - ntohs(nsh->ancount), - (NBTNsResource *)p, - pmax, - &nbtarg - ); - } - - /* Authority Resource Recodrs */ - if (ntohs(nsh->nscount) !=0 ) { - p = AliasHandleResource( - ntohs(nsh->nscount), - (NBTNsResource *)p, - pmax, - &nbtarg - ); - } - - /* Additional Resource Recodrs */ - if (ntohs(nsh->arcount) !=0 ) { - p = AliasHandleResource( - ntohs(nsh->arcount), - (NBTNsResource *)p, - pmax, - &nbtarg - ); - } - -#ifdef DEBUG - if (nsh->rcode) - PrintRcode(nsh->rcode); -#endif - return ((p == NULL) ? -1 : 0); -} diff --git a/alias/alias_pptp.c b/alias/alias_pptp.c deleted file mode 100644 index 03e1a22..0000000 --- a/alias/alias_pptp.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * alias_pptp.c - * - * Copyright (c) 2000 Whistle Communications, Inc. - * All rights reserved. - * - * Subject to the following obligations and disclaimer of warranty, use and - * redistribution of this software, in source or object code forms, with or - * without modifications are expressly permitted by Whistle Communications; - * provided, however, that: - * 1. Any and all reproductions of the source or object code must include the - * copyright notice above and the following disclaimer of warranties; and - * 2. No rights are granted, in any manner or form, to use Whistle - * Communications, Inc. trademarks, including the mark "WHISTLE - * COMMUNICATIONS" on advertising, endorsements, or otherwise except as - * such appears in the above copyright notice or in the software. - * - * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO - * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, - * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. - * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY - * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS - * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. - * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES - * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING - * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Erik Salander - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_pptp.c,v 1.1.2.4 2001/08/01 09:52:27 obrien Exp $ - */ - -/* - Alias_pptp.c performs special processing for PPTP sessions under TCP. - Specifically, watch PPTP control messages and alias the Call ID or the - Peer's Call ID in the appropriate messages. Note, PPTP requires - "de-aliasing" of incoming packets, this is different than any other - TCP applications that are currently (ie. FTP, IRC and RTSP) aliased. - - For Call IDs encountered for the first time, a PPTP alias link is created. - The PPTP alias link uses the Call ID in place of the original port number. - An alias Call ID is created. - - For this routine to work, the PPTP control messages must fit entirely - into a single TCP packet. This is typically the case, but is not - required by the spec. - - Unlike some of the other TCP applications that are aliased (ie. FTP, - IRC and RTSP), the PPTP control messages that need to be aliased are - guaranteed to remain the same length. The aliased Call ID is a fixed - length field. - - Reference: RFC 2637 - - Initial version: May, 2000 (eds) - -*/ - -/* Includes */ -#include -#include -#include -#include -#include - -#include - -#include "alias_local.h" - -/* - * PPTP definitions - */ - -struct grehdr /* Enhanced GRE header. */ -{ - u_int16_t gh_flags; /* Flags. */ - u_int16_t gh_protocol; /* Protocol type. */ - u_int16_t gh_length; /* Payload length. */ - u_int16_t gh_call_id; /* Call ID. */ - u_int32_t gh_seq_no; /* Sequence number (optional). */ - u_int32_t gh_ack_no; /* Acknowledgment number (optional). */ -}; -typedef struct grehdr GreHdr; - -/* The PPTP protocol ID used in the GRE 'proto' field. */ -#define PPTP_GRE_PROTO 0x880b - -/* Bits that must be set a certain way in all PPTP/GRE packets. */ -#define PPTP_INIT_VALUE ((0x2001 << 16) | PPTP_GRE_PROTO) -#define PPTP_INIT_MASK 0xef7fffff - -#define PPTP_MAGIC 0x1a2b3c4d -#define PPTP_CTRL_MSG_TYPE 1 - -enum { - PPTP_StartCtrlConnRequest = 1, - PPTP_StartCtrlConnReply = 2, - PPTP_StopCtrlConnRequest = 3, - PPTP_StopCtrlConnReply = 4, - PPTP_EchoRequest = 5, - PPTP_EchoReply = 6, - PPTP_OutCallRequest = 7, - PPTP_OutCallReply = 8, - PPTP_InCallRequest = 9, - PPTP_InCallReply = 10, - PPTP_InCallConn = 11, - PPTP_CallClearRequest = 12, - PPTP_CallDiscNotify = 13, - PPTP_WanErrorNotify = 14, - PPTP_SetLinkInfo = 15 -}; - - /* Message structures */ - struct pptpMsgHead { - u_int16_t length; /* total length */ - u_int16_t msgType; /* PPTP message type */ - u_int32_t magic; /* magic cookie */ - u_int16_t type; /* control message type */ - u_int16_t resv0; /* reserved */ - }; - typedef struct pptpMsgHead *PptpMsgHead; - - struct pptpCodes { - u_int8_t resCode; /* Result Code */ - u_int8_t errCode; /* Error Code */ - }; - typedef struct pptpCodes *PptpCode; - - struct pptpCallIds { - u_int16_t cid1; /* Call ID field #1 */ - u_int16_t cid2; /* Call ID field #2 */ - }; - typedef struct pptpCallIds *PptpCallId; - -static PptpCallId AliasVerifyPptp(struct ip *, u_int16_t *); - - -void -AliasHandlePptpOut(struct ip *pip, /* IP packet to examine/patch */ - struct alias_link *link) /* The PPTP control link */ -{ - struct alias_link *pptp_link; - PptpCallId cptr; - PptpCode codes; - u_int16_t ctl_type; /* control message type */ - struct tcphdr *tc; - - /* Verify valid PPTP control message */ - if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL) - return; - - /* Modify certain PPTP messages */ - switch (ctl_type) { - case PPTP_OutCallRequest: - case PPTP_OutCallReply: - case PPTP_InCallRequest: - case PPTP_InCallReply: - /* Establish PPTP link for address and Call ID found in control message. */ - pptp_link = AddPptp(GetOriginalAddress(link), GetDestAddress(link), - GetAliasAddress(link), cptr->cid1); - break; - case PPTP_CallClearRequest: - case PPTP_CallDiscNotify: - /* Find PPTP link for address and Call ID found in control message. */ - pptp_link = FindPptpOutByCallId(GetOriginalAddress(link), - GetDestAddress(link), - cptr->cid1); - break; - default: - return; - } - - if (pptp_link != NULL) { - int accumulate = cptr->cid1; - - /* alias the Call Id */ - cptr->cid1 = GetAliasPort(pptp_link); - - /* Compute TCP checksum for revised packet */ - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - accumulate -= cptr->cid1; - ADJUST_CHECKSUM(accumulate, tc->th_sum); - - switch (ctl_type) { - case PPTP_OutCallReply: - case PPTP_InCallReply: - codes = (PptpCode)(cptr + 1); - if (codes->resCode == 1) /* Connection established, */ - SetDestCallId(pptp_link, /* note the Peer's Call ID. */ - cptr->cid2); - else - SetExpire(pptp_link, 0); /* Connection refused. */ - break; - case PPTP_CallDiscNotify: /* Connection closed. */ - SetExpire(pptp_link, 0); - break; - } - } -} - -void -AliasHandlePptpIn(struct ip *pip, /* IP packet to examine/patch */ - struct alias_link *link) /* The PPTP control link */ -{ - struct alias_link *pptp_link; - PptpCallId cptr; - u_int16_t *pcall_id; - u_int16_t ctl_type; /* control message type */ - struct tcphdr *tc; - - /* Verify valid PPTP control message */ - if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL) - return; - - /* Modify certain PPTP messages */ - switch (ctl_type) - { - case PPTP_InCallConn: - case PPTP_WanErrorNotify: - case PPTP_SetLinkInfo: - pcall_id = &cptr->cid1; - break; - case PPTP_OutCallReply: - case PPTP_InCallReply: - pcall_id = &cptr->cid2; - break; - case PPTP_CallDiscNotify: /* Connection closed. */ - pptp_link = FindPptpInByCallId(GetDestAddress(link), - GetAliasAddress(link), - cptr->cid1); - if (pptp_link != NULL) - SetExpire(pptp_link, 0); - return; - default: - return; - } - - /* Find PPTP link for address and Call ID found in PPTP Control Msg */ - pptp_link = FindPptpInByPeerCallId(GetDestAddress(link), - GetAliasAddress(link), - *pcall_id); - - if (pptp_link != NULL) { - int accumulate = *pcall_id; - - /* De-alias the Peer's Call Id. */ - *pcall_id = GetOriginalPort(pptp_link); - - /* Compute TCP checksum for modified packet */ - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - accumulate -= *pcall_id; - ADJUST_CHECKSUM(accumulate, tc->th_sum); - - if (ctl_type == PPTP_OutCallReply || ctl_type == PPTP_InCallReply) { - PptpCode codes = (PptpCode)(cptr + 1); - - if (codes->resCode == 1) /* Connection established, */ - SetDestCallId(pptp_link, /* note the Call ID. */ - cptr->cid1); - else - SetExpire(pptp_link, 0); /* Connection refused. */ - } - } -} - -static PptpCallId -AliasVerifyPptp(struct ip *pip, u_int16_t *ptype) /* IP packet to examine/patch */ -{ - int hlen, tlen, dlen; - PptpMsgHead hptr; - struct tcphdr *tc; - - /* Calculate some lengths */ - 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; - - /* Verify data length */ - if (dlen < (sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds))) - return(NULL); - - /* Move up to PPTP message header */ - hptr = (PptpMsgHead)(((char *) pip) + hlen); - - /* Return the control message type */ - *ptype = ntohs(hptr->type); - - /* Verify PPTP Control Message */ - if ((ntohs(hptr->msgType) != PPTP_CTRL_MSG_TYPE) || - (ntohl(hptr->magic) != PPTP_MAGIC)) - return(NULL); - - /* Verify data length. */ - if ((*ptype == PPTP_OutCallReply || *ptype == PPTP_InCallReply) && - (dlen < sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds) + - sizeof(struct pptpCodes))) - return (NULL); - else - return (PptpCallId)(hptr + 1); -} - - -int -AliasHandlePptpGreOut(struct ip *pip) -{ - GreHdr *gr; - struct alias_link *link; - - gr = (GreHdr *)((char *)pip + (pip->ip_hl << 2)); - - /* Check GRE header bits. */ - if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE) - return (-1); - - link = FindPptpOutByPeerCallId(pip->ip_src, pip->ip_dst, gr->gh_call_id); - if (link != NULL) { - struct in_addr alias_addr = GetAliasAddress(link); - - /* Change source IP address. */ - DifferentialChecksum(&pip->ip_sum, - (u_short *)&alias_addr, - (u_short *)&pip->ip_src, - 2); - pip->ip_src = alias_addr; - } - - return (0); -} - - -int -AliasHandlePptpGreIn(struct ip *pip) -{ - GreHdr *gr; - struct alias_link *link; - - gr = (GreHdr *)((char *)pip + (pip->ip_hl << 2)); - - /* Check GRE header bits. */ - if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE) - return (-1); - - link = FindPptpInByPeerCallId(pip->ip_src, pip->ip_dst, gr->gh_call_id); - if (link != NULL) { - struct in_addr src_addr = GetOriginalAddress(link); - - /* De-alias the Peer's Call Id. */ - gr->gh_call_id = GetOriginalPort(link); - - /* Restore original IP address. */ - DifferentialChecksum(&pip->ip_sum, - (u_short *)&src_addr, - (u_short *)&pip->ip_dst, - 2); - pip->ip_dst = src_addr; - } - - return (0); -} diff --git a/alias/alias_proxy.c b/alias/alias_proxy.c deleted file mode 100644 index a35ba1d..0000000 --- a/alias/alias_proxy.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * Copyright (c) 2000-2009 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -/*- - * Copyright (c) 2001 Charles Mott - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_proxy.c,v 1.4.2.4 2001/08/01 09:52:27 obrien Exp $ - */ - -/* file: alias_proxy.c - - This file encapsulates special operations related to transparent - proxy redirection. This is where packets with a particular destination, - usually tcp port 80, are redirected to a proxy server. - - When packets are proxied, the destination address and port are - modified. In certain cases, it is necessary to somehow encode - the original address/port info into the packet. Two methods are - presently supported: addition of a [DEST addr port] string at the - beginning a of tcp stream, or inclusion of an optional field - in the IP header. - - There is one public API function: - - PacketAliasProxyRule() -- Adds and deletes proxy - rules. - - Rules are stored in a linear linked list, so lookup efficiency - won't be too good for large lists. - - - Initial development: April, 1998 (cjm) -*/ - - -/* System includes */ -#include -#include -#include -#include -#include - -#include -#include - -/* BSD IPV4 includes */ -#include -#include -#include -#include - -#include - -#include "alias_local.h" /* Functions used by alias*.c */ -#include "alias.h" /* Public API functions for libalias */ - - - -/* - Data structures - */ - -/* - * A linked list of arbitrary length, based on struct proxy_entry is - * used to store proxy rules. - */ -struct proxy_entry -{ -#define PROXY_TYPE_ENCODE_NONE 1 -#define PROXY_TYPE_ENCODE_TCPSTREAM 2 -#define PROXY_TYPE_ENCODE_IPHDR 3 - int rule_index; - int proxy_type; - u_char proto; - u_short proxy_port; - u_short server_port; - - struct in_addr server_addr; - - struct in_addr src_addr; - struct in_addr src_mask; - - struct in_addr dst_addr; - struct in_addr dst_mask; - - struct proxy_entry *next; - struct proxy_entry *last; -}; - - - -/* - File scope variables -*/ - -static struct proxy_entry *proxyList; - - - -/* Local (static) functions: - - IpMask() -- Utility function for creating IP - masks from integer (1-32) specification. - IpAddr() -- Utility function for converting string - to IP address - IpPort() -- Utility function for converting string - to port number - RuleAdd() -- Adds an element to the rule list. - RuleDelete() -- Removes an element from the rule list. - RuleNumberDelete() -- Removes all elements from the rule list - having a certain rule number. - ProxyEncodeTcpStream() -- Adds [DEST x.x.x.x xxxx] to the beginning - of a TCP stream. - ProxyEncodeIpHeader() -- Adds an IP option indicating the true - destination of a proxied IP packet -*/ - -static int IpMask(int, struct in_addr *); -static int IpAddr(char *, struct in_addr *); -static int IpPort(char *, int, int *); -static void RuleAdd(struct proxy_entry *); -static void RuleDelete(struct proxy_entry *); -static int RuleNumberDelete(int); -static void ProxyEncodeTcpStream(struct alias_link *, struct ip *, int); -static void ProxyEncodeIpHeader(struct ip *, int); - -static int -IpMask(int nbits, struct in_addr *mask) -{ - int i; - u_int imask; - - if (nbits < 0 || nbits > 32) - return -1; - - imask = 0; - for (i=0; i> 1) + 0x80000000; - mask->s_addr = htonl(imask); - - return 0; -} - -static int -IpAddr(char *s, struct in_addr *addr) -{ - if (inet_aton(s, addr) == 0) - return -1; - else - return 0; -} - -static int -IpPort(char *s, int proto, int *port) -{ - int n; - - n = sscanf(s, "%d", port); - if (n != 1) - { - struct servent *se; - - if (proto == IPPROTO_TCP) - se = getservbyname(s, "tcp"); - else if (proto == IPPROTO_UDP) - se = getservbyname(s, "udp"); - else - return -1; - - if (se == NULL) - return -1; - - *port = (u_int) ntohs(se->s_port); - } - - return 0; -} - -void -RuleAdd(struct proxy_entry *entry) -{ - int rule_index; - struct proxy_entry *ptr; - struct proxy_entry *ptr_last; - - if (proxyList == NULL) - { - proxyList = entry; - entry->last = NULL; - entry->next = NULL; - return; - } - - rule_index = entry->rule_index; - ptr = proxyList; - ptr_last = NULL; - while (ptr != NULL) - { - if (ptr->rule_index >= rule_index) - { - if (ptr_last == NULL) - { - entry->next = proxyList; - entry->last = NULL; - proxyList->last = entry; - proxyList = entry; - return; - } - - ptr_last->next = entry; - ptr->last = entry; - entry->last = ptr->last; - entry->next = ptr; - return; - } - ptr_last = ptr; - ptr = ptr->next; - } - - ptr_last->next = entry; - entry->last = ptr_last; - entry->next = NULL; -} - -static void -RuleDelete(struct proxy_entry *entry) -{ - if (entry->last != NULL) - entry->last->next = entry->next; - else - proxyList = entry->next; - - if (entry->next != NULL) - entry->next->last = entry->last; - - free(entry); -} - -static int -RuleNumberDelete(int rule_index) -{ - int err; - struct proxy_entry *ptr; - - err = -1; - ptr = proxyList; - while (ptr != NULL) - { - struct proxy_entry *ptr_next; - - ptr_next = ptr->next; - if (ptr->rule_index == rule_index) - { - err = 0; - RuleDelete(ptr); - } - - ptr = ptr_next; - } - - return err; -} - -static void -ProxyEncodeTcpStream(struct alias_link *link, - struct ip *pip, - int maxpacketsize) -{ - int slen; - char buffer[40]; - struct tcphdr *tc; - -/* Compute pointer to tcp header */ - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - -/* Don't modify if once already modified */ - - if (GetAckModified (link)) - return; - -/* Translate destination address and port to string form */ - snprintf(buffer, sizeof(buffer) - 2, "[DEST %s %d]", - inet_ntoa(GetProxyAddress (link)), (u_int) ntohs(GetProxyPort (link))); - -/* Pad string out to a multiple of two in length */ - slen = strlen(buffer); - switch (slen % 2) - { - case 0: - strlcat(buffer, " \n", sizeof(buffer)); - slen += 2; - break; - case 1: - strlcat(buffer, "\n", sizeof(buffer)); - slen += 1; - } - -/* Check for packet overflow */ - if ((ntohs(pip->ip_len) + strlen(buffer)) > maxpacketsize) - return; - -/* Shift existing TCP data and insert destination string */ - { - int dlen; - int hlen; - u_char *p; - - hlen = (pip->ip_hl + tc->th_off) << 2; - dlen = ntohs (pip->ip_len) - hlen; - -/* Modify first packet that has data in it */ - - if (dlen == 0) - return; - - p = (u_char *) pip; - p += hlen; - - memmove(p + slen, p, dlen); - memcpy(p, buffer, slen); - } - -/* Save information about modfied sequence number */ - { - int delta; - - SetAckModified(link); - delta = GetDeltaSeqOut(pip, link); - AddSeq(pip, link, delta+slen); - } - -/* Update IP header packet length and checksum */ - { - int accumulate; - - accumulate = pip->ip_len; - pip->ip_len = htons(ntohs(pip->ip_len) + slen); - accumulate -= pip->ip_len; - - ADJUST_CHECKSUM(accumulate, pip->ip_sum); - } - -/* Update TCP checksum, Use TcpChecksum since so many things have - already changed. */ - - tc->th_sum = 0; - tc->th_sum = TcpChecksum (pip); -} - -static void -ProxyEncodeIpHeader(struct ip *pip, - int maxpacketsize) -{ -#define OPTION_LEN_BYTES 8 -#define OPTION_LEN_INT16 4 -#define OPTION_LEN_INT32 2 - u_char option[OPTION_LEN_BYTES]; - -#ifdef DEBUG - fprintf(stdout, " ip cksum 1 = %x\n", (u_int) IpChecksum(pip)); - fprintf(stdout, "tcp cksum 1 = %x\n", (u_int) TcpChecksum(pip)); -#endif - -/* Check to see that there is room to add an IP option */ - if (pip->ip_hl > (0x0f - OPTION_LEN_INT32)) - return; - -/* Build option and copy into packet */ - { - u_char *ptr; - struct tcphdr *tc; - - ptr = (u_char *) pip; - ptr += 20; - memcpy(ptr + OPTION_LEN_BYTES, ptr, ntohs(pip->ip_len) - 20); - - option[0] = 0x64; /* class: 3 (reserved), option 4 */ - option[1] = OPTION_LEN_BYTES; - - memcpy(&option[2], (u_char *) &pip->ip_dst, 4); - - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - memcpy(&option[6], (u_char *) &tc->th_sport, 2); - - memcpy(ptr, option, 8); - } - -/* Update checksum, header length and packet length */ - { - int i; - int accumulate; - u_short *sptr; - - sptr = (u_short *) option; - accumulate = 0; - for (i=0; iip_hl += OPTION_LEN_INT32; - accumulate -= *sptr; - - accumulate += pip->ip_len; - pip->ip_len = htons(ntohs(pip->ip_len) + OPTION_LEN_BYTES); - accumulate -= pip->ip_len; - - ADJUST_CHECKSUM(accumulate, pip->ip_sum); - } -#undef OPTION_LEN_BYTES -#undef OPTION_LEN_INT16 -#undef OPTION_LEN_INT32 -#ifdef DEBUG - fprintf(stdout, " ip cksum 2 = %x\n", (u_int) IpChecksum(pip)); - fprintf(stdout, "tcp cksum 2 = %x\n", (u_int) TcpChecksum(pip)); -#endif -} - - -/* Functions by other packet alias source files - - ProxyCheck() -- Checks whether an outgoing packet should - be proxied. - ProxyModify() -- Encodes the original destination address/port - for a packet which is to be redirected to - a proxy server. -*/ - -int -ProxyCheck(struct ip *pip, - struct in_addr *proxy_server_addr, - u_short *proxy_server_port) -{ - u_short dst_port; - struct in_addr src_addr; - struct in_addr dst_addr; - struct proxy_entry *ptr; - - src_addr = pip->ip_src; - dst_addr = pip->ip_dst; - dst_port = ((struct tcphdr *) ((char *) pip + (pip->ip_hl << 2))) - ->th_dport; - - ptr = proxyList; - while (ptr != NULL) - { - u_short proxy_port; - - proxy_port = ptr->proxy_port; - if ((dst_port == proxy_port || proxy_port == 0) - && pip->ip_p == ptr->proto - && src_addr.s_addr != ptr->server_addr.s_addr) - { - struct in_addr src_addr_masked; - struct in_addr dst_addr_masked; - - src_addr_masked.s_addr = src_addr.s_addr & ptr->src_mask.s_addr; - dst_addr_masked.s_addr = dst_addr.s_addr & ptr->dst_mask.s_addr; - - if ((src_addr_masked.s_addr == ptr->src_addr.s_addr) - && (dst_addr_masked.s_addr == ptr->dst_addr.s_addr)) - { - if ((*proxy_server_port = ptr->server_port) == 0) - *proxy_server_port = dst_port; - *proxy_server_addr = ptr->server_addr; - return ptr->proxy_type; - } - } - ptr = ptr->next; - } - - return 0; -} - -void -ProxyModify(struct alias_link *link, - struct ip *pip, - int maxpacketsize, - int proxy_type) -{ - switch (proxy_type) - { - case PROXY_TYPE_ENCODE_IPHDR: - ProxyEncodeIpHeader(pip, maxpacketsize); - break; - - case PROXY_TYPE_ENCODE_TCPSTREAM: - ProxyEncodeTcpStream(link, pip, maxpacketsize); - break; - } -} - - -/* - Public API functions -*/ - -int -PacketAliasProxyRule(const char *cmd) -{ -/* - * This function takes command strings of the form: - * - * server [:] - * [port ] - * [rule n] - * [proto tcp|udp] - * [src [/n]] - * [dst [/n]] - * [type encode_tcp_stream|encode_ip_hdr|no_encode] - * - * delete - * - * Subfields can be in arbitrary order. Port numbers and addresses - * must be in either numeric or symbolic form. An optional rule number - * is used to control the order in which rules are searched. If two - * rules have the same number, then search order cannot be guaranteed, - * and the rules should be disjoint. If no rule number is specified, - * then 0 is used, and group 0 rules are always checked before any - * others. - */ - int i, n, len; - int cmd_len; - int token_count; - int state; - char *token; - char buffer[256]; - char str_port[sizeof(buffer)]; - char str_server_port[sizeof(buffer)]; - char *res = buffer; - - int rule_index; - int proto; - int proxy_type; - int proxy_port; - int server_port; - struct in_addr server_addr; - struct in_addr src_addr, src_mask; - struct in_addr dst_addr, dst_mask; - struct proxy_entry *proxy_entry; - -/* Copy command line into a buffer */ - cmd += strspn(cmd, " \t"); - cmd_len = strlen(cmd); - if (cmd_len > (sizeof(buffer) - 1)) - return -1; - strlcpy(buffer, cmd, sizeof(buffer)); - -/* Convert to lower case */ - len = strlen(buffer); - for (i=0; iproxy_type = proxy_type; - proxy_entry->rule_index = rule_index; - proxy_entry->proto = proto; - proxy_entry->proxy_port = htons(proxy_port); - proxy_entry->server_port = htons(server_port); - proxy_entry->server_addr = server_addr; - proxy_entry->src_addr.s_addr = src_addr.s_addr & src_mask.s_addr; - proxy_entry->dst_addr.s_addr = dst_addr.s_addr & dst_mask.s_addr; - proxy_entry->src_mask = src_mask; - proxy_entry->dst_mask = dst_mask; - - RuleAdd(proxy_entry); - - return 0; -} diff --git a/alias/alias_smedia.c b/alias/alias_smedia.c deleted file mode 100644 index 14d9f5a..0000000 --- a/alias/alias_smedia.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 2000-2009 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -/* - * alias_smedia.c - * - * Copyright (c) 2000 Whistle Communications, Inc. - * All rights reserved. - * - * Subject to the following obligations and disclaimer of warranty, use and - * redistribution of this software, in source or object code forms, with or - * without modifications are expressly permitted by Whistle Communications; - * provided, however, that: - * 1. Any and all reproductions of the source or object code must include the - * copyright notice above and the following disclaimer of warranties; and - * 2. No rights are granted, in any manner or form, to use Whistle - * Communications, Inc. trademarks, including the mark "WHISTLE - * COMMUNICATIONS" on advertising, endorsements, or otherwise except as - * such appears in the above copyright notice or in the software. - * - * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO - * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, - * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. - * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY - * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS - * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. - * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES - * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING - * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Copyright (c) 2000 Junichi SATOH - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Authors: Erik Salander - * Junichi SATOH - * - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_smedia.c,v 1.1.2.4 2001/03/05 03:48:00 kris Exp $ - */ - -/* - Alias_smedia.c is meant to contain the aliasing code for streaming media - protocols. It performs special processing for RSTP sessions under TCP. - Specifically, when a SETUP request is sent by a client, or a 200 reply - is sent by a server, it is intercepted and modified. The address is - changed to the gateway machine and an aliasing port is used. - - More specifically, the "client_port" configuration parameter is - parsed for SETUP requests. The "server_port" configuration parameter is - parsed for 200 replies eminating from a server. This is intended to handle - the unicast case. - - RTSP also allows a redirection of a stream to another client by using the - "destination" configuration parameter. The destination config parm would - indicate a different IP address. This function is NOT supported by the - RTSP translation code below. - - The RTSP multicast functions without any address translation intervention. - - For this routine to work, the SETUP/200 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 SETUP/200 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. - - Initial version: May, 2000 (eds) -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "alias_local.h" - -#define RTSP_CONTROL_PORT_NUMBER_1 554 -#define RTSP_CONTROL_PORT_NUMBER_2 7070 -#define RTSP_PORT_GROUP 2 - -#define ISDIGIT(a) (((a) >= '0') && ((a) <= '9')) - -static int -search_string(char *data, int dlen, const char *search_str) -{ - int i, j, k; - int search_str_len; - - search_str_len = strlen(search_str); - for (i = 0; i < dlen - search_str_len; i++) { - for (j = i, k = 0; j < dlen - search_str_len; j++, k++) { - if (data[j] != search_str[k] && - data[j] != search_str[k] - ('a' - 'A')) { - break; - } - if (k == search_str_len - 1) { - return j + 1; - } - } - } - return -1; -} - -static int -alias_rtsp_out(struct ip *pip, - struct alias_link *link, - char *data, - const char *port_str) -{ - int hlen, tlen, dlen; - struct tcphdr *tc; - int i, j, pos, state, port_dlen, new_dlen, delta; - u_short p[2], new_len; - u_short sport, eport, base_port; - u_short salias = 0, ealias = 0, base_alias = 0; - const char *transport_str = "transport:"; - char newdata[2048], *port_data, *port_newdata, stemp[80]; - int links_created = 0, pkt_updated = 0; - struct alias_link *rtsp_link = NULL; - struct in_addr null_addr; - - /* 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; - - if (dlen > sizeof(newdata)) { -#if DEBUG - fprintf(stderr, "alias_rtsp_out: data len too big"); -#endif - return -1; - } - /* Find keyword, "Transport: " */ - pos = search_string(data, dlen, transport_str); - if (pos < 0) { -#if DEBUG - fprintf(stderr, "alias_rtsp_out: Transport not found"); -#endif - return -1; - } - if (pos >= sizeof(newdata)) { -#if DEBUG - fprintf(stderr, "alias_rtsp_out: Transport too far"); -#endif - return -1; - } - port_data = data + pos; - port_dlen = dlen - pos; - - memcpy(newdata, data, pos); - port_newdata = newdata + pos; - - while (port_dlen > strlen(port_str)) { - /* Find keyword, appropriate port string */ - pos = search_string(port_data, port_dlen, port_str); - if (pos < 0 || port_data + pos + 1 > newdata + sizeof(newdata)) { -#if DEBUG - fprintf(stderr, "alias_rtsp_out: port_str too far\n"); -#endif - break; - } - - memcpy (port_newdata, port_data, pos + 1); - port_newdata += (pos + 1); - - p[0] = p[1] = 0; - sport = eport = 0; - state = 0; - for (i = pos; i < port_dlen; i++) { - switch(state) { - case 0: - if (port_data[i] == '=') { - state++; - } - break; - case 1: - if (ISDIGIT(port_data[i])) { - p[0] = p[0] * 10 + port_data[i] - '0'; - } else { - if (port_data[i] == ';') { - state = 3; - } - if (port_data[i] == '-') { - state++; - } - } - break; - case 2: - if (ISDIGIT(port_data[i])) { - p[1] = p[1] * 10 + port_data[i] - '0'; - } else { - state++; - } - break; - case 3: - base_port = p[0]; - sport = htons(p[0]); - eport = htons(p[1]); - - if (!links_created) { - - links_created = 1; - /* Find an even numbered port number base that - satisfies the contiguous number of ports we need */ - null_addr.s_addr = 0; - if (0 == (salias = FindNewPortGroup(null_addr, - FindAliasAddress(pip->ip_src), - sport, 0, - RTSP_PORT_GROUP, - IPPROTO_UDP, 1))) { -#ifdef DEBUG - fprintf(stderr, - "PacketAlias/RTSP: Cannot find contiguous RTSP data ports\n"); -#endif - } else { - - base_alias = ntohs(salias); - for (j = 0; j < RTSP_PORT_GROUP; j++) { - /* Establish link to port found in RTSP packet */ - rtsp_link = FindRtspOut(GetOriginalAddress(link), null_addr, - htons(base_port + j), htons(base_alias + j), - IPPROTO_UDP); - if (rtsp_link != NULL) { -#ifndef NO_FW_PUNCH - /* Punch hole in firewall */ - PunchFWHole(rtsp_link); -#endif - } else { -#ifdef DEBUG - fprintf(stderr, - "PacketAlias/RTSP: Cannot allocate RTSP data ports\n"); -#endif - break; - } - } - } - ealias = htons(base_alias + (RTSP_PORT_GROUP - 1)); - } - - if (salias && rtsp_link) { - size_t lentmp; - - /* Copy into IP packet */ - snprintf(stemp, sizeof(stemp), "%d", ntohs(salias)); - lentmp = strlen(stemp); - /* account for ending ';' */ - if (port_newdata + lentmp + 1 > newdata + sizeof(newdata)) { -#if DEBUG - fprintf(stderr, "PacketAlias/RTSP: salias too far\n"); -#endif - break; - } - memcpy(port_newdata, stemp, lentmp); - port_newdata += lentmp; - - if (eport != 0) { - snprintf(stemp, sizeof(stemp), "%d", ntohs(ealias)); - lentmp = strlen(stemp); - - /* account for middle '-' and for ending ';' */ - if (port_newdata + lentmp + 2 > newdata + sizeof(newdata)) { -#if DEBUG - fprintf(stderr, "PacketAlias/RTSP: ealias too far\n"); -#endif - break; - } - *port_newdata = '-'; - port_newdata++; - - /* Copy into IP packet */ - memcpy(port_newdata, stemp, lentmp); - port_newdata += lentmp; - } - pkt_updated = 1; - - *port_newdata = ';'; - port_newdata++; - } - state++; - break; - } - if (state > 3) { - break; - } - } - port_data += i; - port_dlen -= i; - } - - if (!pkt_updated) { -#if DEBUG - fprintf(stderr, "PacketAlias/RTSP: Packet not updated\n"); -#endif - return -1; - } - - memcpy (port_newdata, port_data, port_dlen); - port_newdata += port_dlen; - *port_newdata = '\0'; - - /* Create new packet */ - new_dlen = port_newdata - newdata; - memcpy (data, newdata, new_dlen); - - SetAckModified(link); - delta = GetDeltaSeqOut(pip, link); - AddSeq(pip, link, delta + new_dlen - dlen); - - new_len = htons(hlen + new_dlen); - DifferentialChecksum(&pip->ip_sum, - &new_len, - &pip->ip_len, - 1); - pip->ip_len = new_len; - - tc->th_sum = 0; - tc->th_sum = TcpChecksum(pip); - - return 0; -} - -/* Support the protocol used by early versions of RealPlayer */ - -static int -alias_pna_out(struct ip *pip, - struct alias_link *link, - char *data, - int dlen) -{ - struct alias_link *pna_links; - u_short msg_id, msg_len; - char *work; - u_short alias_port, port; - struct tcphdr *tc; - - work = data; - work += 5; - while (work + 4 < data + dlen) { - memcpy(&msg_id, work, 2); - work += 2; - memcpy(&msg_len, work, 2); - work += 2; - if (ntohs(msg_id) == 0) { - /* end of options */ - return 0; - } - if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) { - memcpy(&port, work, 2); - pna_links = FindUdpTcpOut(pip->ip_src, GetDestAddress(link), - port, 0, IPPROTO_UDP, 1); - if (pna_links != NULL) { -#ifndef NO_FW_PUNCH - /* Punch hole in firewall */ - PunchFWHole(pna_links); -#endif - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - alias_port = GetAliasPort(pna_links); - memcpy(work, &alias_port, 2); - - /* Compute TCP checksum for revised packet */ - tc->th_sum = 0; - tc->th_sum = TcpChecksum(pip); - } - } - work += ntohs(msg_len); - } - - return 0; -} - -void -AliasHandleRtspOut(struct ip *pip, struct alias_link *link, int maxpacketsize) -{ - int hlen, tlen, dlen; - struct tcphdr *tc; - char *data; - const char *setup = "SETUP", *pna = "PNA", *str200 = "200"; - const char *okstr = "OK", *client_port_str = "client_port"; - const char *server_port_str = "server_port"; - int i, parseOk; - - 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; - - data = (char*)pip; - data += hlen; - - /* When aliasing a client, check for the SETUP request */ - if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) || - (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) { - - if (dlen >= strlen(setup)) { - if (memcmp(data, setup, strlen(setup)) == 0) { - alias_rtsp_out(pip, link, data, client_port_str); - return; - } - } - if (dlen >= strlen(pna)) { - if (memcmp(data, pna, strlen(pna)) == 0) { - alias_pna_out(pip, link, data, dlen); - } - } - - } else { - - /* When aliasing a server, check for the 200 reply - Accomodate varying number of blanks between 200 & OK */ - - if (dlen >= strlen(str200)) { - - for (parseOk = 0, i = 0; - i <= dlen - strlen(str200); - i++) { - if (memcmp(&data[i], str200, strlen(str200)) == 0) { - parseOk = 1; - break; - } - } - if (parseOk) { - - i += strlen(str200); /* skip string found */ - while(data[i] == ' ') /* skip blank(s) */ - i++; - - if ((dlen - i) >= strlen(okstr)) { - - if (memcmp(&data[i], okstr, strlen(okstr)) == 0) - alias_rtsp_out(pip, link, data, server_port_str); - - } - } - } - } -} diff --git a/alias/alias_util.c b/alias/alias_util.c deleted file mode 100644 index 28ea257..0000000 --- a/alias/alias_util.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 2001 Charles Mott - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Based upon: - * $FreeBSD: src/lib/libalias/alias_util.c,v 1.4.2.2 2001/06/04 14:59:06 brian Exp $ - */ - -/* - Alias_util.c 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) - - Version 1.7: January 9, 1997 - Added differential checksum update function. -*/ - -/* -Note: the checksum routines assume that the actual checksum word has -been zeroed out. If the checksum word is filled with the proper value, -then these routines will give a result of zero (useful for testing -purposes); -*/ - -#include -#include -#include -#include -#include - -#include "alias.h" -#include "alias_local.h" - -u_short -PacketAliasInternetChecksum(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)[0] = *(u_char *) ptr; - ((u_char *) &oddbyte)[1] = 0; - sum += oddbyte; - } - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - return(~sum); -} - -u_short -IpChecksum(struct ip *pip) -{ - return( PacketAliasInternetChecksum((u_short *) pip, - (pip->ip_hl << 2)) ); - -} - -u_short -TcpChecksum(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)[0] = *(u_char *) ptr; - ((u_char *) &oddbyte)[1] = 0; - 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); -} - - -void -DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n) -{ - int i; - int accumulate; - - accumulate = *cksum; - for (i=0; i> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - *cksum = (u_short) ~accumulate; - } - else - { - accumulate = (accumulate >> 16) + (accumulate & 0xffff); - accumulate += accumulate >> 16; - *cksum = (u_short) accumulate; - } -} - diff --git a/alias/libalias.3 b/alias/libalias.3 deleted file mode 100644 index 9b51de9..0000000 --- a/alias/libalias.3 +++ /dev/null @@ -1,987 +0,0 @@ -.\"- -.\" Copyright (c) 2001 Charles Mott -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libalias/libalias.3,v 1.23.2.9 2001/08/17 15:42:27 ru Exp $ -.\" -.Dd April 13, 2000 -.Dt LIBALIAS 3 -.Os -.Sh NAME -.Nm libalias -.Nd packet aliasing library for masquerading and network address translation -.Sh SYNOPSIS -.Fd #include -.Fd #include -.Fd #include -.Pp -Function prototypes are given in the main body of the text. -.Sh DESCRIPTION -The -.Nm -library is a collection of functions for aliasing and de-aliasing of IP -packets, intended for masquerading and network address translation (NAT). -.Sh INTRODUCTION -This library is a moderately portable set of functions designed to assist -in the process of IP masquerading and network address translation. -Outgoing packets from a local network with unregistered IP addresses can -be aliased to appear as if they came from an accessible IP address. -Incoming packets are then de-aliased so that they are sent to the correct -machine on the local network. -.Pp -A certain amount of flexibility is built into the packet aliasing engine. -In the simplest mode of operation, a many-to-one address mapping takes -place between local network and the packet aliasing host. -This is known as IP masquerading. -In addition, one-to-one mappings between local and public addresses can -also be implemented, which is known as static NAT. -In between these extremes, different groups of private addresses can be -linked to different public addresses, comprising several distinct -many-to-one mappings. -Also, a given public address and port can be statically redirected to a -private address/port. -.Pp -The packet aliasing engine was designed to operate in user space outside -of the kernel, without any access to private kernel data structure, but -the source code can also be ported to a kernel environment. -.Sh INITIALIZATION AND CONTROL -Two special functions, -.Fn PacketAliasInit -and -.Fn PacketAliasSetAddress , -must always be called before any packet handling may be performed. -In addition, the operating mode of the packet aliasing engine can be -customized by calling -.Fn PacketAliasSetMode . -.Pp -.Ft void -.Fn PacketAliasInit void -.Bd -ragged -offset indent -This function has no arguments or return value and is used to initialize -internal data structures. -The following mode bits are always set after calling -.Fn PacketAliasInit . -See the description of -.Fn PacketAliasSetMode -below for the meaning of these mode bits. -.Pp -.Bl -item -offset indent -compact -.It -.Dv PKT_ALIAS_SAME_PORTS -.It -.Dv PKT_ALIAS_USE_SOCKETS -.It -.Dv PKT_ALIAS_RESET_ON_ADDR_CHANGE -.El -.Pp -This function will always return the packet aliasing engine to the same -initial state. -.Fn PacketAliasSetAddress -must be called afterwards, and any desired changes from the default mode -bits listed above require a call to -.Fn PacketAliasSetMode . -.Pp -It is mandatory that this function be called at the beginning of a program -prior to any packet handling. -.Ed -.Pp -.Ft void -.Fn PacketAliasUninit void -.Bd -ragged -offset indent -This function has no arguments or return value and is used to clear any -resources attached to internal data structures. -.Pp -This functions should be called when a program stops using the aliasing -engine; it does, amongst other things, clear out any firewall holes. -To provide backwards compatibility and extra security, it is added to -the -.Xr atexit 3 -chain by -.Fn PacketAliasInit . -Calling it multiple times is harmless. -.Ed -.Pp -.Ft void -.Fn PacketAliasSetAddress "struct in_addr addr" -.Bd -ragged -offset indent -This function sets the source address to which outgoing packets from the -local area network are aliased. -All outgoing packets are re-mapped to this address unless overridden by a -static address mapping established by -.Fn PacketAliasRedirectAddr . -.Pp -If the -.Dv PKT_ALIAS_RESET_ON_ADDR_CHANGE -mode bit is set (the default mode of operation), then the internal aliasing -link tables will be reset any time the aliasing address changes. -This is useful for interfaces such as -.Xr ppp 8 , -where the IP -address may or may not change on successive dial-up attempts. -.Pp -If the -.Dv PKT_ALIAS_RESET_ON_ADDR_CHANGE -mode bit is set to zero, this function can also be used to dynamically change -the aliasing address on a packet to packet basis (it is a low overhead call). -.Pp -It is mandatory that this function be called prior to any packet handling. -.Ed -.Pp -.Ft unsigned int -.Fn PacketAliasSetMode "unsigned int flags" "unsigned int mask" -.Bd -ragged -offset indent -This function sets or clears mode bits -according to the value of -.Fa flags . -Only bits marked in -.Fa mask -are affected. -The following mode bits are defined in -.Aq Pa alias.h : -.Bl -tag -width indent -.It Dv PKT_ALIAS_LOG -Enables logging into -.Pa /var/log/alias.log . -Each time an aliasing link is created or deleted, the log file is appended -with the current number of ICMP, TCP and UDP links. -Mainly useful for debugging when the log file is viewed continuously with -.Xr tail 1 . -.It Dv PKT_ALIAS_DENY_INCOMING -If this mode bit is set, all incoming packets associated with new TCP -connections or new UDP transactions will be marked for being ignored -.Fn ( PacketAliasIn -returns -.Dv PKT_ALIAS_IGNORED -code) -by the calling program. -Response packets to connections or transactions initiated from the packet -aliasing host or local network will be unaffected. -This mode bit is useful for implementing a one-way firewall. -.It Dv PKT_ALIAS_SAME_PORTS -If this mode bit is set, the packet aliasing engine will attempt to leave -the alias port numbers unchanged from the actual local port numbers. -This can be done as long as the quintuple (proto, alias addr, alias port, -remote addr, remote port) is unique. -If a conflict exists, a new aliasing port number is chosen even if this -mode bit is set. -.It Dv PKT_ALIAS_USE_SOCKETS -This bit should be set when the packet aliasing host originates network -traffic as well as forwards it. -When the packet aliasing host is waiting for a connection from an unknown -host address or unknown port number (e.g. an FTP data connection), this -mode bit specifies that a socket be allocated as a place holder to prevent -port conflicts. -Once a connection is established, usually within a minute or so, the socket -is closed. -.It Dv PKT_ALIAS_UNREGISTERED_ONLY -If this mode bit is set, traffic on the local network which does not -originate from unregistered address spaces will be ignored. -Standard Class A, B and C unregistered addresses are: -.Bd -literal -offset indent -10.0.0.0 -> 10.255.255.255 (Class A subnet) -172.16.0.0 -> 172.31.255.255 (Class B subnets) -192.168.0.0 -> 192.168.255.255 (Class C subnets) -.Ed -.Pp -This option is useful in the case that packet aliasing host has both -registered and unregistered subnets on different interfaces. -The registered subnet is fully accessible to the outside world, so traffic -from it does not need to be passed through the packet aliasing engine. -.It Dv PKT_ALIAS_RESET_ON_ADDR_CHANGE -When this mode bit is set and -.Fn PacketAliasSetAddress -is called to change the aliasing address, the internal link table of the -packet aliasing engine will be cleared. -This operating mode is useful for -.Xr ppp 8 -links where the interface address can sometimes change or remain the same -between dial-up attempts. -If this mode bit is not set, the link table will never be reset in the event -of an address change. -.It Dv PKT_ALIAS_PUNCH_FW -This option makes -.Nm -`punch holes' in an -.Xr ipfirewall 4 -based firewall for FTP/IRC DCC connections. -The holes punched are bound by from/to IP address and port; it will not be -possible to use a hole for another connection. -A hole is removed when the connection that uses it dies. -To cater to unexpected death of a program using -.Nm -(e.g. kill -9), -changing the state of the flag will clear the entire firewall range -allocated for holes. -This will also happen on the initial call to -.Fn PacketAliasSetFWBase . -This call must happen prior to setting this flag. -.It Dv PKT_ALIAS_REVERSE -This option makes -.Nm -reverse the way it handles incoming and outgoing packets, allowing it -to be fed with data that passes through the internal interface rather -than the external one. -.It Dv PKT_ALIAS_PROXY_ONLY -This option tells -.Nm -to obey transparent proxy rules only. -Normal packet aliasing is not performed. -See -.Fn PacketAliasProxyRule -below for details. -.El -.Ed -.Pp -.Ft void -.Fn PacketAliasSetFWBase "unsigned int base" "unsigned int num" -.Bd -ragged -offset indent -Set firewall range allocated for punching firewall holes (with the -.Dv PKT_ALIAS_PUNCH_FW -flag). -The range will be cleared for all rules on initialization. -.Ed -.Pp -.Ft void -.Fn PacketAliasClampMSS "u_short mss" -.Bd -ragged -offset indent -Clamp the MSS of TCP connections to the given value. -.Ed -.Sh PACKET HANDLING -The packet handling functions are used to modify incoming (remote to local) -and outgoing (local to remote) packets. -The calling program is responsible for receiving and sending packets via -network interfaces. -.Pp -Along with -.Fn PacketAliasInit -and -.Fn PacketAliasSetAddress , -the two packet handling functions, -.Fn PacketAliasIn -and -.Fn PacketAliasOut , -comprise minimal set of functions needed for a basic IP masquerading -implementation. -.Pp -.Ft int -.Fn PacketAliasIn "char *buffer" "int maxpacketsize" -.Bd -ragged -offset indent -An incoming packet coming from a remote machine to the local network is -de-aliased by this function. -The IP packet is pointed to by -.Fa buffer , -and -.Fa maxpacketsize -indicates the size of the data structure containing the packet and should -be at least as large as the actual packet size. -.Pp -Return codes: -.Bl -tag -width indent -.It Dv PKT_ALIAS_OK -The packet aliasing process was successful. -.It Dv PKT_ALIAS_IGNORED -The packet was ignored and not de-aliased. -This can happen if the protocol is unrecognized, possibly an ICMP message -type is not handled or if incoming packets for new connections are being -ignored (if -.Dv PKT_ALIAS_DENY_INCOMING -mode bit was set by -.Fn PacketAliasSetMode ) . -.It Dv PKT_ALIAS_UNRESOLVED_FRAGMENT -This is returned when a fragment cannot be resolved because the header -fragment has not been sent yet. -In this situation, fragments must be saved with -.Fn PacketAliasSaveFragment -until a header fragment is found. -.It Dv PKT_ALIAS_FOUND_HEADER_FRAGMENT -The packet aliasing process was successful, and a header fragment was found. -This is a signal to retrieve any unresolved fragments with -.Fn PacketAliasGetFragment -and de-alias them with -.Fn PacketAliasFragmentIn . -.It Dv PKT_ALIAS_ERROR -An internal error within the packet aliasing engine occurred. -.El -.Ed -.Pp -.Ft int -.Fn PacketAliasOut "char *buffer" "int maxpacketsize" -.Bd -ragged -offset indent -An outgoing packet coming from the local network to a remote machine is -aliased by this function. -The IP packet is pointed to by -.Fa buffer , -and -.Fa maxpacketsize -indicates the maximum packet size permissible should the packet length be -changed. -IP encoding protocols place address and port information in the encapsulated -data stream which has to be modified and can account for changes in packet -length. -Well known examples of such protocols are FTP and IRC DCC. -.Pp -Return codes: -.Bl -tag -width indent -.It Dv PKT_ALIAS_OK -The packet aliasing process was successful. -.It Dv PKT_ALIAS_IGNORED -The packet was ignored and not aliased. -This can happen if the protocol is unrecognized, or possibly an ICMP message -type is not handled. -.It Dv PKT_ALIAS_ERROR -An internal error within the packet aliasing engine occurred. -.El -.Ed -.Sh PORT AND ADDRESS REDIRECTION -The functions described in this section allow machines on the local network -to be accessible in some degree to new incoming connections from the external -network. -Individual ports can be re-mapped or static network address translations can -be designated. -.Pp -.Ft struct alias_link * -.Fo PacketAliasRedirectPort -.Fa "struct in_addr local_addr" -.Fa "u_short local_port" -.Fa "struct in_addr remote_addr" -.Fa "u_short remote_port" -.Fa "struct in_addr alias_addr" -.Fa "u_short alias_port" -.Fa "u_char proto" -.Fc -.Bd -ragged -offset indent -This function specifies that traffic from a given remote address/port to -an alias address/port be redirected to a specified local address/port. -The parameter -.Fa proto -can be either -.Dv IPPROTO_TCP -or -.Dv IPPROTO_UDP , -as defined in -.Aq Pa netinet/in.h . -.Pp -If -.Fa local_addr -or -.Fa alias_addr -is zero, this indicates that the packet aliasing address as established -by -.Fn PacketAliasSetAddress -is to be used. -Even if -.Fn PacketAliasSetAddress -is called to change the address after -.Fn PacketAliasRedirectPort -is called, a zero reference will track this change. -.Pp -If the link is further set up to operate for a load sharing, then -.Fa local_addr -and -.Fa local_port -are ignored, and are selected dynamically from the server pool, as described in -.Fn PacketAliasAddServer -below. -.Pp -If -.Fa remote_addr -is zero, this indicates to redirect packets from any remote address. -Likewise, if -.Fa remote_port -is zero, this indicates to redirect packets originating from any remote -port number. -Almost always, the remote port specification will be zero, but non-zero -remote addresses can sometimes be useful for firewalling. -If two calls to -.Fn PacketAliasRedirectPort -overlap in their address/port specifications, then the most recent call -will have precedence. -.Pp -This function returns a pointer which can subsequently be used by -.Fn PacketAliasRedirectDelete . -If -.Dv NULL -is returned, then the function call did not complete successfully. -.Pp -All port numbers should be in network address byte order, so it is necessary -to use -.Xr htons 3 -to convert these parameters from internally readable numbers to network byte -order. -Addresses are also in network byte order, which is implicit in the use of the -.Fa struct in_addr -data type. -.Ed -.Pp -.Ft struct alias_link * -.Fo PacketAliasRedirectAddr -.Fa "struct in_addr local_addr" -.Fa "struct in_addr alias_addr" -.Fc -.Bd -ragged -offset indent -This function designates that all incoming traffic to -.Fa alias_addr -be redirected to -.Fa local_addr . -Similarly, all outgoing traffic from -.Fa local_addr -is aliased to -.Fa alias_addr . -.Pp -If -.Fa local_addr -or -.Fa alias_addr -is zero, this indicates that the packet aliasing address as established by -.Fn PacketAliasSetAddress -is to be used. -Even if -.Fn PacketAliasSetAddress -is called to change the address after -.Fn PacketAliasRedirectAddr -is called, a zero reference will track this change. -.Pp -If the link is further set up to operate for a load sharing, then -.Fa local_addr -is ignored, and is selected dynamically from the server pool, as described in -.Fn PacketAliasAddServer -below. -.Pp -If subsequent calls to -.Fn PacketAliasRedirectAddr -use the same aliasing address, all new incoming traffic to this aliasing -address will be redirected to the local address made in the last function -call. -New traffic generated by any of the local machines, designated in the -several function calls, will be aliased to the same address. -Consider the following example: -.Bd -literal -offset indent -PacketAliasRedirectAddr(inet_aton("192.168.0.2"), - inet_aton("141.221.254.101")); -PacketAliasRedirectAddr(inet_aton("192.168.0.3"), - inet_aton("141.221.254.101")); -PacketAliasRedirectAddr(inet_aton("192.168.0.4"), - inet_aton("141.221.254.101")); -.Ed -.Pp -Any outgoing connections such as -.Xr telnet 1 -or -.Xr ftp 1 -from 192.168.0.2, 192.168.0.3 and 192.168.0.4 will appear to come from -141.221.254.101. -Any incoming connections to 141.221.254.101 will be directed to 192.168.0.4. -.Pp -Any calls to -.Fn PacketAliasRedirectPort -will have precedence over address mappings designated by -.Fn PacketAliasRedirectAddr . -.Pp -This function returns a pointer which can subsequently be used by -.Fn PacketAliasRedirectDelete . -If -.Dv NULL -is returned, then the function call did not complete successfully. -.Ed -.Pp -.Ft int -.Fo PacketAliasAddServer -.Fa "struct alias_link *link" -.Fa "struct in_addr addr" -.Fa "u_short port" -.Fc -.Bd -ragged -offset indent -This function sets the -.Fa link -up for Load Sharing using IP Network Address Translation (RFC 2391, LSNAT). -LSNAT operates as follows. -A client attempts to access a server by using the server virtual address. -The LSNAT router transparently redirects the request to one of the hosts -in server pool, selected using a real-time load sharing algorithm. -Multiple sessions may be initiated from the same client, and each session -could be directed to a different host based on load balance across server -pool hosts at the time. -If load share is desired for just a few specific services, the configuration -on LSNAT could be defined to restrict load share for just the services -desired. -.Pp -Currently, only the simplest selection algorithm is implemented, where a -host is selected on a round-robin basis only, without regard to load on -the host. -.Pp -First, the -.Fa link -is created by either -.Fn PacketAliasRedirectPort -or -.Fn PacketAliasRedirectAddr . -Then, -.Fn PacketAliasAddServer -is called multiple times to add entries to the -.Fa link Ns 's -server pool. -.Pp -For links created with -.Fn PacketAliasRedirectAddr , -the -.Fa port -argument is ignored and could have any value, e.g. htons(~0). -.Pp -This function returns 0 on success, -1 otherwise. -.Ed -.Pp -.Ft void -.Fn PacketAliasRedirectDelete "struct alias_link *link" -.Bd -ragged -offset indent -This function will delete a specific static redirect rule entered by -.Fn PacketAliasRedirectPort -or -.Fn PacketAliasRedirectAddr . -The parameter -.Fa link -is the pointer returned by either of the redirection functions. -If an invalid pointer is passed to -.Fn PacketAliasRedirectDelete , -then a program crash or unpredictable operation could result, so it is -necessary to be careful using this function. -.Ed -.Pp -.Ft int -.Fn PacketAliasProxyRule "const char *cmd" -.Bd -ragged -offset indent -The passed -.Fa cmd -string consists of one or more pairs of words. -The first word in each pair is a token and the second is the value that -should be applied for that token. -Tokens and their argument types are as follows: -.Bl -tag -width indent -.It Cm type encode_ip_hdr | encode_tcp_stream | no_encode -In order to support transparent proxying, it is necessary to somehow -pass the original address and port information into the new destination -server. -If -.Cm encode_ip_hdr -is specified, the original address and port is passed as an extra IP -option. -If -.Cm encode_tcp_stream -is specified, the original address and port is passed as the first -piece of data in the TCP stream in the format -.Dq DEST Ar IP port . -.It Cm port Ar portnum -Only packets with the destination port -.Ar portnum -are proxied. -.It Cm server Ar host Ns Xo -.Op : Ns Ar portnum -.Xc -This specifies the -.Ar host -and -.Ar portnum -that the data is to be redirected to. -.Ar host -must be an IP address rather than a DNS host name. -If -.Ar portnum -is not specified, the destination port number is not changed. -.Pp -The -.Ar server -specification is mandatory unless the -.Cm delete -command is being used. -.It Cm rule Ar index -Normally, each call to -.Fn PacketAliasProxyRule -inserts the next rule at the start of a linear list of rules. -If an -.Ar index -is specified, the new rule will be checked after all rules with lower -indices. -Calls to -.Fn PacketAliasProxyRule -that do not specify a rule are assigned rule 0. -.It Cm delete Ar index -This token and its argument MUST NOT be used with any other tokens. -When used, all existing rules with the given -.Ar index -are deleted. -.It Cm proto tcp | udp -If specified, only packets of the given protocol type are matched. -.It Cm src Ar IP Ns Xo -.Op / Ns Ar bits -.Xc -If specified, only packets with a source address matching the given -.Ar IP -are matched. -If -.Ar bits -is also specified, then the first -.Ar bits -bits of -.Ar IP -are taken as a network specification, and all IP addresses from that -network will be matched. -.It Cm dst Ar IP Ns Xo -.Op / Ns Ar bits -.Xc -If specified, only packets with a destination address matching the given -.Ar IP -are matched. -If -.Ar bits -is also specified, then the first -.Ar bits -bits of -.Ar IP -are taken as a network specification, and all IP addresses from that -network will be matched. -.El -.Pp -This function is usually used to redirect outgoing connections for -internal machines that are not permitted certain types of internet -access, or to restrict access to certain external machines. -.Ed -.Pp -.Ft struct alias_link * -.Fo PacketAliasRedirectProto -.Fa "struct in_addr local_addr" -.Fa "struct in_addr remote_addr" -.Fa "struct in_addr alias_addr" -.Fa "u_char proto" -.Fc -.Bd -ragged -offset indent -This function specifies that any IP packet with protocol number of -.Fa proto -from a given remote address to an alias address be -redirected to a specified local address. -.Pp -If -.Fa local_addr -or -.Fa alias_addr -is zero, this indicates that the packet aliasing address as established -by -.Fn PacketAliasSetAddress -is to be used. -Even if -.Fn PacketAliasSetAddress -is called to change the address after -.Fn PacketAliasRedirectProto -is called, a zero reference will track this change. -.Pp -If -.Fa remote_addr -is zero, this indicates to redirect packets from any remote address. -Non-zero remote addresses can sometimes be useful for firewalling. -.Pp -If two calls to -.Fn PacketAliasRedirectProto -overlap in their address specifications, then the most recent call -will have precedence. -.Pp -This function returns a pointer which can subsequently be used by -.Fn PacketAliasRedirectDelete . -If -.Dv NULL -is returned, then the function call did not complete successfully. -.Ed -.Sh FRAGMENT HANDLING -The functions in this section are used to deal with incoming fragments. -.Pp -Outgoing fragments are handled within -.Fn PacketAliasOut -by changing the address according to any applicable mapping set by -.Fn PacketAliasRedirectAddr , -or the default aliasing address set by -.Fn PacketAliasSetAddress . -.Pp -Incoming fragments are handled in one of two ways. -If the header of a fragmented IP packet has already been seen, then all -subsequent fragments will be re-mapped in the same manner the header -fragment was. -Fragments which arrive before the header are saved and then retrieved -once the header fragment has been resolved. -.Pp -.Ft int -.Fn PacketAliasSaveFragment "char *ptr" -.Bd -ragged -offset indent -When -.Fn PacketAliasIn -returns -.Dv PKT_ALIAS_UNRESOLVED_FRAGMENT , -this function can be used to save the pointer to the unresolved fragment. -.Pp -It is implicitly assumed that -.Fa ptr -points to a block of memory allocated by -.Xr malloc 3 . -If the fragment is never resolved, the packet aliasing engine will -automatically free the memory after a timeout period. -[Eventually this function should be modified so that a callback function -for freeing memory is passed as an argument.] -.Pp -This function returns -.Dv PKT_ALIAS_OK -if it was successful and -.Dv PKT_ALIAS_ERROR -if there was an error. -.Ed -.Pp -.Ft char * -.Fn PacketAliasGetFragment "char *buffer" -.Bd -ragged -offset indent -This function can be used to retrieve fragment pointers saved by -.Fn PacketAliasSaveFragment . -The IP header fragment pointed to by -.Fa buffer -is the header fragment indicated when -.Fn PacketAliasIn -returns -.Dv PKT_ALIAS_FOUND_HEADER_FRAGMENT . -Once a fragment pointer is retrieved, it becomes the calling program's -responsibility to free the dynamically allocated memory for the fragment. -.Pp -.Fn PacketAliasGetFragment -can be called sequentially until there are no more fragments available, -at which time it returns -.Dv NULL . -.Ed -.Pp -.Ft void -.Fn PacketAliasFragmentIn "char *header" "char *fragment" -.Bd -ragged -offset indent -When a fragment is retrieved with -.Fn PacketAliasGetFragment , -it can then be de-aliased with a call to -.Fn PacketAliasFragmentIn . -The -.Fa header -argument is the pointer to a header fragment used as a template, and -.Fa fragment -is the pointer to the packet to be de-aliased. -.Ed -.Sh MISCELLANEOUS FUNCTIONS -.Ft void -.Fn PacketAliasSetTarget "struct in_addr addr" -.Bd -ragged -offset indent -When an incoming packet not associated with any pre-existing aliasing link -arrives at the host machine, it will be sent to the address indicated by a -call to -.Fn PacketAliasSetTarget . -.Pp -If this function is called with an -.Dv INADDR_NONE -address argument, then all new incoming packets go to the address set by -.Fn PacketAliasSetAddress . -.Pp -If this function is not called, or is called with an -.Dv INADDR_ANY -address argument, then all new incoming packets go to the address specified -in the packet. -This allows external machines to talk directly to internal machines if they -can route packets to the machine in question. -.Ed -.Pp -.Ft int -.Fn PacketAliasCheckNewLink void -.Bd -ragged -offset indent -This function returns a non-zero value when a new aliasing link is created. -In circumstances where incoming traffic is being sequentially sent to -different local servers, this function can be used to trigger when -.Fn PacketAliasSetTarget -is called to change the default target address. -.Ed -.Pp -.Ft u_short -.Fn PacketAliasInternetChecksum "u_short *buffer" "int nbytes" -.Bd -ragged -offset indent -This is a utility function that does not seem to be available elsewhere and -is included as a convenience. -It computes the internet checksum, which is used in both IP and -protocol-specific headers (TCP, UDP, ICMP). -.Pp -The -.Fa buffer -argument points to the data block to be checksummed, and -.Fa nbytes -is the number of bytes. -The 16-bit checksum field should be zeroed before computing the checksum. -.Pp -Checksums can also be verified by operating on a block of data including -its checksum. -If the checksum is valid, -.Fn PacketAliasInternetChecksum -will return zero. -.Ed -.Pp -.Ft int -.Fn PacketUnaliasOut "char *buffer" "int maxpacketsize" -.Bd -ragged -offset indent -An outgoing packet, which has already been aliased, -has its private address/port information restored by this function. -The IP packet is pointed to by -.Fa buffer , -and -.Fa maxpacketsize -is provided for error checking purposes. -This function can be used if an already-aliased packet needs to have its -original IP header restored for further processing (eg. logging). -.Ed -.Sh BUGS -PPTP aliasing does not work when more than one internal client -connects to the same external server at the same time, because -PPTP requires a single TCP control connection to be established -between any two IP addresses. -.Sh AUTHORS -.An Charles Mott Aq cmott@scientech.com , -versions 1.0 - 1.8, 2.0 - 2.4. -.An Eivind Eklund Aq eivind@FreeBSD.org , -versions 1.8b, 1.9 and 2.5. -Added IRC DCC support as well as contributing a number of architectural -improvements; added the firewall bypass for FTP/IRC DCC. -.An Erik Salander Aq erik@whistle.com -added support for PPTP and RTSP. -.An Junichi Satoh Aq junichi@junichi.org -added support for RTSP/PNA. -.Sh ACKNOWLEDGMENTS -Listed below, in approximate chronological order, are individuals who -have provided valuable comments and/or debugging assistance. -.Pp -.Bd -ragged -offset indent -.An -split -.An Gary Roberts -.An Tom Torrance -.An Reto Burkhalter -.An Martin Renters -.An Brian Somers -.An Paul Traina -.An Ari Suutari -.An Dave Remien -.An J. Fortes -.An Andrzej Bialecki -.An Gordon Burditt -.Ed -.Sh CONCEPTUAL BACKGROUND -This section is intended for those who are planning to modify the source -code or want to create somewhat esoteric applications using the packet -aliasing functions. -.Pp -The conceptual framework under which the packet aliasing engine operates -is described here. -Central to the discussion is the idea of an -.Em aliasing link -which describes the relationship for a given packet transaction between -the local machine, aliased identity and remote machine. -It is discussed how such links come into existence and are destroyed. -.Ss ALIASING LINKS -There is a notion of an -.Em aliasing link , -which is a 7-tuple describing a specific translation: -.Bd -literal -offset indent -(local addr, local port, alias addr, alias port, - remote addr, remote port, protocol) -.Ed -.Pp -Outgoing packets have the local address and port number replaced with the -alias address and port number. -Incoming packets undergo the reverse process. -The packet aliasing engine attempts to match packets against an internal -table of aliasing links to determine how to modify a given IP packet. -Both the IP header and protocol dependent headers are modified as necessary. -Aliasing links are created and deleted as necessary according to network -traffic. -.Pp -Protocols can be TCP, UDP or even ICMP in certain circumstances. -(Some types of ICMP packets can be aliased according to sequence or ID -number which acts as an equivalent port number for identifying how -individual packets should be handled.) -.Pp -Each aliasing link must have a unique combination of the following five -quantities: alias address/port, remote address/port and protocol. -This ensures that several machines on a local network can share the -same aliasing IP address. -In cases where conflicts might arise, the aliasing port is chosen so that -uniqueness is maintained. -.Ss STATIC AND DYNAMIC LINKS -Aliasing links can either be static or dynamic. -Static links persist indefinitely and represent fixed rules for translating -IP packets. -Dynamic links come into existence for a specific TCP connection or UDP -transaction or ICMP ECHO sequence. -For the case of TCP, the connection can be monitored to see when the -associated aliasing link should be deleted. -Aliasing links for UDP transactions (and ICMP ECHO and TIMESTAMP requests) -work on a simple timeout rule. -When no activity is observed on a dynamic link for a certain amount of time -it is automatically deleted. -Timeout rules also apply to TCP connections which do not open or close -properly. -.Ss PARTIALLY SPECIFIED ALIASING LINKS -Aliasing links can be partially specified, meaning that the remote address -and/or remote port are unknown. -In this case, when a packet matching the incomplete specification is found, -a fully specified dynamic link is created. -If the original partially specified link is dynamic, it will be deleted -after the fully specified link is created, otherwise it will persist. -.Pp -For instance, a partially specified link might be -.Bd -literal -offset indent -(192.168.0.4, 23, 204.228.203.215, 8066, 0, 0, tcp) -.Ed -.Pp -The zeros denote unspecified components for the remote address and port. -If this link were static it would have the effect of redirecting all -incoming traffic from port 8066 of 204.228.203.215 to port 23 (telnet) -of machine 192.168.0.4 on the local network. -Each individual telnet connection would initiate the creation of a distinct -dynamic link. -.Ss DYNAMIC LINK CREATION -In addition to aliasing links, there are also address mappings that can be -stored within the internal data table of the packet aliasing mechanism. -.Bd -literal -offset indent -(local addr, alias addr) -.Ed -.Pp -Address mappings are searched when creating new dynamic links. -.Pp -All outgoing packets from the local network automatically create a dynamic -link if they do not match an already existing fully specified link. -If an address mapping exists for the outgoing packet, this determines -the alias address to be used. -If no mapping exists, then a default address, usually the address of the -packet aliasing host, is used. -If necessary, this default address can be changed as often as each individual -packet arrives. -.Pp -The aliasing port number is determined such that the new dynamic link does -not conflict with any existing links. -In the default operating mode, the packet aliasing engine attempts to set -the aliasing port equal to the local port number. -If this results in a conflict, then port numbers are randomly chosen until -a unique aliasing link can be established. -In an alternate operating mode, the first choice of an aliasing port is also -random and unrelated to the local port number. diff --git a/ifconfig.tproj/ifconfig.c b/ifconfig.tproj/ifconfig.c index d20a2f7..33af6fb 100644 --- a/ifconfig.tproj/ifconfig.c +++ b/ifconfig.tproj/ifconfig.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2015 Apple Inc. All rights reserved. + * Copyright (c) 2009-2017 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -1188,12 +1188,13 @@ setqosmarking(const char *cmd, const char *arg, int s, const struct afswtch *afp "\020\1AUTOCONFIGURING\5FASTLN_CAP\6IPV6_DISABLED\7ACCEPT_RTADV\10TXSTART\11RXPOLL" \ "\12VLAN\13BOND\14ARPLL\15NOWINDOWSCALE\16NOAUTOIPV6LL\17EXPENSIVE\20ROUTER4" \ "\21ROUTER6\22LOCALNET_PRIVATE\23ND6ALT\24RESTRICTED_RECV\25AWDL\26NOACKPRI" \ -"\27AWDL_RESTRICTED\30CL2K\31ECN_ENABLE\32ECN_DISABLE\34CA\35SENDLIST\36DIRECTLINK" \ -"\37FASTLN_ON\40UPDOWNCHANGE" +"\27AWDL_RESTRICTED\30CL2K\31ECN_ENABLE\32ECN_DISABLE\33CHANNEL_DRV\34CA" \ +"\35SENDLIST\36DIRECTLINK\37FASTLN_ON\40UPDOWNCHANGE" #define IFCAPBITS \ "\020\1RXCSUM\2TXCSUM\3VLAN_MTU\4VLAN_HWTAGGING\5JUMBO_MTU" \ -"\6TSO4\7TSO6\10LRO\11AV\12TXSTATUS\14HW_TIMESTAMP\15SW_TIMESTAMP" +"\6TSO4\7TSO6\10LRO\11AV\12TXSTATUS\13CHANNEL_IO\14HW_TIMESTAMP\15SW_TIMESTAMP" \ +"\16PARTIAL_CSUM\17ZEROINVERT_CSUM" #define IFRLOGF_BITS \ "\020\1DLIL\21FAMILY\31DRIVER\35FIRMWARE" @@ -1939,24 +1940,15 @@ sched2str(unsigned int s) case PKTSCHEDT_NONE: c = "NONE"; break; - case PKTSCHEDT_CBQ: - c = "CBQ"; - break; - case PKTSCHEDT_HFSC: - c = "HFSC"; - break; - case PKTSCHEDT_PRIQ: - c = "PRIQ"; - break; - case PKTSCHEDT_FAIRQ: - c = "FAIRQ"; - break; case PKTSCHEDT_TCQ: c = "TCQ"; break; case PKTSCHEDT_QFQ: c = "QFQ"; break; + case PKTSCHEDT_FQ_CODEL: + c = "FQ_CODEL"; + break; default: c = "UNKNOWN"; break; diff --git a/ifconfig.tproj/iffake.c b/ifconfig.tproj/iffake.c new file mode 100644 index 0000000..c8065a2 --- /dev/null +++ b/ifconfig.tproj/iffake.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2017 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * iffake.c + * - manage fake interfaces that pretend to be e.g. ethernet + */ + +/* + * Modification History: + * + * January 17, 2017 Dieter Siegmund (dieter@apple.com) + * - created + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ifconfig.h" + +static void +fake_status(int s) +{ + struct ifdrv ifd; + struct if_fake_request iffr; + + bzero((char *)&ifd, sizeof(ifd)); + bzero((char *)&iffr, sizeof(iffr)); + strlcpy(ifd.ifd_name, ifr.ifr_name, sizeof(ifd.ifd_name)); + ifd.ifd_cmd = IF_FAKE_G_CMD_GET_PEER; + ifd.ifd_len = sizeof(iffr); + ifd.ifd_data = &iffr; + if (ioctl(s, SIOCGDRVSPEC, &ifd) < 0) { + return; + } + if (iffr.iffr_peer_name[0] == '\0') { + printf("\tpeer: \n"); + } else { + printf("\tpeer: %s\n", iffr.iffr_peer_name); + } + return; +} + +static void +set_peer(int s, const char * operation, const char * val) +{ + struct ifdrv ifd; + struct if_fake_request iffr; + + bzero((char *)&ifd, sizeof(ifd)); + bzero((char *)&iffr, sizeof(iffr)); + strlcpy(ifd.ifd_name, ifr.ifr_name, sizeof(ifd.ifd_name)); + ifd.ifd_cmd = IF_FAKE_S_CMD_SET_PEER; + ifd.ifd_len = sizeof(iffr); + ifd.ifd_data = &iffr; + if (val != NULL) { + strlcpy(iffr.iffr_peer_name, val, sizeof(iffr.iffr_peer_name)); + } + if (ioctl(s, SIOCSDRVSPEC, &ifd) < 0) { + err(1, "SIOCDRVSPEC %s peer", operation); + } + return; +} + +static +DECL_CMD_FUNC(setpeer, val, d) +{ + set_peer(s, "set", val); + return; +} + +static +DECL_CMD_FUNC(unsetpeer, val, d) +{ + set_peer(s, "unset", NULL); + return; +} + +static struct cmd fake_cmds[] = { + DEF_CLONE_CMD_ARG("peer", setpeer), + DEF_CMD_OPTARG("-peer", unsetpeer), +}; +static struct afswtch af_fake = { + .af_name = "af_fake", + .af_af = AF_UNSPEC, + .af_other_status = fake_status, +}; + +static __constructor void +fake_ctor(void) +{ +#define N(a) (sizeof(a) / sizeof(a[0])) + int i; + + for (i = 0; i < N(fake_cmds); i++) + cmd_register(&fake_cmds[i]); + af_register(&af_fake); +#undef N +} + diff --git a/ifconfig.tproj/nexus.c b/ifconfig.tproj/nexus.c new file mode 100644 index 0000000..692e211 --- /dev/null +++ b/ifconfig.tproj/nexus.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * nexus.c + * - report information about attached nexus + */ + +/* + * Modification History: + * + * April 10, 2017 Dieter Siegmund (dieter@apple.com) + * - created + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ifconfig.h" + +static void +nexus_status(int s) +{ + struct if_nexusreq ifnr; + uuid_string_t multistack; + uuid_string_t netif; + + if (!verbose) { + return; + } + bzero((char *)&ifnr, sizeof(ifnr)); + strlcpy(ifnr.ifnr_name, ifr.ifr_name, sizeof(ifnr.ifnr_name)); + if (ioctl(s, SIOCGIFNEXUS, &ifnr) < 0) { + return; + } + if (uuid_is_null(ifnr.ifnr_netif)) { + /* technically, this shouldn't happen */ + return; + } + uuid_unparse_upper(ifnr.ifnr_netif, netif); + printf("\tnetif: %s\n", netif); + if (uuid_is_null(ifnr.ifnr_multistack) == 0) { + uuid_unparse_upper(ifnr.ifnr_multistack, multistack); + printf("\tmultistack: %s\n", multistack); + } + return; +} + +static struct afswtch af_fake = { + .af_name = "af_fake", + .af_af = AF_UNSPEC, + .af_other_status = nexus_status, +}; + +static __constructor void +fake_ctor(void) +{ + af_register(&af_fake); +} + diff --git a/mptcp_client/conn_lib.c b/mptcp_client/conn_lib.c index f808fc2..1c83915 100644 --- a/mptcp_client/conn_lib.c +++ b/mptcp_client/conn_lib.c @@ -49,38 +49,38 @@ copyassocids(int s, sae_associd_t **aidpp, uint32_t *cnt) struct so_aidreq aidr; sae_associd_t *buf; int err; - + if (aidpp == NULL || cnt == NULL) { errno = EINVAL; return (-1); } *aidpp = NULL; *cnt = 0; - + bzero(&aidr, sizeof (aidr)); - + err = ioctl(s, SIOCGASSOCIDS, &aidr); if (err != 0) return (-1); - + /* none, just return */ if (aidr.sar_cnt == 0) return (0); - + buf = calloc(aidr.sar_cnt, sizeof (sae_associd_t)); if (buf == NULL) return (-1); - + aidr.sar_aidp = buf; err = ioctl(s, SIOCGASSOCIDS, &aidr); if (err != 0) { free(buf); return (-1); } - + *aidpp = buf; *cnt = aidr.sar_cnt; - + return (0); } @@ -96,39 +96,39 @@ copyconnids(int s, sae_associd_t aid, sae_connid_t **cidp, uint32_t *cnt) struct so_cidreq cidr; sae_connid_t *buf; int err; - + if (cidp == NULL || cnt == NULL) { errno = EINVAL; return (-1); } *cidp = NULL; *cnt = 0; - + bzero(&cidr, sizeof (cidr)); - + cidr.scr_aid = aid; err = ioctl(s, SIOCGCONNIDS, &cidr); if (err != 0) return (-1); - + /* none, just return */ if (cidr.scr_cnt == 0) return (0); - + buf = calloc(cidr.scr_cnt, sizeof (sae_connid_t)); if (buf == NULL) return (-1); - + cidr.scr_cidp = buf; err = ioctl(s, SIOCGCONNIDS, &cidr); if (err != 0) { free(buf); return (-1); } - + *cidp = buf; *cnt = cidr.scr_cnt; - + return (0); } @@ -144,19 +144,19 @@ copyconninfo(int s, sae_connid_t cid, conninfo_t **cfop) struct sockaddr *src = NULL, *dst = NULL, *aux = NULL; struct so_cinforeq scir; conninfo_t *buf = NULL; - + if (cfop == NULL) { errno = EINVAL; goto error; } *cfop = NULL; - + bzero(&scir, sizeof (scir)); - + scir.scir_cid = cid; if (ioctl(s, SIOCGCONNINFO, &scir) != 0) goto error; - + if (scir.scir_src_len != 0) { src = calloc(1, scir.scir_src_len); if (src == NULL) @@ -175,14 +175,14 @@ copyconninfo(int s, sae_connid_t cid, conninfo_t **cfop) goto error; scir.scir_aux_data = aux; } - + if (ioctl(s, SIOCGCONNINFO, &scir) != 0) goto error; - + buf = calloc(1, sizeof (*buf)); if (buf == NULL) goto error; - + // When we query for the length using the first ioctl call above, the kernel // tells us the length of the aux structure so we know how much to allocate // memory. There may not be any aux data, which will be indicated by the aux @@ -192,7 +192,7 @@ copyconninfo(int s, sae_connid_t cid, conninfo_t **cfop) aux = NULL; scir.scir_aux_data = NULL; } - + buf->ci_flags = scir.scir_flags; buf->ci_ifindex = scir.scir_ifindex; buf->ci_src = src; @@ -201,9 +201,9 @@ copyconninfo(int s, sae_connid_t cid, conninfo_t **cfop) buf->ci_aux_type = scir.scir_aux_type; buf->ci_aux_data = aux; *cfop = (conninfo_t*)buf; - + return (0); - + error: if (src != NULL) free(src); @@ -213,7 +213,7 @@ error: free(aux); if (buf != NULL) free(buf); - + return (-1); } @@ -222,12 +222,12 @@ freeconninfo(conninfo_t *cfo) { if (cfo->ci_src != NULL) free(cfo->ci_src); - + if (cfo->ci_dst != NULL) free(cfo->ci_dst); - + if (cfo->ci_aux_data != NULL) free(cfo->ci_aux_data); - + free(cfo); } diff --git a/mptcp_client/mptcp_client.1 b/mptcp_client/mptcp_client.1 index eb9f15c..2ca3cad 100644 --- a/mptcp_client/mptcp_client.1 +++ b/mptcp_client/mptcp_client.1 @@ -13,9 +13,7 @@ .Ar times .Ar alt_addr .Ar 0 -.Ar connorder .Ar longlived -.Ar fastjoin .Sh DESCRIPTION .Nm is as an MPTCP client test tool that use the diff --git a/mptcp_client/mptcp_client.c b/mptcp_client/mptcp_client.c index 2816fdd..37a43ec 100644 --- a/mptcp_client/mptcp_client.c +++ b/mptcp_client/mptcp_client.c @@ -79,14 +79,18 @@ static int verbose = 0; static int32_t thiszone = 0; /* time difference with gmt */ -char* setup_buffer1(int bufsz) +char *setup_buffer1(int bufsz) { int i = 0, j = 1; - char *buf = malloc(bufsz); - if (buf) { - bzero(buf, bufsz); - strlcpy(buf, MSG_HDR, sizeof(MSG_HDR)); - } + char *buf; + + buf = malloc(bufsz); + if (!buf) + return NULL; + + bzero(buf, bufsz); + strlcpy(buf, MSG_HDR, sizeof(MSG_HDR)); + for (i = sizeof(MSG_HDR); i < bufsz; i++) { buf[i] = j; j++; @@ -96,15 +100,19 @@ char* setup_buffer1(int bufsz) return buf; } -char* setup_buffer2(int bufsz) +char *setup_buffer2(int bufsz) { int i = 0; char j = 'A'; - char *buf = malloc(bufsz); - if (buf) { - bzero(buf, bufsz); - strlcpy(buf, MSG_HDR, sizeof(MSG_HDR)); - } + char *buf; + + buf = malloc(bufsz); + if (!buf) + return NULL; + + bzero(buf, bufsz); + strlcpy(buf, MSG_HDR, sizeof(MSG_HDR)); + for (i = sizeof(MSG_HDR); i < bufsz; i++) { buf[i] = j; j++; @@ -116,10 +124,13 @@ char* setup_buffer2(int bufsz) char *setup_buffer3(int bufsz) { - char *buf = malloc(bufsz); - if (buf) { - bzero(buf, bufsz); - } + char *buf; + + buf = malloc(bufsz); + if (!buf) + return NULL; + + bzero(buf, bufsz); return buf; } @@ -134,7 +145,7 @@ gmt2local(time_t t) int dt, dir; struct tm *gmt, *loc; struct tm sgmt; - + if (t == 0) t = time(NULL); gmt = &sgmt; @@ -142,7 +153,7 @@ gmt2local(time_t t) loc = localtime(&t); dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + (loc->tm_min - gmt->tm_min) * 60; - + /* * If the year or julian day is different, we span 00:00 GMT * and must add or subtract a day. Check the year first to @@ -152,7 +163,7 @@ gmt2local(time_t t) if (dir == 0) dir = loc->tm_yday - gmt->tm_yday; dt += dir * 24 * 60 * 60; - + return (dt); } @@ -165,9 +176,9 @@ ts_print(void) { int s; struct timeval tv; - + gettimeofday(&tv, NULL); - + /* Default */ s = (tv.tv_sec + thiszone) % 86400; printf("%02d:%02d:%02d.%06u ", s / 3600, (s % 3600) / 60, s % 60, @@ -178,7 +189,7 @@ static const char * basename(const char * str) { const char *last_slash = strrchr(str, '/'); - + if (last_slash == NULL) return (str); else @@ -198,10 +209,6 @@ struct option_desc option_desc_list[] = { { "--rsplen n", "length of response (256 by default)", 0 }, { "--ntimes n", "number of time to send request (1 by default)", 0 }, { "--alt_addr addr", "alternate server to connect to", 0 }, - { "--connorder add", "alternate server to connect to", 0 }, - { "--longlived n", "number of reconnection for long lived (default 0)", 0 }, - { "--fastjoin (0|1)", "use fast join (default 0)", 0 }, - { "--nowaitforjoin (0|1)", "do not wait for join (default 0 -- i.e. wait)", 0 }, { "--verbose", "increase verbosity", 0 }, { "--help", "display this help", 0 }, @@ -214,54 +221,47 @@ usage(const char *cmd) struct option_desc *option_desc; char *usage_str = malloc(LINE_MAX); size_t usage_len; - + if (usage_str == NULL) err(1, "%s: malloc(%d)", __func__, LINE_MAX); - + usage_len = snprintf(usage_str, LINE_MAX, "# usage: %s ", basename(cmd)); - + for (option_desc = option_desc_list; option_desc->option != NULL; option_desc++) { int len; - + if (option_desc->required) len = snprintf(usage_str + usage_len, LINE_MAX - usage_len, "%s ", option_desc->option); else len = snprintf(usage_str + usage_len, LINE_MAX - usage_len, "[%s] ", option_desc->option); if (len < 0) err(1, "%s: snprintf(", __func__); - + usage_len += len; if (usage_len > LINE_MAX) break; } printf("%s\n", usage_str); printf("options:\n"); - + for (option_desc = option_desc_list; option_desc->option != NULL; option_desc++) { printf(" %-24s # %s\n", option_desc->option, option_desc->description); } printf("\n"); printf("# legacy usage: "); - printf("%s hostname port reqlen rsplen ntimes alt_addr 0 connorder longlived fastjoin nowaitforjoin\n", - basename(cmd)); } static struct option longopts[] = { - { "host", required_argument, NULL, 'c' }, - { "port", required_argument, NULL, 'p' }, - { "reqlen", required_argument, NULL, 'r' }, - { "rsplen", required_argument, NULL, 'R' }, - { "ntimes", required_argument, NULL, 'n' }, - { "alt_addr", required_argument, NULL, 'a' }, - { "connorder", required_argument, NULL, 'o' }, - { "longlived", required_argument, NULL, 'l' }, - { "fastjoin", required_argument, NULL, 'f' }, - { "nowaitforjoin", required_argument, NULL, 'w' }, - { "help", no_argument, NULL, 'h' }, - { "verbose", no_argument, NULL, 'v' }, - { "quiet", no_argument, NULL, 'q' }, - { NULL, 0, NULL, 0 } - + { "host", required_argument, NULL, 'c' }, + { "port", required_argument, NULL, 'p' }, + { "reqlen", required_argument, NULL, 'r' }, + { "rsplen", required_argument, NULL, 'R' }, + { "ntimes", required_argument, NULL, 'n' }, + { "alt_addr", required_argument, NULL, 'a' }, + { "help", no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { "quiet", no_argument, NULL, 'q' }, + { NULL, 0, NULL, 0 } }; static int @@ -272,16 +272,16 @@ sprint_sockaddr(char *str, socklen_t strlen, struct sockaddr *sa) if (sa->sa_family == AF_INET) { struct sockaddr_in *sin = (struct sockaddr_in*)sa; char str4[INET_ADDRSTRLEN]; - + inet_ntop(AF_INET, &sin->sin_addr, str4, sizeof(str4)); - + retval = snprintf(str, strlen, "%s:%u", str4, ntohs(sin->sin_port)); } else if (sa->sa_family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa; char str6[INET6_ADDRSTRLEN]; char ifname[IF_NAMESIZE]; char scopestr[2 + IF_NAMESIZE]; - + inet_ntop(AF_INET6, &sin6->sin6_addr, str6, sizeof(str6)); if (sin6->sin6_scope_id == 0) @@ -290,7 +290,7 @@ sprint_sockaddr(char *str, socklen_t strlen, struct sockaddr *sa) if_indextoname(sin6->sin6_scope_id, ifname); snprintf(scopestr, sizeof(scopestr), "%%%s", ifname); } - + retval = snprintf(str, strlen, "%s%s:%u", str6, scopestr, @@ -301,14 +301,11 @@ sprint_sockaddr(char *str, socklen_t strlen, struct sockaddr *sa) int main(int argc, char * const *argv) { - int sockfd, ps, portno; + int sockfd, portno; ssize_t n; int reqlen = 256; int rsplen = 256; int ntimes = 1; - int connordrtest = 0; - int longlived = 0; - int fastjoin = 0; char *buffer = NULL; char *buffer1; char *buffer2; @@ -320,8 +317,6 @@ int main(int argc, char * const *argv) sae_connid_t cid1, cid2; int iter; int bytes_to_rdwr; - int peeled_off = 0; - int nowaitforjoin = 0; int ch; const char *host_arg = NULL; const char *port_arg = NULL; @@ -330,15 +325,11 @@ int main(int argc, char * const *argv) const char *ntimes_arg = "1"; const char *alt_addr_arg = NULL; const char *alt_port_arg = "0"; - const char *connorder_arg = NULL; - const char *longlived_arg = NULL; - const char *fastjoin_arg = NULL; - const char *nowaitforjoin_arg = NULL; int gotopt = 0; thiszone = gmt2local(0); - - while ((ch = getopt_long(argc, argv, "a:c:f:hl:n:o:p:qr:R:vw:", longopts, NULL)) != -1) { + + while ((ch = getopt_long(argc, argv, "a:c:hn:p:qr:R:v", longopts, NULL)) != -1) { gotopt = 1; switch (ch) { case 'a': @@ -347,18 +338,9 @@ int main(int argc, char * const *argv) case 'c': host_arg = optarg; break; - case 'f': - fastjoin_arg = optarg; - break; - case 'l': - longlived_arg = optarg; - break; case 'n': ntimes_arg = optarg; break; - case 'o': - connorder_arg = optarg; - break; case 'p': port_arg = optarg; break; @@ -374,17 +356,12 @@ int main(int argc, char * const *argv) case 'v': verbose++; break; - case 'w': - nowaitforjoin_arg = optarg; - break; - default: usage(argv[0]); exit(EX_USAGE); - } } - + if (gotopt == 0) { if (argc == 12) { host_arg = argv[1]; @@ -393,16 +370,12 @@ int main(int argc, char * const *argv) rsplen_arg = argv[4]; ntimes_arg = argv[5]; alt_addr_arg = argv[6]; - connorder_arg = argv[8]; - longlived_arg = argv[9]; - fastjoin_arg = argv[10]; - nowaitforjoin_arg = argv[11]; } else { usage(argv[0]); exit(EX_USAGE); } } - + if (host_arg == NULL) errx(EX_USAGE, "missing required host option\n"); @@ -414,97 +387,68 @@ int main(int argc, char * const *argv) if (reqlen_arg != NULL) { reqlen = atoi(reqlen_arg); - if (reqlen < 0) + if (reqlen < 0 || reqlen > 1024 * 1024) errx(EX_USAGE, "invalid request length %s\n", reqlen_arg); } if (rsplen_arg != NULL) { rsplen = atoi(rsplen_arg); - if (rsplen < 0) + if (rsplen < 0 || rsplen > 1024 * 1024) errx(EX_USAGE, "invalid response length %s\n", rsplen_arg); } - + if (ntimes_arg != NULL) { ntimes = atoi(ntimes_arg); if (ntimes < 1) errx(EX_USAGE, "invalid ntimes option %s\n", ntimes_arg); } - - if (connorder_arg != NULL) { - connordrtest = atoi(connorder_arg); - if (connordrtest != 0 && connordrtest != 1) - errx(EX_USAGE, "invalid connorder count %s\n", connorder_arg); - } - - if (longlived_arg != NULL) { - longlived = atoi(longlived_arg); - if (longlived < 0) - errx(EX_USAGE, "invalid longlived count %s\n", longlived_arg); - } - - if (fastjoin_arg != NULL) { - fastjoin = atoi(fastjoin_arg); - if (fastjoin != 0 && fastjoin != 1) - errx(EX_USAGE, "invalid fastjoin option %s\n", fastjoin_arg); - } - - if (nowaitforjoin_arg != NULL) { - nowaitforjoin = atoi(nowaitforjoin_arg); - if (nowaitforjoin != 0 && nowaitforjoin != 1) - errx(EX_USAGE, "invalid nowaitforjoin option %s\n", nowaitforjoin_arg); - } - + buffer1 = setup_buffer1(reqlen); if (!buffer1) { printf("client: failed to alloc buffer space \n"); return -1; } - + buffer2 = setup_buffer2(reqlen); if (!buffer2) { printf("client: failed to alloc buffer space \n"); return -1; } - + buffer3 = setup_buffer3(rsplen); if (!buffer3) { printf("client: failed to alloc buffer space \n"); return -1; } - + if (verbose > 0) - printf("host: %s port: %s reqlen: %d rsplen: %d ntimes: %d alt_addr: %s connorder: %d longlived: %d fasjoin: %d nowaitforjoin: %d\n", - host_arg, port_arg, reqlen, rsplen, ntimes, alt_addr_arg, connordrtest, longlived, fastjoin, nowaitforjoin); - + printf("host: %s port: %s reqlen: %d rsplen: %d ntimes: %d alt_addr: %s\n", + host_arg, port_arg, reqlen, rsplen, ntimes, alt_addr_arg); + sockfd = socket(AF_MULTIPATH, SOCK_STREAM, 0); if (sockfd < 0) err(EX_OSERR, "ERROR opening socket"); -#define SO_MPTCP_FASTJOIN 0x1111 - opterr = setsockopt(sockfd, SOL_SOCKET, SO_MPTCP_FASTJOIN, &fastjoin, sizeof(fastjoin)); - if (opterr != 0) - warn("setsockopt(SO_MPTCP_FASTJOIN, %d)", fastjoin); - + memset(&ahints, 0, sizeof(struct addrinfo)); ahints.ai_family = AF_INET; ahints.ai_socktype = SOCK_STREAM; ahints.ai_protocol = IPPROTO_TCP; - + retval = getaddrinfo(host_arg, port_arg, &ahints, &ares); if (retval != 0) printf("getaddrinfo(%s, %s) failed %d\n", host_arg, port_arg, retval); - + bytes_to_rdwr = reqlen; -connect_again: - + cid1 = cid2 = SAE_CONNID_ANY; int ifscope = 0; int error = 0; - + if (verbose > 0) { char str[2 * INET6_ADDRSTRLEN]; - + ts_print(); - + sprint_sockaddr(str, sizeof(str), ares->ai_addr); printf("connectx(%s, %d, %d)\n", str, ifscope, cid1); } @@ -515,30 +459,18 @@ connect_again: sa.sae_srcif = ifscope; error = connectx(sockfd, &sa, SAE_ASSOCID_ANY, 0, NULL, 0, NULL, &cid1); - if ((error != 0) && (errno != EPROTO)) { + if (error != 0) err(EX_OSERR, "ERROR connecting"); - } else if ((error != 0) && (errno == EPROTO)) { - ps = peeloff(sockfd, SAE_ASSOCID_ANY); - - if (ps != -1) { - close(sockfd); - sockfd = ps; - } - peeled_off = 1; - ts_print(); - printf("%s: peeled off\n", __func__); - } - + iter = 0; - + while (ntimes) { - - if ((iter == 0) && (peeled_off == 0)) { + if (iter == 0) { /* Add alternate path if available */ - + if (alt_addr_arg && alt_addr_arg[0] != 0) { retval = getaddrinfo(alt_addr_arg, alt_port_arg, &ahints, &altres); - + if (retval != 0) printf("client: alternate address resolution failed. \n"); else { @@ -548,7 +480,7 @@ connect_again: char str[2 * INET6_ADDRSTRLEN]; ts_print(); - + sprint_sockaddr(str, sizeof(str), altres->ai_addr); printf("connectx(%s, %d, %d)\n", str, ifscope, cid1); } @@ -559,42 +491,15 @@ connect_again: sa.sae_srcaddrlen = altres->ai_addrlen; sa.sae_dstaddr = ares->ai_addr; sa.sae_dstaddrlen = ares->ai_addrlen; - + error = connectx(sockfd, &sa, SAE_ASSOCID_ANY, 0, NULL, 0, NULL, &cid2); if (error < 0) { err(EX_OSERR, "ERROR setting up alternate path"); } } } - - } - - if ((iter == 10) && (connordrtest == 1)) { - int retval = 0; - - socorder.sco_cid = cid2; - socorder.sco_rank = 1; - retval = ioctl(sockfd, SIOCSCONNORDER, &socorder); - if (retval != 0) - warn("Error in changing priority"); - - bzero(&socorder, sizeof(socorder)); - socorder.sco_cid = cid2; - retval = ioctl(sockfd, SIOCGCONNORDER, &socorder); - printf("cid %d rank %d", socorder.sco_cid, socorder.sco_rank); - - socorder.sco_cid = cid1; - socorder.sco_rank = 0; - retval = ioctl(sockfd, SIOCSCONNORDER, &socorder); - if (retval != 0) - warn("Error in changing priority"); - - bzero(&socorder, sizeof(socorder)); - socorder.sco_cid = cid1; - retval = ioctl(sockfd, SIOCGCONNORDER, &socorder); - printf("cid %d rank %d \n", socorder.sco_cid, socorder.sco_rank); } - + if (which_buf == 0) { buffer = buffer1; which_buf = 1; @@ -602,7 +507,7 @@ connect_again: buffer = buffer2; which_buf = 0; } - + while (bytes_to_rdwr) { if (verbose) { ts_print(); @@ -625,7 +530,7 @@ connect_again: printf("reading %d bytes\n", rsplen); } n = read(sockfd, buffer3, rsplen); - + if (n <= 0) { err(EX_OSERR, "ERROR reading from socket"); } @@ -639,60 +544,18 @@ connect_again: ntimes--; iter++; } - + printf("client: Req size %d Rsp size %d Read/Write %d times \n", reqlen, rsplen, iter); - + showmpinfo(sockfd); - - if ((!longlived) || (peeled_off == 1)) { - if (verbose) { - ts_print(); - printf("close(%d)\n", sockfd); - } - close(sockfd); - } else { - printf("Longlived countdown # %d. \n", longlived); - if (verbose) { - ts_print(); - printf("disconnectx(%d, %d)\n", sockfd, cid1); - } - disconnectx(sockfd, SAE_ASSOCID_ANY, cid1); - if (cid2 != SAE_CONNID_ANY) { - if (verbose) { - ts_print(); - printf("disconnectx(%d, %d)\n", sockfd, cid2); - } - disconnectx(sockfd, SAE_ASSOCID_ANY, cid2); - } - if (!nowaitforjoin) { - if (verbose) { - ts_print(); - printf("sleep(10)\n"); - } - sleep(10); - } - longlived--; - - ntimes = atoi(ntimes_arg); - - /* If fastjoin must be tested, write some data before doing the next connectx() */ - bytes_to_rdwr = reqlen / 2; - if (verbose) { - ts_print(); - printf("fastjoin writing %d bytes\n", bytes_to_rdwr); - } - n = write(sockfd, buffer, bytes_to_rdwr); - if (n <= 0) { - warnx("Fastjoin: Error writing to socket. \n"); - } else { - bytes_to_rdwr = reqlen - (int)n; - printf("FastJoin: Wrote %zd bytes, remaining %d of %d \n", n, bytes_to_rdwr, reqlen); - } - - goto connect_again; + + if (verbose) { + ts_print(); + printf("close(%d)\n", sockfd); } - if (ares) - freeaddrinfo(ares); + close(sockfd); + + freeaddrinfo(ares); if (altres) freeaddrinfo(altres); return 0; @@ -711,7 +574,7 @@ printb(const char *s, unsigned v, const char *bits) { int i, any = 0; char c; - + if (bits && *bits == 8) printf("%s=%o", s, v); else @@ -741,18 +604,17 @@ showconninfo(int s, sae_connid_t cid) char buf[INET6_ADDRSTRLEN]; conninfo_t *cfo = NULL; int err; - + err = copyconninfo(s, cid, &cfo); if (err != 0) { printf("getconninfo failed for cid %d\n", cid); goto out; } - + printf("%6d:\t", cid); printb("flags", cfo->ci_flags, CIF_BITS); printf("\n"); - //printf("\toutif %s\n", if_indextoname(cfo->ci_ifindex, buf)); -#if 1 + if (cfo->ci_src != NULL) { printf("\tsrc %s port %d\n", inet_ntop(cfo->ci_src->sa_family, (cfo->ci_src->sa_family == AF_INET) ? @@ -785,11 +647,10 @@ showconninfo(int s, sae_connid_t cid) break; } } -#endif out: if (cfo != NULL) freeconninfo(cfo); - + return (err); } @@ -800,7 +661,7 @@ showmpinfo(int s) sae_associd_t *aid = NULL; sae_connid_t *cid = NULL; int i, error = 0; - + error = copyassocids(s, &aid, &aid_cnt); if (error != 0) { printf("copyassocids failed\n"); @@ -814,7 +675,7 @@ showmpinfo(int s) } printf("\n"); } - + /* just do an association for now */ error = copyconnids(s, SAE_ASSOCID_ANY, &cid, &cid_cnt); if (error != 0) { @@ -831,7 +692,7 @@ showmpinfo(int s) } printf("\n"); } - + done: if (aid != NULL) freeassocids(aid); diff --git a/natd.tproj/HISTORY b/natd.tproj/HISTORY deleted file mode 100644 index f929e80..0000000 --- a/natd.tproj/HISTORY +++ /dev/null @@ -1,146 +0,0 @@ -* Version 0.1 - - Initial version of natd. - -* Version 0.2 - - - Alias address can now be set by giving interface name with - new (-n) command-line option. - - - New Makefile based on bsd.prog.mk. - - - Error messages are written to syslog - after natd has become a daemon. - -* Version 1.0 - - - Support for using only single socket (-p option) - -* Version 1.1 - - - -a option now understands a hostname also. - - -a option no longer dumps core. - - Packet aliasing software upgraded to v. 1.9 - - added long option names (like -address) - -* Version 1.2 - - - Fixed core dump with -port option. - - Added -Wall to CFLAGS and some headers added to natd.c - to get clean compile by Brian Somers [brian@awfulhak.org]. - -* Version 1.3 - - - Aliasing address initialization is delayed until first - packet arrives. This allows natd to start up before - interface address is set. - - SIGTERM is now catched to allow kernel to close - existing connections when system is shutting down. - - SIGHUP is now catched to allow natd to refresh aliasing - address from interface, which might be useful to tun devices. - -* Version 1.4 - - - Changed command line options to be compatible with - command names used in ppp+packetAlias package (which is the - original application using aliasing routines). - - The options which map directly to packet aliasing options are: - - -unregistered_only [yes|no] - -log [yes|no] - -deny_incoming [yes|no] - -use_sockets [yes|no] - -same_ports [yes|no] - - The short option names are the same as in previous - releases. - - - Command line parser rewritten to provide more flexible - way to support new packet aliasing options. - - - Support for natd.cf configuration file has been added. - - - SIGHUP no longer causes problems when running without - interface name option. - - - When using -interface command line option, routing socket - is optionally listened for interface address changes. This - mode is activated by -dynamic option. - - - Directory tree reorganized, alias package is now a library. - - - Manual page written by Brian Somers added. - - README file updated. - -* Version 1.5 - - - Support for sending ICMP 'need fragmentation' messages - when packet size exceeds mtu size of outgoing network interface. - - - ipfw rule example in manual page fixed. - -* Version 1.6 - - - Upgrade to new packet aliasing engine (2.1) - - redirect_port and redirect_address configuration - parameters added. - - It is no longer necessary to quote complex parameter values - in command line. - - Manual page fixed (same_port -> same_ports). - -* Version 1.7 - - - A bug in command-line parsing fixed (it appeared due - to changes made in 1.6). - -* Version 1.8 - - - Fixed problems with -dynamic option. - - Added /var/run/natd.pid - -* Version 1.9 - - - Changes to manual page by - Brian Somers integrated. - - Checksum for incoming packets is always recalculated - for FreeBSD 2.2 and never recalculated for newer - versions. This should fix the problem with wrong - checksum of fragmented packets. - - Buffer space problem found by Sergio Lenzi - fixed. Natd now waits with select(2) for buffer space - to become available if write fails. - - Packet aliasing library upgraded to 2.2. - -* Version 1.10 - - - Ignored incoming packets are now dropped when - deny_incoming option is set to yes. - - Packet aliasing library upgraded to 2.4. - -* Version 1.11 - - - Code cleanup work done in FreeBSD-current development merged. - - Port numbers are now unsigned as they should always have been. - -* Version 1.12 - - - Typos in comment fixed. Copyright message added to - source & header files that were missing it. - - A small patch to libalias to make static NAT work correctly. - -* Version 2.0 - - - Upgrade to libalias 3.0 which gives: - - Transparent proxy support. - - permanent_link is now obsolete, use redirect_port instead. - - Drop support for early FreeBSD 2.2 versions - - If separate input & output sockets are being used - use them to find out packet direction instead of - normal mechanism. This can be handy in complex environments - with multiple interfaces. - - libalias is no longer part of this distribution. - - New sample configuration file - from Ted Mittelstaedt . - - PPTP redirect support by Dru Nelson added. - - Logging enhancements from Martin Machacek added. diff --git a/natd.tproj/README b/natd.tproj/README deleted file mode 100644 index a697e61..0000000 --- a/natd.tproj/README +++ /dev/null @@ -1,50 +0,0 @@ -# $FreeBSD: src/sbin/natd/README,v 1.1.4.1 2000/04/02 20:24:48 brian Exp $ - - A Network Address Translation Daemon for FreeBSD - - -1. WHAT IS NATD ? - - This is a simple daemon based on FreeBSD divert sockets - which performs network address translation (or masquerading) - for IP packets (see related RFCs 1631 and 1918). - It is based on packet aliasing package (see README.alias) - written by Charles Mott (cmott@scientech.com). - - This package works with any network interface (doesn't have - to be ppp). I run it on a computer having two ethernet cards, - one connected to internet and the other one to local network. - -2. GETTING IT RUNNING - - 1) Get FreeBSD 2.2 - I think the divert sockets are - not available on earlier versions, - - 2) Compile this software by executing "make". - - 3) Install the software by executing "make install". - - 4) See man natd for further instructions. - -3. FTP SITES FOR NATD - - This package is available at ftp://ftp.suutari.iki.fi/pub/natd. - -4. AUTHORS - - This program is the result of the efforts of many people - at different times: - - Archie Cobbs Divert sockets - Charles Mott Packet aliasing engine - Eivind Eklund Packet aliasing engine - Ari Suutari Natd - Brian Somers Manual page, glue and - bunch of good ideas. - - Happy Networking - comments and fixes are welcome! - - Ari S. (suutari@iki.fi) - - - diff --git a/natd.tproj/icmp.c b/natd.tproj/icmp.c deleted file mode 100644 index 4e62d3f..0000000 --- a/natd.tproj/icmp.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * natd - Network Address Translation Daemon for FreeBSD. - * - * This software is provided free of charge, with no - * warranty of any kind, either expressed or implied. - * Use at your own risk. - * - * You may copy, modify and distribute this software (icmp.c) freely. - * - * Ari Suutari - * - * Based upon: - * $FreeBSD: src/sbin/natd/icmp.c,v 1.6 1999/08/28 00:13:45 peter Exp $ - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -#include "natd.h" - -int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu) -{ - char icmpBuf[IP_MAXPACKET]; - struct ip* ip; - struct icmp* icmp; - int icmpLen; - int failBytes; - int failHdrLen; - struct sockaddr_in addr; - int wrote; - struct in_addr swap; -/* - * Don't send error if packet is - * not the first fragment. - */ - if (ntohs (failedDgram->ip_off) & ~(IP_MF | IP_DF)) - return 0; -/* - * Dont respond if failed datagram is ICMP. - */ - if (failedDgram->ip_p == IPPROTO_ICMP) - return 0; -/* - * Start building the message. - */ - ip = (struct ip*) icmpBuf; - icmp = (struct icmp*) (icmpBuf + sizeof (struct ip)); -/* - * Complete ICMP part. - */ - icmp->icmp_type = ICMP_UNREACH; - icmp->icmp_code = ICMP_UNREACH_NEEDFRAG; - icmp->icmp_cksum = 0; - icmp->icmp_void = 0; - icmp->icmp_nextmtu = htons (mtu); -/* - * Copy header + 64 bits of original datagram. - */ - failHdrLen = (failedDgram->ip_hl << 2); - failBytes = failedDgram->ip_len - failHdrLen; - if (failBytes > 8) - failBytes = 8; - - failBytes += failHdrLen; - icmpLen = ICMP_MINLEN + failBytes; - - memcpy (&icmp->icmp_ip, failedDgram, failBytes); -/* - * Calculate checksum. - */ - icmp->icmp_cksum = PacketAliasInternetChecksum ((u_short*) icmp, - icmpLen); -/* - * Add IP header using old IP header as template. - */ - memcpy (ip, failedDgram, sizeof (struct ip)); - - ip->ip_v = 4; - ip->ip_hl = 5; - ip->ip_len = htons (sizeof (struct ip) + icmpLen); - ip->ip_p = IPPROTO_ICMP; - ip->ip_tos = 0; - - swap = ip->ip_dst; - ip->ip_dst = ip->ip_src; - ip->ip_src = swap; - - PacketAliasIn ((char*) ip, IP_MAXPACKET); - - addr.sin_family = AF_INET; - addr.sin_addr = ip->ip_dst; - addr.sin_port = 0; -/* - * Put packet into processing queue. - */ - wrote = sendto (sock, - icmp, - icmpLen, - 0, - (struct sockaddr*) &addr, - sizeof addr); - - if (wrote != icmpLen) - Warn ("Cannot send ICMP message."); - - return 1; -} - - diff --git a/natd.tproj/natd.8 b/natd.tproj/natd.8 deleted file mode 100644 index 6e3a284..0000000 --- a/natd.tproj/natd.8 +++ /dev/null @@ -1,11 +0,0 @@ -.Dd September 27, 2012 -.Dt Darwin 8 -.Os Darwin -.Sh NAME -.Nm natd -.Sh DESCRIPTION -This utility is -.Cm DEPRECATED. -Please use -.Xr pfctl 8 -instead. diff --git a/natd.tproj/natd.c b/natd.tproj/natd.c deleted file mode 100644 index e47fd1c..0000000 --- a/natd.tproj/natd.c +++ /dev/null @@ -1,2407 +0,0 @@ -/* - * Copyright (c) 2000-2009 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -/* - * natd - Network Address Translation Daemon for FreeBSD. - * - * This software is provided free of charge, with no - * warranty of any kind, either expressed or implied. - * Use at your own risk. - * - * You may copy, modify and distribute this software (natd.c) freely. - * - * Ari Suutari - * - * Based upon: - * $FreeBSD: src/sbin/natd/natd.c,v 1.25.2.3 2000/07/11 20:00:57 ru Exp $ - */ - -#define SYSLOG_NAMES - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -void DumpInfo(void); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "natd.h" - -/* - * Default values for input and output - * divert socket ports. - */ - -#define DEFAULT_SERVICE "natd" - -/* - * Definition of a port range, and macros to deal with values. - * FORMAT: HI 16-bits == first port in range, 0 == all ports. - * LO 16-bits == number of ports in range - * NOTES: - Port values are not stored in network byte order. - */ - -typedef uint32_t port_range; - -#define GETLOPORT(x) ((x) >> 0x10) -#define GETNUMPORTS(x) ((x) & 0x0000ffff) -#define GETHIPORT(x) (GETLOPORT((x)) + GETNUMPORTS((x))) - -/* Set y to be the low-port value in port_range variable x. */ -#define SETLOPORT(x,y) ((x) = ((x) & 0x0000ffff) | ((y) << 0x10)) - -/* Set y to be the number of ports in port_range variable x. */ -#define SETNUMPORTS(x,y) ((x) = ((x) & 0xffff0000) | (y)) - -/* - * Function prototypes. - */ - -static void DoAliasing (int fd, int direction); -static void DaemonMode (void); -static void HandleRoutingInfo (int fd); -static void Usage (void); -static char* FormatPacket (struct ip*); -static void PrintPacket (struct ip*); -static void SyslogPacket (struct ip*, int priority, const char *label); -static void SetAliasAddressFromIfName (const char *ifName); -static void InitiateShutdown (int); -static void Shutdown (int); -static void RefreshAddr (int); -static void HandleInfo (int); -static void ParseOption (const char* option, const char* parms); -static void ReadConfigFile (const char* fileName); -static void SetupPortRedirect (const char* parms); -static void SetupProtoRedirect(const char* parms); -static void SetupAddressRedirect (const char* parms); -static void StrToAddr (const char* str, struct in_addr* addr); -static u_short StrToPort (const char* str, const char* proto); -static int StrToPortRange (const char* str, const char* proto, port_range *portRange); -static int StrToProto (const char* str); -static int StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange); -static void ParseArgs (int argc, char** argv); -static void FlushPacketBuffer (int fd); -static void DiscardIncomingPackets (int fd); -static void SetupPunchFW(const char *strValue); - -/* - * Globals. - */ - -static int verbose; -static int background; -static int running; -static int assignAliasAddr; -static char* ifName; -static int ifIndex; -static u_short inPort; -static u_short outPort; -static u_short inOutPort; -static struct in_addr aliasAddr; -static int dynamicMode; -static int clampMSS; -static int ifMTU; -static int aliasOverhead; -static int icmpSock; -static char packetBuf[IP_MAXPACKET]; -static int packetLen; -static struct sockaddr_in packetAddr; -static int packetSock; -static int packetDirection; -static int dropIgnoredIncoming; -static int logDropped; -static int logFacility; -static int dumpinfo; - -#define NATPORTMAP 1 - -#ifdef NATPORTMAP - -/* - * Note: more details on NAT-PMP can be found at : - * - */ - -#define NATPMP_ANNOUNCEMENT_PORT 5350 -#define NATPMP_PORT 5351 - -#define NATPMVERSION 0 -#define PUBLICADDRREQ 0 -#define MAPUDPREQ 1 -#define MAPTCPREQ 2 -#define MAPUDPTCPREQ 3 -#define SERVERREPLYOP 128 - -#define SUCCESS 0 -#define NOTSUPPORTEDVERSION 1 -#define NOTAUTHORIZED 2 -#define NETWORKFAILURE 3 -#define OUTOFRESOURCES 4 -#define UNSUPPORTEDOPCODE 5 - -#define MAXRETRY 10 -#define TIMER_RATE 250000 - -#define FAILED -1 - -typedef struct stdportmaprequest { - uint8_t version; - uint8_t opcode; -} stdportmaprequest; - -typedef struct publicportreq { - uint8_t version; - uint8_t opcode; - uint16_t reserved; - uint16_t privateport; - uint16_t publicport; - uint32_t lifetime; /* in seconds */ -} publicportreq; - -typedef struct publicaddrreply { - uint8_t version; - uint8_t opcode; - uint16_t result; - uint32_t epoch; - struct in_addr addr; -} publicaddrreply; - -typedef struct publicportreply { - uint8_t version; - uint8_t opcode; - uint16_t result; - uint32_t epoch; - uint16_t privateport; - uint16_t publicport; - uint32_t lifetime; /* in seconds */ -} publicportreply; - -typedef struct stderrreply { - uint8_t version; - uint8_t opcode; - uint16_t result; - uint32_t epoch; -} stderrreply; - - -static int enable_natportmap = 0; -static struct in_addr lastassignaliasAddr; -static int portmapSock = -1; -static struct in_addr *forwardedinterfaceaddr; -static char **forwardedinterfacename; -static int numofinterfaces = 0; /* has to be at least one */ -static int numoftries=MAXRETRY; -static struct itimerval itval; -static int Natdtimerset = 0; -static double secdivisor; - - -static void HandlePortMap( int fd ); -static void SendPortMapResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, unsigned char origopcode, unsigned short result); -static void SendPublicAddress( int fd, struct sockaddr_in *clientaddr, int clientaddrlen ); -static void SendPublicPortResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, publicportreq *reply, u_short publicport, int result); -static void Doubletime( struct timeval *tvp); -static void Stoptimer(); -static void Natdtimer(); -static void SendPortMapMulti( ); -static void NotifyPublicAddress(); -static void DoPortMapping( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, publicportreq *req); -static void NatPortMapPInit(); - -extern int FindAliasPortOut(struct in_addr src_addr, struct in_addr dst_addr, u_short src_port, u_short pub_port, u_char proto, int lifetime, char addmapping); - -#endif /* NATPORTMAP */ - -int main (int argc, char** argv) -{ - int divertIn; - int divertOut; - int divertInOut; - int routeSock; - struct sockaddr_in addr; - fd_set readMask; - fd_set writeMask; - int fdMax; - int fdFlags; -/* - * Initialize packet aliasing software. - * Done already here to be able to alter option bits - * during command line and configuration file processing. - */ - PacketAliasInit (); -/* - * Parse options. - */ - inPort = 0; - outPort = 0; - verbose = 0; - inOutPort = 0; - ifName = NULL; - ifMTU = -1; - background = 0; - running = 1; - assignAliasAddr = 0; - aliasAddr.s_addr = INADDR_NONE; -#ifdef NATPORTMAP - lastassignaliasAddr.s_addr = INADDR_NONE; -#endif - aliasOverhead = 12; - dynamicMode = 0; - logDropped = 0; - logFacility = LOG_DAEMON; -/* - * Mark packet buffer empty. - */ - packetSock = -1; - packetDirection = DONT_KNOW; - - ParseArgs (argc, argv); -/* - * Open syslog channel. - */ - openlog ("natd", LOG_CONS | LOG_PID | (verbose ? LOG_PERROR : 0), - logFacility); -/* - * Check that valid aliasing address has been given. - */ - if (aliasAddr.s_addr == INADDR_NONE && ifName == NULL) - errx (1, "aliasing address not given"); - -/* - * Check that valid port number is known. - */ - if (inPort != 0 || outPort != 0) - if (inPort == 0 || outPort == 0) - errx (1, "both input and output ports are required"); - - if (inPort == 0 && outPort == 0 && inOutPort == 0) - ParseOption ("port", DEFAULT_SERVICE); - -/* - * Check if ignored packets should be dropped. - */ - dropIgnoredIncoming = PacketAliasSetMode (0, 0); - dropIgnoredIncoming &= PKT_ALIAS_DENY_INCOMING; -/* - * Create divert sockets. Use only one socket if -p was specified - * on command line. Otherwise, create separate sockets for - * outgoing and incoming connnections. - */ - if (inOutPort) { - - divertInOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); - if (divertInOut == -1) - Quit ("Unable to create divert socket."); - - divertIn = -1; - divertOut = -1; -/* - * Bind socket. - */ - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = inOutPort; - - if (bind (divertInOut, - (struct sockaddr*) &addr, - sizeof addr) == -1) - Quit ("Unable to bind divert socket."); - } - else { - - divertIn = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); - if (divertIn == -1) - Quit ("Unable to create incoming divert socket."); - - divertOut = socket (PF_INET, SOCK_RAW, IPPROTO_DIVERT); - if (divertOut == -1) - Quit ("Unable to create outgoing divert socket."); - - divertInOut = -1; - -/* - * Bind divert sockets. - */ - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = inPort; - - if (bind (divertIn, - (struct sockaddr*) &addr, - sizeof addr) == -1) - Quit ("Unable to bind incoming divert socket."); - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = outPort; - - if (bind (divertOut, - (struct sockaddr*) &addr, - sizeof addr) == -1) - Quit ("Unable to bind outgoing divert socket."); - } -/* - * Create routing socket if interface name specified and in dynamic mode. - */ - routeSock = -1; - if (ifName) { - if (dynamicMode) { - - routeSock = socket (PF_ROUTE, SOCK_RAW, 0); - if (routeSock == -1) - Quit ("Unable to create routing info socket."); - - assignAliasAddr = 1; - } - else{ - SetAliasAddressFromIfName (ifName); - } - } -/* - * Create socket for sending ICMP messages. - */ - icmpSock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (icmpSock == -1) - Quit ("Unable to create ICMP socket."); - - if ((fdFlags = fcntl(icmpSock, F_GETFL, 0)) == -1) - Quit ("fcntl F_GETFL ICMP socket."); - fdFlags |= O_NONBLOCK; - if (fcntl(icmpSock, F_SETFL, fdFlags) == -1) - Quit ("fcntl F_SETFL ICMP socket."); - -#if NATPORTMAP - if ( enable_natportmap ) - { - /* create socket to listen for port mapping */ - portmapSock = socket( AF_INET, SOCK_DGRAM, 0); - if ( portmapSock != -1 ) - { - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons(NATPMP_PORT); - - if (bind ( portmapSock, - (struct sockaddr*) &addr, - sizeof addr) == -1) - printf("Binding to NATPM port failed!\n"); - - /* NATPORTMAPP initial set up */ - NatPortMapPInit(); - } - if ( !Natdtimerset ){ - Natdtimerset = 1; - signal(SIGALRM, Natdtimer); - } - } -#endif /* NATPORTMAP */ - -/* - * Become a daemon unless verbose mode was requested. - */ - if (!verbose) - DaemonMode (); -/* - * Catch signals to manage shutdown and - * refresh of interface address. - */ - siginterrupt(SIGTERM, 1); - siginterrupt(SIGHUP, 1); - signal (SIGTERM, InitiateShutdown); - signal (SIGHUP, RefreshAddr); - signal (SIGINFO, HandleInfo); -/* - * Set alias address if it has been given. - */ - if (aliasAddr.s_addr != INADDR_NONE) - { - PacketAliasSetAddress (aliasAddr); -#ifdef NATPORTMAP - if ( (enable_natportmap) && (aliasAddr.s_addr != lastassignaliasAddr.s_addr) ){ - lastassignaliasAddr.s_addr = aliasAddr.s_addr; - NotifyPublicAddress(); - } -#endif - } -/* - * We need largest descriptor number for select. - */ - - fdMax = -1; - - if (divertIn > fdMax) - fdMax = divertIn; - - if (divertOut > fdMax) - fdMax = divertOut; - - if (divertInOut > fdMax) - fdMax = divertInOut; - - if (routeSock > fdMax) - fdMax = routeSock; - - if (icmpSock > fdMax) - fdMax = icmpSock; - -#ifdef NATPORTMAP - if ( portmapSock > fdMax ) - fdMax = portmapSock; - -#endif - - while (running) { - - if (divertInOut != -1 && !ifName && packetSock == -1) { -/* - * When using only one socket, just call - * DoAliasing repeatedly to process packets. - */ - DoAliasing (divertInOut, DONT_KNOW); - continue; - } -/* - * Build read mask from socket descriptors to select. - */ - FD_ZERO (&readMask); - FD_ZERO (&writeMask); - -/* - * If there is unsent packet in buffer, use select - * to check when socket comes writable again. - */ - if (packetSock != -1) { - - FD_SET (packetSock, &writeMask); - } - else { -/* - * No unsent packet exists - safe to check if - * new ones are available. - */ - if (divertIn != -1) - FD_SET (divertIn, &readMask); - - if (divertOut != -1) - FD_SET (divertOut, &readMask); - - if (divertInOut != -1) - FD_SET (divertInOut, &readMask); - - if (icmpSock != -1) - FD_SET(icmpSock, &readMask); - } -/* - * Routing info is processed always. - */ - if (routeSock != -1) - FD_SET (routeSock, &readMask); -#ifdef NATPORTMAP - if ( portmapSock != -1 ) - FD_SET (portmapSock, &readMask); -#endif - if (select (fdMax + 1, - &readMask, - &writeMask, - NULL, - NULL) == -1) { - - if (errno == EINTR) { - if (dumpinfo) { - DumpInfo(); - dumpinfo = 0; - } - continue; - } - Quit ("Select failed."); - } - - if (packetSock != -1) - if (FD_ISSET (packetSock, &writeMask)) - FlushPacketBuffer (packetSock); - - if (divertIn != -1) - if (FD_ISSET (divertIn, &readMask)) - DoAliasing (divertIn, INPUT); - - if (divertOut != -1) - if (FD_ISSET (divertOut, &readMask)) - DoAliasing (divertOut, OUTPUT); - - if (divertInOut != -1) - if (FD_ISSET (divertInOut, &readMask)) - DoAliasing (divertInOut, DONT_KNOW); - - if (routeSock != -1) - if (FD_ISSET (routeSock, &readMask)) - HandleRoutingInfo (routeSock); - - if (icmpSock != -1) - if (FD_ISSET (icmpSock, &readMask)) - DiscardIncomingPackets (icmpSock); - -#ifdef NATPORTMAP - if ( portmapSock != -1) - if (FD_ISSET (portmapSock, &readMask)) - HandlePortMap( portmapSock ); -#endif - } - - if (background) - unlink (PIDFILE); - - return 0; -} - -static void DaemonMode () -{ - FILE* pidFile; - - daemon (0, 0); - background = 1; - - pidFile = fopen (PIDFILE, "w"); - if (pidFile) { - - fprintf (pidFile, "%d\n", getpid ()); - fclose (pidFile); - } - -#ifdef DEBUG -#include - { - int fd; - - fd = open("/var/run/natd.log", O_WRONLY|O_CREAT|O_TRUNC, 0644); - if (fd >= 0) { - if (fd != STDOUT_FILENO) { - dup2(fd, STDOUT_FILENO); - close(fd); - } - dup2(STDOUT_FILENO, STDERR_FILENO); - } - } -#endif -} - -static void ParseArgs (int argc, char** argv) -{ - int arg; - char* opt; - char parmBuf[256]; - int len; /* bounds checking */ - - for (arg = 1; arg < argc; arg++) { - - opt = argv[arg]; - if (*opt != '-') { - - warnx ("invalid option %s", opt); - Usage (); - } - - parmBuf[0] = '\0'; - len = 0; - - while (arg < argc - 1) { - - if (argv[arg + 1][0] == '-') - break; - - if (len) { - strncat (parmBuf, " ", sizeof(parmBuf) - (len + 1)); - len += strlen(parmBuf + len); - } - - ++arg; - strncat (parmBuf, argv[arg], sizeof(parmBuf) - (len + 1)); - len += strlen(parmBuf + len); - - } - - ParseOption (opt + 1, (len ? parmBuf : NULL)); - - } -} - -static void DoAliasing (int fd, int direction) -{ - int bytes; - int origBytes; - int status; - socklen_t addrSize; - struct ip* ip; - - if (assignAliasAddr) { - - SetAliasAddressFromIfName (ifName); - assignAliasAddr = 0; - } -/* - * Get packet from socket. - */ - addrSize = sizeof packetAddr; - origBytes = recvfrom (fd, - packetBuf, - sizeof packetBuf, - 0, - (struct sockaddr*) &packetAddr, - &addrSize); - - if (origBytes == -1) { - - if (errno != EINTR) - Warn ("read from divert socket failed"); - - return; - } -/* - * This is a IP packet. - */ - ip = (struct ip*) packetBuf; - if (direction == DONT_KNOW) { - if (packetAddr.sin_addr.s_addr == INADDR_ANY) - direction = OUTPUT; - else - direction = INPUT; - } - - if (verbose) { -/* - * Print packet direction and protocol type. - */ - printf (direction == OUTPUT ? "Out " : "In "); - - switch (ip->ip_p) { - case IPPROTO_TCP: - printf ("[TCP] "); - break; - - case IPPROTO_UDP: - printf ("[UDP] "); - break; - - case IPPROTO_ICMP: - printf ("[ICMP] "); - break; - - default: - printf ("[%d] ", ip->ip_p); - break; - } -/* - * Print addresses. - */ - PrintPacket (ip); - } - - if (direction == OUTPUT) { -/* - * Outgoing packets. Do aliasing. - */ - PacketAliasOut (packetBuf, IP_MAXPACKET); - } - else { - -/* - * Do aliasing. - */ - status = PacketAliasIn (packetBuf, IP_MAXPACKET); - if (status == PKT_ALIAS_IGNORED && - dropIgnoredIncoming) { - - if (verbose) - printf (" dropped.\n"); - - if (logDropped) - SyslogPacket (ip, LOG_WARNING, "denied"); - - return; - } - } -/* - * Length might have changed during aliasing. - */ - bytes = ntohs (ip->ip_len); -/* - * Update alias overhead size for outgoing packets. - */ - if (direction == OUTPUT && - bytes - origBytes > aliasOverhead) - aliasOverhead = bytes - origBytes; - - if (verbose) { - -/* - * Print addresses after aliasing. - */ - printf (" aliased to\n"); - printf (" "); - PrintPacket (ip); - printf ("\n"); - } - - packetLen = bytes; - packetSock = fd; - packetDirection = direction; - - FlushPacketBuffer (fd); -} - -static void FlushPacketBuffer (int fd) -{ - int wrote; - char msgBuf[80]; -/* - * Put packet back for processing. - */ - wrote = sendto (fd, - packetBuf, - packetLen, - 0, - (struct sockaddr*) &packetAddr, - sizeof packetAddr); - - if (wrote != packetLen) { -/* - * If buffer space is not available, - * just return. Main loop will take care of - * retrying send when space becomes available. - */ - if (errno == ENOBUFS) - return; - - if (errno == EMSGSIZE) { - - if (packetDirection == OUTPUT && - ifMTU != -1) - SendNeedFragIcmp (icmpSock, - (struct ip*) packetBuf, - ifMTU - aliasOverhead); - } - else { - - snprintf (msgBuf, sizeof(msgBuf), "failed to write packet back"); - Warn (msgBuf); - } - } - - packetSock = -1; -} - -static void HandleRoutingInfo (int fd) -{ - int bytes; - struct if_msghdr ifMsg; -/* - * Get packet from socket. - */ - bytes = read (fd, &ifMsg, sizeof ifMsg); - if (bytes == -1) { - - Warn ("read from routing socket failed"); - return; - } - - if (ifMsg.ifm_version != RTM_VERSION) { - - Warn ("unexpected packet read from routing socket"); - return; - } - - if (verbose) - printf ("Routing message %#x received.\n", ifMsg.ifm_type); - - if ((ifMsg.ifm_type == RTM_NEWADDR || ifMsg.ifm_type == RTM_IFINFO) && - ifMsg.ifm_index == ifIndex) { - if (verbose) - printf("Interface address/MTU has probably changed.\n"); - assignAliasAddr = 1; - } -} - -static void DiscardIncomingPackets (int fd) -{ - struct sockaddr_in sin; - char buffer[80]; - socklen_t slen = sizeof(sin); - - while (recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr *)&sin, &slen) != -1) { - ; - } -} - -#ifdef NATPORTMAP - -void getdivisor() -{ - struct mach_timebase_info info; - - (void) mach_timebase_info (&info); - - secdivisor = ( (double)info.denom / (double)info.numer) * 1000; - -} - -uint32_t getuptime() -{ - uint64_t now; - uint32_t epochtime; - - now = mach_absolute_time(); - epochtime = (now / secdivisor) / USEC_PER_SEC; - return ( epochtime ); - -} - -/* set up neccessary info for doing NatPortMapP */ -static void NatPortMapPInit() -{ - int i; - struct ifaddrs *ifap, *ifa; - - forwardedinterfaceaddr = (struct in_addr *) - malloc(numofinterfaces * sizeof(*forwardedinterfaceaddr)); - bzero(forwardedinterfaceaddr, - numofinterfaces * sizeof(*forwardedinterfaceaddr)); - /* interface address hasn't been set up, get interface address */ - - if (getifaddrs(&ifap) == -1) - Quit ("getifaddrs failed."); - - for ( ifa= ifap; ifa; ifa=ifa->ifa_next) - { - struct sockaddr_in * a; - if (ifa->ifa_addr->sa_family != AF_INET) - { - continue; - } - a = (struct sockaddr_in *)ifa->ifa_addr; - for ( i = 0; i < numofinterfaces; i++ ) - { - if (strcmp(ifa->ifa_name, forwardedinterfacename[i])) - { - continue; - } - if (forwardedinterfaceaddr[i].s_addr == 0) - { - /* copy the first IP address */ - forwardedinterfaceaddr[i] = a->sin_addr; - } - break; - } - } - freeifaddrs( ifap ); - getdivisor(); -} - -/* SendPortMapResponse */ -/* send generic reponses to NATPORTMAP requests */ -static void SendPortMapResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, unsigned char origopcode, unsigned short result) -{ - stderrreply reply; - int bytes; - - reply.version = NATPMVERSION; - reply.opcode = origopcode + SERVERREPLYOP; - reply.result = htons(result); - reply.epoch = htonl(getuptime()); - bytes = sendto( fd, (void*)&reply, sizeof(reply), 0, (struct sockaddr*)clientaddr, clientaddrlen ); - if ( bytes != sizeof(reply) ) - printf( "PORTMAP::problem sending portmap reply - opcode %d\n", reply.opcode ); -} - -/* SendPublicAddress */ -/* return public address to requestor */ -static void SendPublicAddress( int fd, struct sockaddr_in *clientaddr, int clientaddrlen ) -{ - - publicaddrreply reply; - int bytes; - - reply.version = NATPMVERSION; - reply.opcode = SERVERREPLYOP + PUBLICADDRREQ; - reply.result = SUCCESS; - reply.addr = lastassignaliasAddr; - reply.epoch = htonl(getuptime()); - - bytes = sendto (fd, (void*)&reply, sizeof(reply), 0, (struct sockaddr*)clientaddr, clientaddrlen); - if ( bytes != sizeof(reply) ) - printf( "PORTMAP::problem sending portmap reply - opcode %d\n", reply.opcode ); -} - -/* SendPublicPortResponse */ -/* response for portmap request and portmap removal request */ -/* publicport <= 0 means error */ -static void SendPublicPortResponse( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, publicportreq *req, u_short publicport, int result) -{ - - int bytes; - publicportreply reply; - - bzero(&reply, sizeof(publicportreply)); - reply.version = NATPMVERSION; - reply.opcode = SERVERREPLYOP + req->opcode; - if (result) - /* error in port mapping */ - reply.result = htons(OUTOFRESOURCES); - else - reply.result = SUCCESS; - - reply.epoch = htonl(getuptime()); - - reply.privateport = req->privateport; - - /* adding or renewing a mapping */ - if ( req->lifetime ) { - reply.publicport = publicport; - reply.lifetime = req->lifetime; - } - bytes = sendto (fd, (void*)&reply, sizeof(publicportreply), 0, (struct sockaddr*)clientaddr, clientaddrlen); - if ( bytes != sizeof(publicportreply) ) - printf( "PORTMAP::problem sending portmap reply - opcode %d\n", req->opcode ); -} - -/* SendPortMapMulti */ -/* send multicast to local network for new alias address */ -static void SendPortMapMulti() -{ - - publicaddrreply reply; - int bytes; - struct sockaddr_in multiaddr; - int multisock; - int i; - -#define LOCALGROUP "224.0.0.1" - numoftries++; - memset(&multiaddr,0,sizeof(struct sockaddr_in)); - multiaddr.sin_family=AF_INET; - multiaddr.sin_addr.s_addr=inet_addr(LOCALGROUP); - multiaddr.sin_port=htons(NATPMP_ANNOUNCEMENT_PORT); - reply.version = NATPMVERSION; - reply.opcode = SERVERREPLYOP + PUBLICADDRREQ; - reply.result = SUCCESS; - reply.addr = lastassignaliasAddr; - reply.epoch = 0; - - /* send multicast to all forwarded interfaces */ - for ( i = 0; i < numofinterfaces; i++) - { - if (forwardedinterfaceaddr[i].s_addr == 0) - { - continue; - } - multisock = socket( AF_INET, SOCK_DGRAM, 0); - - if ( multisock == -1 ) - { - printf("cannot get socket for sending multicast\n"); - return; - } - if (setsockopt(multisock, IPPROTO_IP, IP_MULTICAST_IF, &forwardedinterfaceaddr[i], sizeof(struct in_addr)) < 0) - { - printf("setsockopt failed\n"); - close(multisock); - continue; - } - bytes = sendto (multisock, (void*)&reply, sizeof(reply), 0, (struct sockaddr*)&multiaddr, sizeof(multiaddr)); - if ( bytes != sizeof(reply) ) - printf( "PORTMAP::problem sending multicast alias address - opcode %d\n", reply.opcode ); - close(multisock); - } - -} - -/* double the time value */ -static void Doubletime( struct timeval *tvp) -{ - - timeradd(tvp, tvp, tvp); - -} - -/* stop running natd timer */ -static void Stoptimer() -{ - itval.it_value.tv_sec = 0; - itval.it_value.tv_usec = 0; - if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) - printf( "setitimer err: %d\n", errno); -} - -/* natdtimer */ -/* timer routine to send new public IP address */ -static void Natdtimer() -{ - if ( !enable_natportmap ) - return; - - SendPortMapMulti(); - - if ( numoftries < MAXRETRY ){ - Doubletime( &itval.it_value); - itval.it_interval.tv_sec = 0; - itval.it_interval.tv_usec = 0; - if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) - printf( "setitimer err: %d\n", errno); - } - else - { - Stoptimer(); - return; - } - -} - -/* NotifyPublicAddress */ -/* Advertise new public address */ -static void NotifyPublicAddress() -{ - if ( numoftries < MAXRETRY) - { - /* there is an old timer running, cancel it */ - Stoptimer(); - } - /* send up new timer */ - numoftries = 0; - SendPortMapMulti(); - itval.it_value.tv_sec = 0; - itval.it_value.tv_usec = TIMER_RATE; - itval.it_interval.tv_sec = 0; - itval.it_interval.tv_usec = 0; - if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) - printf( "setitimer err: %d\n", errno); - -} - -/* DoPortMapping */ -/* find/add/remove port mapping from alias manager */ -void DoPortMapping( int fd, struct sockaddr_in *clientaddr, int clientaddrlen, publicportreq *req) -{ - u_char proto = IPPROTO_TCP; - int aliasport; - struct in_addr inany = { INADDR_ANY }; - - if ( req->opcode == MAPUDPREQ) - proto = IPPROTO_UDP; - if ( req->lifetime == 0) - { - /* remove port mapping */ - if ( !FindAliasPortOut( clientaddr->sin_addr, - inany, - req->privateport, - req->publicport, - proto, - ntohl(req->lifetime), - 0) ) - /* FindAliasPortOut returns no error, port successfully removed, return no error response to client */ - SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, 0, 0 ); - else - /* deleting port fails, return error */ - SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, 0, -1 ); - } - else - { - /* look for port mapping - public port is ignored in this case */ - /* create port mapping - map provided public port to private port if public port is not 0 */ - aliasport = FindAliasPortOut( clientaddr->sin_addr, - inany, /* lastassignaliasAddr */ - req->privateport, - 0, - proto, - ntohl(req->lifetime), - 1); - /* aliasport should be non zero if mapping is successfully, else -1 is returned, alias port shouldn't be zero???? */ - SendPublicPortResponse( fd, clientaddr, clientaddrlen, req, aliasport, 0 ); - - } -} - -/* HandlePortMap */ -/* handle all packets sent to NATPORTMAP port */ -static void HandlePortMap( int fd ) -{ - #define MAXBUFFERSIZE 100 - - struct sockaddr_in clientaddr; - socklen_t clientaddrlen; - unsigned char buffer[MAXBUFFERSIZE]; - int bytes; - unsigned short result = SUCCESS; - struct stdportmaprequest *req; - - clientaddrlen = sizeof( clientaddr ); - bytes = recvfrom( fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&clientaddr, &clientaddrlen); - if ( bytes == -1 ) - { - printf( "Read NATPM port error\n"); - return; - } - else if ( bytes < sizeof(stdportmaprequest) ) - { - /* drop any requests that are too short */ - return; - } - - req = (struct stdportmaprequest*)buffer; - - #ifdef DEBUG - { - int i; - - printf("HandlePortMap from %s:%u length= %d: ", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, bytes); - for ( i = 0; iopcode >= SERVERREPLYOP ) - { - return; - } - - /* check client version */ - if ( req->version > NATPMVERSION ) - result = NOTSUPPORTEDVERSION; - else if ( !enable_natportmap ) - /* natd wasn't launched with portmapping enabled */ - result = NOTAUTHORIZED; - - if ( result ) - { - SendPortMapResponse( fd, &clientaddr, clientaddrlen, req->opcode, result ); - return; - } - - switch ( req->opcode ) - { - case PUBLICADDRREQ: - { - if ( bytes == sizeof(stdportmaprequest) ) - SendPublicAddress(fd, &clientaddr, clientaddrlen); - break; - } - - case MAPUDPREQ: - case MAPTCPREQ: - case MAPUDPTCPREQ: - { - if ( bytes == sizeof(publicportreq) ) - DoPortMapping( fd, &clientaddr, clientaddrlen, (publicportreq*)req); - break; - } - - - default: - SendPortMapResponse( fd, &clientaddr, clientaddrlen, req->opcode, UNSUPPORTEDOPCODE ); - } - -} - -#endif /* NATPORTMAP */ - -static void PrintPacket (struct ip* ip) -{ - printf ("%s", FormatPacket (ip)); -} - -static void SyslogPacket (struct ip* ip, int priority, const char *label) -{ - syslog (priority, "%s %s", label, FormatPacket (ip)); -} - -static char* FormatPacket (struct ip* ip) -{ - static char buf[256]; - struct tcphdr* tcphdr; - struct udphdr* udphdr; - struct icmp* icmphdr; - char src[20]; - char dst[20]; - - strlcpy (src, inet_ntoa (ip->ip_src), sizeof(src)); - strlcpy (dst, inet_ntoa (ip->ip_dst), sizeof(dst)); - - switch (ip->ip_p) { - case IPPROTO_TCP: - tcphdr = (struct tcphdr*) ((char*) ip + (ip->ip_hl << 2)); - snprintf (buf, sizeof(buf), "[TCP] %s:%d -> %s:%d", - src, - ntohs (tcphdr->th_sport), - dst, - ntohs (tcphdr->th_dport)); - break; - - case IPPROTO_UDP: - udphdr = (struct udphdr*) ((char*) ip + (ip->ip_hl << 2)); - snprintf (buf, sizeof(buf), "[UDP] %s:%d -> %s:%d", - src, - ntohs (udphdr->uh_sport), - dst, - ntohs (udphdr->uh_dport)); - break; - - case IPPROTO_ICMP: - icmphdr = (struct icmp*) ((char*) ip + (ip->ip_hl << 2)); - snprintf (buf, sizeof(buf), "[ICMP] %s -> %s %u(%u)", - src, - dst, - icmphdr->icmp_type, - icmphdr->icmp_code); - break; - - default: - snprintf (buf, sizeof(buf), "[%d] %s -> %s ", ip->ip_p, src, dst); - break; - } - - return buf; -} - -static void -SetAliasAddressFromIfName(const char *ifn) -{ - size_t needed; - int mib[6]; - char *buf, *lim, *next; - struct if_msghdr *ifm; - struct ifa_msghdr *ifam; - struct sockaddr_dl *sdl; - struct sockaddr_in *sin; - - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; - mib[3] = AF_INET; /* Only IP addresses please */ - mib[4] = NET_RT_IFLIST; - mib[5] = 0; /* ifIndex??? */ -/* - * Get interface data. - */ - if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) - err(1, "iflist-sysctl-estimate"); - if ((buf = malloc(needed)) == NULL) - errx(1, "malloc failed"); - if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) - err(1, "iflist-sysctl-get"); - lim = buf + needed; -/* - * Loop through interfaces until one with - * given name is found. This is done to - * find correct interface index for routing - * message processing. - */ - ifIndex = 0; - next = buf; - while (next < lim) { - ifm = (struct if_msghdr *)next; - next += ifm->ifm_msglen; - if (ifm->ifm_version != RTM_VERSION) { - if (verbose) - warnx("routing message version %d " - "not understood", ifm->ifm_version); - continue; - } - if (ifm->ifm_type == RTM_IFINFO) { - sdl = (struct sockaddr_dl *)(ifm + 1); - if (strlen(ifn) == sdl->sdl_nlen && - strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) { - ifIndex = ifm->ifm_index; - ifMTU = ifm->ifm_data.ifi_mtu; - if (clampMSS) - PacketAliasClampMSS(ifMTU - sizeof(struct tcphdr) - sizeof(struct ip)); - break; - } - } - } - if (!ifIndex) - errx(1, "unknown interface name %s", ifn); -/* - * Get interface address. - */ - if (aliasAddr.s_addr == INADDR_NONE) { - sin = NULL; - while (next < lim) { - ifam = (struct ifa_msghdr *)next; - next += ifam->ifam_msglen; - if (ifam->ifam_version != RTM_VERSION) { - if (verbose) - warnx("routing message version %d " - "not understood", ifam->ifam_version); - continue; - } - if (ifam->ifam_type != RTM_NEWADDR) - break; - if (ifam->ifam_addrs & RTA_IFA) { - int i; - char *cp = (char *)(ifam + 1); - -#define ROUNDUP(a) \ - ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t)) -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) - - for (i = 1; i < RTA_IFA; i <<= 1) - if (ifam->ifam_addrs & i) - ADVANCE(cp, (struct sockaddr *)cp); - if (((struct sockaddr *)cp)->sa_family == AF_INET) { - sin = (struct sockaddr_in *)cp; - break; - } - } - } - if (sin == NULL) - errx(1, "%s: cannot get interface address", ifn); - - PacketAliasSetAddress(sin->sin_addr); -#ifdef NATPORTMAP - if ( (enable_natportmap) && (sin->sin_addr.s_addr != lastassignaliasAddr.s_addr) ) - { - lastassignaliasAddr.s_addr = sin->sin_addr.s_addr; - /* make sure the timer handler was set before setting timer */ - if ( !Natdtimerset ){ - Natdtimerset = 1; - signal(SIGALRM, Natdtimer); - } - NotifyPublicAddress(); - } -#endif - syslog(LOG_INFO, "Aliasing to %s, mtu %d bytes", - inet_ntoa(sin->sin_addr), ifMTU); - } - - free(buf); -} - -void Quit (const char* msg) -{ - Warn (msg); - exit (1); -} - -void Warn (const char* msg) -{ - if (background) - syslog (LOG_ALERT, "%s (%m)", msg); - else - warn ("%s", msg); -} - -static void RefreshAddr (int sig) -{ - if (ifName) - assignAliasAddr = 1; -} - -static void InitiateShutdown (int sig) -{ -/* - * Start timer to allow kernel gracefully - * shutdown existing connections when system - * is shut down. - */ - siginterrupt(SIGALRM, 1); - signal (SIGALRM, Shutdown); - alarm (10); -} - -static void Shutdown (int sig) -{ - running = 0; -} - -static void HandleInfo (int sig) -{ - dumpinfo++; -} - -/* - * Different options recognized by this program. - */ - -enum Option { - - PacketAliasOption, - Verbose, - InPort, - OutPort, - Port, - AliasAddress, - TargetAddress, - InterfaceName, - RedirectPort, - RedirectProto, - RedirectAddress, - ConfigFile, - DynamicMode, - ClampMSS, - ProxyRule, - LogDenied, - LogFacility, - PunchFW, -#ifdef NATPORTMAP - NATPortMap, - ToInterfaceName -#endif -}; - -enum Param { - - YesNo, - Numeric, - String, - None, - Address, - Service -}; - -/* - * Option information structure (used by ParseOption). - */ - -struct OptionInfo { - - enum Option type; - int packetAliasOpt; - enum Param parm; - const char* parmDescription; - const char* description; - const char* name; - const char* shortName; -}; - -/* - * Table of known options. - */ - -static struct OptionInfo optionTable[] = { - - { PacketAliasOption, - PKT_ALIAS_UNREGISTERED_ONLY, - YesNo, - "[yes|no]", - "alias only unregistered addresses", - "unregistered_only", - "u" }, - - { PacketAliasOption, - PKT_ALIAS_LOG, - YesNo, - "[yes|no]", - "enable logging", - "log", - "l" }, - - { PacketAliasOption, - PKT_ALIAS_PROXY_ONLY, - YesNo, - "[yes|no]", - "proxy only", - "proxy_only", - NULL }, - - { PacketAliasOption, - PKT_ALIAS_REVERSE, - YesNo, - "[yes|no]", - "operate in reverse mode", - "reverse", - NULL }, - - { PacketAliasOption, - PKT_ALIAS_DENY_INCOMING, - YesNo, - "[yes|no]", - "allow incoming connections", - "deny_incoming", - "d" }, - - { PacketAliasOption, - PKT_ALIAS_USE_SOCKETS, - YesNo, - "[yes|no]", - "use sockets to inhibit port conflict", - "use_sockets", - "s" }, - - { PacketAliasOption, - PKT_ALIAS_SAME_PORTS, - YesNo, - "[yes|no]", - "try to keep original port numbers for connections", - "same_ports", - "m" }, - - { Verbose, - 0, - YesNo, - "[yes|no]", - "verbose mode, dump packet information", - "verbose", - "v" }, - - { DynamicMode, - 0, - YesNo, - "[yes|no]", - "dynamic mode, automatically detect interface address changes", - "dynamic", - NULL }, - - { ClampMSS, - 0, - YesNo, - "[yes|no]", - "enable TCP MSS clamping", - "clamp_mss", - NULL }, - - { InPort, - 0, - Service, - "number|service_name", - "set port for incoming packets", - "in_port", - "i" }, - - { OutPort, - 0, - Service, - "number|service_name", - "set port for outgoing packets", - "out_port", - "o" }, - - { Port, - 0, - Service, - "number|service_name", - "set port (defaults to natd/divert)", - "port", - "p" }, - - { AliasAddress, - 0, - Address, - "x.x.x.x", - "address to use for aliasing", - "alias_address", - "a" }, - - { TargetAddress, - 0, - Address, - "x.x.x.x", - "address to use for incoming sessions", - "target_address", - "t" }, - - { InterfaceName, - 0, - String, - "network_if_name", - "take aliasing address from interface", - "interface", - "n" }, - - { ProxyRule, - 0, - String, - "[type encode_ip_hdr|encode_tcp_stream] port xxxx server " - "a.b.c.d:yyyy", - "add transparent proxying / destination NAT", - "proxy_rule", - NULL }, - - { RedirectPort, - 0, - String, - "tcp|udp local_addr:local_port_range[,...] [public_addr:]public_port_range" - " [remote_addr[:remote_port_range]]", - "redirect a port (or ports) for incoming traffic", - "redirect_port", - NULL }, - - { RedirectProto, - 0, - String, - "proto local_addr [public_addr] [remote_addr]", - "redirect packets of a given proto", - "redirect_proto", - NULL }, - - { RedirectAddress, - 0, - String, - "local_addr[,...] public_addr", - "define mapping between local and public addresses", - "redirect_address", - NULL }, - - { ConfigFile, - 0, - String, - "file_name", - "read options from configuration file", - "config", - "f" }, - - { LogDenied, - 0, - YesNo, - "[yes|no]", - "enable logging of denied incoming packets", - "log_denied", - NULL }, - - { LogFacility, - 0, - String, - "facility", - "name of syslog facility to use for logging", - "log_facility", - NULL }, - - { PunchFW, - 0, - String, - "basenumber:count", - "punch holes in the firewall for incoming FTP/IRC DCC connections", - "punch_fw", - NULL }, - -#ifdef NATPORTMAP - { NATPortMap, - 0, - YesNo, - "[yes|no]", - "enable NATPortMap protocol", - "enable_natportmap", - NULL }, - - { ToInterfaceName, - 0, - String, - "network_if_name", - "take aliasing address to interface", - "natportmap_interface", - NULL }, - -#endif -}; - -static void ParseOption (const char* option, const char* parms) -{ - int i; - struct OptionInfo* info; - int yesNoValue; - int aliasValue; - int numValue; - u_short uNumValue; - const char* strValue; - struct in_addr addrValue; - int max; - char* end; - CODE* fac_record = NULL; -/* - * Find option from table. - */ - max = sizeof (optionTable) / sizeof (struct OptionInfo); - for (i = 0, info = optionTable; i < max; i++, info++) { - - if (!strcmp (info->name, option)) - break; - - if (info->shortName) - if (!strcmp (info->shortName, option)) - break; - } - - if (i >= max) { - - warnx ("unknown option %s", option); - Usage (); - } - - uNumValue = 0; - yesNoValue = 0; - numValue = 0; - strValue = NULL; -/* - * Check parameters. - */ - switch (info->parm) { - case YesNo: - if (!parms) - parms = "yes"; - - if (!strcmp (parms, "yes")) - yesNoValue = 1; - else - if (!strcmp (parms, "no")) - yesNoValue = 0; - else - errx (1, "%s needs yes/no parameter", option); - break; - - case Service: - if (!parms) - errx (1, "%s needs service name or " - "port number parameter", - option); - - uNumValue = StrToPort (parms, "divert"); - break; - - case Numeric: - if (parms) - numValue = strtol (parms, &end, 10); - else - end = NULL; - - if (end == parms) - errx (1, "%s needs numeric parameter", option); - break; - - case String: - strValue = parms; - if (!strValue) - errx (1, "%s needs parameter", option); - break; - - case None: - if (parms) - errx (1, "%s does not take parameters", option); - break; - - case Address: - if (!parms) - errx (1, "%s needs address/host parameter", option); - - StrToAddr (parms, &addrValue); - break; - } - - switch (info->type) { - case PacketAliasOption: - - aliasValue = yesNoValue ? info->packetAliasOpt : 0; - PacketAliasSetMode (aliasValue, info->packetAliasOpt); - break; - - case Verbose: - verbose = yesNoValue; - break; - - case DynamicMode: - dynamicMode = yesNoValue; - break; - - case ClampMSS: - clampMSS = yesNoValue; - break; - - case InPort: - inPort = uNumValue; - break; - - case OutPort: - outPort = uNumValue; - break; - - case Port: - inOutPort = uNumValue; - break; - - case AliasAddress: - memcpy (&aliasAddr, &addrValue, sizeof (struct in_addr)); - break; - - case TargetAddress: - PacketAliasSetTarget(addrValue); - break; - - case RedirectPort: - SetupPortRedirect (strValue); - break; - - case RedirectProto: - SetupProtoRedirect(strValue); - break; - - case RedirectAddress: - SetupAddressRedirect (strValue); - break; - - case ProxyRule: - PacketAliasProxyRule (strValue); - break; - - case InterfaceName: - if (ifName) - free (ifName); - - ifName = strdup (strValue); - break; - - case ConfigFile: - ReadConfigFile (strValue); - break; - - case LogDenied: - logDropped = 1; - break; - - case LogFacility: - - fac_record = facilitynames; - while (fac_record->c_name != NULL) { - - if (!strcmp (fac_record->c_name, strValue)) { - - logFacility = fac_record->c_val; - break; - - } - else - fac_record++; - } - - if(fac_record->c_name == NULL) - errx(1, "Unknown log facility name: %s", strValue); - - break; - - case PunchFW: - SetupPunchFW(strValue); - break; - -#ifdef NATPORTMAP - case NATPortMap: - enable_natportmap = yesNoValue; - break; - - - case ToInterfaceName: - { - if (forwardedinterfacename != NULL) - { - if ( (forwardedinterfacename = realloc( forwardedinterfacename, (numofinterfaces+1) * sizeof(*forwardedinterfacename ))) == NULL ){ - printf("realloc error, cannot allocate memory for fowarded interface name.\n"); - return; - } - } - else { - if ( (forwardedinterfacename = malloc( sizeof(*forwardedinterfacename) )) == NULL ){ - printf("malloc error, cannot allocate memory for fowarded interface name.\n"); - return; - } - } - - forwardedinterfacename[numofinterfaces] = strdup(strValue); - numofinterfaces++; - - break; - } - -#endif - - } -} - -void ReadConfigFile (const char* fileName) -{ - FILE* file; - char *buf; - size_t len; - char *ptr, *p; - char* option; - - file = fopen (fileName, "r"); - if (!file) - err(1, "cannot open config file %s", fileName); - - while ((buf = fgetln(file, &len)) != NULL) { - if (buf[len - 1] == '\n') - buf[len - 1] = '\0'; - else - errx(1, "config file format error: " - "last line should end with newline"); - -/* - * Check for comments, strip off trailing spaces. - */ - if ((ptr = strchr(buf, '#'))) - *ptr = '\0'; - for (ptr = buf; isspace(*ptr); ++ptr) - continue; - if (*ptr == '\0') - continue; - for (p = strchr(buf, '\0'); isspace(*--p);) - continue; - *++p = '\0'; - -/* - * Extract option name. - */ - option = ptr; - while (*ptr && !isspace (*ptr)) - ++ptr; - - if (*ptr != '\0') { - - *ptr = '\0'; - ++ptr; - } -/* - * Skip white space between name and parms. - */ - while (*ptr && isspace (*ptr)) - ++ptr; - - ParseOption (option, *ptr ? ptr : NULL); - } - - fclose (file); -} - -static void Usage () -{ - int i; - int max; - struct OptionInfo* info; - - fprintf (stderr, "Recognized options:\n\n"); - - max = sizeof (optionTable) / sizeof (struct OptionInfo); - for (i = 0, info = optionTable; i < max; i++, info++) { - - fprintf (stderr, "-%-20s %s\n", info->name, - info->parmDescription); - - if (info->shortName) - fprintf (stderr, "-%-20s %s\n", info->shortName, - info->parmDescription); - - fprintf (stderr, " %s\n\n", info->description); - } - - exit (1); -} - -void SetupPortRedirect (const char* parms) -{ - char buf[128]; - char* ptr; - char* serverPool; - struct in_addr localAddr; - struct in_addr publicAddr; - struct in_addr remoteAddr; - port_range portRange; - u_short localPort = 0; - u_short publicPort = 0; - u_short remotePort = 0; - u_short numLocalPorts = 0; - u_short numPublicPorts = 0; - u_short numRemotePorts = 0; - int proto; - char* protoName; - char* separator; - int i; - struct alias_link *link = NULL; - - strlcpy (buf, parms, sizeof(buf)); -/* - * Extract protocol. - */ - protoName = strtok (buf, " \t"); - if (!protoName) - errx (1, "redirect_port: missing protocol"); - - proto = StrToProto (protoName); -/* - * Extract local address. - */ - ptr = strtok (NULL, " \t"); - if (!ptr) - errx (1, "redirect_port: missing local address"); - - separator = strchr(ptr, ','); - if (separator) { /* LSNAT redirection syntax. */ - localAddr.s_addr = INADDR_NONE; - localPort = ~0; - numLocalPorts = 1; - serverPool = ptr; - } else { - if ( StrToAddrAndPortRange (ptr, &localAddr, protoName, &portRange) != 0 ) - errx (1, "redirect_port: invalid local port range"); - - localPort = GETLOPORT(portRange); - numLocalPorts = GETNUMPORTS(portRange); - serverPool = NULL; - } - -/* - * Extract public port and optionally address. - */ - ptr = strtok (NULL, " \t"); - if (!ptr) - errx (1, "redirect_port: missing public port"); - - separator = strchr (ptr, ':'); - if (separator) { - if (StrToAddrAndPortRange (ptr, &publicAddr, protoName, &portRange) != 0 ) - errx (1, "redirect_port: invalid public port range"); - } - else { - publicAddr.s_addr = INADDR_ANY; - if (StrToPortRange (ptr, protoName, &portRange) != 0) - errx (1, "redirect_port: invalid public port range"); - } - - publicPort = GETLOPORT(portRange); - numPublicPorts = GETNUMPORTS(portRange); - -/* - * Extract remote address and optionally port. - */ - ptr = strtok (NULL, " \t"); - if (ptr) { - separator = strchr (ptr, ':'); - if (separator) { - if (StrToAddrAndPortRange (ptr, &remoteAddr, protoName, &portRange) != 0) - errx (1, "redirect_port: invalid remote port range"); - } else { - SETLOPORT(portRange, 0); - SETNUMPORTS(portRange, 1); - StrToAddr (ptr, &remoteAddr); - } - } - else { - SETLOPORT(portRange, 0); - SETNUMPORTS(portRange, 1); - remoteAddr.s_addr = INADDR_ANY; - } - - remotePort = GETLOPORT(portRange); - numRemotePorts = GETNUMPORTS(portRange); - -/* - * Make sure port ranges match up, then add the redirect ports. - */ - if (numLocalPorts != numPublicPorts) - errx (1, "redirect_port: port ranges must be equal in size"); - - /* Remote port range is allowed to be '0' which means all ports. */ - if (numRemotePorts != numLocalPorts && (numRemotePorts != 1 || remotePort != 0)) - errx (1, "redirect_port: remote port must be 0 or equal to local port range in size"); - - for (i = 0 ; i < numPublicPorts ; ++i) { - /* If remotePort is all ports, set it to 0. */ - u_short remotePortCopy = remotePort + i; - if (numRemotePorts == 1 && remotePort == 0) - remotePortCopy = 0; - - link = PacketAliasRedirectPort (localAddr, - htons(localPort + i), - remoteAddr, - htons(remotePortCopy), - publicAddr, - htons(publicPort + i), - proto); - } - -/* - * Setup LSNAT server pool. - */ - if (serverPool != NULL && link != NULL) { - ptr = strtok(serverPool, ","); - while (ptr != NULL) { - if (StrToAddrAndPortRange(ptr, &localAddr, protoName, &portRange) != 0) - errx(1, "redirect_port: invalid local port range"); - - localPort = GETLOPORT(portRange); - if (GETNUMPORTS(portRange) != 1) - errx(1, "redirect_port: local port must be single in this context"); - PacketAliasAddServer(link, localAddr, htons(localPort)); - ptr = strtok(NULL, ","); - } - } -} - -void -SetupProtoRedirect(const char* parms) -{ - char buf[128]; - char* ptr; - struct in_addr localAddr; - struct in_addr publicAddr; - struct in_addr remoteAddr; - int proto; - char* protoName; - struct protoent *protoent; - - strlcpy (buf, parms, sizeof(buf)); -/* - * Extract protocol. - */ - protoName = strtok(buf, " \t"); - if (!protoName) - errx(1, "redirect_proto: missing protocol"); - - protoent = getprotobyname(protoName); - if (protoent == NULL) - errx(1, "redirect_proto: unknown protocol %s", protoName); - else - proto = protoent->p_proto; -/* - * Extract local address. - */ - ptr = strtok(NULL, " \t"); - if (!ptr) - errx(1, "redirect_proto: missing local address"); - else - StrToAddr(ptr, &localAddr); -/* - * Extract optional public address. - */ - ptr = strtok(NULL, " \t"); - if (ptr) - StrToAddr(ptr, &publicAddr); - else - publicAddr.s_addr = INADDR_ANY; -/* - * Extract optional remote address. - */ - ptr = strtok(NULL, " \t"); - if (ptr) - StrToAddr(ptr, &remoteAddr); - else - remoteAddr.s_addr = INADDR_ANY; -/* - * Create aliasing link. - */ - (void)PacketAliasRedirectProto(localAddr, remoteAddr, publicAddr, - proto); -} - -void SetupAddressRedirect (const char* parms) -{ - char buf[128]; - char* ptr; - char* separator; - struct in_addr localAddr; - struct in_addr publicAddr; - char* serverPool; - struct alias_link *link; - - strlcpy (buf, parms, sizeof(buf)); -/* - * Extract local address. - */ - ptr = strtok (buf, " \t"); - if (!ptr) - errx (1, "redirect_address: missing local address"); - - separator = strchr(ptr, ','); - if (separator) { /* LSNAT redirection syntax. */ - localAddr.s_addr = INADDR_NONE; - serverPool = ptr; - } else { - StrToAddr (ptr, &localAddr); - serverPool = NULL; - } -/* - * Extract public address. - */ - ptr = strtok (NULL, " \t"); - if (!ptr) - errx (1, "redirect_address: missing public address"); - - StrToAddr (ptr, &publicAddr); - link = PacketAliasRedirectAddr(localAddr, publicAddr); - -/* - * Setup LSNAT server pool. - */ - if (serverPool != NULL && link != NULL) { - ptr = strtok(serverPool, ","); - while (ptr != NULL) { - StrToAddr(ptr, &localAddr); - PacketAliasAddServer(link, localAddr, htons(~0)); - ptr = strtok(NULL, ","); - } - } -} - -void StrToAddr (const char* str, struct in_addr* addr) -{ - struct hostent* hp; - - if (inet_aton (str, addr)) - return; - - hp = gethostbyname (str); - if (!hp) - errx (1, "unknown host %s", str); - - memcpy (addr, hp->h_addr, sizeof (struct in_addr)); -} - -u_short StrToPort (const char* str, const char* proto) -{ - u_short port; - struct servent* sp; - char* end; - - port = strtol (str, &end, 10); - if (end != str) - return htons (port); - - sp = getservbyname (str, proto); - if (!sp) - errx (1, "unknown service %s/%s", str, proto); - - return sp->s_port; -} - -int StrToPortRange (const char* str, const char* proto, port_range *portRange) -{ - char* sep; - struct servent* sp; - char* end; - u_short loPort; - u_short hiPort; - - /* First see if this is a service, return corresponding port if so. */ - sp = getservbyname (str,proto); - if (sp) { - SETLOPORT(*portRange, ntohs(sp->s_port)); - SETNUMPORTS(*portRange, 1); - return 0; - } - - /* Not a service, see if it's a single port or port range. */ - sep = strchr (str, '-'); - if (sep == NULL) { - SETLOPORT(*portRange, strtol(str, &end, 10)); - if (end != str) { - /* Single port. */ - SETNUMPORTS(*portRange, 1); - return 0; - } - - /* Error in port range field. */ - errx (1, "unknown service %s/%s", str, proto); - } - - /* Port range, get the values and sanity check. */ - sscanf (str, "%hu-%hu", &loPort, &hiPort); - SETLOPORT(*portRange, loPort); - SETNUMPORTS(*portRange, 0); /* Error by default */ - if (loPort <= hiPort) - SETNUMPORTS(*portRange, hiPort - loPort + 1); - - if (GETNUMPORTS(*portRange) == 0) - errx (1, "invalid port range %s", str); - - return 0; -} - - -int StrToProto (const char* str) -{ - if (!strcmp (str, "tcp")) - return IPPROTO_TCP; - - if (!strcmp (str, "udp")) - return IPPROTO_UDP; - - errx (1, "unknown protocol %s. Expected tcp or udp", str); -} - -int StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange) -{ - char* ptr; - - ptr = strchr (str, ':'); - if (!ptr) - errx (1, "%s is missing port number", str); - - *ptr = '\0'; - ++ptr; - - StrToAddr (str, addr); - return StrToPortRange (ptr, proto, portRange); -} - -static void -SetupPunchFW(const char *strValue) -{ - unsigned int base, num; - - if (sscanf(strValue, "%u:%u", &base, &num) != 2) - errx(1, "punch_fw: basenumber:count parameter required"); - - PacketAliasSetFWBase(base, num); - (void)PacketAliasSetMode(PKT_ALIAS_PUNCH_FW, PKT_ALIAS_PUNCH_FW); -} diff --git a/natd.tproj/natd.cf.sample b/natd.tproj/natd.cf.sample deleted file mode 100644 index db33c28..0000000 --- a/natd.tproj/natd.cf.sample +++ /dev/null @@ -1,92 +0,0 @@ -# -# $FreeBSD: src/sbin/natd/samples/natd.cf.sample,v 1.5 1999/09/13 18:18:33 ru Exp $ -# -# -# Configuration file for natd. -# -# -# Enable logging to file /var/log/alias.log -# -log no -# -# Incoming connections. Should NEVER be set to "yes" if redirect_port -# or redirect_address statements are activated in this file! -# -# Setting to yes provides additional anti-crack protection -# -deny_incoming no -# -# Use sockets to avoid port clashes. Uses additional system resources, but -# guarantees successful connections when port numbers conflict -# -use_sockets no -# -# Avoid port changes if possible when altering outbound packets. Makes rlogin -# work in most cases. -# -same_ports yes -# -# Verbose mode. Enables dumping of packets and disables -# forking to background. Only set to yes for debugging. -# -verbose no -# -# Divert port. Can be a name in /etc/services or numeric value. -# -port 32000 -# -# Interface name or address being aliased. Either one, -# not both is required. -# -# Obtain interface name from the command output of "ifconfig -a" -# -# alias_address 192.168.0.1 -interface ep0 -# -# Alias unregistered addresses or all addresses. Set this to yes if -# the inside network is all RFC1918 addresses. -# -unregistered_only no -# -# Configure permanent links. If you use host names instead -# of addresses here, be sure that name server works BEFORE -# natd is up - this is usually not the case. So either use -# numeric addresses or hosts that are in /etc/hosts. -# -# Note: Current versions of FreeBSD all call /etc/rc.firewall -# BEFORE running named, so if the DNS server and NAT are on the same -# machine, the nameserver won't be up if natd is called from /etc/rc.firewall -# -# Map connections coming to port 30000 to telnet in my_private_host. -# Remember to allow the connection /etc/rc.firewall also. -# -#redirect_port tcp my_private_host:telnet 30000 -# -# Map connections coming from host.xyz.com to port 30001 to -# telnet in another_host. -#redirect_port tcp another_host:telnet 30001 host.xyz.com -# -# Static NAT address mapping: -# -# ipconfig must apply any legal IP numbers that inside hosts -# will be known by to the outside interface. These are sometimes known as -# virtual IP numbers. It's suggested to use the "interface" directive -# instead of the "alias_address" directive to make it more clear what is -# going on. (although both will work) -# -# DNS in this situation can get hairy. For example, an inside host -# named aweb.company.com is located at 192.168.1.56, and needs to be -# accessible through a legal IP number like 198.105.232.1. If both -# 192.168.1.56 and 198.105.232.1 are set up as address records in the DNS -# for aweb.company.com, then external hosts attempting to access -# aweb.company.com may use address 192.168.1.56 which is inaccessible to them. -# -# The obvious solution is to use only a single address for the name, the -# outside address. However, this creates needless traffic through the -# NAT, because inside hosts will go through the NAT to get to the legal -# number, even when the inside number is on the same subnet as they are! -# -# It's probably not a good idea to use DNS names in redirect_address statements -# -#The following mapping points outside address 198.105.232.1 to 192.168.1.56 -#redirect_address 192.168.1.56 198.105.232.1 diff --git a/natd.tproj/natd.h b/natd.tproj/natd.h deleted file mode 100644 index f2c1f26..0000000 --- a/natd.tproj/natd.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * natd - Network Address Translation Daemon for FreeBSD. - * - * This software is provided free of charge, with no - * warranty of any kind, either expressed or implied. - * Use at your own risk. - * - * You may copy, modify and distribute this software (natd.h) freely. - * - * Ari Suutari - * - * Based upon: - * $FreeBSD: src/sbin/natd/natd.h,v 1.4 1999/08/28 00:13:46 peter Exp $ - */ - -#define PIDFILE "/var/run/natd.pid" -#define INPUT 1 -#define OUTPUT 2 -#define DONT_KNOW 3 - -extern void Quit (const char* msg); -extern void Warn (const char* msg); -extern int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu); - - diff --git a/natd.tproj/natd.test b/natd.tproj/natd.test deleted file mode 100644 index cfdbd15..0000000 --- a/natd.tproj/natd.test +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - - if [ $# != 1 ] - then - echo "usage: natd.test ifname" - exit 1 - fi - - ipfw flush - ipfw add divert 32000 ip from any to any via $1 - ipfw add pass ip from any to any - - ./natd -port 32000 -interface $1 -verbose - diff --git a/netstat.tproj/if.c b/netstat.tproj/if.c index a0ef208..5d82d82 100644 --- a/netstat.tproj/if.c +++ b/netstat.tproj/if.c @@ -129,14 +129,6 @@ struct queue_stats { unsigned int handle; }; -static void print_cbqstats(int slot, struct cbq_classstats *, - struct queue_stats *); -static void print_priqstats(int slot, struct priq_classstats *, - struct queue_stats *); -static void print_hfscstats(int slot, struct hfsc_classstats *, - struct queue_stats *); -static void print_fairqstats(int slot, struct fairq_classstats *, - struct queue_stats *); static void print_tcqstats(int slot, struct tcq_classstats *, struct queue_stats *); static void print_qfqstats(int slot, struct qfq_classstats *, @@ -1449,22 +1441,6 @@ loop: update_avg(ifcqs, &qstats[n]); switch (scheduler) { - case PKTSCHEDT_CBQ: - print_cbqstats(n, &ifcqs->ifqs_cbq_stats, - &qstats[n]); - break; - case PKTSCHEDT_HFSC: - print_hfscstats(n, &ifcqs->ifqs_hfsc_stats, - &qstats[n]); - break; - case PKTSCHEDT_PRIQ: - print_priqstats(n, &ifcqs->ifqs_priq_stats, - &qstats[n]); - break; - case PKTSCHEDT_FAIRQ: - print_fairqstats(n, &ifcqs->ifqs_fairq_stats, - &qstats[n]); - break; case PKTSCHEDT_TCQ: print_tcqstats(n, &ifcqs->ifqs_tcq_stats, &qstats[n]); @@ -1505,131 +1481,6 @@ done: close(s); } -static void -print_cbqstats(int slot, struct cbq_classstats *cs, struct queue_stats *qs) -{ - printf(" %2d: [ pkts: %10llu bytes: %10llu " - "dropped pkts: %6llu bytes: %6llu ]\n", slot, - (unsigned long long)cs->xmit_cnt.packets, - (unsigned long long)cs->xmit_cnt.bytes, - (unsigned long long)cs->drop_cnt.packets, - (unsigned long long)cs->drop_cnt.bytes); - printf(" [ qlength: %3d/%3d borrows: %6u " - "suspends: %6u qalg: %s ]\n", cs->qcnt, cs->qmax, - cs->borrows, cs->delays, qtype2str(cs->qtype)); - printf(" [ service class: %5s ]\n", qid2str(cs->handle)); - - if (qs->avgn >= 2) { - printf(" [ measured: %7.1f packets/s, %s/s ]\n", - qs->avg_packets / interval, - rate2str((8 * qs->avg_bytes) / interval)); - } - - if (qflag < 2) - return; - - switch (cs->qtype) { - case Q_SFB: - print_sfbstats(&cs->sfb); - break; - default: - break; - } -} - -static void -print_priqstats(int slot, struct priq_classstats *cs, struct queue_stats *qs) -{ - printf(" %2d: [ pkts: %10llu bytes: %10llu " - "dropped pkts: %6llu bytes: %6llu ]\n", slot, - (unsigned long long)cs->xmitcnt.packets, - (unsigned long long)cs->xmitcnt.bytes, - (unsigned long long)cs->dropcnt.packets, - (unsigned long long)cs->dropcnt.bytes); - printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]\n", - cs->qlength, cs->qlimit, qtype2str(cs->qtype), - qid2str(cs->class_handle)); - - if (qs->avgn >= 2) { - printf(" [ measured: %7.1f packets/s, %s/s ]\n", - qs->avg_packets / interval, - rate2str((8 * qs->avg_bytes) / interval)); - } - - if (qflag < 2) - return; - - switch (cs->qtype) { - case Q_SFB: - print_sfbstats(&cs->sfb); - break; - default: - break; - } -} - -static void -print_hfscstats(int slot, struct hfsc_classstats *cs, struct queue_stats *qs) -{ - printf(" %2d: [ pkts: %10llu bytes: %10llu " - "dropped pkts: %6llu bytes: %6llu ]\n", slot, - (unsigned long long)cs->xmit_cnt.packets, - (unsigned long long)cs->xmit_cnt.bytes, - (unsigned long long)cs->drop_cnt.packets, - (unsigned long long)cs->drop_cnt.bytes); - printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]\n", - cs->qlength, cs->qlimit, qtype2str(cs->qtype), - qid2str(cs->class_handle)); - - if (qs->avgn >= 2) { - printf(" [ measured: %7.1f packets/s, %s/s ]\n", - qs->avg_packets / interval, - rate2str((8 * qs->avg_bytes) / interval)); - } - - if (qflag < 2) - return; - - switch (cs->qtype) { - case Q_SFB: - print_sfbstats(&cs->sfb); - break; - default: - break; - } -} - -static void -print_fairqstats(int slot, struct fairq_classstats *cs, struct queue_stats *qs) -{ - printf(" %2d: [ pkts: %10llu bytes: %10llu " - "dropped pkts: %6llu bytes: %6llu ]\n", slot, - (unsigned long long)cs->xmit_cnt.packets, - (unsigned long long)cs->xmit_cnt.bytes, - (unsigned long long)cs->drop_cnt.packets, - (unsigned long long)cs->drop_cnt.bytes); - printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]]\n", - cs->qlength, cs->qlimit, qtype2str(cs->qtype), - qid2str(cs->class_handle)); - - if (qs->avgn >= 2) { - printf(" [ measured: %7.1f packets/s, %s/s ]\n", - qs->avg_packets / interval, - rate2str((8 * qs->avg_bytes) / interval)); - } - - if (qflag < 2) - return; - - switch (cs->qtype) { - case Q_SFB: - print_sfbstats(&cs->sfb); - break; - default: - break; - } -} - static void print_tcqstats(int slot, struct tcq_classstats *cs, struct queue_stats *qs) { @@ -1713,12 +1564,23 @@ static void print_fq_codel_stats(int pri, struct fq_codel_classstats *fqst, struct queue_stats *qs) { + int i = 0; + + if (fqst->fcls_service_class == 0 && fqst->fcls_pri == 0) + return; + printf("=====================================================\n"); printf(" [ pri: %s (%d)\tsrv_cl: 0x%x\tquantum: %d\tdrr_max: %d ]\n", pri2str(fqst->fcls_pri), fqst->fcls_pri, fqst->fcls_service_class, fqst->fcls_quantum, fqst->fcls_drr_max); - printf(" [ budget: %lld\t\ttarget qdelay: %14s ]\n", + printf(" [ queued pkts: %llu\tbytes: %llu ]\n", + fqst->fcls_pkt_cnt, fqst->fcls_byte_cnt); + printf(" [ dequeued pkts: %llu\tbytes: %llu ]\n", + fqst->fcls_dequeue, fqst->fcls_dequeue_bytes); + printf(" [ budget: %lld\ttarget qdelay: %10s\t", fqst->fcls_budget, nsec_to_str(fqst->fcls_target_qdelay)); + printf("update interval:%10s ]\n", + nsec_to_str(fqst->fcls_update_interval)); printf(" [ flow control: %u\tfeedback: %u\tstalls: %u\tfailed: %u ]\n", fqst->fcls_flow_control, fqst->fcls_flow_feedback, fqst->fcls_dequeue_stall, fqst->fcls_flow_control_fail); @@ -1728,14 +1590,38 @@ print_fq_codel_stats(int pri, struct fq_codel_classstats *fqst, printf(" [ flows total: %u\tnew: %u\told: %u ]\n", fqst->fcls_flows_cnt, fqst->fcls_newflows_cnt, fqst->fcls_oldflows_cnt); - printf(" [ queued pkts: %llu\tbytes: %llu ]\n", - fqst->fcls_pkt_cnt, fqst->fcls_byte_cnt); - printf(" [ dequeued pkts: %llu\tbytes: %llu ]\n", - fqst->fcls_dequeue, fqst->fcls_dequeue_bytes); printf(" [ throttle on: %u\toff: %u\tdrop: %u ]\n", fqst->fcls_throttle_on, fqst->fcls_throttle_off, fqst->fcls_throttle_drops); - printf("=====================================================\n"); + + if (qflag < 2) + return; + + if (fqst->fcls_flowstats_cnt > 0) { + printf("Flowhash\tBytes\tMin qdelay\tFlags\t\n"); + for (i = 0; i < fqst->fcls_flowstats_cnt; i++) { + printf("%u\t%u\t%14s\t", + fqst->fcls_flowstats[i].fqst_flowhash, + fqst->fcls_flowstats[i].fqst_bytes, + nsec_to_str(fqst->fcls_flowstats[i].fqst_min_qdelay)); + if (fqst->fcls_flowstats[i].fqst_flags & + FQ_FLOWSTATS_OLD_FLOW) + printf("O"); + if (fqst->fcls_flowstats[i].fqst_flags & + FQ_FLOWSTATS_NEW_FLOW) + printf("N"); + if (fqst->fcls_flowstats[i].fqst_flags & + FQ_FLOWSTATS_LARGE_FLOW) + printf("L"); + if (fqst->fcls_flowstats[i].fqst_flags & + FQ_FLOWSTATS_DELAY_HIGH) + printf("D"); + if (fqst->fcls_flowstats[i].fqst_flags & + FQ_FLOWSTATS_FLOWCTL_ON) + printf("F"); + printf("\n"); + } + } } static void @@ -1823,22 +1709,6 @@ update_avg(struct if_ifclassq_stats *ifcqs, struct queue_stats *qs) n = qs->avgn; switch (ifcqs->ifqs_scheduler) { - case PKTSCHEDT_CBQ: - b = ifcqs->ifqs_cbq_stats.xmit_cnt.bytes; - p = ifcqs->ifqs_cbq_stats.xmit_cnt.packets; - break; - case PKTSCHEDT_PRIQ: - b = ifcqs->ifqs_priq_stats.xmitcnt.bytes; - p = ifcqs->ifqs_priq_stats.xmitcnt.packets; - break; - case PKTSCHEDT_HFSC: - b = ifcqs->ifqs_hfsc_stats.xmit_cnt.bytes; - p = ifcqs->ifqs_hfsc_stats.xmit_cnt.packets; - break; - case PKTSCHEDT_FAIRQ: - b = ifcqs->ifqs_fairq_stats.xmit_cnt.bytes; - p = ifcqs->ifqs_fairq_stats.xmit_cnt.packets; - break; case PKTSCHEDT_TCQ: b = ifcqs->ifqs_tcq_stats.xmitcnt.bytes; p = ifcqs->ifqs_tcq_stats.xmitcnt.packets; @@ -1890,15 +1760,6 @@ qtype2str(classq_type_t t) case Q_DROPTAIL: c = "DROPTAIL"; break; - case Q_RED: - c = "RED"; - break; - case Q_RIO: - c = "RIO"; - break; - case Q_BLUE: - c = "BLUE"; - break; case Q_SFB: c = "SFB"; break; @@ -1948,18 +1809,6 @@ sched2str(unsigned int s) case PKTSCHEDT_NONE: c = "NONE"; break; - case PKTSCHEDT_CBQ: - c = "CBQ"; - break; - case PKTSCHEDT_HFSC: - c = "HFSC"; - break; - case PKTSCHEDT_PRIQ: - c = "PRIQ"; - break; - case PKTSCHEDT_FAIRQ: - c = "FAIRQ"; - break; case PKTSCHEDT_TCQ: c = "TCQ"; break; diff --git a/netstat.tproj/inet.c b/netstat.tproj/inet.c index d614aec..94034e5 100644 --- a/netstat.tproj/inet.c +++ b/netstat.tproj/inet.c @@ -728,6 +728,16 @@ tcp_stats(uint32_t off , char *name, int af) p(tcps_mss_to_medium,"\t%u time%s maximum segment size was changed to medium\n"); p(tcps_mss_to_low,"\t%u time%s maximum segment size was changed to low\n"); + p(tcps_timer_drift_le_1_ms,"\t%u timer drift%s less or equal to 1 ms\n"); + p(tcps_timer_drift_le_10_ms,"\t%u timer drift%s less or equal to 10 ms\n"); + p(tcps_timer_drift_le_20_ms,"\t%u timer drift%s less or equal to 20 ms\n"); + p(tcps_timer_drift_le_50_ms,"\t%u timer drift%s less or equal to 50 ms\n"); + p(tcps_timer_drift_le_100_ms,"\t%u timer drift%s less or equal to 100 ms\n"); + p(tcps_timer_drift_le_200_ms,"\t%u timer drift%s less or equal to 200 ms\n"); + p(tcps_timer_drift_le_500_ms,"\t%u timer drift%s less or equal to 500 ms\n"); + p(tcps_timer_drift_le_1000_ms,"\t%u timer drift%s less or equal to 1000 ms\n"); + p(tcps_timer_drift_gt_1000_ms,"\t%u timer drift%s greater than to 1000 ms\n"); + if (interval > 0) { bcopy(&tcpstat, &ptcpstat, len); pr_swcsum = r_swcsum; @@ -1021,6 +1031,7 @@ ip_stats(uint32_t off , char *name, int af ) p(ips_badaddr, "\t\t%u datagram%s with bad address in header\n"); p(ips_pktdropcntrl, "\t\t%u packet%s dropped due to no bufs for control data\n"); + p(ips_necp_policy_drop, "\t\t%u packet%s dropped due to NECP policy\n"); p2(ips_snd_swcsum, ips_snd_swcsum_bytes, "\t\t%u header%s (%u byte%s) checksummed in software\n"); diff --git a/netstat.tproj/inet6.c b/netstat.tproj/inet6.c index 6e81df7..ae50278 100644 --- a/netstat.tproj/inet6.c +++ b/netstat.tproj/inet6.c @@ -364,8 +364,6 @@ static const char *srcrulenames[IP6S_SRCRULE_COUNT] = { "avoid deprecated addresses", // IP6S_SRCRULE_3 "prefer home addresses", // IP6S_SRCRULE_4 "prefer outgoing interface", // IP6S_SRCRULE_5 - "prefer addresses in a prefix advertised by the next-hop", - // IP6S_SRCRULE_5_5 "prefer matching label", // IP6S_SRCRULE_6 "prefer temporary addresses", // IP6S_SRCRULE_7 "prefer addresses on alive interfaces", // IP6S_SRCRULE_7x @@ -374,6 +372,7 @@ static const char *srcrulenames[IP6S_SRCRULE_COUNT] = { NULL, NULL, NULL, + NULL, NULL }; @@ -485,6 +484,7 @@ ip6_stats(uint32_t off __unused, char *name, int af __unused) p(ip6s_ofragments, "\t\t%llu fragment%s created\n"); p(ip6s_cantfrag, "\t\t%llu datagram%s that can't be fragmented\n"); p(ip6s_badscope, "\t\t%llu packet%s that violated scope rules\n"); + p(ip6s_necp_policy_drop, "\t\t%llu packet%s dropped due to NECP policy\n"); #define OUTPERFDIFF(f) (out_net_perf.f - pout_net_perf.f) if (OUTPERFDIFF(np_total_pkts) > 0 && out_net_perf.np_total_usecs > 0) { @@ -692,6 +692,10 @@ ip6_ifstats(char *ifname) p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n"); p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n"); + p(ifs6_cantfoward_icmp6, "\t%llu ICMPv6 packet%s received for unreachable destination\n"); + p(ifs6_addr_expiry_cnt, "\t%llu address expiry event%s reported\n"); + p(ifs6_pfx_expiry_cnt, "\t%llu prefix expiry event%s reported\n"); + p(ifs6_defrtr_expiry_cnt, "\t%llu default router expiry event%s reported\n"); end: close(s); diff --git a/netstat.tproj/main.c b/netstat.tproj/main.c index 6830b67..52c0a0f 100644 --- a/netstat.tproj/main.c +++ b/netstat.tproj/main.c @@ -166,6 +166,10 @@ struct protox ipcprotox[] = { { NULL, NULL, NULL, NULL, 0 } }; +struct protox kernprotox[] = { + { NULL, print_net_api_stats, NULL, "net_api", 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; struct protox *protoprotox[] = { protox, @@ -178,6 +182,7 @@ struct protox *protoprotox[] = { systmprotox, nstatprotox, ipcprotox, + kernprotox, NULL }; @@ -454,6 +459,11 @@ main(argc, argv) for (tp = ipcprotox; tp->pr_name; tp++) printproto(tp, tp->pr_name); + if (af == AF_UNSPEC && !Lflag) + for (tp = kernprotox; tp->pr_name; tp++) + printproto(tp, tp->pr_name); + + #ifdef SRVCACHE _serv_cache_close(); #endif diff --git a/netstat.tproj/misc.c b/netstat.tproj/misc.c new file mode 100644 index 0000000..ac2a2ca --- /dev/null +++ b/netstat.tproj/misc.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include + +#include +#include +#include + +#include "netstat.h" + +void +print_net_api_stats(uint32_t off __unused, char *name, int af __unused) +{ + static struct net_api_stats pnet_api_stats; + struct net_api_stats net_api_stats; + size_t len = sizeof(struct net_api_stats); + const char *mibvar = "net.api_stats"; + + if (sysctlbyname(mibvar, &net_api_stats, &len, 0, 0) < 0) { + warn("sysctl: %s", mibvar); + return; + } + +#define STATDIFF(f) (net_api_stats.f - pnet_api_stats.f) +#define p(f, m) if (STATDIFF(f) || sflag <= 1) \ + printf(m, STATDIFF(f), plural(STATDIFF(f))) +#define p1a(f, m) if (STATDIFF(f) || sflag <= 1) \ + printf(m, STATDIFF(f)) + + if (interval && vflag > 0) + print_time(); + printf ("%s:\n", name); + + p(nas_iflt_attach_count, "\t%lld interface filter%s currently attached\n"); + p(nas_iflt_attach_total, "\t%lld interface filter%s attached since boot\n"); + p(nas_iflt_attach_os_total, "\t%lld interface filter%s attached since boot by OS\n"); + + p(nas_ipf_add_count, "\t%lld IP filter%s currently attached\n"); + p(nas_ipf_add_total, "\t%lld IP filter%s attached since boot\n"); + p(nas_ipf_add_os_total, "\t%lld IP filter%s attached since boot by OS\n"); + + p(nas_sfltr_register_count, "\t%lld socket filter%s currently attached\n"); + p(nas_sfltr_register_total, "\t%lld socket filter%s attached since boot\n"); + p(nas_sfltr_register_os_total, "\t%lld socket filter%s attached since boot by OS\n"); + + p(nas_socket_alloc_total, "\t%lld socket%s allocated since boot\n"); + p(nas_socket_in_kernel_total, "\t%lld socket%s allocated in-kernel since boot\n"); + p(nas_socket_in_kernel_os_total, "\t%lld socket%s allocated in-kernel by OS\n"); + p(nas_socket_necp_clientuuid_total, "\t%lld socket%s with NECP client UUID since boot\n"); + + p(nas_socket_domain_local_total, "\t%lld local domain socket%s allocated since boot\n"); + p(nas_socket_domain_route_total, "\t%lld route domain socket%s allocated since boot\n"); + p(nas_socket_domain_inet_total, "\t%lld inet domain socket%s allocated since boot\n"); + p(nas_socket_domain_inet6_total, "\t%lld inet6 domain socket%s allocated since boot\n"); + p(nas_socket_domain_system_total, "\t%lld system domain socket%s allocated since boot\n"); + p(nas_socket_domain_multipath_total, "\t%lld multipath domain socket%s allocated since boot\n"); + p(nas_socket_domain_key_total, "\t%lld key domain socket%s allocated since boot\n"); + p(nas_socket_domain_ndrv_total, "\t%lld ndrv domain socket%s allocated since boot\n"); + p(nas_socket_domain_other_total, "\t%lld other domains socket%s allocated since boot\n"); + + p(nas_socket_inet_stream_total, "\t%lld IPv4 stream socket%s created since boot\n"); + p(nas_socket_inet_dgram_total, "\t%lld IPv4 datagram socket%s created since boot\n"); + p(nas_socket_inet_dgram_connected, "\t%lld IPv4 datagram socket%s connected\n"); + p(nas_socket_inet_dgram_dns, "\t%lld IPv4 DNS socket%s\n"); + p(nas_socket_inet_dgram_no_data, "\t%lld IPv4 datagram socket%s without data\n"); + + p(nas_socket_inet6_stream_total, "\t%lld IPv6 stream socket%s created since boot\n"); + p(nas_socket_inet6_dgram_total, "\t%lld IPv6 datagram socket%s created since boot\n"); + p(nas_socket_inet6_dgram_connected, "\t%lld IPv6 datagram socket%s connected\n"); + p(nas_socket_inet6_dgram_dns, "\t%lld IPv6 DNS socket%s\n"); + p(nas_socket_inet6_dgram_no_data, "\t%lld IPv6 datagram socket%s without data\n"); + + p(nas_socket_mcast_join_total, "\t%lld socket multicast join%s since boot\n"); + p(nas_socket_mcast_join_os_total, "\t%lld socket multicast join%s since boot by OS\n"); + + p(nas_nx_flow_inet_stream_total, "\t%lld IPv4 stream nexus flow%s added since boot\n"); + p(nas_nx_flow_inet_dgram_total, "\t%lld IPv4 datagram nexus flow%s added since boot\n"); + + p(nas_nx_flow_inet6_stream_total, "\t%lld IPv6 stream nexus flow%s added since boot\n"); + p(nas_nx_flow_inet6_dgram_total, "\t%lld IPv6 datagram nexus flow%s added since boot\n"); + + p(nas_ifnet_alloc_count, "\t%lld interface%s currently allocated\n"); + p(nas_ifnet_alloc_total, "\t%lld interface%s allocated since boot\n"); + p(nas_ifnet_alloc_os_count, "\t%lld interface%s currently allocated by OS\n"); + p(nas_ifnet_alloc_os_total, "\t%lld extended interface%s allocated since boot by OS\n"); + + p(nas_pf_addrule_total, "\t%lld PF addrule operation%s since boot\n"); + p(nas_pf_addrule_os, "\t%lld PF addrule operation%s since boot by OS\n"); + + p(nas_vmnet_total, "\t%lld vmnet start%s since boot\n"); + +#undef STATDIFF +#undef p +#undef p1a +} + diff --git a/netstat.tproj/mptcp.c b/netstat.tproj/mptcp.c index b3e13ff..70be928 100644 --- a/netstat.tproj/mptcp.c +++ b/netstat.tproj/mptcp.c @@ -78,7 +78,7 @@ printmptcp(int id, conninfo_mptcp_t *mptcp) "aid(%d)]\n", id, mptcp->mptcpci_mpte_flags, mptcp->mptcpci_flags, mptcpstates[mptcp->mptcpci_state], mptcp->mptcpci_rtoken, - mptcp->mptcpci_sndnxt, mptcp->mptcpci_rcvatmark, + mptcp->mptcpci_sndnxt, mptcp->mptcpci_rcvnxt, mptcp->mptcpci_mpte_addrid); flow = (mptcp_flow_t*)((caddr_t)mptcp + mptcp->mptcpci_flow_offset); @@ -113,9 +113,8 @@ printmptcp(int id, conninfo_mptcp_t *mptcp) tcpci = (conninfo_tcp_t*)((caddr_t)flow + flow->flow_tcpci_offset); printf("%s \n" - " [dsn(%#"PRIx64"), relseq(%-4.4d), err(%d)]\n", + " [relseq(%-4.4d), err(%d)]\n", tcpstates[tcpci->tcpci_tcp_info.tcpi_state], - flow->flow_sndnxt, flow->flow_relseq, flow->flow_soerror); diff --git a/netstat.tproj/netstat.h b/netstat.tproj/netstat.h index 015b3cb..dd78e0b 100644 --- a/netstat.tproj/netstat.h +++ b/netstat.tproj/netstat.h @@ -166,3 +166,5 @@ extern void print_link_status(const char *); extern void print_extbkidle_stats(uint32_t, char *, int); extern void print_nstat_stats(uint32_t, char *, int); +extern void print_net_api_stats(uint32_t, char *, int); + diff --git a/netstat.tproj/route.c b/netstat.tproj/route.c index a5b556f..4f220ec 100644 --- a/netstat.tproj/route.c +++ b/netstat.tproj/route.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Apple Inc. All rights reserved. + * Copyright (c) 2008-2017 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -702,6 +702,8 @@ rt_stats(void) p(rts_newgateway, "\t%u new gateway%s due to redirects\n"); p(rts_unreach, "\t%u destination%s found unreachable\n"); p(rts_wildcard, "\t%u use%s of a wildcard route\n"); + p(rts_badrtgwroute, "\t%u lookup%s returned indirect " + "routes pointing to indirect gateway route\n"); #undef p if (rttrash || sflag <= 1) diff --git a/network_cmds.xcodeproj/project.pbxproj b/network_cmds.xcodeproj/project.pbxproj index 1de7d67..b979f57 100755 --- a/network_cmds.xcodeproj/project.pbxproj +++ b/network_cmds.xcodeproj/project.pbxproj @@ -107,7 +107,6 @@ buildPhases = ( ); dependencies = ( - 72C77D3B1484199C002D2577 /* PBXTargetDependency */, ); name = network_cmds_libs; productName = "network_cmds (Aggregate)"; @@ -174,8 +173,6 @@ 713298CC1A93D3A0002359CF /* modstack.c in Sources */ = {isa = PBXBuildFile; fileRef = 713298C01A93D3A0002359CF /* modstack.c */; }; 713298CD1A93D3A0002359CF /* outbound_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 713298C21A93D3A0002359CF /* outbound_list.c */; }; 713298CE1A93D3A0002359CF /* outside_network.c in Sources */ = {isa = PBXBuildFile; fileRef = 713298C41A93D3A0002359CF /* outside_network.c */; }; - 713298D01A93D452002359CF /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 713298CF1A93D452002359CF /* libssl.dylib */; }; - 713298D21A93D498002359CF /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 713298D11A93D498002359CF /* libcrypto.dylib */; }; 713298D61A93D50A002359CF /* dns64.c in Sources */ = {isa = PBXBuildFile; fileRef = 713298D41A93D50A002359CF /* dns64.c */; }; 713298EA1A93D567002359CF /* iter_delegpt.c in Sources */ = {isa = PBXBuildFile; fileRef = 713298D81A93D567002359CF /* iter_delegpt.c */; }; 713298EB1A93D567002359CF /* iter_donotq.c in Sources */ = {isa = PBXBuildFile; fileRef = 713298DA1A93D567002359CF /* iter_donotq.c */; }; @@ -201,6 +198,7 @@ 71D958BC1A9452DC00C9B286 /* unbound.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 71D958B41A9451D400C9B286 /* unbound.8 */; }; 71D958BF1A9453C100C9B286 /* unbound.conf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 71D958BD1A94537000C9B286 /* unbound.conf */; }; 7200F2FD1958A34D0033E22C /* packet_mangler.c in Sources */ = {isa = PBXBuildFile; fileRef = 7200F2FC1958A34D0033E22C /* packet_mangler.c */; }; + 721654C31EC52447005B17BA /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 721654C21EC52447005B17BA /* misc.c */; }; 7216D24C0EE896F300AE70E4 /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261208B0EE86F4800AFED1B /* data.c */; }; 7216D24D0EE896F300AE70E4 /* if.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261208D0EE86F4800AFED1B /* if.c */; }; 7216D24E0EE896F300AE70E4 /* inet.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261208E0EE86F4800AFED1B /* inet.c */; }; @@ -254,22 +252,10 @@ 724DABA70EE88FED008900D0 /* kdumpsubs.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120720EE86F2D00AFED1B /* kdumpsubs.c */; }; 724DABAB0EE89006008900D0 /* kdumpd.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 726120700EE86F2D00AFED1B /* kdumpd.8 */; }; 724DABBC0EE8908A008900D0 /* com.apple.kdumpd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7261206E0EE86F2D00AFED1B /* com.apple.kdumpd.plist */; }; - 724DABDF0EE89151008900D0 /* natd.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261207C0EE86F3600AFED1B /* natd.c */; }; - 724DABE00EE89155008900D0 /* icmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120790EE86F3600AFED1B /* icmp.c */; }; - 724DABE40EE8916B008900D0 /* natd.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7261207B0EE86F3600AFED1B /* natd.8 */; }; - 724DABF90EE89269008900D0 /* libalias.A.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7261210C0EE8707500AFED1B /* libalias.A.dylib */; }; 724DAC120EE89423008900D0 /* ndp.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120870EE86F4000AFED1B /* ndp.c */; }; 724DAC3B0EE89555008900D0 /* ndp.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 726120860EE86F4000AFED1B /* ndp.8 */; }; - 726121110EE870AB00AFED1B /* alias.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120390EE86EEB00AFED1B /* alias.c */; }; - 726121130EE870AB00AFED1B /* alias_cuseeme.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261203B0EE86EEB00AFED1B /* alias_cuseeme.c */; }; - 726121140EE870AB00AFED1B /* alias_db.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261203C0EE86EEB00AFED1B /* alias_db.c */; }; - 726121150EE870AB00AFED1B /* alias_ftp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261203D0EE86EEB00AFED1B /* alias_ftp.c */; }; - 726121160EE870AB00AFED1B /* alias_irc.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261203E0EE86EEB00AFED1B /* alias_irc.c */; }; - 726121180EE870AB00AFED1B /* alias_nbt.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120400EE86EEB00AFED1B /* alias_nbt.c */; }; - 726121190EE870AB00AFED1B /* alias_pptp.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120410EE86EEB00AFED1B /* alias_pptp.c */; }; - 7261211A0EE870AB00AFED1B /* alias_proxy.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120420EE86EEB00AFED1B /* alias_proxy.c */; }; - 7261211B0EE870AB00AFED1B /* alias_smedia.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120430EE86EEB00AFED1B /* alias_smedia.c */; }; - 7261211C0EE870AB00AFED1B /* alias_util.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120440EE86EEB00AFED1B /* alias_util.c */; }; + 7255D4311E44036D008F4A32 /* libcrypto.35.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7255D4301E44036D008F4A32 /* libcrypto.35.dylib */; }; + 7255D4331E44037F008F4A32 /* libssl.35.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7255D4321E44037F008F4A32 /* libssl.35.dylib */; }; 726121310EE8711E00AFED1B /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7261204E0EE86EF900AFED1B /* arp.c */; }; 726121350EE8713800AFED1B /* arp.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7261204D0EE86EF900AFED1B /* arp.8 */; }; 7261215A0EE8883900AFED1B /* ifbond.c in Sources */ = {isa = PBXBuildFile; fileRef = 726120550EE86F0900AFED1B /* ifbond.c */; }; @@ -309,6 +295,8 @@ 72E650AA107BF2F000AAF325 /* ifbridge.c in Sources */ = {isa = PBXBuildFile; fileRef = 72E650A5107BF2F000AAF325 /* ifbridge.c */; }; 72E650AB107BF2F000AAF325 /* ifclone.c in Sources */ = {isa = PBXBuildFile; fileRef = 72E650A6107BF2F000AAF325 /* ifclone.c */; }; E01AB0901368880F008C66FF /* libutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E01AB08F1368880F008C66FF /* libutil.dylib */; }; + F940359D1E2FF5A900283EB1 /* iffake.c in Sources */ = {isa = PBXBuildFile; fileRef = F940359C1E2FF58500283EB1 /* iffake.c */; }; + F97F1E041E9C3FC8002355FF /* nexus.c in Sources */ = {isa = PBXBuildFile; fileRef = F97F1E031E9C3FBC002355FF /* nexus.c */; }; /* End PBXBuildFile section */ /* Begin PBXBuildRule section */ @@ -768,13 +756,6 @@ remoteGlobalIDString = 72B732D91899B0380060E6D4; remoteInfo = cfilutil; }; - 72C77D3C1484199C002D2577 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 724862310EE86EB7001D0DE9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 7261210B0EE8707500AFED1B; - remoteInfo = alias; - }; 72CD1D9B0EE8C47C005F825D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 724862310EE86EB7001D0DE9 /* Project object */; @@ -1015,16 +996,6 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - 724DABE90EE891AD008900D0 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/share/man/man8; - dstSubfolderSpec = 0; - files = ( - 724DABE40EE8916B008900D0 /* natd.8 in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; - }; 724DAC1D0EE894E8008900D0 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -1274,6 +1245,7 @@ 7200F2FA1958A34D0033E22C /* pktmnglr */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = pktmnglr; sourceTree = BUILT_PRODUCTS_DIR; }; 7200F2FC1958A34D0033E22C /* packet_mangler.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = packet_mangler.c; sourceTree = ""; }; 7211D9B2190713A60086EF20 /* network-client-server-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "network-client-server-entitlements.plist"; sourceTree = ""; }; + 721654C21EC52447005B17BA /* misc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = misc.c; sourceTree = ""; }; 7216D2460EE896C000AE70E4 /* netstat */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = netstat; sourceTree = BUILT_PRODUCTS_DIR; }; 7216D27C0EE8980A00AE70E4 /* ping */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ping; sourceTree = BUILT_PRODUCTS_DIR; }; 7216D29A0EE898BD00AE70E4 /* ping6 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ping6; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1294,18 +1266,9 @@ 7247B83516165EDC00873B3C /* pktapctl.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pktapctl.8; sourceTree = ""; }; 7247B83B16165F0100873B3C /* pktapctl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pktapctl.c; sourceTree = ""; }; 724DABA20EE88FE3008900D0 /* kdumpd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = kdumpd; sourceTree = BUILT_PRODUCTS_DIR; }; - 724DABDB0EE8912D008900D0 /* natd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = natd; sourceTree = BUILT_PRODUCTS_DIR; }; 724DAC0D0EE8940D008900D0 /* ndp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ndp; sourceTree = BUILT_PRODUCTS_DIR; }; - 726120390EE86EEB00AFED1B /* alias.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias.c; sourceTree = ""; }; - 7261203B0EE86EEB00AFED1B /* alias_cuseeme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_cuseeme.c; sourceTree = ""; }; - 7261203C0EE86EEB00AFED1B /* alias_db.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_db.c; sourceTree = ""; }; - 7261203D0EE86EEB00AFED1B /* alias_ftp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_ftp.c; sourceTree = ""; }; - 7261203E0EE86EEB00AFED1B /* alias_irc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_irc.c; sourceTree = ""; }; - 726120400EE86EEB00AFED1B /* alias_nbt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_nbt.c; sourceTree = ""; }; - 726120410EE86EEB00AFED1B /* alias_pptp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_pptp.c; sourceTree = ""; }; - 726120420EE86EEB00AFED1B /* alias_proxy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_proxy.c; sourceTree = ""; }; - 726120430EE86EEB00AFED1B /* alias_smedia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_smedia.c; sourceTree = ""; }; - 726120440EE86EEB00AFED1B /* alias_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_util.c; sourceTree = ""; }; + 7255D4301E44036D008F4A32 /* libcrypto.35.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.35.dylib; path = usr/lib/libcrypto.35.dylib; sourceTree = SDKROOT; }; + 7255D4321E44037F008F4A32 /* libssl.35.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libssl.35.dylib; path = usr/lib/libssl.35.dylib; sourceTree = SDKROOT; }; 7261204D0EE86EF900AFED1B /* arp.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = arp.8; sourceTree = ""; }; 7261204E0EE86EF900AFED1B /* arp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arp.c; sourceTree = ""; }; 7261204F0EE86EF900AFED1B /* arp4.4 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = arp4.4; sourceTree = ""; }; @@ -1321,14 +1284,6 @@ 726120710EE86F2D00AFED1B /* kdumpd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kdumpd.c; sourceTree = ""; }; 726120720EE86F2D00AFED1B /* kdumpsubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kdumpsubs.c; sourceTree = ""; }; 726120730EE86F2D00AFED1B /* kdumpsubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kdumpsubs.h; sourceTree = ""; }; - 726120780EE86F3600AFED1B /* HISTORY */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HISTORY; sourceTree = ""; }; - 726120790EE86F3600AFED1B /* icmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = icmp.c; sourceTree = ""; }; - 7261207B0EE86F3600AFED1B /* natd.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = natd.8; sourceTree = ""; }; - 7261207C0EE86F3600AFED1B /* natd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = natd.c; sourceTree = ""; }; - 7261207D0EE86F3600AFED1B /* natd.cf.sample */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = natd.cf.sample; sourceTree = ""; }; - 7261207E0EE86F3600AFED1B /* natd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = natd.h; sourceTree = ""; }; - 7261207F0EE86F3600AFED1B /* natd.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = natd.test; sourceTree = ""; }; - 726120800EE86F3600AFED1B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; 726120840EE86F4000AFED1B /* gnuc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gnuc.h; sourceTree = ""; }; 726120860EE86F4000AFED1B /* ndp.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ndp.8; sourceTree = ""; }; 726120870EE86F4000AFED1B /* ndp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ndp.c; sourceTree = ""; }; @@ -1404,10 +1359,6 @@ 726120F30EE86FA700AFED1B /* version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = version.c; sourceTree = ""; }; 726120FA0EE86FB500AFED1B /* traceroute6.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = traceroute6.8; sourceTree = ""; }; 726120FB0EE86FB500AFED1B /* traceroute6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = traceroute6.c; sourceTree = ""; }; - 7261210C0EE8707500AFED1B /* libalias.A.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libalias.A.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; - 726121220EE870D400AFED1B /* alias_local.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alias_local.h; sourceTree = ""; }; - 726121230EE870D400AFED1B /* alias.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alias.h; sourceTree = ""; }; - 726121240EE870D400AFED1B /* libalias.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libalias.3; sourceTree = ""; }; 7261212D0EE8710B00AFED1B /* arp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = arp; sourceTree = BUILT_PRODUCTS_DIR; }; 726121540EE8881700AFED1B /* ifconfig */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ifconfig; sourceTree = BUILT_PRODUCTS_DIR; }; 7263724C1BCC718B00E4B026 /* frame_delay.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = frame_delay.8; sourceTree = ""; }; @@ -1447,6 +1398,8 @@ 72E650A5107BF2F000AAF325 /* ifbridge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ifbridge.c; sourceTree = ""; }; 72E650A6107BF2F000AAF325 /* ifclone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ifclone.c; sourceTree = ""; }; E01AB08F1368880F008C66FF /* libutil.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libutil.dylib; path = $SDKROOT/usr/lib/libutil.dylib; sourceTree = ""; }; + F940359C1E2FF58500283EB1 /* iffake.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iffake.c; sourceTree = ""; }; + F97F1E031E9C3FBC002355FF /* nexus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nexus.c; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1468,8 +1421,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 713298D21A93D498002359CF /* libcrypto.dylib in Frameworks */, - 713298D01A93D452002359CF /* libssl.dylib in Frameworks */, + 7255D4331E44037F008F4A32 /* libssl.35.dylib in Frameworks */, + 7255D4311E44036D008F4A32 /* libcrypto.35.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1566,14 +1519,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 724DABD90EE8912D008900D0 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 724DABF90EE89269008900D0 /* libalias.A.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 724DAC0B0EE8940D008900D0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1581,13 +1526,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7261210A0EE8707500AFED1B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 7261212B0EE8710B00AFED1B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1977,7 +1915,6 @@ 72E42BA214B7CF37003AAE28 /* network_cmds.plist */, 7211D9B2190713A60086EF20 /* network-client-server-entitlements.plist */, E01AB08F1368880F008C66FF /* libutil.dylib */, - 726120380EE86EEB00AFED1B /* alias */, 7261204C0EE86EF900AFED1B /* arp.tproj */, 72B732DB1899B0380060E6D4 /* cfilutil */, 723C706A142BAFEA007C87E9 /* dnctl */, @@ -1989,7 +1926,6 @@ 56582591133920B5003E5FA5 /* mnc.tproj */, 72311F43194A349100EB4788 /* mptcp_client */, 690D973F12DE5A21004323A7 /* mtest.tproj */, - 726120770EE86F3600AFED1B /* natd.tproj */, 726120830EE86F4000AFED1B /* ndp.tproj */, 7261208A0EE86F4800AFED1B /* netstat.tproj */, 7247B83216165EDC00873B3C /* pktapctl */, @@ -2006,27 +1942,17 @@ 713297F01A93C9CF002359CF /* unbound */, 72CD1DB50EE8C619005F825D /* libipsec.dylib */, 7261210D0EE8707500AFED1B /* Products */, + 7255D42F1E44036D008F4A32 /* Frameworks */, ); sourceTree = ""; }; - 726120380EE86EEB00AFED1B /* alias */ = { + 7255D42F1E44036D008F4A32 /* Frameworks */ = { isa = PBXGroup; children = ( - 726121220EE870D400AFED1B /* alias_local.h */, - 726121230EE870D400AFED1B /* alias.h */, - 726121240EE870D400AFED1B /* libalias.3 */, - 726120390EE86EEB00AFED1B /* alias.c */, - 7261203B0EE86EEB00AFED1B /* alias_cuseeme.c */, - 7261203C0EE86EEB00AFED1B /* alias_db.c */, - 7261203D0EE86EEB00AFED1B /* alias_ftp.c */, - 7261203E0EE86EEB00AFED1B /* alias_irc.c */, - 726120400EE86EEB00AFED1B /* alias_nbt.c */, - 726120410EE86EEB00AFED1B /* alias_pptp.c */, - 726120420EE86EEB00AFED1B /* alias_proxy.c */, - 726120430EE86EEB00AFED1B /* alias_smedia.c */, - 726120440EE86EEB00AFED1B /* alias_util.c */, - ); - path = alias; + 7255D4321E44037F008F4A32 /* libssl.35.dylib */, + 7255D4301E44036D008F4A32 /* libcrypto.35.dylib */, + ); + name = Frameworks; sourceTree = ""; }; 7261204C0EE86EF900AFED1B /* arp.tproj */ = { @@ -2051,8 +1977,10 @@ 726120560EE86F0900AFED1B /* ifconfig.8 */, 726120570EE86F0900AFED1B /* ifconfig.c */, 726120580EE86F0900AFED1B /* ifconfig.h */, + F940359C1E2FF58500283EB1 /* iffake.c */, 726120590EE86F0900AFED1B /* ifmedia.c */, 7261205A0EE86F0900AFED1B /* ifvlan.c */, + F97F1E031E9C3FBC002355FF /* nexus.c */, ); path = ifconfig.tproj; sourceTree = ""; @@ -2070,21 +1998,6 @@ path = kdumpd.tproj; sourceTree = ""; }; - 726120770EE86F3600AFED1B /* natd.tproj */ = { - isa = PBXGroup; - children = ( - 726120780EE86F3600AFED1B /* HISTORY */, - 726120790EE86F3600AFED1B /* icmp.c */, - 7261207B0EE86F3600AFED1B /* natd.8 */, - 7261207C0EE86F3600AFED1B /* natd.c */, - 7261207D0EE86F3600AFED1B /* natd.cf.sample */, - 7261207E0EE86F3600AFED1B /* natd.h */, - 7261207F0EE86F3600AFED1B /* natd.test */, - 726120800EE86F3600AFED1B /* README */, - ); - path = natd.tproj; - sourceTree = ""; - }; 726120830EE86F4000AFED1B /* ndp.tproj */ = { isa = PBXGroup; children = ( @@ -2114,6 +2027,7 @@ 7261209A0EE86F4800AFED1B /* tp_astring.c */, 7261209B0EE86F4800AFED1B /* unix.c */, 7218B549191D4202001B7B52 /* systm.c */, + 721654C21EC52447005B17BA /* misc.c */, ); path = netstat.tproj; sourceTree = ""; @@ -2242,11 +2156,9 @@ 7261210D0EE8707500AFED1B /* Products */ = { isa = PBXGroup; children = ( - 7261210C0EE8707500AFED1B /* libalias.A.dylib */, 7261212D0EE8710B00AFED1B /* arp */, 726121540EE8881700AFED1B /* ifconfig */, 724DABA20EE88FE3008900D0 /* kdumpd */, - 724DABDB0EE8912D008900D0 /* natd */, 724DAC0D0EE8940D008900D0 /* ndp */, 7216D2460EE896C000AE70E4 /* netstat */, 7216D27C0EE8980A00AE70E4 /* ping */, @@ -2318,16 +2230,6 @@ }; /* End PBXGroup section */ -/* Begin PBXHeadersBuildPhase section */ - 726121080EE8707500AFED1B /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - /* Begin PBXNativeTarget section */ 4D2B04F21208C2040004A3F3 /* ip6addrctl */ = { isa = PBXNativeTarget; @@ -2636,24 +2538,6 @@ productReference = 724DABA20EE88FE3008900D0 /* kdumpd */; productType = "com.apple.product-type.tool"; }; - 724DABDA0EE8912D008900D0 /* natd */ = { - isa = PBXNativeTarget; - buildConfigurationList = 724DABEA0EE891AD008900D0 /* Build configuration list for PBXNativeTarget "natd" */; - buildPhases = ( - 724DABD80EE8912D008900D0 /* Sources */, - 724DABD90EE8912D008900D0 /* Frameworks */, - 724DABE90EE891AD008900D0 /* CopyFiles */, - 724DABE80EE8917A008900D0 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = natd; - productName = natd; - productReference = 724DABDB0EE8912D008900D0 /* natd */; - productType = "com.apple.product-type.tool"; - }; 724DAC0C0EE8940D008900D0 /* ndp */ = { isa = PBXNativeTarget; buildConfigurationList = 724DAC1E0EE894E8008900D0 /* Build configuration list for PBXNativeTarget "ndp" */; @@ -2672,24 +2556,6 @@ productReference = 724DAC0D0EE8940D008900D0 /* ndp */; productType = "com.apple.product-type.tool"; }; - 7261210B0EE8707500AFED1B /* alias */ = { - isa = PBXNativeTarget; - buildConfigurationList = 726121100EE8707600AFED1B /* Build configuration list for PBXNativeTarget "alias" */; - buildPhases = ( - 726121080EE8707500AFED1B /* Headers */, - 726121090EE8707500AFED1B /* Sources */, - 7261210A0EE8707500AFED1B /* Frameworks */, - 7294F1510EE8BF2D0052EC88 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = alias; - productName = alias; - productReference = 7261210C0EE8707500AFED1B /* libalias.A.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; 7261212C0EE8710B00AFED1B /* arp */ = { isa = PBXNativeTarget; buildConfigurationList = 726121400EE8713B00AFED1B /* Build configuration list for PBXNativeTarget "arp" */; @@ -2857,7 +2723,6 @@ 72570DA20EE8EBF3000F4CFB /* All-Embedded */, 72ABD0811083D742008C721C /* All-EmbeddedOther */, 72C77D3A1484199C002D2577 /* network_cmds_libs */, - 7261210B0EE8707500AFED1B /* alias */, 7261212C0EE8710B00AFED1B /* arp */, 72B732D91899B0380060E6D4 /* cfilutil */, 723C7067142BAFEA007C87E9 /* dnctl */, @@ -2870,7 +2735,6 @@ 72311F41194A349000EB4788 /* mptcp_client */, 690D978012DE6034004323A7 /* mtest */, 724DAC0C0EE8940D008900D0 /* ndp */, - 724DABDA0EE8912D008900D0 /* natd */, 7216D2450EE896C000AE70E4 /* netstat */, 7247B83016165EDC00873B3C /* pktapctl */, 7200F2F91958A34D0033E22C /* pktmnglr */, @@ -3048,19 +2912,6 @@ shellPath = /bin/sh; shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/spray.8"; }; - 724DABE80EE8917A008900D0 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/natd.8\t"; - }; 724DAC440EE89562008900D0 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; @@ -3100,19 +2951,6 @@ shellPath = /bin/sh; shellScript = "/bin/chmod 0444 $DSTROOT/usr/share/man/man8/traceroute6.8"; }; - 7294F1510EE8BF2D0052EC88 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "/bin/ln -s libalias.A.dylib $DSTROOT/usr/lib/libalias.dylib"; - }; 72CD1DA00EE8C4EC005F825D /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; @@ -3271,6 +3109,7 @@ 7216D2570EE896F300AE70E4 /* tp_astring.c in Sources */, 56B6B66816F79A1C00D8A7A9 /* mptcp.c in Sources */, 7216D2580EE896F300AE70E4 /* unix.c in Sources */, + 721654C31EC52447005B17BA /* misc.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3379,15 +3218,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 724DABD80EE8912D008900D0 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 724DABDF0EE89151008900D0 /* natd.c in Sources */, - 724DABE00EE89155008900D0 /* icmp.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 724DAC0A0EE8940D008900D0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -3396,23 +3226,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 726121090EE8707500AFED1B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 726121110EE870AB00AFED1B /* alias.c in Sources */, - 726121130EE870AB00AFED1B /* alias_cuseeme.c in Sources */, - 726121140EE870AB00AFED1B /* alias_db.c in Sources */, - 726121150EE870AB00AFED1B /* alias_ftp.c in Sources */, - 726121160EE870AB00AFED1B /* alias_irc.c in Sources */, - 726121180EE870AB00AFED1B /* alias_nbt.c in Sources */, - 726121190EE870AB00AFED1B /* alias_pptp.c in Sources */, - 7261211A0EE870AB00AFED1B /* alias_proxy.c in Sources */, - 7261211B0EE870AB00AFED1B /* alias_smedia.c in Sources */, - 7261211C0EE870AB00AFED1B /* alias_util.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 7261212A0EE8710B00AFED1B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -3434,6 +3247,8 @@ 72E650A9107BF2F000AAF325 /* af_link.c in Sources */, 72E650AA107BF2F000AAF325 /* ifbridge.c in Sources */, 72E650AB107BF2F000AAF325 /* ifclone.c in Sources */, + F940359D1E2FF5A900283EB1 /* iffake.c in Sources */, + F97F1E041E9C3FC8002355FF /* nexus.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3807,11 +3622,6 @@ target = 72B732D91899B0380060E6D4 /* cfilutil */; targetProxy = 72B732EA1899B19A0060E6D4 /* PBXContainerItemProxy */; }; - 72C77D3B1484199C002D2577 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 7261210B0EE8707500AFED1B /* alias */; - targetProxy = 72C77D3C1484199C002D2577 /* PBXContainerItemProxy */; - }; 72CD1D9C0EE8C47C005F825D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 7294F1290EE8BD280052EC88 /* traceroute6 */; @@ -3871,36 +3681,11 @@ }; name = "Ignore Me"; }; - 03B2DBE5100BE71D005349BC /* Ignore Me */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEAD_CODE_STRIPPING = YES; - DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_PREFIX = lib; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G5; - HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; - INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; - INSTALL_PATH = /usr/lib; - PREBINDING = NO; - PRODUCT_NAME = alias.A; - ZERO_LINK = NO; - }; - name = "Ignore Me"; - }; 03B2DBE6100BE71D005349BC /* Ignore Me */ = { isa = XCBuildConfiguration; buildSettings = { HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = arp; }; @@ -3921,9 +3706,7 @@ USE_BONDS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ifconfig; ZERO_LINK = NO; @@ -3935,31 +3718,12 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist"; CODE_SIGN_IDENTITY = "-"; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/libexec; PRODUCT_NAME = kdumpd; }; name = "Ignore Me"; }; - 03B2DBEC100BE71D005349BC /* Ignore Me */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; - HEADER_SEARCH_PATHS = ../alias; - INSTALL_GROUP = wheel; - INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; - INSTALL_PATH = /usr/sbin; - PRODUCT_NAME = natd; - WARNING_CFLAGS = ( - "$(inherited)", - "-Wno-deprecated-declarations", - ); - }; - name = "Ignore Me"; - }; 03B2DBED100BE71D005349BC /* Ignore Me */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3970,9 +3734,7 @@ KAME_SCOPEID, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = ndp; }; @@ -3987,9 +3749,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = netstat; }; @@ -4001,9 +3761,7 @@ CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist"; CODE_SIGN_IDENTITY = "-"; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ping; }; @@ -4015,9 +3773,7 @@ CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist"; CODE_SIGN_IDENTITY = "-"; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ping6; }; @@ -4033,9 +3789,7 @@ "$(inherited)", "TFTP_DIR=\\\"/tftpboot\\\"", ); - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = rarpd; }; @@ -4050,9 +3804,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = route; }; @@ -4069,9 +3821,7 @@ HAVE_GETIFADDRS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = rtadvd; WARNING_CFLAGS = ( @@ -4094,9 +3844,7 @@ HAVE_GETIFADDRS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = rtsol; WARNING_CFLAGS = ( @@ -4109,9 +3857,7 @@ 03B2DBF5100BE71D005349BC /* Ignore Me */ = { isa = XCBuildConfiguration; buildSettings = { - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = spray; }; @@ -4128,9 +3874,7 @@ HAVE_SOCKADDR_SA_LEN, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = traceroute; }; @@ -4147,9 +3891,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = traceroute6; }; @@ -4158,18 +3900,14 @@ 4D2B04F51208C2050004A3F3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALTERNATE_GROUP = wheel; ALTERNATE_MODE = 0555; - ALTERNATE_OWNER = root; ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/local/bin; PREBINDING = NO; PRODUCT_NAME = ip6addrctl; @@ -4263,9 +4001,7 @@ GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/local/bin; PREBINDING = NO; PRODUCT_NAME = mtest; @@ -4283,9 +4019,7 @@ "DEBUG_INFORMATION_FORMAT[sdk=iphoneos*][arch=*]" = dwarf; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/local/bin; PREBINDING = NO; PRODUCT_NAME = mtest; @@ -4302,9 +4036,7 @@ "DEBUG_INFORMATION_FORMAT[sdk=iphoneos*][arch=*]" = dwarf; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/local/bin; PREBINDING = NO; PRODUCT_NAME = mtest; @@ -4335,9 +4067,7 @@ GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNUSED_FUNCTION = YES; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/libexec; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4368,9 +4098,7 @@ GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNUSED_FUNCTION = YES; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/libexec; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4401,9 +4129,7 @@ GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNUSED_FUNCTION = YES; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/libexec; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4522,9 +4248,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = netstat; }; @@ -4539,9 +4263,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = netstat; }; @@ -4559,9 +4281,7 @@ "DEBUG=1", ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ping; }; @@ -4573,9 +4293,7 @@ CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist"; CODE_SIGN_IDENTITY = "-"; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ping; }; @@ -4587,9 +4305,7 @@ CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist"; CODE_SIGN_IDENTITY = "-"; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ping6; }; @@ -4601,9 +4317,7 @@ CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist"; CODE_SIGN_IDENTITY = "-"; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ping6; }; @@ -4619,9 +4333,7 @@ "$(inherited)", "TFTP_DIR=\\\"/tftpboot\\\"", ); - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = rarpd; }; @@ -4637,9 +4349,7 @@ "$(inherited)", "TFTP_DIR=\\\"/tftpboot\\\"", ); - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = rarpd; }; @@ -4654,9 +4364,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = route; }; @@ -4671,9 +4379,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = route; }; @@ -4690,9 +4396,7 @@ HAVE_GETIFADDRS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = rtadvd; WARNING_CFLAGS = ( @@ -4714,9 +4418,7 @@ HAVE_GETIFADDRS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = rtadvd; WARNING_CFLAGS = ( @@ -4739,9 +4441,7 @@ HAVE_GETIFADDRS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = rtsol; WARNING_CFLAGS = ( @@ -4763,9 +4463,7 @@ HAVE_GETIFADDRS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = rtsol; WARNING_CFLAGS = ( @@ -4778,9 +4476,7 @@ 7216D3A90EE8A3BB00AE70E4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = spray; }; @@ -4789,9 +4485,7 @@ 7216D3AA0EE8A3BB00AE70E4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = spray; }; @@ -4915,9 +4609,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -4931,9 +4623,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -4947,9 +4637,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -4959,9 +4647,7 @@ isa = XCBuildConfiguration; buildSettings = { HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -4970,9 +4656,7 @@ isa = XCBuildConfiguration; buildSettings = { HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -4981,9 +4665,7 @@ isa = XCBuildConfiguration; buildSettings = { HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = "Ignore Me"; @@ -5054,9 +4736,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist"; CODE_SIGN_IDENTITY = "-"; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/libexec; PRODUCT_NAME = kdumpd; }; @@ -5067,48 +4747,12 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/network-client-server-entitlements.plist"; CODE_SIGN_IDENTITY = "-"; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/libexec; PRODUCT_NAME = kdumpd; }; name = Release; }; - 724DABDD0EE8912E008900D0 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; - HEADER_SEARCH_PATHS = ../alias; - INSTALL_GROUP = wheel; - INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; - INSTALL_PATH = /usr/sbin; - PRODUCT_NAME = natd; - WARNING_CFLAGS = ( - "$(inherited)", - "-Wno-deprecated-declarations", - ); - }; - name = Debug; - }; - 724DABDE0EE8912E008900D0 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; - HEADER_SEARCH_PATHS = ../alias; - INSTALL_GROUP = wheel; - INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; - INSTALL_PATH = /usr/sbin; - PRODUCT_NAME = natd; - WARNING_CFLAGS = ( - "$(inherited)", - "-Wno-deprecated-declarations", - ); - }; - name = Release; - }; 724DAC0F0EE8940E008900D0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5119,9 +4763,7 @@ KAME_SCOPEID, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = ndp; }; @@ -5137,9 +4779,7 @@ KAME_SCOPEID, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = ndp; }; @@ -5165,59 +4805,11 @@ }; name = Release; }; - 7261210E0EE8707600AFED1B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_PREFIX = lib; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; - INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; - INSTALL_PATH = /usr/lib; - PREBINDING = NO; - PRODUCT_NAME = alias.A; - }; - name = Debug; - }; - 7261210F0EE8707600AFED1B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEAD_CODE_STRIPPING = YES; - DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_PREFIX = lib; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G5; - HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; - INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; - INSTALL_PATH = /usr/lib; - PREBINDING = NO; - PRODUCT_NAME = alias.A; - ZERO_LINK = NO; - }; - name = Release; - }; 7261212F0EE8710B00AFED1B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = arp; }; @@ -5227,9 +4819,7 @@ isa = XCBuildConfiguration; buildSettings = { HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = arp; }; @@ -5271,9 +4861,7 @@ USE_BONDS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ifconfig; }; @@ -5294,9 +4882,7 @@ USE_BONDS, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; INSTALL_PATH = /sbin; PRODUCT_NAME = ifconfig; ZERO_LINK = NO; @@ -5525,9 +5111,7 @@ HAVE_SOCKADDR_SA_LEN, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = traceroute; }; @@ -5544,9 +5128,7 @@ HAVE_SOCKADDR_SA_LEN, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = traceroute; }; @@ -5563,9 +5145,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = traceroute6; }; @@ -5582,9 +5162,7 @@ IPSEC, ); HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 04555; - INSTALL_OWNER = root; INSTALL_PATH = /usr/sbin; PRODUCT_NAME = traceroute6; }; @@ -5659,9 +5237,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; MACOSX_DEPLOYMENT_TARGET = ""; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -5691,9 +5267,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; MACOSX_DEPLOYMENT_TARGET = ""; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -5723,9 +5297,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_GROUP = wheel; INSTALL_MODE_FLAG = 0555; - INSTALL_OWNER = root; MACOSX_DEPLOYMENT_TARGET = ""; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -5946,16 +5518,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 724DABEA0EE891AD008900D0 /* Build configuration list for PBXNativeTarget "natd" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 724DABDD0EE8912E008900D0 /* Debug */, - 724DABDE0EE8912E008900D0 /* Release */, - 03B2DBEC100BE71D005349BC /* Ignore Me */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 724DAC1E0EE894E8008900D0 /* Build configuration list for PBXNativeTarget "ndp" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -5976,16 +5538,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 726121100EE8707600AFED1B /* Build configuration list for PBXNativeTarget "alias" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7261210E0EE8707600AFED1B /* Debug */, - 7261210F0EE8707600AFED1B /* Release */, - 03B2DBE5100BE71D005349BC /* Ignore Me */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 726121400EE8713B00AFED1B /* Build configuration list for PBXNativeTarget "arp" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/ping.tproj/ping.8 b/ping.tproj/ping.8 index defb856..a2955a6 100644 --- a/ping.tproj/ping.8 +++ b/ping.tproj/ping.8 @@ -83,7 +83,7 @@ packets to network hosts .Op Fl W Ar waittime .Op Fl z Ar tos .Op Fl Fl apple-connect -.Op Fl Fl apple-print +.Op Fl Fl apple-time .Ar host .Nm .Op Fl AaDdfLnoQqRrv @@ -105,7 +105,7 @@ packets to network hosts .Op Fl W Ar waittime .Op Fl z Ar tos .Op Fl Fl apple-connect -.Op Fl Fl apple-print +.Op Fl Fl apple-time .Ar mcast-group .Sh DESCRIPTION The @@ -372,7 +372,7 @@ Use the specified type of service. .It Fl Fl apple-connect Connects the socket to the destination address. This option is an Apple addition. -.It Fl Fl apple-print +.It Fl Fl apple-time Prints the time a packet was received. This option is an Apple addition. .El diff --git a/ping6.tproj/ping6.8 b/ping6.tproj/ping6.8 index e19b066..7ec0b70 100644 --- a/ping6.tproj/ping6.8 +++ b/ping6.tproj/ping6.8 @@ -125,7 +125,7 @@ packets to network hosts .Op Fl Fl apple-connect .Ek .Bk -words -.Op Fl Fl apple-print +.Op Fl Fl apple-time .Ek .Bk -words .Op Ar hops ... @@ -395,7 +395,7 @@ Use the specified traffic class. .It Fl Fl apple-connect Connects the socket to the destination address. This option is an Apple addition. -.It Fl Fl apple-print +.It Fl Fl apple-time Prints the time a packet was received. This option is an Apple addition. .It Ar hops diff --git a/ping6.tproj/ping6.c b/ping6.tproj/ping6.c index c5b0785..f4d2411 100644 --- a/ping6.tproj/ping6.c +++ b/ping6.tproj/ping6.c @@ -148,9 +148,6 @@ __unused static const char copyright[] = #include #include #include -#ifdef HAVE_POLL_H -#include -#endif #include #include @@ -178,6 +175,8 @@ struct tv32 { #define DEFDATALEN ICMP6ECHOTMLEN #define MAXDATALEN MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN #define NROUTES 9 /* number of record route slots */ +#define MAXWAIT 10000 /* max ms to wait for response */ +#define MAXALARM (60 * 60) /* max seconds for alarm timeout */ #define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ #define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ @@ -217,6 +216,7 @@ struct tv32 { #define F_SWEEP 0x2000000 #define F_CONNECT 0x4000000 #define F_NOUSERDATA (F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES) +#define F_WAITTIME 0x8000000 u_int options; static int longopt_flag = 0; @@ -267,12 +267,6 @@ struct cmsghdr *cm = NULL; char *boundif; unsigned int ifscope; int nocell; -#ifdef HAVE_POLL_H -struct pollfd fdmaskp[1]; -#else -fd_set *fdmaskp = NULL; -int fdmasks; -#endif /* counters */ long nmissedmax; /* max value of ntransmitted - nreceived - 1 */ @@ -280,7 +274,10 @@ long npackets; /* max packets to transmit */ long nreceived; /* # of packets we got back */ long nrepeats; /* number of duplicates */ long ntransmitted; /* sequence # for outbound packets = #sent */ -struct timeval interval = {1, 0}; /* interval between packets */ +static int interval = 1000; /* interval between packets in ms */ +static int waittime = MAXWAIT; /* timeout for each packet */ +static long nrcvtimeout = 0; /* # of packets we got back after waittime */ + long snpackets = 0; /* max packets to transmit in one sweep */ long sntransmitted = 0; /* # of packets we sent in this sweep */ int sweepmax = 0; /* max value of payload in sweep */ @@ -327,7 +324,6 @@ int get_tclass(struct msghdr *); int get_so_traffic_class(struct msghdr *); struct in6_pktinfo *get_rcvpktinfo(struct msghdr *); void onsignal(int); -void retransmit(void); void onint(int); size_t pingerlen(void); int pinger(void); @@ -349,7 +345,7 @@ void pr_retip(struct ip6_hdr *, u_char *); void summary(void); void tvsub(struct timeval *, struct timeval *); int setpolicy(int, char *); -char *nigroup(char *); +char *nigroup(char *, int); static int str2sotc(const char *, bool *); static int str2netservicetype(const char *, bool *); static u_int8_t str2tclass(const char *, bool *); @@ -358,19 +354,12 @@ void usage(void); int main(int argc, char *argv[]) { - struct itimerval itimer; + struct timeval last, intvl; struct sockaddr_in6 from; -#ifndef HAVE_ARC4RANDOM - struct timeval seed; -#endif -#ifdef HAVE_POLL_H - int timeout; -#else - struct timeval timeout, *tv; -#endif struct addrinfo hints; int cc, i; - int ch, hold, packlen, preload, optval, ret_ga; + int almost_done, ch, hold, packlen, preload, optval, ret_ga; + int nig_oldmcprefix = -1; u_char *datap; char *e, *target, *ifname = NULL, *gateway = NULL; int ip6optlen = 0; @@ -388,7 +377,8 @@ main(int argc, char *argv[]) char *policy_in = NULL; char *policy_out = NULL; #endif - double intval; + double t; + u_long alarmtimeout; size_t rthlen; #ifdef IPV6_USE_MIN_MTU int mflag = 0; @@ -396,7 +386,6 @@ main(int argc, char *argv[]) /* T_CLASS value -1 means default, so -2 means do not bother */ int tclass = -2; bool valid; - struct timeval intvl; /* just to be sure */ memset(&smsghdr, 0, sizeof(smsghdr)); @@ -583,22 +572,22 @@ main(int argc, char *argv[]) #endif break; case 'i': /* wait between sending packets */ - intval = strtod(optarg, &e); + t = strtod(optarg, &e); if (*optarg == '\0' || *e != '\0') errx(1, "illegal timing interval %s", optarg); - if (intval < 0.1 && getuid()) { - errx(1, "%s: only root may use interval < 0.1s", + if (t < 1 && getuid()) { + errx(1, "%s: only root may use interval < 1s", strerror(EPERM)); } - interval.tv_sec = (long)intval; - interval.tv_usec = - (long)((intval - interval.tv_sec) * 1000000); - if (interval.tv_sec < 0) + intvl.tv_sec = (long)t; + intvl.tv_usec = + (long)((t - intvl.tv_sec) * 1000000); + if (intvl.tv_sec < 0) errx(1, "illegal timing interval %s", optarg); /* less than 1/hz does not make sense */ - if (interval.tv_sec == 0 && interval.tv_usec < 1) { + if (intvl.tv_sec == 0 && intvl.tv_usec < 1) { warnx("too small interval, raised to .000001"); - interval.tv_usec = 1; + intvl.tv_usec = 1; } options |= F_INTERVAL; break; @@ -650,6 +639,7 @@ main(int argc, char *argv[]) break; case 'N': options |= F_NIGROUP; + nig_oldmcprefix++; break; case 'o': options |= F_ONCE; @@ -720,6 +710,16 @@ main(int argc, char *argv[]) errx(1, "illegal TOS value -- %s", optarg); rcvtclass = 1; break; + case 'X': + alarmtimeout = strtoul(optarg, &e, 0); + if (alarmtimeout < 1 || alarmtimeout == ULONG_MAX) + errx(EX_USAGE, "invalid timeout: `%s'", + optarg); + if (alarmtimeout > MAXALARM) + errx(EX_USAGE, "invalid timeout: `%s' > %d", + optarg, MAXALARM); + alarm((int)alarmtimeout); + break; #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC case 'P': @@ -794,7 +794,7 @@ main(int argc, char *argv[]) } if (options & F_NIGROUP) { - target = nigroup(argv[argc - 1]); + target = nigroup(argv[argc - 1], nig_oldmcprefix); if (target == NULL) { usage(); /*NOTREACHED*/ @@ -813,7 +813,7 @@ main(int argc, char *argv[]) if (ret_ga) errx(1, "getaddrinfo -- %s", gai_strerror(ret_ga)); if (res->ai_canonname) - hostname = res->ai_canonname; + hostname = strdup(res->ai_canonname); else hostname = target; @@ -935,6 +935,11 @@ main(int argc, char *argv[]) } if ((options & F_NOUSERDATA) == 0) { + if (datalen >= sizeof(struct tv32)) { + /* we can time transfer */ + timing = 1; + } else + timing = 0; /* in F_VERBOSE case, we may get non-echoreply packets*/ if (options & F_VERBOSE) packlen = MAX(2048, sweepmax) + IP6LEN + ICMP6ECHOLEN + EXTRA; @@ -947,30 +952,21 @@ main(int argc, char *argv[]) packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA; } - if (!(packet = (u_char *)malloc((u_int)MAX(datalen, sweepmax)))) + if (!(packet = (u_char *)malloc(packlen))) err(1, "Unable to allocate packet"); if (!(options & F_PINGFILLED)) for (i = ICMP6ECHOLEN; i < MAX(datalen, sweepmax); ++i) *datap++ = i; ident = getpid() & 0xFFFF; -#ifndef HAVE_ARC4RANDOM - gettimeofday(&seed, NULL); - srand((unsigned int)(seed.tv_sec ^ seed.tv_usec ^ (long)ident)); - memset(nonce, 0, sizeof(nonce)); - for (i = 0; i < sizeof(nonce); i += sizeof(int)) - *((int *)&nonce[i]) = rand(); -#else - memset(nonce, 0, sizeof(nonce)); - for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t)) - *((u_int32_t *)&nonce[i]) = arc4random(); -#endif + arc4random_buf(nonce, sizeof(nonce)); optval = 1; if (options & F_DONTFRAG) if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG, &optval, sizeof(optval)) == -1) err(1, "IPV6_DONTFRAG"); hold = 1; + if (options & F_SO_DEBUG) (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold, sizeof(hold)); @@ -1375,8 +1371,15 @@ main(int argc, char *argv[]) printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src))); printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst))); - while (preload--) /* Fire off them quickies. */ - (void)pinger(); + if (preload == 0) + pinger(); + else { + if (npackets != 0 && preload > npackets) + preload = npackets; + while (preload--) + pinger(); + } + gettimeofday(&last, NULL); /* * rdar://25829310 @@ -1397,171 +1400,146 @@ main(int argc, char *argv[]) #ifdef SIGINFO (void)signal(SIGINFO, onsignal); #endif - - if ((options & F_FLOOD) == 0) { - if (signal(SIGALRM, onsignal) == SIG_ERR) - warn("signal(SIGALRM)"); - itimer.it_interval = interval; - itimer.it_value = interval; - (void)setitimer(ITIMER_REAL, &itimer, NULL); - if (ntransmitted == 0) - retransmit(); + if (alarmtimeout > 0) { + (void)signal(SIGALRM, onsignal); } if (options & F_FLOOD) { intvl.tv_sec = 0; intvl.tv_usec = 10000; - } else { - intvl.tv_sec = interval.tv_sec; - intvl.tv_usec = interval.tv_usec; + } else if ((options & F_INTERVAL) == 0) { + intvl.tv_sec = interval / 1000; + intvl.tv_usec = interval % 1000 * 1000; } - -#ifndef HAVE_POLL_H - fdmasks = howmany(s + 1, NFDBITS) * sizeof(fd_mask); - if ((fdmaskp = malloc(fdmasks)) == NULL) - err(1, "malloc"); -#endif /* For control (ancillary) data received from recvmsg() */ cm = (struct cmsghdr *)malloc(CONTROLLEN); if (cm == NULL) err(1, "malloc"); - for (;;) { + almost_done = 0; + while (seenint == 0) { + struct timeval now, timeout; struct msghdr m; struct iovec iov[2]; + fd_set rfds; + int n; /* signal handling */ - if (seenalrm) { - seenalrm = 0; - /* last packet sent, timeout reached? */ - if (npackets && ntransmitted >= npackets) - break; - /* sweep done ? */ - if (sweepmax && datalen > sweepmax) - break; - retransmit(); - continue; - } - if (seenint) { - seenint = 0; + if (seenint) onint(SIGINT); - continue; - } #ifdef SIGINFO if (seeninfo) { - seeninfo = 0; summary(); + seeninfo = 0; continue; } #endif - - if (options & F_FLOOD) { - if (pinger() != 0) - break; -#ifdef HAVE_POLL_H - timeout = 10; -#else - timeout.tv_sec = 0; - timeout.tv_usec = 10000; - tv = &timeout; -#endif - } else { -#ifdef HAVE_POLL_H - timeout = INFTIM; -#else - tv = NULL; -#endif - } -#ifdef HAVE_POLL_H - fdmaskp[0].fd = s; - fdmaskp[0].events = POLLIN; - cc = poll(fdmaskp, 1, timeout); -#else - memset(fdmaskp, 0, fdmasks); - FD_SET(s, fdmaskp); - cc = select(s + 1, fdmaskp, NULL, NULL, tv); -#endif - if (cc < 0) { - if (errno != EINTR) { -#ifdef HAVE_POLL_H - warn("poll"); -#else - warn("select"); -#endif - sleep(1); + FD_ZERO(&rfds); + FD_SET(s, &rfds); + gettimeofday(&now, NULL); + timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec; + timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec; + while (timeout.tv_usec < 0) { + timeout.tv_usec += 1000000; + timeout.tv_sec--; } - continue; - } else if (cc == 0) { - continue; + while (timeout.tv_usec > 1000000) { + timeout.tv_usec -= 1000000; + timeout.tv_sec++; } - m.msg_name = (caddr_t)&from; - m.msg_namelen = sizeof(from); - memset(&iov, 0, sizeof(iov)); - iov[0].iov_base = (caddr_t)packet; - iov[0].iov_len = packlen; - m.msg_iov = iov; - m.msg_iovlen = 1; - memset(cm, 0, CONTROLLEN); - m.msg_control = (void *)cm; - m.msg_controllen = CONTROLLEN; - - cc = recvmsg(s, &m, 0); - if (cc < 0) { - if (errno != EINTR) { - warn("recvmsg"); - sleep(1); - } - continue; - } else if (cc == 0) { - int mtu; + if (timeout.tv_sec < 0) + timeout.tv_sec = timeout.tv_usec = 0; + + n = select(s + 1, &rfds, NULL, NULL, &timeout); + if (n < 0) + continue; /* EINTR */ + if (n == 1) { + m.msg_name = (caddr_t)&from; + m.msg_namelen = sizeof(from); + memset(&iov, 0, sizeof(iov)); + iov[0].iov_base = (caddr_t)packet; + iov[0].iov_len = packlen; + m.msg_iov = iov; + m.msg_iovlen = 1; + memset(cm, 0, CONTROLLEN); + m.msg_control = (void *)cm; + m.msg_controllen = CONTROLLEN; + m.msg_flags = 0; + + cc = recvmsg(s, &m, 0); + if (cc < 0) { + if (errno != EINTR) { + warn("recvmsg"); + sleep(1); + } + continue; + } else if (cc == 0) { + int mtu; - /* - * receive control messages only. Process the - * exceptions (currently the only possibility is - * a path MTU notification.) - */ - if ((mtu = get_pathmtu(&m)) > 0) { - if ((options & F_VERBOSE) != 0) { - printf("new path MTU (%d) is " - "notified\n", mtu); + /* + * receive control messages only. Process the + * exceptions (currently the only possibility is + * a path MTU notification.) + */ + if ((mtu = get_pathmtu(&m)) > 0) { + if ((options & F_VERBOSE) != 0) { + printf("new path MTU (%d) is " + "notified\n", mtu); + } } + continue; + } else { + /* + * an ICMPv6 message (probably an echoreply) + * arrived. + */ + pr_pack(packet, cc, &m); } - continue; - } else { - /* - * an ICMPv6 message (probably an echoreply) arrived. - */ - pr_pack(packet, cc, &m); + if (((options & F_ONCE) != 0 && nreceived > 0) || + (npackets > 0 && nreceived >= npackets) || + (sweepmax && datalen > sweepmax)) + break; } - if (((options & F_ONCE) != 0 && nreceived > 0) || - (npackets > 0 && nreceived >= npackets)) - break; - if (ntransmitted - nreceived - 1 > nmissedmax) { - nmissedmax = ntransmitted - nreceived - 1; - if (options & F_MISSED) - (void)write(STDOUT_FILENO, &BBELL, 1); + if (n == 0 || (options & F_FLOOD)) { + if (npackets == 0 || ntransmitted < npackets) + pinger(); + else { + if (almost_done) + break; + almost_done = 1; + /* + * If we're not transmitting any more packets, + * change the timer to wait two round-trip times + * if we've received any packets or (waittime) + * milliseconds if we haven't. + */ + intvl.tv_usec = 0; + if (nreceived) { + intvl.tv_sec = 2 * tmax / 1000; + if (intvl.tv_sec == 0) + intvl.tv_sec = 1; + } else { + intvl.tv_sec = waittime / 1000; + intvl.tv_usec = waittime % 1000 * 1000; + } + } + gettimeofday(&last, NULL); + if (ntransmitted - nreceived - 1 > nmissedmax) { + nmissedmax = ntransmitted - nreceived - 1; + if (options & F_MISSED) + (void)write(STDOUT_FILENO, &BBELL, 1); + } } } + sigemptyset(&newset); + if (sigprocmask(SIG_SETMASK, &newset, NULL) != 0) + err(EX_OSERR, "sigprocmask(newset)"); summary(); - if (res != NULL) - freeaddrinfo(res); - if (packet != NULL) free(packet); - if (cm != NULL) - free(cm); - - if (scmsg != NULL) - free(scmsg); - -#ifndef HAVE_POLL_H - if (fdmaskp != NULL) - free(fdmaskp); -#endif - exit(nreceived == 0 ? 2 : 0); } @@ -1571,10 +1549,8 @@ onsignal(int sig) fflush(stdout); switch (sig) { - case SIGALRM: - seenalrm++; - break; case SIGINT: + case SIGALRM: seenint++; break; #ifdef SIGINFO @@ -1585,38 +1561,6 @@ onsignal(int sig) } } -/* - * retransmit -- - * This routine transmits another ping6. - */ -void -retransmit(void) -{ - struct itimerval itimer; - - if (pinger() == 0) { - return; - } - /* - * If we're not transmitting any more packets, change the timer - * to wait two round-trip times if we've received any packets or - * ten seconds if we haven't. - */ -#define MAXWAIT 10 - if (nreceived) { - itimer.it_value.tv_sec = 2 * tmax / 1000; - if (itimer.it_value.tv_sec == 0) - itimer.it_value.tv_sec = 1; - } else - itimer.it_value.tv_sec = MAXWAIT; - itimer.it_interval.tv_sec = 0; - itimer.it_interval.tv_usec = 0; - itimer.it_value.tv_usec = 0; - - (void)signal(SIGALRM, onsignal); - (void)setitimer(ITIMER_REAL, &itimer, NULL); -} - /* * pinger -- * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet @@ -1727,11 +1671,6 @@ pinger(void) icp->icmp6_code = 0; icp->icmp6_id = htons(ident); icp->icmp6_seq = ntohs(seq); - if (datalen >= sizeof(struct tv32)) { - /* we can time transfer */ - timing = 1; - } else - timing = 0; if (timing) { struct timeval tv; struct tv32 *tv32; @@ -1956,6 +1895,11 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) if (options & F_QUIET) return; + if (options & F_WAITTIME && triptime > waittime) { + ++nrcvtimeout; + return; + } + if (options & F_FLOOD) (void)write(STDOUT_FILENO, &BSPACE, 1); else { @@ -1993,9 +1937,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) dp = outpack + ICMP6ECHOLEN + ICMP6ECHOTMLEN; for (i = 8; cp < end; ++i, ++cp, ++dp) { if (*cp != *dp) { - (void)printf("\nwrong data byte #%d " - "should be 0x%x but was 0x%x", - i, *dp, *cp); + (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, *dp, *cp); break; } } @@ -2006,8 +1948,10 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) if (TST(seq % mx_dup_ck)) { ++nrepeats; --nreceived; + dupflag = 1; } else { SET(seq % mx_dup_ck); + dupflag = 0; } if (options & F_QUIET) @@ -2101,8 +2045,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) putchar(')'); goto fqdnend; } - ttl = (int32_t)ntohl(*(u_int32_t *) - &buf[off+ICMP6ECHOLEN+8]); + ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]); if (comma) printf(","); if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) { @@ -2173,6 +2116,7 @@ pr_exthdrs(struct msghdr *mhdr) void *bufp; struct cmsghdr *cm; + bufsize = 0; bufp = mhdr->msg_control; for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { @@ -2673,30 +2617,12 @@ tvsub(struct timeval *out, struct timeval *in) void onint(int notused __unused) { - summary(); - - if (res != NULL) - freeaddrinfo(res); - - if (packet != NULL) - free(packet); - - if (cm != NULL) - free(cm); - - if (scmsg != NULL) - free(scmsg); - -#ifndef HAVE_POLL_H - if (fdmaskp != NULL) - free(fdmaskp); -#endif - - (void)signal(SIGINT, SIG_DFL); - (void)kill(getpid(), SIGINT); - - /* NOTREACHED */ - exit(1); + /* + * When doing reverse DNS lookups, the seenint flag might not + * be noticed for a while. Just exit if we get a second SIGINT. + */ + if ((options & F_HOSTNAME) && seenint != 0) + _exit(nreceived ? 0 : 2); } /* @@ -2719,6 +2645,8 @@ summary(void) ((((double)ntransmitted - nreceived) * 100.0) / ntransmitted)); } + if (nrcvtimeout) + printf(", %ld packets out of wait time", nrcvtimeout); (void)putchar('\n'); if (nreceived && timing) { /* Only display average to microseconds */ @@ -3162,7 +3090,7 @@ setpolicy(int so __unused, char *policy) #endif char * -nigroup(char *name) +nigroup(char *name, int nig_oldmcprefix) { char *p; char *q; @@ -3172,6 +3100,7 @@ nigroup(char *name) size_t l; char hbuf[NI_MAXHOST]; struct in6_addr in6; + int valid; p = strchr(name, '.'); if (!p) @@ -3187,7 +3116,7 @@ nigroup(char *name) *q = tolower(*(unsigned char *)q); } - /* generate 8 bytes of pseudo-random value. */ + /* generate 16 bytes of pseudo-random value. */ memset(&ctxt, 0, sizeof(ctxt)); MD5Init(&ctxt); c = l & 0xff; @@ -3195,9 +3124,23 @@ nigroup(char *name) MD5Update(&ctxt, (unsigned char *)name, l); MD5Final(digest, &ctxt); - if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1) + if (nig_oldmcprefix) { + /* draft-ietf-ipngwg-icmp-name-lookup */ + valid = inet_pton(AF_INET6, "ff02::2:0000:0000", &in6); + } else { + /* RFC 4620 */ + valid = inet_pton(AF_INET6, "ff02::2:ff00:0000", &in6); + } + if (valid != 1) return NULL; /*XXX*/ + + if (nig_oldmcprefix) { + /* draft-ietf-ipngwg-icmp-name-lookup */ bcopy(digest, &in6.s6_addr[12], 4); + } else { + /* RFC 4620 */ + bcopy(digest, &in6.s6_addr[13], 3); + } if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL) return NULL; diff --git a/rtadvd.tproj/rtadvd.c b/rtadvd.tproj/rtadvd.c index aea6118..7ca027d 100644 --- a/rtadvd.tproj/rtadvd.c +++ b/rtadvd.tproj/rtadvd.c @@ -1535,7 +1535,8 @@ struct rainfo *rainfo; struct in6_pktinfo *pi; struct soliciter *sol, *nextsol; - if ((iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) { + if (iflist[rainfo->ifindex] == NULL || + (iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) { syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA", __func__, rainfo->ifname); return; -- 2.45.2