2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Copyright (c) 2001 Charles Mott <cmott@scientech.com>
25 * All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
36 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * $FreeBSD: src/lib/libalias/alias.c,v 1.16.2.7 2001/08/21 03:50:25 brian Exp $
53 Alias.c provides supervisory control for the functions of the
54 packet aliasing software. It consists of routines to monitor
55 TCP connection state, protocol-specific aliasing routines,
56 fragment handling and the following outside world functional
57 interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn,
58 PacketAliasIn and PacketAliasOut.
60 The other C program files are briefly described. The data
61 structure framework which holds information needed to translate
62 packets is encapsulated in alias_db.c. Data is accessed by
63 function calls, so other segments of the program need not know
64 about the underlying data structures. Alias_ftp.c contains
65 special code for modifying the ftp PORT command used to establish
66 data connections, while alias_irc.c does the same for IRC
67 DCC. Alias_util.c contains a few utility routines.
69 Version 1.0 August, 1996 (cjm)
71 Version 1.1 August 20, 1996 (cjm)
72 PPP host accepts incoming connections for ports 0 to 1023.
73 (Gary Roberts pointed out the need to handle incoming
76 Version 1.2 September 7, 1996 (cjm)
77 Fragment handling error in alias_db.c corrected.
78 (Tom Torrance helped fix this problem.)
80 Version 1.4 September 16, 1996 (cjm)
81 - A more generalized method for handling incoming
82 connections, without the 0-1023 restriction, is
83 implemented in alias_db.c
84 - Improved ICMP support in alias.c. Traceroute
85 packet streams can now be correctly aliased.
86 - TCP connection closing logic simplified in
87 alias.c and now allows for additional 1 minute
88 "grace period" after FIN or RST is observed.
90 Version 1.5 September 17, 1996 (cjm)
91 Corrected error in handling incoming UDP packets with 0 checksum.
92 (Tom Torrance helped fix this problem.)
94 Version 1.6 September 18, 1996 (cjm)
95 Simplified ICMP aliasing scheme. Should now support
96 traceroute from Win95 as well as FreeBSD.
98 Version 1.7 January 9, 1997 (cjm)
99 - Out-of-order fragment handling.
100 - IP checksum error fixed for ftp transfers
102 - Integer return codes added to all
103 aliasing/de-aliasing functions.
104 - Some obsolete comments cleaned up.
105 - Differential checksum computations for
106 IP header (TCP, UDP and ICMP were already
109 Version 2.1 May 1997 (cjm)
110 - Added support for outgoing ICMP error
112 - Added two functions PacketAliasIn2()
113 and PacketAliasOut2() for dynamic address
114 control (e.g. round-robin allocation of
117 Version 2.2 July 1997 (cjm)
118 - Rationalized API function names to begin
119 with "PacketAlias..."
120 - Eliminated PacketAliasIn2() and
121 PacketAliasOut2() as poorly conceived.
123 Version 2.3 Dec 1998 (dillon)
124 - Major bounds checking additions, see FreeBSD/CVS
126 Version 3.1 May, 2000 (salander)
127 - Added hooks to handle PPTP.
129 Version 3.2 July, 2000 (salander and satoh)
130 - Added PacketUnaliasOut routine.
131 - Added hooks to handle RTSP/RTP.
133 See HISTORY file for additional revisions.
136 #include <sys/types.h>
138 #include <netinet/in_systm.h>
139 #include <netinet/in.h>
140 #include <netinet/ip.h>
141 #include <netinet/ip_icmp.h>
142 #include <netinet/tcp.h>
143 #include <netinet/udp.h>
147 #include "alias_local.h"
150 #define NETBIOS_NS_PORT_NUMBER 137
151 #define NETBIOS_DGM_PORT_NUMBER 138
152 #define FTP_CONTROL_PORT_NUMBER 21
153 #define IRC_CONTROL_PORT_NUMBER_1 6667
154 #define IRC_CONTROL_PORT_NUMBER_2 6668
155 #define CUSEEME_PORT_NUMBER 7648
156 #define RTSP_CONTROL_PORT_NUMBER_1 554
157 #define RTSP_CONTROL_PORT_NUMBER_2 7070
158 #define PPTP_CONTROL_PORT_NUMBER 1723
163 /* TCP Handling Routines
165 TcpMonitorIn() -- These routines monitor TCP connections, and
166 TcpMonitorOut() delete a link when a connection is closed.
168 DoMSSClamp() -- Clamps the MSS of the given TCP header to the
169 value in packetAliasMSS.
171 These routines look for SYN, FIN and RST flags to determine when TCP
172 connections open and close. When a TCP connection closes, the data
173 structure containing packet aliasing information is deleted after
177 /* Local prototypes */
178 static void TcpMonitorIn(struct ip
*, struct alias_link
*);
180 static void TcpMonitorOut(struct ip
*, struct alias_link
*);
183 static u_short packetAliasMSS
;
185 void PacketAliasClampMSS(u_short mss
)
187 packetAliasMSS
= mss
;
190 static void DoMSSClamp(struct tcphdr
*tc
)
192 u_char
*option
= (u_char
*) tc
+ sizeof(*tc
);
193 u_char
*optionEnd
= option
+ ((tc
->th_off
<< 2) - sizeof(*tc
));
195 while (optionEnd
> option
)
210 u_short
*mssPtr
= (u_short
*) option
+ 1;
211 u_short mssVal
= ntohs(*mssPtr
);
213 if (packetAliasMSS
< mssVal
)
215 int accumulate
= mssVal
;
216 accumulate
-= packetAliasMSS
;
217 *mssPtr
= htons(packetAliasMSS
);
218 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
233 TcpMonitorIn(struct ip
*pip
, struct alias_link
*link
)
237 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
239 switch (GetStateIn(link
))
241 case ALIAS_TCP_STATE_NOT_CONNECTED
:
242 if (tc
->th_flags
& TH_RST
)
243 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
244 else if (tc
->th_flags
& TH_SYN
)
246 SetStateIn(link
, ALIAS_TCP_STATE_CONNECTED
);
252 case ALIAS_TCP_STATE_CONNECTED
:
253 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
254 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
260 TcpMonitorOut(struct ip
*pip
, struct alias_link
*link
)
264 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
266 switch (GetStateOut(link
))
268 case ALIAS_TCP_STATE_NOT_CONNECTED
:
269 if (tc
->th_flags
& TH_RST
)
270 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
271 else if (tc
->th_flags
& TH_SYN
)
273 SetStateOut(link
, ALIAS_TCP_STATE_CONNECTED
);
279 case ALIAS_TCP_STATE_CONNECTED
:
280 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
281 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
290 /* Protocol Specific Packet Aliasing Routines
292 IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2()
293 IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2()
294 ProtoAliasIn(), ProtoAliasOut()
295 UdpAliasIn(), UdpAliasOut()
296 TcpAliasIn(), TcpAliasOut()
298 These routines handle protocol specific details of packet aliasing.
299 One may observe a certain amount of repetitive arithmetic in these
300 functions, the purpose of which is to compute a revised checksum
301 without actually summing over the entire data packet, which could be
302 unnecessarily time consuming.
304 The purpose of the packet aliasing routines is to replace the source
305 address of the outgoing packet and then correctly put it back for
306 any incoming packets. For TCP and UDP, ports are also re-mapped.
308 For ICMP echo/timestamp requests and replies, the following scheme
309 is used: the ID number is replaced by an alias for the outgoing
312 ICMP error messages are handled by looking at the IP fragment
313 in the data section of the message.
315 For TCP and UDP protocols, a port number is chosen for an outgoing
316 packet, and then incoming packets are identified by IP address and
317 port numbers. For TCP packets, there is additional logic in the event
318 that sequence and ACK numbers have been altered (as in the case for
319 FTP data port commands).
321 The port numbers used by the packet aliasing module are not true
322 ports in the Unix sense. No sockets are actually bound to ports.
323 They are more correctly thought of as placeholders.
325 All packets go through the aliasing mechanism, whether they come from
326 the gateway machine or other machines on a local area network.
330 /* Local prototypes */
331 static int IcmpAliasIn1(struct ip
*);
332 static int IcmpAliasIn2(struct ip
*);
333 static int IcmpAliasIn (struct ip
*);
335 static int IcmpAliasOut1(struct ip
*);
336 static int IcmpAliasOut2(struct ip
*);
337 static int IcmpAliasOut (struct ip
*);
339 static int ProtoAliasIn(struct ip
*);
340 static int ProtoAliasOut(struct ip
*);
342 static int UdpAliasOut(struct ip
*);
343 static int UdpAliasIn (struct ip
*);
345 static int TcpAliasOut(struct ip
*, int);
346 static int TcpAliasIn (struct ip
*);
350 IcmpAliasIn1(struct ip
*pip
)
353 De-alias incoming echo and timestamp replies.
354 Alias incoming echo and timestamp requests.
356 struct alias_link
*link
;
359 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
361 /* Get source address from ICMP data field and restore original data */
362 link
= FindIcmpIn(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
368 original_id
= GetOriginalPort(link
);
370 /* Adjust ICMP checksum */
371 accumulate
= ic
->icmp_id
;
372 accumulate
-= original_id
;
373 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
375 /* Put original sequence number back in */
376 ic
->icmp_id
= original_id
;
378 /* Put original address back into IP header */
380 struct in_addr original_address
;
382 original_address
= GetOriginalAddress(link
);
383 DifferentialChecksum(&pip
->ip_sum
,
384 (u_short
*) &original_address
,
385 (u_short
*) &pip
->ip_dst
,
387 pip
->ip_dst
= original_address
;
390 return(PKT_ALIAS_OK
);
392 return(PKT_ALIAS_IGNORED
);
396 IcmpAliasIn2(struct ip
*pip
)
399 Alias incoming ICMP error messages containing
400 IP header and first 64 bits of datagram.
403 struct icmp
*ic
, *ic2
;
406 struct alias_link
*link
;
408 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
411 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
412 tc
= (struct tcphdr
*) ud
;
413 ic2
= (struct icmp
*) ud
;
415 if (ip
->ip_p
== IPPROTO_UDP
)
416 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
417 ud
->uh_dport
, ud
->uh_sport
,
419 else if (ip
->ip_p
== IPPROTO_TCP
)
420 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
421 tc
->th_dport
, tc
->th_sport
,
423 else if (ip
->ip_p
== IPPROTO_ICMP
) {
424 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
425 link
= FindIcmpIn(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
433 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
437 struct in_addr original_address
;
438 u_short original_port
;
440 original_address
= GetOriginalAddress(link
);
441 original_port
= GetOriginalPort(link
);
443 /* Adjust ICMP checksum */
444 sptr
= (u_short
*) &(ip
->ip_src
);
445 accumulate
= *sptr
++;
447 sptr
= (u_short
*) &original_address
;
448 accumulate
-= *sptr
++;
450 accumulate
+= ud
->uh_sport
;
451 accumulate
-= original_port
;
452 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
454 /* Un-alias address in IP header */
455 DifferentialChecksum(&pip
->ip_sum
,
456 (u_short
*) &original_address
,
457 (u_short
*) &pip
->ip_dst
,
459 pip
->ip_dst
= original_address
;
461 /* Un-alias address and port number of original IP packet
462 fragment contained in ICMP data section */
463 ip
->ip_src
= original_address
;
464 ud
->uh_sport
= original_port
;
466 else if (ip
->ip_p
== IPPROTO_ICMP
)
470 struct in_addr original_address
;
473 original_address
= GetOriginalAddress(link
);
474 original_id
= GetOriginalPort(link
);
476 /* Adjust ICMP checksum */
477 sptr
= (u_short
*) &(ip
->ip_src
);
478 accumulate
= *sptr
++;
480 sptr
= (u_short
*) &original_address
;
481 accumulate
-= *sptr
++;
483 accumulate
+= ic2
->icmp_id
;
484 accumulate
-= original_id
;
485 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
487 /* Un-alias address in IP header */
488 DifferentialChecksum(&pip
->ip_sum
,
489 (u_short
*) &original_address
,
490 (u_short
*) &pip
->ip_dst
,
492 pip
->ip_dst
= original_address
;
494 /* Un-alias address of original IP packet and sequence number of
495 embedded ICMP datagram */
496 ip
->ip_src
= original_address
;
497 ic2
->icmp_id
= original_id
;
499 return(PKT_ALIAS_OK
);
501 return(PKT_ALIAS_IGNORED
);
506 IcmpAliasIn(struct ip
*pip
)
511 /* Return if proxy-only mode is enabled */
512 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
515 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
517 iresult
= PKT_ALIAS_IGNORED
;
518 switch (ic
->icmp_type
)
521 case ICMP_TSTAMPREPLY
:
522 if (ic
->icmp_code
== 0)
524 iresult
= IcmpAliasIn1(pip
);
528 case ICMP_SOURCEQUENCH
:
531 iresult
= IcmpAliasIn2(pip
);
535 iresult
= IcmpAliasIn1(pip
);
543 IcmpAliasOut1(struct ip
*pip
)
546 Alias outgoing echo and timestamp requests.
547 De-alias outgoing echo and timestamp replies.
549 struct alias_link
*link
;
552 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
554 /* Save overwritten data for when echo packet returns */
555 link
= FindIcmpOut(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
561 alias_id
= GetAliasPort(link
);
563 /* Since data field is being modified, adjust ICMP checksum */
564 accumulate
= ic
->icmp_id
;
565 accumulate
-= alias_id
;
566 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
568 /* Alias sequence number */
569 ic
->icmp_id
= alias_id
;
571 /* Change source address */
573 struct in_addr alias_address
;
575 alias_address
= GetAliasAddress(link
);
576 DifferentialChecksum(&pip
->ip_sum
,
577 (u_short
*) &alias_address
,
578 (u_short
*) &pip
->ip_src
,
580 pip
->ip_src
= alias_address
;
583 return(PKT_ALIAS_OK
);
585 return(PKT_ALIAS_IGNORED
);
590 IcmpAliasOut2(struct ip
*pip
)
593 Alias outgoing ICMP error messages containing
594 IP header and first 64 bits of datagram.
597 struct icmp
*ic
, *ic2
;
600 struct alias_link
*link
;
602 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
605 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
606 tc
= (struct tcphdr
*) ud
;
607 ic2
= (struct icmp
*) ud
;
609 if (ip
->ip_p
== IPPROTO_UDP
)
610 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
611 ud
->uh_dport
, ud
->uh_sport
,
613 else if (ip
->ip_p
== IPPROTO_TCP
)
614 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
615 tc
->th_dport
, tc
->th_sport
,
617 else if (ip
->ip_p
== IPPROTO_ICMP
) {
618 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
619 link
= FindIcmpOut(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
627 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
631 struct in_addr alias_address
;
634 alias_address
= GetAliasAddress(link
);
635 alias_port
= GetAliasPort(link
);
637 /* Adjust ICMP checksum */
638 sptr
= (u_short
*) &(ip
->ip_dst
);
639 accumulate
= *sptr
++;
641 sptr
= (u_short
*) &alias_address
;
642 accumulate
-= *sptr
++;
644 accumulate
+= ud
->uh_dport
;
645 accumulate
-= alias_port
;
646 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
649 * Alias address in IP header if it comes from the host
650 * the original TCP/UDP packet was destined for.
652 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
653 DifferentialChecksum(&pip
->ip_sum
,
654 (u_short
*) &alias_address
,
655 (u_short
*) &pip
->ip_src
,
657 pip
->ip_src
= alias_address
;
660 /* Alias address and port number of original IP packet
661 fragment contained in ICMP data section */
662 ip
->ip_dst
= alias_address
;
663 ud
->uh_dport
= alias_port
;
665 else if (ip
->ip_p
== IPPROTO_ICMP
)
669 struct in_addr alias_address
;
672 alias_address
= GetAliasAddress(link
);
673 alias_id
= GetAliasPort(link
);
675 /* Adjust ICMP checksum */
676 sptr
= (u_short
*) &(ip
->ip_dst
);
677 accumulate
= *sptr
++;
679 sptr
= (u_short
*) &alias_address
;
680 accumulate
-= *sptr
++;
682 accumulate
+= ic2
->icmp_id
;
683 accumulate
-= alias_id
;
684 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
687 * Alias address in IP header if it comes from the host
688 * the original ICMP message was destined for.
690 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
691 DifferentialChecksum(&pip
->ip_sum
,
692 (u_short
*) &alias_address
,
693 (u_short
*) &pip
->ip_src
,
695 pip
->ip_src
= alias_address
;
698 /* Alias address of original IP packet and sequence number of
699 embedded ICMP datagram */
700 ip
->ip_dst
= alias_address
;
701 ic2
->icmp_id
= alias_id
;
703 return(PKT_ALIAS_OK
);
705 return(PKT_ALIAS_IGNORED
);
710 IcmpAliasOut(struct ip
*pip
)
715 /* Return if proxy-only mode is enabled */
716 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
719 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
721 iresult
= PKT_ALIAS_IGNORED
;
722 switch (ic
->icmp_type
)
726 if (ic
->icmp_code
== 0)
728 iresult
= IcmpAliasOut1(pip
);
732 case ICMP_SOURCEQUENCH
:
735 iresult
= IcmpAliasOut2(pip
);
738 case ICMP_TSTAMPREPLY
:
739 iresult
= IcmpAliasOut1(pip
);
747 ProtoAliasIn(struct ip
*pip
)
750 Handle incoming IP packets. The
751 only thing which is done in this case is to alias
752 the dest IP address of the packet to our inside
755 struct alias_link
*link
;
757 /* Return if proxy-only mode is enabled */
758 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
761 link
= FindProtoIn(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
764 struct in_addr original_address
;
766 original_address
= GetOriginalAddress(link
);
768 /* Restore original IP address */
769 DifferentialChecksum(&pip
->ip_sum
,
770 (u_short
*) &original_address
,
771 (u_short
*) &pip
->ip_dst
,
773 pip
->ip_dst
= original_address
;
775 return(PKT_ALIAS_OK
);
777 return(PKT_ALIAS_IGNORED
);
782 ProtoAliasOut(struct ip
*pip
)
785 Handle outgoing IP packets. The
786 only thing which is done in this case is to alias
787 the source IP address of the packet.
789 struct alias_link
*link
;
791 /* Return if proxy-only mode is enabled */
792 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
795 link
= FindProtoOut(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
798 struct in_addr alias_address
;
800 alias_address
= GetAliasAddress(link
);
802 /* Change source address */
803 DifferentialChecksum(&pip
->ip_sum
,
804 (u_short
*) &alias_address
,
805 (u_short
*) &pip
->ip_src
,
807 pip
->ip_src
= alias_address
;
809 return(PKT_ALIAS_OK
);
811 return(PKT_ALIAS_IGNORED
);
816 UdpAliasIn(struct ip
*pip
)
819 struct alias_link
*link
;
821 /* Return if proxy-only mode is enabled */
822 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
825 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
827 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
828 ud
->uh_sport
, ud
->uh_dport
,
832 struct in_addr alias_address
;
833 struct in_addr original_address
;
839 alias_address
= GetAliasAddress(link
);
840 original_address
= GetOriginalAddress(link
);
841 alias_port
= ud
->uh_dport
;
842 ud
->uh_dport
= GetOriginalPort(link
);
844 /* Special processing for IP encoding protocols */
845 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
846 AliasHandleCUSeeMeIn(pip
, original_address
);
847 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
848 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
849 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
850 r
= AliasHandleUdpNbt(pip
, link
, &original_address
, ud
->uh_dport
);
851 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
852 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
853 r
= AliasHandleUdpNbtNS(pip
, link
, &alias_address
, &alias_port
,
854 &original_address
, &ud
->uh_dport
);
856 /* If UDP checksum is not zero, then adjust since destination port */
857 /* is being unaliased and destination address is being altered. */
860 accumulate
= alias_port
;
861 accumulate
-= ud
->uh_dport
;
862 sptr
= (u_short
*) &alias_address
;
863 accumulate
+= *sptr
++;
865 sptr
= (u_short
*) &original_address
;
866 accumulate
-= *sptr
++;
868 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
871 /* Restore original IP address */
872 DifferentialChecksum(&pip
->ip_sum
,
873 (u_short
*) &original_address
,
874 (u_short
*) &pip
->ip_dst
,
876 pip
->ip_dst
= original_address
;
879 * If we cannot figure out the packet, ignore it.
882 return(PKT_ALIAS_IGNORED
);
884 return(PKT_ALIAS_OK
);
886 return(PKT_ALIAS_IGNORED
);
890 UdpAliasOut(struct ip
*pip
)
893 struct alias_link
*link
;
895 /* Return if proxy-only mode is enabled */
896 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
899 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
901 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
902 ud
->uh_sport
, ud
->uh_dport
,
907 struct in_addr alias_address
;
909 alias_address
= GetAliasAddress(link
);
910 alias_port
= GetAliasPort(link
);
912 /* Special processing for IP encoding protocols */
913 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
914 AliasHandleCUSeeMeOut(pip
, link
);
915 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
916 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
917 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
918 AliasHandleUdpNbt(pip
, link
, &alias_address
, alias_port
);
919 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
920 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
921 AliasHandleUdpNbtNS(pip
, link
, &pip
->ip_src
, &ud
->uh_sport
,
922 &alias_address
, &alias_port
);
924 /* If UDP checksum is not zero, adjust since source port is */
925 /* being aliased and source address is being altered */
931 accumulate
= ud
->uh_sport
;
932 accumulate
-= alias_port
;
933 sptr
= (u_short
*) &(pip
->ip_src
);
934 accumulate
+= *sptr
++;
936 sptr
= (u_short
*) &alias_address
;
937 accumulate
-= *sptr
++;
939 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
942 /* Put alias port in UDP header */
943 ud
->uh_sport
= alias_port
;
945 /* Change source address */
946 DifferentialChecksum(&pip
->ip_sum
,
947 (u_short
*) &alias_address
,
948 (u_short
*) &pip
->ip_src
,
950 pip
->ip_src
= alias_address
;
952 return(PKT_ALIAS_OK
);
954 return(PKT_ALIAS_IGNORED
);
960 TcpAliasIn(struct ip
*pip
)
963 struct alias_link
*link
;
965 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
967 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
968 tc
->th_sport
, tc
->th_dport
,
970 !(packetAliasMode
& PKT_ALIAS_PROXY_ONLY
));
973 struct in_addr alias_address
;
974 struct in_addr original_address
;
975 struct in_addr proxy_address
;
981 /* Special processing for IP encoding protocols */
982 if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
983 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
984 AliasHandlePptpIn(pip
, link
);
986 alias_address
= GetAliasAddress(link
);
987 original_address
= GetOriginalAddress(link
);
988 proxy_address
= GetProxyAddress(link
);
989 alias_port
= tc
->th_dport
;
990 tc
->th_dport
= GetOriginalPort(link
);
991 proxy_port
= GetProxyPort(link
);
993 /* Adjust TCP checksum since destination port is being unaliased */
994 /* and destination port is being altered. */
995 accumulate
= alias_port
;
996 accumulate
-= tc
->th_dport
;
997 sptr
= (u_short
*) &alias_address
;
998 accumulate
+= *sptr
++;
1000 sptr
= (u_short
*) &original_address
;
1001 accumulate
-= *sptr
++;
1002 accumulate
-= *sptr
;
1004 /* If this is a proxy, then modify the TCP source port and
1005 checksum accumulation */
1006 if (proxy_port
!= 0)
1008 accumulate
+= tc
->th_sport
;
1009 tc
->th_sport
= proxy_port
;
1010 accumulate
-= tc
->th_sport
;
1012 sptr
= (u_short
*) &pip
->ip_src
;
1013 accumulate
+= *sptr
++;
1014 accumulate
+= *sptr
;
1015 sptr
= (u_short
*) &proxy_address
;
1016 accumulate
-= *sptr
++;
1017 accumulate
-= *sptr
;
1020 /* See if ACK number needs to be modified */
1021 if (GetAckModified(link
) == 1)
1025 delta
= GetDeltaAckIn(pip
, link
);
1028 sptr
= (u_short
*) &tc
->th_ack
;
1029 accumulate
+= *sptr
++;
1030 accumulate
+= *sptr
;
1031 tc
->th_ack
= htonl(ntohl(tc
->th_ack
) - delta
);
1032 sptr
= (u_short
*) &tc
->th_ack
;
1033 accumulate
-= *sptr
++;
1034 accumulate
-= *sptr
;
1038 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1040 /* Restore original IP address */
1041 sptr
= (u_short
*) &pip
->ip_dst
;
1042 accumulate
= *sptr
++;
1043 accumulate
+= *sptr
;
1044 pip
->ip_dst
= original_address
;
1045 sptr
= (u_short
*) &pip
->ip_dst
;
1046 accumulate
-= *sptr
++;
1047 accumulate
-= *sptr
;
1049 /* If this is a transparent proxy packet, then modify the source
1051 if (proxy_address
.s_addr
!= 0)
1053 sptr
= (u_short
*) &pip
->ip_src
;
1054 accumulate
+= *sptr
++;
1055 accumulate
+= *sptr
;
1056 pip
->ip_src
= proxy_address
;
1057 sptr
= (u_short
*) &pip
->ip_src
;
1058 accumulate
-= *sptr
++;
1059 accumulate
-= *sptr
;
1062 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1064 /* Monitor TCP connection state */
1065 TcpMonitorIn(pip
, link
);
1067 return(PKT_ALIAS_OK
);
1069 return(PKT_ALIAS_IGNORED
);
1073 TcpAliasOut(struct ip
*pip
, int maxpacketsize
)
1077 u_short proxy_server_port
;
1078 struct in_addr dest_address
;
1079 struct in_addr proxy_server_address
;
1081 struct alias_link
*link
;
1083 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1085 proxy_type
= ProxyCheck(pip
, &proxy_server_address
, &proxy_server_port
);
1087 if (proxy_type
== 0 && (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
))
1088 return PKT_ALIAS_OK
;
1090 /* If this is a transparent proxy, save original destination,
1091 then alter the destination and adjust checksums */
1092 dest_port
= tc
->th_dport
;
1093 dest_address
= pip
->ip_dst
;
1094 if (proxy_type
!= 0)
1099 accumulate
= tc
->th_dport
;
1100 tc
->th_dport
= proxy_server_port
;
1101 accumulate
-= tc
->th_dport
;
1103 sptr
= (u_short
*) &(pip
->ip_dst
);
1104 accumulate
+= *sptr
++;
1105 accumulate
+= *sptr
;
1106 sptr
= (u_short
*) &proxy_server_address
;
1107 accumulate
-= *sptr
++;
1108 accumulate
-= *sptr
;
1110 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1112 sptr
= (u_short
*) &(pip
->ip_dst
);
1113 accumulate
= *sptr
++;
1114 accumulate
+= *sptr
;
1115 pip
->ip_dst
= proxy_server_address
;
1116 sptr
= (u_short
*) &(pip
->ip_dst
);
1117 accumulate
-= *sptr
++;
1118 accumulate
-= *sptr
;
1120 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1123 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
1124 tc
->th_sport
, tc
->th_dport
,
1129 struct in_addr alias_address
;
1133 /* Save original destination address, if this is a proxy packet.
1134 Also modify packet to include destination encoding. */
1135 if (proxy_type
!= 0)
1137 SetProxyPort(link
, dest_port
);
1138 SetProxyAddress(link
, dest_address
);
1139 ProxyModify(link
, pip
, maxpacketsize
, proxy_type
);
1142 /* Get alias address and port */
1143 alias_port
= GetAliasPort(link
);
1144 alias_address
= GetAliasAddress(link
);
1146 /* Monitor TCP connection state */
1147 TcpMonitorOut(pip
, link
);
1149 /* Special processing for IP encoding protocols */
1150 if (ntohs(tc
->th_dport
) == FTP_CONTROL_PORT_NUMBER
1151 || ntohs(tc
->th_sport
) == FTP_CONTROL_PORT_NUMBER
)
1152 AliasHandleFtpOut(pip
, link
, maxpacketsize
);
1153 else if (ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_1
1154 || ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_2
)
1155 AliasHandleIrcOut(pip
, link
, maxpacketsize
);
1156 else if (ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_1
1157 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_1
1158 || ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_2
1159 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_2
)
1160 AliasHandleRtspOut(pip
, link
, maxpacketsize
);
1161 else if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
1162 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
1163 AliasHandlePptpOut(pip
, link
);
1165 /* Adjust TCP checksum since source port is being aliased */
1166 /* and source address is being altered */
1167 accumulate
= tc
->th_sport
;
1168 tc
->th_sport
= alias_port
;
1169 accumulate
-= tc
->th_sport
;
1171 sptr
= (u_short
*) &(pip
->ip_src
);
1172 accumulate
+= *sptr
++;
1173 accumulate
+= *sptr
;
1174 sptr
= (u_short
*) &alias_address
;
1175 accumulate
-= *sptr
++;
1176 accumulate
-= *sptr
;
1178 /* Modify sequence number if necessary */
1179 if (GetAckModified(link
) == 1)
1183 delta
= GetDeltaSeqOut(pip
, link
);
1186 sptr
= (u_short
*) &tc
->th_seq
;
1187 accumulate
+= *sptr
++;
1188 accumulate
+= *sptr
;
1189 tc
->th_seq
= htonl(ntohl(tc
->th_seq
) + delta
);
1190 sptr
= (u_short
*) &tc
->th_seq
;
1191 accumulate
-= *sptr
++;
1192 accumulate
-= *sptr
;
1196 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1198 /* Change source address */
1199 sptr
= (u_short
*) &(pip
->ip_src
);
1200 accumulate
= *sptr
++;
1201 accumulate
+= *sptr
;
1202 pip
->ip_src
= alias_address
;
1203 sptr
= (u_short
*) &(pip
->ip_src
);
1204 accumulate
-= *sptr
++;
1205 accumulate
-= *sptr
;
1207 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1209 return(PKT_ALIAS_OK
);
1211 return(PKT_ALIAS_IGNORED
);
1217 /* Fragment Handling
1222 The packet aliasing module has a limited ability for handling IP
1223 fragments. If the ICMP, TCP or UDP header is in the first fragment
1224 received, then the ID number of the IP packet is saved, and other
1225 fragments are identified according to their ID number and IP address
1226 they were sent from. Pointers to unresolved fragments can also be
1227 saved and recalled when a header fragment is seen.
1230 /* Local prototypes */
1231 static int FragmentIn(struct ip
*);
1232 static int FragmentOut(struct ip
*);
1236 FragmentIn(struct ip
*pip
)
1238 struct alias_link
*link
;
1240 link
= FindFragmentIn2(pip
->ip_src
, pip
->ip_dst
, pip
->ip_id
);
1243 struct in_addr original_address
;
1245 GetFragmentAddr(link
, &original_address
);
1246 DifferentialChecksum(&pip
->ip_sum
,
1247 (u_short
*) &original_address
,
1248 (u_short
*) &pip
->ip_dst
,
1250 pip
->ip_dst
= original_address
;
1252 return(PKT_ALIAS_OK
);
1254 return(PKT_ALIAS_UNRESOLVED_FRAGMENT
);
1259 FragmentOut(struct ip
*pip
)
1261 struct in_addr alias_address
;
1263 alias_address
= FindAliasAddress(pip
->ip_src
);
1264 DifferentialChecksum(&pip
->ip_sum
,
1265 (u_short
*) &alias_address
,
1266 (u_short
*) &pip
->ip_src
,
1268 pip
->ip_src
= alias_address
;
1270 return(PKT_ALIAS_OK
);
1278 /* Outside World Access
1280 PacketAliasSaveFragment()
1281 PacketAliasGetFragment()
1282 PacketAliasFragmentIn()
1287 (prototypes in alias.h)
1292 PacketAliasSaveFragment(char *ptr
)
1295 struct alias_link
*link
;
1298 pip
= (struct ip
*) ptr
;
1299 link
= AddFragmentPtrLink(pip
->ip_src
, pip
->ip_id
);
1300 iresult
= PKT_ALIAS_ERROR
;
1303 SetFragmentPtr(link
, ptr
);
1304 iresult
= PKT_ALIAS_OK
;
1311 PacketAliasGetFragment(char *ptr
)
1313 struct alias_link
*link
;
1317 pip
= (struct ip
*) ptr
;
1318 link
= FindFragmentPtr(pip
->ip_src
, pip
->ip_id
);
1321 GetFragmentPtr(link
, &fptr
);
1322 SetFragmentPtr(link
, NULL
);
1323 SetExpire(link
, 0); /* Deletes link */
1335 PacketAliasFragmentIn(char *ptr
, /* Points to correctly de-aliased
1337 char *ptr_fragment
/* Points to fragment which must
1344 pip
= (struct ip
*) ptr
;
1345 fpip
= (struct ip
*) ptr_fragment
;
1347 DifferentialChecksum(&fpip
->ip_sum
,
1348 (u_short
*) &pip
->ip_dst
,
1349 (u_short
*) &fpip
->ip_dst
,
1351 fpip
->ip_dst
= pip
->ip_dst
;
1356 PacketAliasIn(char *ptr
, int maxpacketsize
)
1358 struct in_addr alias_addr
;
1362 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1363 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1364 iresult
= PacketAliasOut(ptr
, maxpacketsize
);
1365 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1370 ClearCheckNewLink();
1371 pip
= (struct ip
*) ptr
;
1372 alias_addr
= pip
->ip_dst
;
1374 /* Defense against mangled packets */
1375 if (ntohs(pip
->ip_len
) > maxpacketsize
1376 || (pip
->ip_hl
<<2) > maxpacketsize
)
1377 return PKT_ALIAS_IGNORED
;
1379 iresult
= PKT_ALIAS_IGNORED
;
1380 if ( (ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0 )
1385 iresult
= IcmpAliasIn(pip
);
1388 iresult
= UdpAliasIn(pip
);
1391 iresult
= TcpAliasIn(pip
);
1394 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
||
1395 AliasHandlePptpGreIn(pip
) == 0)
1396 iresult
= PKT_ALIAS_OK
;
1398 iresult
= ProtoAliasIn(pip
);
1401 iresult
= ProtoAliasIn(pip
);
1405 if (ntohs(pip
->ip_off
) & IP_MF
)
1407 struct alias_link
*link
;
1409 link
= FindFragmentIn1(pip
->ip_src
, alias_addr
, pip
->ip_id
);
1412 iresult
= PKT_ALIAS_FOUND_HEADER_FRAGMENT
;
1413 SetFragmentAddr(link
, pip
->ip_dst
);
1417 iresult
= PKT_ALIAS_ERROR
;
1423 iresult
= FragmentIn(pip
);
1431 /* Unregistered address ranges */
1433 /* 10.0.0.0 -> 10.255.255.255 */
1434 #define UNREG_ADDR_A_LOWER 0x0a000000
1435 #define UNREG_ADDR_A_UPPER 0x0affffff
1437 /* 172.16.0.0 -> 172.31.255.255 */
1438 #define UNREG_ADDR_B_LOWER 0xac100000
1439 #define UNREG_ADDR_B_UPPER 0xac1fffff
1441 /* 192.168.0.0 -> 192.168.255.255 */
1442 #define UNREG_ADDR_C_LOWER 0xc0a80000
1443 #define UNREG_ADDR_C_UPPER 0xc0a8ffff
1446 PacketAliasOut(char *ptr
, /* valid IP packet */
1447 int maxpacketsize
/* How much the packet data may grow
1448 (FTP and IRC inline changes) */
1452 struct in_addr addr_save
;
1455 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1456 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1457 iresult
= PacketAliasIn(ptr
, maxpacketsize
);
1458 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1463 ClearCheckNewLink();
1464 pip
= (struct ip
*) ptr
;
1466 /* Defense against mangled packets */
1467 if (ntohs(pip
->ip_len
) > maxpacketsize
1468 || (pip
->ip_hl
<<2) > maxpacketsize
)
1469 return PKT_ALIAS_IGNORED
;
1471 addr_save
= GetDefaultAliasAddress();
1472 if (packetAliasMode
& PKT_ALIAS_UNREGISTERED_ONLY
)
1478 addr
= ntohl(pip
->ip_src
.s_addr
);
1479 if (addr
>= UNREG_ADDR_C_LOWER
&& addr
<= UNREG_ADDR_C_UPPER
)
1481 else if (addr
>= UNREG_ADDR_B_LOWER
&& addr
<= UNREG_ADDR_B_UPPER
)
1483 else if (addr
>= UNREG_ADDR_A_LOWER
&& addr
<= UNREG_ADDR_A_UPPER
)
1488 SetDefaultAliasAddress(pip
->ip_src
);
1492 iresult
= PKT_ALIAS_IGNORED
;
1493 if ((ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0)
1498 iresult
= IcmpAliasOut(pip
);
1501 iresult
= UdpAliasOut(pip
);
1504 iresult
= TcpAliasOut(pip
, maxpacketsize
);
1507 if (AliasHandlePptpGreOut(pip
) == 0)
1508 iresult
= PKT_ALIAS_OK
;
1510 iresult
= ProtoAliasOut(pip
);
1513 iresult
= ProtoAliasOut(pip
);
1519 iresult
= FragmentOut(pip
);
1522 SetDefaultAliasAddress(addr_save
);
1527 PacketUnaliasOut(char *ptr
, /* valid IP packet */
1528 int maxpacketsize
/* for error checking */
1535 struct alias_link
*link
;
1536 int iresult
= PKT_ALIAS_IGNORED
;
1538 pip
= (struct ip
*) ptr
;
1540 /* Defense against mangled packets */
1541 if (ntohs(pip
->ip_len
) > maxpacketsize
1542 || (pip
->ip_hl
<<2) > maxpacketsize
)
1545 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1546 tc
= (struct tcphdr
*) ud
;
1547 ic
= (struct icmp
*) ud
;
1550 if (pip
->ip_p
== IPPROTO_UDP
)
1551 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1552 ud
->uh_dport
, ud
->uh_sport
,
1554 else if (pip
->ip_p
== IPPROTO_TCP
)
1555 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1556 tc
->th_dport
, tc
->th_sport
,
1558 else if (pip
->ip_p
== IPPROTO_ICMP
)
1559 link
= FindIcmpIn(pip
->ip_dst
, pip
->ip_src
, ic
->icmp_id
, 0);
1563 /* Change it from an aliased packet to an unaliased packet */
1566 if (pip
->ip_p
== IPPROTO_UDP
|| pip
->ip_p
== IPPROTO_TCP
)
1570 struct in_addr original_address
;
1571 u_short original_port
;
1573 original_address
= GetOriginalAddress(link
);
1574 original_port
= GetOriginalPort(link
);
1576 /* Adjust TCP/UDP checksum */
1577 sptr
= (u_short
*) &(pip
->ip_src
);
1578 accumulate
= *sptr
++;
1579 accumulate
+= *sptr
;
1580 sptr
= (u_short
*) &original_address
;
1581 accumulate
-= *sptr
++;
1582 accumulate
-= *sptr
;
1584 if (pip
->ip_p
== IPPROTO_UDP
) {
1585 accumulate
+= ud
->uh_sport
;
1586 accumulate
-= original_port
;
1587 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
1589 accumulate
+= tc
->th_sport
;
1590 accumulate
-= original_port
;
1591 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1594 /* Adjust IP checksum */
1595 DifferentialChecksum(&pip
->ip_sum
,
1596 (u_short
*) &original_address
,
1597 (u_short
*) &pip
->ip_src
,
1600 /* Un-alias source address and port number */
1601 pip
->ip_src
= original_address
;
1602 if (pip
->ip_p
== IPPROTO_UDP
)
1603 ud
->uh_sport
= original_port
;
1605 tc
->th_sport
= original_port
;
1607 iresult
= PKT_ALIAS_OK
;
1609 } else if (pip
->ip_p
== IPPROTO_ICMP
) {
1613 struct in_addr original_address
;
1614 u_short original_id
;
1616 original_address
= GetOriginalAddress(link
);
1617 original_id
= GetOriginalPort(link
);
1619 /* Adjust ICMP checksum */
1620 sptr
= (u_short
*) &(pip
->ip_src
);
1621 accumulate
= *sptr
++;
1622 accumulate
+= *sptr
;
1623 sptr
= (u_short
*) &original_address
;
1624 accumulate
-= *sptr
++;
1625 accumulate
-= *sptr
;
1626 accumulate
+= ic
->icmp_id
;
1627 accumulate
-= original_id
;
1628 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
1630 /* Adjust IP checksum */
1631 DifferentialChecksum(&pip
->ip_sum
,
1632 (u_short
*) &original_address
,
1633 (u_short
*) &pip
->ip_src
,
1636 /* Un-alias source address and port number */
1637 pip
->ip_src
= original_address
;
1638 ic
->icmp_id
= original_id
;
1640 iresult
= PKT_ALIAS_OK
;