*~.m
*~.c
*~.h
+cscope.*
+tags
+TAGS
+++ /dev/null
-$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 <perhaps@yes.no>)
- - 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 <dnelson@redwoodsoft.com>.
-
-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.
+++ /dev/null
-/*
- * 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 <cmott@scientech.com>
- * 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 <sys/types.h>
-
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-
-#include <stdio.h>
-
-#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);
-
-}
+++ /dev/null
-/*
- * 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 <cmott@scientech.com>
- * 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 */
+++ /dev/null
-/*
- * 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 <brian@Awfulhak.org>
- * with the aid of code written by
- * Junichi SATOH <junichi@astec.co.jp> 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 <sys/types.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-
-#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;
- }
- }
-}
+++ /dev/null
-/*
- * 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 <cmott@scientech.com>
- * 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 <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <syslog.h>
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-/* BSD network include files */
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-
-#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; i<max_trials; i++)
- {
- int go_ahead;
- struct alias_link *search_result;
-
- search_result = FindLinkIn(link->dst_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; i<LINK_TABLE_OUT_SIZE; i++)
- {
- link = LIST_FIRST(&linkTableOut[i]);
- while (link != NULL)
- {
- struct alias_link *link_next;
- link_next = LIST_NEXT(link, list_out);
- icount++;
- DeleteLink(link);
- link = link_next;
- }
- }
-
- cleanupIndex =0;
-}
-
-
-static void
-IncrementalCleanup(void)
-{
- int icount;
- struct alias_link *link;
-
- icount = 0;
- link = LIST_FIRST(&linkTableOut[cleanupIndex++]);
- while (link != NULL)
- {
- int idelta;
- struct alias_link *link_next;
-
- link_next = LIST_NEXT(link, list_out);
- idelta = timeStamp - link->timestamp;
- 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; i<N_LINK_TCP_DATA; i++)
- aux_tcp->ack[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; i<LINK_TABLE_OUT_SIZE; i++)
- {
- link = LIST_FIRST(&linkTableOut[i]);
- while (link != NULL)
- {
- struct alias_link *link_next;
- char src_str[32], dst_str[32], alias_str[32];
-
- snprintf(src_str, sizeof(src_str), "%s:%u",
- inet_ntoa(link->src_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; i<N_LINK_TCP_DATA; i++)
- {
- struct ack_data_record x;
-
- x = link->data.tcp->ack[i];
- if (x.active == 1)
- {
- int ack_diff;
-
- ack_diff = SeqDiff(x.ack_new, ack);
- if (ack_diff >= 0)
- {
- if (ack_diff_min >= 0)
- {
- if (ack_diff < ack_diff_min)
- {
- delta = x.delta;
- ack_diff_min = ack_diff;
- }
- }
- else
- {
- delta = x.delta;
- ack_diff_min = ack_diff;
- }
- }
- }
- }
- return (delta);
-}
-
-
-int
-GetDeltaSeqOut(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; i<N_LINK_TCP_DATA; i++)
- {
- struct ack_data_record x;
-
- x = link->data.tcp->ack[i];
- if (x.active == 1)
- {
- int seq_diff;
-
- seq_diff = SeqDiff(x.ack_old, seq);
- if (seq_diff >= 0)
- {
- if (seq_diff_min >= 0)
- {
- if (seq_diff < seq_diff_min)
- {
- delta = x.delta;
- seq_diff_min = seq_diff;
- }
- }
- else
- {
- delta = x.delta;
- seq_diff_min = seq_diff;
- }
- }
- }
- }
- return (delta);
-}
-
-
-void
-AddSeq(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<n; i++)
- IncrementalCleanup();
- }
- else if (n > 0)
- {
- lastCleanupTime = timeStamp;
- houseKeepingResidual = n100 - 100*n;
-
- for (i=0; i<n; i++)
- IncrementalCleanup();
- }
- else if (n < 0)
- {
-#ifdef DEBUG
- fprintf(stderr, "PacketAlias/HouseKeeping(): ");
- fprintf(stderr, "something unexpected in time values\n");
-#endif
- lastCleanupTime = timeStamp;
- houseKeepingResidual = 0;
- }
-}
-
-
-/* Init the log file and enable logging */
-static void
-InitPacketAliasLog(void)
-{
- if ((~packetAliasMode & PKT_ALIAS_LOG)
- && (monitorFile = fopen("/var/log/alias.log", "w")))
- {
- packetAliasMode |= PKT_ALIAS_LOG;
- fprintf(monitorFile,
- "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n");
- }
-}
-
-
-/* Close the log-file and disable logging. */
-static void
-UninitPacketAliasLog(void)
-{
- if (monitorFile) {
- fclose(monitorFile);
- monitorFile = NULL;
- }
- packetAliasMode &= ~PKT_ALIAS_LOG;
-}
-
-
-
-
-
-
-/* Outside world interfaces
-
--- "outside world" means other than alias*.c routines --
-
- PacketAliasRedirectPort()
- PacketAliasAddServer()
- PacketAliasRedirectProto()
- PacketAliasRedirectAddr()
- PacketAliasRedirectDelete()
- PacketAliasSetAddress()
- PacketAliasInit()
- PacketAliasUninit()
- PacketAliasSetMode()
-
-(prototypes in alias.h)
-*/
-
-/* Redirection from a specific public addr:port to a
- private addr:port */
-struct alias_link *
-PacketAliasRedirectPort(struct in_addr src_addr, u_short src_port,
- struct in_addr dst_addr, u_short dst_port,
- struct in_addr alias_addr, 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:
-#ifdef DEBUG
- fprintf(stderr, "PacketAliasRedirectPort(): ");
- fprintf(stderr, "only TCP and UDP protocols allowed\n");
-#endif
- return NULL;
- }
-
- link = AddLink(src_addr, dst_addr, alias_addr,
- src_port, dst_port, alias_port,
- link_type);
-
- if (link != NULL)
- {
- link->flags |= 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<LINK_TABLE_OUT_SIZE; i++)
- LIST_INIT(&linkTableOut[i]);
- for (i=0; i<LINK_TABLE_IN_SIZE; i++)
- LIST_INIT(&linkTableIn[i]);
-
- atexit(PacketAliasUninit);
- firstCall = 0;
- }
- else
- {
- deleteAllLinks = 1;
- CleanupAliasData();
- deleteAllLinks = 0;
- }
-
- aliasAddress.s_addr = INADDR_ANY;
- targetAddress.s_addr = INADDR_ANY;
-
- icmpLinkCount = 0;
- udpLinkCount = 0;
- tcpLinkCount = 0;
- pptpLinkCount = 0;
- protoLinkCount = 0;
- fragmentIdLinkCount = 0;
- fragmentPtrLinkCount = 0;
- sockCount = 0;
-
- cleanupIndex =0;
-
- packetAliasMode = PKT_ALIAS_SAME_PORTS
- | PKT_ALIAS_USE_SOCKETS
- | PKT_ALIAS_RESET_ON_ADDR_CHANGE;
-}
-
-void
-PacketAliasUninit(void) {
- deleteAllLinks = 1;
- CleanupAliasData();
- deleteAllLinks = 0;
- UninitPacketAliasLog();
-#ifndef NO_FW_PUNCH
- UninitPunchFW();
-#endif
-}
-
-
-/* Change mode for some operations */
-unsigned int
-PacketAliasSetMode(
- unsigned int flags, /* Which state to bring flags to */
- unsigned int mask /* Mask of which flags to affect (use 0 to do a
- probe for flag values) */
-)
-{
-/* Enable logging? */
- if (flags & mask & PKT_ALIAS_LOG)
- {
- InitPacketAliasLog(); /* Do the enable */
- } else
-/* _Disable_ logging? */
- if (~flags & mask & PKT_ALIAS_LOG) {
- UninitPacketAliasLog();
- }
-
-#ifndef NO_FW_PUNCH
-/* Start punching holes in the firewall? */
- if (flags & mask & PKT_ALIAS_PUNCH_FW) {
- InitPunchFW();
- } else
-/* Stop punching holes in the firewall? */
- if (~flags & mask & PKT_ALIAS_PUNCH_FW) {
- UninitPunchFW();
- }
-#endif
-
-/* Other flags can be set/cleared without special action */
- packetAliasMode = (flags & mask) | (packetAliasMode & ~mask);
- return packetAliasMode;
-}
-
-
-int
-PacketAliasCheckNewLink(void)
-{
- return newDefaultLink;
-}
-
-
-#ifndef NO_FW_PUNCH
-
-/*****************
- Code to support firewall punching. This shouldn't really be in this
- file, but making variables global is evil too.
- ****************/
-
-/* Firewall include files */
-#include <net/if.h>
-#include <netinet/ip_fw.h>
-#include <string.h>
-#include <err.h>
-
-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; i<LINK_TABLE_OUT_SIZE; i++)
- {
- link = LIST_FIRST(&linkTableOut[i]);
- while (link != NULL)
- {
- struct alias_link *link_next;
- char src_str[32], dst_str[32], alias_str[32];
-
- snprintf(src_str, sizeof(src_str), "%s:%u",
- inet_ntoa(link->src_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;
- }
- }
-
-}
+++ /dev/null
-/*
- * 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 <cmott@scientech.com>
- * 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 <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#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
- }
-}
+++ /dev/null
-/*
- * 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 <cmott@scientech.com>
- * 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 <perhaps@yes.no> (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 <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <limits.h>
-
-#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<sizeof(":A!a@n.n PRIVMSG A :aDCC 1 1a")-1)
- return;
-
-/* Place string pointer at beginning of data */
- sptr = (char *) pip;
- sptr += hlen;
- maxsize -= hlen; /* We're interested in maximum size of data, not packet */
-
- /* Search for a CTCP command [Note 1] */
- for( i=0; i<dlen; i++ ) {
- if(sptr[i]=='\001')
- goto lFOUND_CTCP;
- }
- return; /* No CTCP commands in */
- /* Handle CTCP commands - the buffer may have to be copied */
-lFOUND_CTCP:
- {
- char newpacket[65536]; /* Estimate of maximum packet size :) */
- int copyat = i; /* Same */
- int iCopy = 0; /* How much data have we written to copy-back string? */
- in_addr_t org_addr; /* Original IP address */
- unsigned short org_port; /* Original source port address */
- lCTCP_START:
- if( i >= 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<dlen && isdigit(sptr[i])) {
- if( org_addr > 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<dlen && isdigit(sptr[i])) {
- if( org_port > 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<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
- newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
- if(sptr[i] == '\001') {
- goto lNORMAL_TEXT;
- }
- }
- goto lPACKET_DONE;
- /* Normal text */
- lNORMAL_TEXT:
- for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
- newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
- if(sptr[i] == '\001') {
- goto lCTCP_START;
- }
- }
- /* Handle the end of a packet */
- lPACKET_DONE:
- iCopy = iCopy > 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.
- */
+++ /dev/null
-/*
- * 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 <cmott@scientech.com>
- * 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)
- *
- * <updated several times by original author and Eivind Eklund>
- */
-
-#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_ */
+++ /dev/null
-/*
- * 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 <amurai@spec.co.jp>
- * 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 <amurai@spec.co.jp>)
-
- See HISTORY file for record of revisions.
-*/
-
-/* Includes */
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <netinet/tcp.h>
-
-#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);
-}
+++ /dev/null
-/*
- * 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 <erik@whistle.com>
- *
- * 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 <sys/types.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#include <stdio.h>
-
-#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);
-}
+++ /dev/null
-/*
- * 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 <cmott@scientech.com>
- * 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 <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netdb.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-/* BSD IPV4 includes */
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#include <arpa/inet.h>
-
-#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<nbits; i++)
- imask = (imask >> 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; i<OPTION_LEN_INT16; i++)
- accumulate -= *(sptr++);
-
- sptr = (u_short *) pip;
- accumulate += *sptr;
- pip->ip_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 <addr>[:<port>]
- * [port <port>]
- * [rule n]
- * [proto tcp|udp]
- * [src <addr>[/n]]
- * [dst <addr>[/n]]
- * [type encode_tcp_stream|encode_ip_hdr|no_encode]
- *
- * delete <rule number>
- *
- * 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; i<len; i++)
- buffer[i] = tolower((unsigned char)buffer[i]);
-
-/* Set default proxy type */
-
-/* Set up default values */
- rule_index = 0;
- proxy_type = PROXY_TYPE_ENCODE_NONE;
- proto = IPPROTO_TCP;
- proxy_port = 0;
- server_addr.s_addr = 0;
- server_port = 0;
- src_addr.s_addr = 0;
- IpMask(0, &src_mask);
- dst_addr.s_addr = 0;
- IpMask(0, &dst_mask);
-
- str_port[0] = 0;
- str_server_port[0] = 0;
-
-/* Parse command string with state machine */
-#define STATE_READ_KEYWORD 0
-#define STATE_READ_TYPE 1
-#define STATE_READ_PORT 2
-#define STATE_READ_SERVER 3
-#define STATE_READ_RULE 4
-#define STATE_READ_DELETE 5
-#define STATE_READ_PROTO 6
-#define STATE_READ_SRC 7
-#define STATE_READ_DST 8
- state = STATE_READ_KEYWORD;
- token = strsep(&res, " \t");
- token_count = 0;
- while (token != NULL)
- {
- token_count++;
- switch (state)
- {
- case STATE_READ_KEYWORD:
- if (strcmp(token, "type") == 0)
- state = STATE_READ_TYPE;
- else if (strcmp(token, "port") == 0)
- state = STATE_READ_PORT;
- else if (strcmp(token, "server") == 0)
- state = STATE_READ_SERVER;
- else if (strcmp(token, "rule") == 0)
- state = STATE_READ_RULE;
- else if (strcmp(token, "delete") == 0)
- state = STATE_READ_DELETE;
- else if (strcmp(token, "proto") == 0)
- state = STATE_READ_PROTO;
- else if (strcmp(token, "src") == 0)
- state = STATE_READ_SRC;
- else if (strcmp(token, "dst") == 0)
- state = STATE_READ_DST;
- else
- return -1;
- break;
-
- case STATE_READ_TYPE:
- if (strcmp(token, "encode_ip_hdr") == 0)
- proxy_type = PROXY_TYPE_ENCODE_IPHDR;
- else if (strcmp(token, "encode_tcp_stream") == 0)
- proxy_type = PROXY_TYPE_ENCODE_TCPSTREAM;
- else if (strcmp(token, "no_encode") == 0)
- proxy_type = PROXY_TYPE_ENCODE_NONE;
- else
- return -1;
- state = STATE_READ_KEYWORD;
- break;
-
- case STATE_READ_PORT:
- strlcpy(str_port, token, sizeof(str_port));
- state = STATE_READ_KEYWORD;
- break;
-
- case STATE_READ_SERVER:
- {
- int err;
- char *p;
- char s[sizeof(buffer)];
-
- p = token;
- while (*p != ':' && *p != 0)
- p++;
-
- if (*p != ':')
- {
- err = IpAddr(token, &server_addr);
- if (err)
- return -1;
- }
- else
- {
- *p = ' ';
-
- n = sscanf(token, "%s %s", s, str_server_port);
- if (n != 2)
- return -1;
-
- err = IpAddr(s, &server_addr);
- if (err)
- return -1;
- }
- }
- state = STATE_READ_KEYWORD;
- break;
-
- case STATE_READ_RULE:
- n = sscanf(token, "%d", &rule_index);
- if (n != 1 || rule_index < 0)
- return -1;
- state = STATE_READ_KEYWORD;
- break;
-
- case STATE_READ_DELETE:
- {
- int err;
- int rule_to_delete;
-
- if (token_count != 2)
- return -1;
-
- n = sscanf(token, "%d", &rule_to_delete);
- if (n != 1)
- return -1;
- err = RuleNumberDelete(rule_to_delete);
- if (err)
- return -1;
- return 0;
- }
-
- case STATE_READ_PROTO:
- if (strcmp(token, "tcp") == 0)
- proto = IPPROTO_TCP;
- else if (strcmp(token, "udp") == 0)
- proto = IPPROTO_UDP;
- else
- return -1;
- state = STATE_READ_KEYWORD;
- break;
-
- case STATE_READ_SRC:
- case STATE_READ_DST:
- {
- int err;
- char *p;
- struct in_addr mask;
- struct in_addr addr;
-
- p = token;
- while (*p != '/' && *p != 0)
- p++;
-
- if (*p != '/')
- {
- IpMask(32, &mask);
- err = IpAddr(token, &addr);
- if (err)
- return -1;
- }
- else
- {
- int nbits;
- char s[sizeof(buffer)];
-
- *p = ' ';
- n = sscanf(token, "%s %d", s, &nbits);
- if (n != 2)
- return -1;
-
- err = IpAddr(s, &addr);
- if (err)
- return -1;
-
- err = IpMask(nbits, &mask);
- if (err)
- return -1;
- }
-
- if (state == STATE_READ_SRC)
- {
- src_addr = addr;
- src_mask = mask;
- }
- else
- {
- dst_addr = addr;
- dst_mask = mask;
- }
- }
- state = STATE_READ_KEYWORD;
- break;
-
- default:
- return -1;
- break;
- }
-
- do {
- token = strsep(&res, " \t");
- } while (token != NULL && !*token);
- }
-#undef STATE_READ_KEYWORD
-#undef STATE_READ_TYPE
-#undef STATE_READ_PORT
-#undef STATE_READ_SERVER
-#undef STATE_READ_RULE
-#undef STATE_READ_DELETE
-#undef STATE_READ_PROTO
-#undef STATE_READ_SRC
-#undef STATE_READ_DST
-
-/* Convert port strings to numbers. This needs to be done after
- the string is parsed, because the prototype might not be designated
- before the ports (which might be symbolic entries in /etc/services) */
-
- if (strlen(str_port) != 0)
- {
- int err;
-
- err = IpPort(str_port, proto, &proxy_port);
- if (err)
- return -1;
- }
- else
- {
- proxy_port = 0;
- }
-
- if (strlen(str_server_port) != 0)
- {
- int err;
-
- err = IpPort(str_server_port, proto, &server_port);
- if (err)
- return -1;
- }
- else
- {
- server_port = 0;
- }
-
-/* Check that at least the server address has been defined */
- if (server_addr.s_addr == 0)
- return -1;
-
-/* Add to linked list */
- proxy_entry = malloc(sizeof(struct proxy_entry));
- if (proxy_entry == NULL)
- return -1;
-
- proxy_entry->proxy_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;
-}
+++ /dev/null
-/*
- * 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 <junichi@astec.co.jp>
- * <junichi@junichi.org>
- * 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 <erik@whistle.com>
- * Junichi SATOH <junichi@astec.co.jp>
- * <junichi@junichi.org>
- *
- * 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 <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-
-#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);
-
- }
- }
- }
- }
-}
+++ /dev/null
-/*
- * 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 <cmott@scientech.com>
- * 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 <sys/types.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#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<n; i++)
- {
- accumulate -= *new++;
- accumulate += *old++;
- }
-
- if (accumulate < 0)
- {
- accumulate = -accumulate;
- accumulate = (accumulate >> 16) + (accumulate & 0xffff);
- accumulate += accumulate >> 16;
- *cksum = (u_short) ~accumulate;
- }
- else
- {
- accumulate = (accumulate >> 16) + (accumulate & 0xffff);
- accumulate += accumulate >> 16;
- *cksum = (u_short) accumulate;
- }
-}
-
+++ /dev/null
-.\"-
-.\" Copyright (c) 2001 Charles Mott <cmott@scientech.com>
-.\" 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 <sys/types.h>
-.Fd #include <netinet/in.h>
-.Fd #include <alias.h>
-.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.
/*
- * Copyright (c) 2009-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2017 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
"\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"
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;
--- /dev/null
+/*
+ * 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 <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_fake_var.h>
+
+#include <net/route.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <errno.h>
+
+#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: <none>\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
+}
+
--- /dev/null
+/*
+ * 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 <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_fake_var.h>
+
+#include <net/route.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <errno.h>
+
+#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);
+}
+
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);
}
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);
}
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)
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
aux = NULL;
scir.scir_aux_data = NULL;
}
-
+
buf->ci_flags = scir.scir_flags;
buf->ci_ifindex = scir.scir_ifindex;
buf->ci_src = src;
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);
free(aux);
if (buf != NULL)
free(buf);
-
+
return (-1);
}
{
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);
}
.Ar times\r
.Ar alt_addr\r
.Ar 0\r
-.Ar connorder\r
.Ar longlived\r
-.Ar fastjoin\r
.Sh DESCRIPTION\r
.Nm\r
is as an MPTCP client test tool that use the\r
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++;
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++;
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;
}
int dt, dir;
struct tm *gmt, *loc;
struct tm sgmt;
-
+
if (t == 0)
t = time(NULL);
gmt = &sgmt;
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
if (dir == 0)
dir = loc->tm_yday - gmt->tm_yday;
dt += dir * 24 * 60 * 60;
-
+
return (dt);
}
{
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,
basename(const char * str)
{
const char *last_slash = strrchr(str, '/');
-
+
if (last_slash == NULL)
return (str);
else
{ "--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 },
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
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)
if_indextoname(sin6->sin6_scope_id, ifname);
snprintf(scopestr, sizeof(scopestr), "%%%s", ifname);
}
-
+
retval = snprintf(str, strlen, "%s%s:%u",
str6,
scopestr,
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;
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;
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':
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;
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];
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");
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);
}
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 {
char str[2 * INET6_ADDRSTRLEN];
ts_print();
-
+
sprint_sockaddr(str, sizeof(str), altres->ai_addr);
printf("connectx(%s, %d, %d)\n", str, ifscope, cid1);
}
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;
buffer = buffer2;
which_buf = 0;
}
-
+
while (bytes_to_rdwr) {
if (verbose) {
ts_print();
printf("reading %d bytes\n", rsplen);
}
n = read(sockfd, buffer3, rsplen);
-
+
if (n <= 0) {
err(EX_OSERR, "ERROR reading from socket");
}
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;
{
int i, any = 0;
char c;
-
+
if (bits && *bits == 8)
printf("%s=%o", s, v);
else
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) ?
break;
}
}
-#endif
out:
if (cfo != NULL)
freeconninfo(cfo);
-
+
return (err);
}
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");
}
printf("\n");
}
-
+
/* just do an association for now */
error = copyconnids(s, SAE_ASSOCID_ANY, &cid, &cid_cnt);
if (error != 0) {
}
printf("\n");
}
-
+
done:
if (aid != NULL)
freeassocids(aid);
+++ /dev/null
-* Version 0.1
-
- Initial version of natd.
-
-* Version 0.2
-
- - Alias address can now be set by giving interface name with
- new (-n) command-line option.
-
- - New Makefile based on bsd.prog.mk.
-
- - Error messages are written to syslog
- after natd has become a daemon.
-
-* Version 1.0
-
- - Support for using only single socket (-p option)
-
-* Version 1.1
-
- - -a option now understands a hostname also.
- - -a option no longer dumps core.
- - Packet aliasing software upgraded to v. 1.9
- - added long option names (like -address)
-
-* Version 1.2
-
- - Fixed core dump with -port option.
- - Added -Wall to CFLAGS and some headers added to natd.c
- to get clean compile by Brian Somers [brian@awfulhak.org].
-
-* Version 1.3
-
- - Aliasing address initialization is delayed until first
- packet arrives. This allows natd to start up before
- interface address is set.
- - SIGTERM is now catched to allow kernel to close
- existing connections when system is shutting down.
- - SIGHUP is now catched to allow natd to refresh aliasing
- address from interface, which might be useful to tun devices.
-
-* Version 1.4
-
- - Changed command line options to be compatible with
- command names used in ppp+packetAlias package (which is the
- original application using aliasing routines).
-
- The options which map directly to packet aliasing options are:
-
- -unregistered_only [yes|no]
- -log [yes|no]
- -deny_incoming [yes|no]
- -use_sockets [yes|no]
- -same_ports [yes|no]
-
- The short option names are the same as in previous
- releases.
-
- - Command line parser rewritten to provide more flexible
- way to support new packet aliasing options.
-
- - Support for natd.cf configuration file has been added.
-
- - SIGHUP no longer causes problems when running without
- interface name option.
-
- - When using -interface command line option, routing socket
- is optionally listened for interface address changes. This
- mode is activated by -dynamic option.
-
- - Directory tree reorganized, alias package is now a library.
-
- - Manual page written by Brian Somers <brian@awfulhak.org> added.
- - README file updated.
-
-* Version 1.5
-
- - Support for sending ICMP 'need fragmentation' messages
- when packet size exceeds mtu size of outgoing network interface.
-
- - ipfw rule example in manual page fixed.
-
-* Version 1.6
-
- - Upgrade to new packet aliasing engine (2.1)
- - redirect_port and redirect_address configuration
- parameters added.
- - It is no longer necessary to quote complex parameter values
- in command line.
- - Manual page fixed (same_port -> same_ports).
-
-* Version 1.7
-
- - A bug in command-line parsing fixed (it appeared due
- to changes made in 1.6).
-
-* Version 1.8
-
- - Fixed problems with -dynamic option.
- - Added /var/run/natd.pid
-
-* Version 1.9
-
- - Changes to manual page by
- Brian Somers <brian@awfulhak.org> integrated.
- - Checksum for incoming packets is always recalculated
- for FreeBSD 2.2 and never recalculated for newer
- versions. This should fix the problem with wrong
- checksum of fragmented packets.
- - Buffer space problem found by Sergio Lenzi <lenzi@bsi.com.br>
- fixed. Natd now waits with select(2) for buffer space
- to become available if write fails.
- - Packet aliasing library upgraded to 2.2.
-
-* Version 1.10
-
- - Ignored incoming packets are now dropped when
- deny_incoming option is set to yes.
- - Packet aliasing library upgraded to 2.4.
-
-* Version 1.11
-
- - Code cleanup work done in FreeBSD-current development merged.
- - Port numbers are now unsigned as they should always have been.
-
-* Version 1.12
-
- - Typos in comment fixed. Copyright message added to
- source & header files that were missing it.
- - A small patch to libalias to make static NAT work correctly.
-
-* Version 2.0
-
- - Upgrade to libalias 3.0 which gives:
- - Transparent proxy support.
- - permanent_link is now obsolete, use redirect_port instead.
- - Drop support for early FreeBSD 2.2 versions
- - If separate input & output sockets are being used
- use them to find out packet direction instead of
- normal mechanism. This can be handy in complex environments
- with multiple interfaces.
- - libalias is no longer part of this distribution.
- - New sample configuration file
- from Ted Mittelstaedt <tedm@portsoft.com>.
- - PPTP redirect support by Dru Nelson <dnelson@redwoodsoft.com> added.
- - Logging enhancements from Martin Machacek <mm@i.cz> added.
+++ /dev/null
-# $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 <archie@whistle.com> Divert sockets
- Charles Mott <cmott@scientech.com> Packet aliasing engine
- Eivind Eklund <eivind@dimaga.com> Packet aliasing engine
- Ari Suutari <suutari@iki.fi> Natd
- Brian Somers <brian@awfulhak.org> Manual page, glue and
- bunch of good ideas.
-
- Happy Networking - comments and fixes are welcome!
-
- Ari S. (suutari@iki.fi)
-
-
-
+++ /dev/null
-/*
- * 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 <suutari@iki.fi>
- *
- * Based upon:
- * $FreeBSD: src/sbin/natd/icmp.c,v 1.6 1999/08/28 00:13:45 peter Exp $
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <netdb.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-
-#include <alias.h>
-
-#include "natd.h"
-
-int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu)
-{
- char icmpBuf[IP_MAXPACKET];
- struct ip* ip;
- struct icmp* icmp;
- int icmpLen;
- int failBytes;
- int failHdrLen;
- struct sockaddr_in addr;
- int wrote;
- struct in_addr swap;
-/*
- * Don't send error if packet is
- * not the first fragment.
- */
- if (ntohs (failedDgram->ip_off) & ~(IP_MF | IP_DF))
- return 0;
-/*
- * Dont respond if failed datagram is ICMP.
- */
- if (failedDgram->ip_p == IPPROTO_ICMP)
- return 0;
-/*
- * Start building the message.
- */
- ip = (struct ip*) icmpBuf;
- icmp = (struct icmp*) (icmpBuf + sizeof (struct ip));
-/*
- * Complete ICMP part.
- */
- icmp->icmp_type = ICMP_UNREACH;
- icmp->icmp_code = ICMP_UNREACH_NEEDFRAG;
- icmp->icmp_cksum = 0;
- icmp->icmp_void = 0;
- icmp->icmp_nextmtu = htons (mtu);
-/*
- * Copy header + 64 bits of original datagram.
- */
- failHdrLen = (failedDgram->ip_hl << 2);
- failBytes = failedDgram->ip_len - failHdrLen;
- if (failBytes > 8)
- failBytes = 8;
-
- failBytes += failHdrLen;
- icmpLen = ICMP_MINLEN + failBytes;
-
- memcpy (&icmp->icmp_ip, failedDgram, failBytes);
-/*
- * Calculate checksum.
- */
- icmp->icmp_cksum = PacketAliasInternetChecksum ((u_short*) icmp,
- icmpLen);
-/*
- * Add IP header using old IP header as template.
- */
- memcpy (ip, failedDgram, sizeof (struct ip));
-
- ip->ip_v = 4;
- ip->ip_hl = 5;
- ip->ip_len = htons (sizeof (struct ip) + icmpLen);
- ip->ip_p = IPPROTO_ICMP;
- ip->ip_tos = 0;
-
- swap = ip->ip_dst;
- ip->ip_dst = ip->ip_src;
- ip->ip_src = swap;
-
- PacketAliasIn ((char*) ip, IP_MAXPACKET);
-
- addr.sin_family = AF_INET;
- addr.sin_addr = ip->ip_dst;
- addr.sin_port = 0;
-/*
- * Put packet into processing queue.
- */
- wrote = sendto (sock,
- icmp,
- icmpLen,
- 0,
- (struct sockaddr*) &addr,
- sizeof addr);
-
- if (wrote != icmpLen)
- Warn ("Cannot send ICMP message.");
-
- return 1;
-}
-
-
+++ /dev/null
-.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.
+++ /dev/null
-/*
- * 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 <suutari@iki.fi>
- *
- * 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 <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <ifaddrs.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <arpa/inet.h>
-
-#include <alias.h>
-void DumpInfo(void);
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <netdb.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <mach/mach_time.h>
-#include <mach/clock_types.h>
-
-#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 :
- * <http://files.dns-sd.org/draft-cheshire-nat-pmp.txt>
- */
-
-#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 <fcntl.h>
- {
- 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; i<bytes; i++)
- {
- printf("%02x", buffer[i]);
- }
- printf("\n");
- }
- #endif
-
- /* drop any reply packets that we receive on the floor */
- if ( req->opcode >= 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);
-}
+++ /dev/null
-#
-# $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
+++ /dev/null
-/*
- * 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 <suutari@iki.fi>
- *
- * 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);
-
-
+++ /dev/null
-#!/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
-
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 *,
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]);
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)
{
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);
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
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;
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;
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;
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;
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");
"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
NULL,
NULL,
NULL,
+ NULL,
NULL
};
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) {
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);
{ 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,
systmprotox,
nstatprotox,
ipcprotox,
+ kernprotox,
NULL
};
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
--- /dev/null
+/*
+ * 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 <sys/sysctl.h>
+
+#include <net/net_api_stats.h>
+#include <err.h>
+#include <stdio.h>
+
+#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
+}
+
"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);
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);
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);
+
/*
- * Copyright (c) 2008-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2017 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
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)
buildPhases = (
);
dependencies = (
- 72C77D3B1484199C002D2577 /* PBXTargetDependency */,
);
name = network_cmds_libs;
productName = "network_cmds (Aggregate)";
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 */; };
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 */; };
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 */; };
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 */
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 */;
);
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;
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 = "<group>"; };
7211D9B2190713A60086EF20 /* network-client-server-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "network-client-server-entitlements.plist"; sourceTree = "<group>"; };
+ 721654C21EC52447005B17BA /* misc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = misc.c; sourceTree = "<group>"; };
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; };
7247B83516165EDC00873B3C /* pktapctl.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pktapctl.8; sourceTree = "<group>"; };
7247B83B16165F0100873B3C /* pktapctl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pktapctl.c; sourceTree = "<group>"; };
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 = "<group>"; };
- 7261203B0EE86EEB00AFED1B /* alias_cuseeme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_cuseeme.c; sourceTree = "<group>"; };
- 7261203C0EE86EEB00AFED1B /* alias_db.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_db.c; sourceTree = "<group>"; };
- 7261203D0EE86EEB00AFED1B /* alias_ftp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_ftp.c; sourceTree = "<group>"; };
- 7261203E0EE86EEB00AFED1B /* alias_irc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_irc.c; sourceTree = "<group>"; };
- 726120400EE86EEB00AFED1B /* alias_nbt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_nbt.c; sourceTree = "<group>"; };
- 726120410EE86EEB00AFED1B /* alias_pptp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_pptp.c; sourceTree = "<group>"; };
- 726120420EE86EEB00AFED1B /* alias_proxy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_proxy.c; sourceTree = "<group>"; };
- 726120430EE86EEB00AFED1B /* alias_smedia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_smedia.c; sourceTree = "<group>"; };
- 726120440EE86EEB00AFED1B /* alias_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alias_util.c; sourceTree = "<group>"; };
+ 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 = "<group>"; };
7261204E0EE86EF900AFED1B /* arp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arp.c; sourceTree = "<group>"; };
7261204F0EE86EF900AFED1B /* arp4.4 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = arp4.4; sourceTree = "<group>"; };
726120710EE86F2D00AFED1B /* kdumpd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kdumpd.c; sourceTree = "<group>"; };
726120720EE86F2D00AFED1B /* kdumpsubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kdumpsubs.c; sourceTree = "<group>"; };
726120730EE86F2D00AFED1B /* kdumpsubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kdumpsubs.h; sourceTree = "<group>"; };
- 726120780EE86F3600AFED1B /* HISTORY */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HISTORY; sourceTree = "<group>"; };
- 726120790EE86F3600AFED1B /* icmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = icmp.c; sourceTree = "<group>"; };
- 7261207B0EE86F3600AFED1B /* natd.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = natd.8; sourceTree = "<group>"; };
- 7261207C0EE86F3600AFED1B /* natd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = natd.c; sourceTree = "<group>"; };
- 7261207D0EE86F3600AFED1B /* natd.cf.sample */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = natd.cf.sample; sourceTree = "<group>"; };
- 7261207E0EE86F3600AFED1B /* natd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = natd.h; sourceTree = "<group>"; };
- 7261207F0EE86F3600AFED1B /* natd.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = natd.test; sourceTree = "<group>"; };
- 726120800EE86F3600AFED1B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
726120840EE86F4000AFED1B /* gnuc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gnuc.h; sourceTree = "<group>"; };
726120860EE86F4000AFED1B /* ndp.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ndp.8; sourceTree = "<group>"; };
726120870EE86F4000AFED1B /* ndp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ndp.c; sourceTree = "<group>"; };
726120F30EE86FA700AFED1B /* version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = version.c; sourceTree = "<group>"; };
726120FA0EE86FB500AFED1B /* traceroute6.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = traceroute6.8; sourceTree = "<group>"; };
726120FB0EE86FB500AFED1B /* traceroute6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = traceroute6.c; sourceTree = "<group>"; };
- 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 = "<group>"; };
- 726121230EE870D400AFED1B /* alias.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alias.h; sourceTree = "<group>"; };
- 726121240EE870D400AFED1B /* libalias.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = libalias.3; sourceTree = "<group>"; };
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 = "<group>"; };
72E650A5107BF2F000AAF325 /* ifbridge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ifbridge.c; sourceTree = "<group>"; };
72E650A6107BF2F000AAF325 /* ifclone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ifclone.c; sourceTree = "<group>"; };
E01AB08F1368880F008C66FF /* libutil.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libutil.dylib; path = $SDKROOT/usr/lib/libutil.dylib; sourceTree = "<group>"; };
+ F940359C1E2FF58500283EB1 /* iffake.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iffake.c; sourceTree = "<group>"; };
+ F97F1E031E9C3FBC002355FF /* nexus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nexus.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
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;
};
);
runOnlyForDeploymentPostprocessing = 0;
};
- 724DABD90EE8912D008900D0 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 724DABF90EE89269008900D0 /* libalias.A.dylib in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
724DAC0B0EE8940D008900D0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
- 7261210A0EE8707500AFED1B /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
7261212B0EE8710B00AFED1B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
72E42BA214B7CF37003AAE28 /* network_cmds.plist */,
7211D9B2190713A60086EF20 /* network-client-server-entitlements.plist */,
E01AB08F1368880F008C66FF /* libutil.dylib */,
- 726120380EE86EEB00AFED1B /* alias */,
7261204C0EE86EF900AFED1B /* arp.tproj */,
72B732DB1899B0380060E6D4 /* cfilutil */,
723C706A142BAFEA007C87E9 /* dnctl */,
56582591133920B5003E5FA5 /* mnc.tproj */,
72311F43194A349100EB4788 /* mptcp_client */,
690D973F12DE5A21004323A7 /* mtest.tproj */,
- 726120770EE86F3600AFED1B /* natd.tproj */,
726120830EE86F4000AFED1B /* ndp.tproj */,
7261208A0EE86F4800AFED1B /* netstat.tproj */,
7247B83216165EDC00873B3C /* pktapctl */,
713297F01A93C9CF002359CF /* unbound */,
72CD1DB50EE8C619005F825D /* libipsec.dylib */,
7261210D0EE8707500AFED1B /* Products */,
+ 7255D42F1E44036D008F4A32 /* Frameworks */,
);
sourceTree = "<group>";
};
- 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 = "<group>";
};
7261204C0EE86EF900AFED1B /* arp.tproj */ = {
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 = "<group>";
path = kdumpd.tproj;
sourceTree = "<group>";
};
- 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 = "<group>";
- };
726120830EE86F4000AFED1B /* ndp.tproj */ = {
isa = PBXGroup;
children = (
7261209A0EE86F4800AFED1B /* tp_astring.c */,
7261209B0EE86F4800AFED1B /* unix.c */,
7218B549191D4202001B7B52 /* systm.c */,
+ 721654C21EC52447005B17BA /* misc.c */,
);
path = netstat.tproj;
sourceTree = "<group>";
7261210D0EE8707500AFED1B /* Products */ = {
isa = PBXGroup;
children = (
- 7261210C0EE8707500AFED1B /* libalias.A.dylib */,
7261212D0EE8710B00AFED1B /* arp */,
726121540EE8881700AFED1B /* ifconfig */,
724DABA20EE88FE3008900D0 /* kdumpd */,
- 724DABDB0EE8912D008900D0 /* natd */,
724DAC0D0EE8940D008900D0 /* ndp */,
7216D2460EE896C000AE70E4 /* netstat */,
7216D27C0EE8980A00AE70E4 /* ping */,
};
/* 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;
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" */;
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" */;
72570DA20EE8EBF3000F4CFB /* All-Embedded */,
72ABD0811083D742008C721C /* All-EmbeddedOther */,
72C77D3A1484199C002D2577 /* network_cmds_libs */,
- 7261210B0EE8707500AFED1B /* alias */,
7261212C0EE8710B00AFED1B /* arp */,
72B732D91899B0380060E6D4 /* cfilutil */,
723C7067142BAFEA007C87E9 /* dnctl */,
72311F41194A349000EB4788 /* mptcp_client */,
690D978012DE6034004323A7 /* mtest */,
724DAC0C0EE8940D008900D0 /* ndp */,
- 724DABDA0EE8912D008900D0 /* natd */,
7216D2450EE896C000AE70E4 /* netstat */,
7247B83016165EDC00873B3C /* pktapctl */,
7200F2F91958A34D0033E22C /* pktmnglr */,
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;
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;
7216D2570EE896F300AE70E4 /* tp_astring.c in Sources */,
56B6B66816F79A1C00D8A7A9 /* mptcp.c in Sources */,
7216D2580EE896F300AE70E4 /* unix.c in Sources */,
+ 721654C31EC52447005B17BA /* misc.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
);
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;
);
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;
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;
};
target = 72B732D91899B0380060E6D4 /* cfilutil */;
targetProxy = 72B732EA1899B19A0060E6D4 /* PBXContainerItemProxy */;
};
- 72C77D3B1484199C002D2577 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 7261210B0EE8707500AFED1B /* alias */;
- targetProxy = 72C77D3C1484199C002D2577 /* PBXContainerItemProxy */;
- };
72CD1D9C0EE8C47C005F825D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 7294F1290EE8BD280052EC88 /* traceroute6 */;
};
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;
};
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;
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 = {
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;
};
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;
};
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;
};
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;
};
"$(inherited)",
"TFTP_DIR=\\\"/tftpboot\\\"",
);
- INSTALL_GROUP = wheel;
INSTALL_MODE_FLAG = 0555;
- INSTALL_OWNER = root;
INSTALL_PATH = /usr/sbin;
PRODUCT_NAME = rarpd;
};
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;
};
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 = (
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 = (
03B2DBF5100BE71D005349BC /* Ignore Me */ = {
isa = XCBuildConfiguration;
buildSettings = {
- INSTALL_GROUP = wheel;
INSTALL_MODE_FLAG = 0555;
- INSTALL_OWNER = root;
INSTALL_PATH = /usr/sbin;
PRODUCT_NAME = spray;
};
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;
};
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;
};
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;
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;
"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;
"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;
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)";
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)";
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)";
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;
};
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;
};
"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;
};
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;
};
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;
};
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;
};
"$(inherited)",
"TFTP_DIR=\\\"/tftpboot\\\"",
);
- INSTALL_GROUP = wheel;
INSTALL_MODE_FLAG = 0555;
- INSTALL_OWNER = root;
INSTALL_PATH = /usr/sbin;
PRODUCT_NAME = rarpd;
};
"$(inherited)",
"TFTP_DIR=\\\"/tftpboot\\\"",
);
- INSTALL_GROUP = wheel;
INSTALL_MODE_FLAG = 0555;
- INSTALL_OWNER = root;
INSTALL_PATH = /usr/sbin;
PRODUCT_NAME = rarpd;
};
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;
};
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;
};
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 = (
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 = (
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 = (
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 = (
7216D3A90EE8A3BB00AE70E4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- INSTALL_GROUP = wheel;
INSTALL_MODE_FLAG = 0555;
- INSTALL_OWNER = root;
INSTALL_PATH = /usr/sbin;
PRODUCT_NAME = spray;
};
7216D3AA0EE8A3BB00AE70E4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- INSTALL_GROUP = wheel;
INSTALL_MODE_FLAG = 0555;
- INSTALL_OWNER = root;
INSTALL_PATH = /usr/sbin;
PRODUCT_NAME = spray;
};
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)";
};
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)";
};
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)";
};
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;
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;
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";
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;
};
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 = {
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;
};
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;
};
};
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;
};
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;
};
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;
};
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;
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;
};
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;
};
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;
};
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;
};
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)";
};
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)";
};
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)";
};
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 = (
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 = (
.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
.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
.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
.Op Fl Fl apple-connect
.Ek
.Bk -words
-.Op Fl Fl apple-print
+.Op Fl Fl apple-time
.Ek
.Bk -words
.Op Ar hops ...
.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
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
#include <sysexits.h>
#include <getopt.h>
#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 */
#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;
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 */
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 */
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);
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 *);
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;
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;
/* 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));
#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;
break;
case 'N':
options |= F_NIGROUP;
+ nig_oldmcprefix++;
break;
case 'o':
options |= F_ONCE;
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':
}
if (options & F_NIGROUP) {
- target = nigroup(argv[argc - 1]);
+ target = nigroup(argv[argc - 1], nig_oldmcprefix);
if (target == NULL) {
usage();
/*NOTREACHED*/
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;
}
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;
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));
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
#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);
}
fflush(stdout);
switch (sig) {
- case SIGALRM:
- seenalrm++;
- break;
case SIGINT:
+ case SIGALRM:
seenint++;
break;
#ifdef SIGINFO
}
}
-/*
- * 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
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;
if (options & F_QUIET)
return;
+ if (options & F_WAITTIME && triptime > waittime) {
+ ++nrcvtimeout;
+ return;
+ }
+
if (options & F_FLOOD)
(void)write(STDOUT_FILENO, &BSPACE, 1);
else {
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;
}
}
if (TST(seq % mx_dup_ck)) {
++nrepeats;
--nreceived;
+ dupflag = 1;
} else {
SET(seq % mx_dup_ck);
+ dupflag = 0;
}
if (options & F_QUIET)
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)) {
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)) {
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);
}
/*
((((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 */
#endif
char *
-nigroup(char *name)
+nigroup(char *name, int nig_oldmcprefix)
{
char *p;
char *q;
size_t l;
char hbuf[NI_MAXHOST];
struct in6_addr in6;
+ int valid;
p = strchr(name, '.');
if (!p)
*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;
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;
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;