2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 2001 Charles Mott <cmott@scientech.com>
24 * All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * $FreeBSD: src/lib/libalias/alias.c,v 1.16.2.7 2001/08/21 03:50:25 brian Exp $
52 Alias.c provides supervisory control for the functions of the
53 packet aliasing software. It consists of routines to monitor
54 TCP connection state, protocol-specific aliasing routines,
55 fragment handling and the following outside world functional
56 interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn,
57 PacketAliasIn and PacketAliasOut.
59 The other C program files are briefly described. The data
60 structure framework which holds information needed to translate
61 packets is encapsulated in alias_db.c. Data is accessed by
62 function calls, so other segments of the program need not know
63 about the underlying data structures. Alias_ftp.c contains
64 special code for modifying the ftp PORT command used to establish
65 data connections, while alias_irc.c does the same for IRC
66 DCC. Alias_util.c contains a few utility routines.
68 Version 1.0 August, 1996 (cjm)
70 Version 1.1 August 20, 1996 (cjm)
71 PPP host accepts incoming connections for ports 0 to 1023.
72 (Gary Roberts pointed out the need to handle incoming
75 Version 1.2 September 7, 1996 (cjm)
76 Fragment handling error in alias_db.c corrected.
77 (Tom Torrance helped fix this problem.)
79 Version 1.4 September 16, 1996 (cjm)
80 - A more generalized method for handling incoming
81 connections, without the 0-1023 restriction, is
82 implemented in alias_db.c
83 - Improved ICMP support in alias.c. Traceroute
84 packet streams can now be correctly aliased.
85 - TCP connection closing logic simplified in
86 alias.c and now allows for additional 1 minute
87 "grace period" after FIN or RST is observed.
89 Version 1.5 September 17, 1996 (cjm)
90 Corrected error in handling incoming UDP packets with 0 checksum.
91 (Tom Torrance helped fix this problem.)
93 Version 1.6 September 18, 1996 (cjm)
94 Simplified ICMP aliasing scheme. Should now support
95 traceroute from Win95 as well as FreeBSD.
97 Version 1.7 January 9, 1997 (cjm)
98 - Out-of-order fragment handling.
99 - IP checksum error fixed for ftp transfers
101 - Integer return codes added to all
102 aliasing/de-aliasing functions.
103 - Some obsolete comments cleaned up.
104 - Differential checksum computations for
105 IP header (TCP, UDP and ICMP were already
108 Version 2.1 May 1997 (cjm)
109 - Added support for outgoing ICMP error
111 - Added two functions PacketAliasIn2()
112 and PacketAliasOut2() for dynamic address
113 control (e.g. round-robin allocation of
116 Version 2.2 July 1997 (cjm)
117 - Rationalized API function names to begin
118 with "PacketAlias..."
119 - Eliminated PacketAliasIn2() and
120 PacketAliasOut2() as poorly conceived.
122 Version 2.3 Dec 1998 (dillon)
123 - Major bounds checking additions, see FreeBSD/CVS
125 Version 3.1 May, 2000 (salander)
126 - Added hooks to handle PPTP.
128 Version 3.2 July, 2000 (salander and satoh)
129 - Added PacketUnaliasOut routine.
130 - Added hooks to handle RTSP/RTP.
132 See HISTORY file for additional revisions.
135 #include <sys/types.h>
137 #include <netinet/in_systm.h>
138 #include <netinet/in.h>
139 #include <netinet/ip.h>
140 #include <netinet/ip_icmp.h>
141 #include <netinet/tcp.h>
142 #include <netinet/udp.h>
146 #include "alias_local.h"
149 #define NETBIOS_NS_PORT_NUMBER 137
150 #define NETBIOS_DGM_PORT_NUMBER 138
151 #define FTP_CONTROL_PORT_NUMBER 21
152 #define IRC_CONTROL_PORT_NUMBER_1 6667
153 #define IRC_CONTROL_PORT_NUMBER_2 6668
154 #define CUSEEME_PORT_NUMBER 7648
155 #define RTSP_CONTROL_PORT_NUMBER_1 554
156 #define RTSP_CONTROL_PORT_NUMBER_2 7070
157 #define PPTP_CONTROL_PORT_NUMBER 1723
162 /* TCP Handling Routines
164 TcpMonitorIn() -- These routines monitor TCP connections, and
165 TcpMonitorOut() delete a link when a connection is closed.
167 DoMSSClamp() -- Clamps the MSS of the given TCP header to the
168 value in packetAliasMSS.
170 These routines look for SYN, FIN and RST flags to determine when TCP
171 connections open and close. When a TCP connection closes, the data
172 structure containing packet aliasing information is deleted after
176 /* Local prototypes */
177 static void TcpMonitorIn(struct ip
*, struct alias_link
*);
179 static void TcpMonitorOut(struct ip
*, struct alias_link
*);
182 static u_short packetAliasMSS
;
184 void PacketAliasClampMSS(u_short mss
)
186 packetAliasMSS
= mss
;
189 static void DoMSSClamp(struct tcphdr
*tc
)
191 u_char
*option
= (u_char
*) tc
+ sizeof(*tc
);
192 u_char
*optionEnd
= option
+ ((tc
->th_off
<< 2) - sizeof(*tc
));
194 while (optionEnd
> option
)
196 /* Bounds checking to avoid infinite loops */
197 if (option
[0] == TCPOPT_EOL
)
200 if (option
[0] == TCPOPT_NOP
) {
204 if (optionEnd
- option
< 2)
206 if (option
[1] < 2 || option
+ option
[1] >= optionEnd
)
215 u_short
*mssPtr
= (u_short
*) option
+ 1;
216 u_short mssVal
= ntohs(*mssPtr
);
218 if (packetAliasMSS
< mssVal
)
220 int accumulate
= mssVal
;
221 int accnetorder
= 0 ;
223 accumulate
-= packetAliasMSS
;
224 *mssPtr
= htons(packetAliasMSS
);
225 accnetorder
= htons(accumulate
);
226 ADJUST_CHECKSUM(accnetorder
, tc
->th_sum
);
241 TcpMonitorIn(struct ip
*pip
, struct alias_link
*link
)
245 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
247 switch (GetStateIn(link
))
249 case ALIAS_TCP_STATE_NOT_CONNECTED
:
250 if (tc
->th_flags
& TH_RST
)
251 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
252 else if (tc
->th_flags
& TH_SYN
)
254 SetStateIn(link
, ALIAS_TCP_STATE_CONNECTED
);
260 case ALIAS_TCP_STATE_CONNECTED
:
261 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
262 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
268 TcpMonitorOut(struct ip
*pip
, struct alias_link
*link
)
272 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
274 switch (GetStateOut(link
))
276 case ALIAS_TCP_STATE_NOT_CONNECTED
:
277 if (tc
->th_flags
& TH_RST
)
278 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
279 else if (tc
->th_flags
& TH_SYN
)
281 SetStateOut(link
, ALIAS_TCP_STATE_CONNECTED
);
287 case ALIAS_TCP_STATE_CONNECTED
:
288 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
289 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
298 /* Protocol Specific Packet Aliasing Routines
300 IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2()
301 IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2()
302 ProtoAliasIn(), ProtoAliasOut()
303 UdpAliasIn(), UdpAliasOut()
304 TcpAliasIn(), TcpAliasOut()
306 These routines handle protocol specific details of packet aliasing.
307 One may observe a certain amount of repetitive arithmetic in these
308 functions, the purpose of which is to compute a revised checksum
309 without actually summing over the entire data packet, which could be
310 unnecessarily time consuming.
312 The purpose of the packet aliasing routines is to replace the source
313 address of the outgoing packet and then correctly put it back for
314 any incoming packets. For TCP and UDP, ports are also re-mapped.
316 For ICMP echo/timestamp requests and replies, the following scheme
317 is used: the ID number is replaced by an alias for the outgoing
320 ICMP error messages are handled by looking at the IP fragment
321 in the data section of the message.
323 For TCP and UDP protocols, a port number is chosen for an outgoing
324 packet, and then incoming packets are identified by IP address and
325 port numbers. For TCP packets, there is additional logic in the event
326 that sequence and ACK numbers have been altered (as in the case for
327 FTP data port commands).
329 The port numbers used by the packet aliasing module are not true
330 ports in the Unix sense. No sockets are actually bound to ports.
331 They are more correctly thought of as placeholders.
333 All packets go through the aliasing mechanism, whether they come from
334 the gateway machine or other machines on a local area network.
338 /* Local prototypes */
339 static int IcmpAliasIn1(struct ip
*);
340 static int IcmpAliasIn2(struct ip
*);
341 static int IcmpAliasIn (struct ip
*);
343 static int IcmpAliasOut1(struct ip
*);
344 static int IcmpAliasOut2(struct ip
*);
345 static int IcmpAliasOut (struct ip
*);
347 static int ProtoAliasIn(struct ip
*);
348 static int ProtoAliasOut(struct ip
*);
350 static int UdpAliasOut(struct ip
*);
351 static int UdpAliasIn (struct ip
*);
353 static int TcpAliasOut(struct ip
*, int);
354 static int TcpAliasIn (struct ip
*);
358 IcmpAliasIn1(struct ip
*pip
)
361 De-alias incoming echo and timestamp replies.
362 Alias incoming echo and timestamp requests.
364 struct alias_link
*link
;
367 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
369 /* Get source address from ICMP data field and restore original data */
370 link
= FindIcmpIn(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
376 original_id
= GetOriginalPort(link
);
378 /* Adjust ICMP checksum */
379 accumulate
= ic
->icmp_id
;
380 accumulate
-= original_id
;
381 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
383 /* Put original sequence number back in */
384 ic
->icmp_id
= original_id
;
386 /* Put original address back into IP header */
388 struct in_addr original_address
;
390 original_address
= GetOriginalAddress(link
);
391 DifferentialChecksum(&pip
->ip_sum
,
392 (u_short
*) &original_address
,
393 (u_short
*) &pip
->ip_dst
,
395 pip
->ip_dst
= original_address
;
398 return(PKT_ALIAS_OK
);
400 return(PKT_ALIAS_IGNORED
);
404 IcmpAliasIn2(struct ip
*pip
)
407 Alias incoming ICMP error messages containing
408 IP header and first 64 bits of datagram.
411 struct icmp
*ic
, *ic2
;
414 struct alias_link
*link
;
416 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
419 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
420 tc
= (struct tcphdr
*) ud
;
421 ic2
= (struct icmp
*) ud
;
423 if (ip
->ip_p
== IPPROTO_UDP
)
424 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
425 ud
->uh_dport
, ud
->uh_sport
,
427 else if (ip
->ip_p
== IPPROTO_TCP
)
428 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
429 tc
->th_dport
, tc
->th_sport
,
431 else if (ip
->ip_p
== IPPROTO_ICMP
) {
432 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
433 link
= FindIcmpIn(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
441 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
445 struct in_addr original_address
;
446 u_short original_port
;
448 original_address
= GetOriginalAddress(link
);
449 original_port
= GetOriginalPort(link
);
451 /* Adjust ICMP checksum */
452 sptr
= (u_short
*) &(ip
->ip_src
);
453 accumulate
= *sptr
++;
455 sptr
= (u_short
*) &original_address
;
456 accumulate
-= *sptr
++;
458 accumulate
+= ud
->uh_sport
;
459 accumulate
-= original_port
;
460 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
462 /* Un-alias address in IP header */
463 DifferentialChecksum(&pip
->ip_sum
,
464 (u_short
*) &original_address
,
465 (u_short
*) &pip
->ip_dst
,
467 pip
->ip_dst
= original_address
;
469 /* Un-alias address and port number of original IP packet
470 fragment contained in ICMP data section */
471 ip
->ip_src
= original_address
;
472 ud
->uh_sport
= original_port
;
474 else if (ip
->ip_p
== IPPROTO_ICMP
)
478 struct in_addr original_address
;
481 original_address
= GetOriginalAddress(link
);
482 original_id
= GetOriginalPort(link
);
484 /* Adjust ICMP checksum */
485 sptr
= (u_short
*) &(ip
->ip_src
);
486 accumulate
= *sptr
++;
488 sptr
= (u_short
*) &original_address
;
489 accumulate
-= *sptr
++;
491 accumulate
+= ic2
->icmp_id
;
492 accumulate
-= original_id
;
493 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
495 /* Un-alias address in IP header */
496 DifferentialChecksum(&pip
->ip_sum
,
497 (u_short
*) &original_address
,
498 (u_short
*) &pip
->ip_dst
,
500 pip
->ip_dst
= original_address
;
502 /* Un-alias address of original IP packet and sequence number of
503 embedded ICMP datagram */
504 ip
->ip_src
= original_address
;
505 ic2
->icmp_id
= original_id
;
507 return(PKT_ALIAS_OK
);
509 return(PKT_ALIAS_IGNORED
);
514 IcmpAliasIn(struct ip
*pip
)
519 /* Return if proxy-only mode is enabled */
520 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
523 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
525 iresult
= PKT_ALIAS_IGNORED
;
526 switch (ic
->icmp_type
)
529 case ICMP_TSTAMPREPLY
:
530 if (ic
->icmp_code
== 0)
532 iresult
= IcmpAliasIn1(pip
);
536 case ICMP_SOURCEQUENCH
:
539 iresult
= IcmpAliasIn2(pip
);
543 iresult
= IcmpAliasIn1(pip
);
551 IcmpAliasOut1(struct ip
*pip
)
554 Alias outgoing echo and timestamp requests.
555 De-alias outgoing echo and timestamp replies.
557 struct alias_link
*link
;
560 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
562 /* Save overwritten data for when echo packet returns */
563 link
= FindIcmpOut(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
569 alias_id
= GetAliasPort(link
);
571 /* Since data field is being modified, adjust ICMP checksum */
572 accumulate
= ic
->icmp_id
;
573 accumulate
-= alias_id
;
574 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
576 /* Alias sequence number */
577 ic
->icmp_id
= alias_id
;
579 /* Change source address */
581 struct in_addr alias_address
;
583 alias_address
= GetAliasAddress(link
);
584 DifferentialChecksum(&pip
->ip_sum
,
585 (u_short
*) &alias_address
,
586 (u_short
*) &pip
->ip_src
,
588 pip
->ip_src
= alias_address
;
591 return(PKT_ALIAS_OK
);
593 return(PKT_ALIAS_IGNORED
);
598 IcmpAliasOut2(struct ip
*pip
)
601 Alias outgoing ICMP error messages containing
602 IP header and first 64 bits of datagram.
605 struct icmp
*ic
, *ic2
;
608 struct alias_link
*link
;
610 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
613 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
614 tc
= (struct tcphdr
*) ud
;
615 ic2
= (struct icmp
*) ud
;
617 if (ip
->ip_p
== IPPROTO_UDP
)
618 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
619 ud
->uh_dport
, ud
->uh_sport
,
621 else if (ip
->ip_p
== IPPROTO_TCP
)
622 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
623 tc
->th_dport
, tc
->th_sport
,
625 else if (ip
->ip_p
== IPPROTO_ICMP
) {
626 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
627 link
= FindIcmpOut(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
635 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
639 struct in_addr alias_address
;
642 alias_address
= GetAliasAddress(link
);
643 alias_port
= GetAliasPort(link
);
645 /* Adjust ICMP checksum */
646 sptr
= (u_short
*) &(ip
->ip_dst
);
647 accumulate
= *sptr
++;
649 sptr
= (u_short
*) &alias_address
;
650 accumulate
-= *sptr
++;
652 accumulate
+= ud
->uh_dport
;
653 accumulate
-= alias_port
;
654 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
657 * Alias address in IP header if it comes from the host
658 * the original TCP/UDP packet was destined for.
660 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
661 DifferentialChecksum(&pip
->ip_sum
,
662 (u_short
*) &alias_address
,
663 (u_short
*) &pip
->ip_src
,
665 pip
->ip_src
= alias_address
;
668 /* Alias address and port number of original IP packet
669 fragment contained in ICMP data section */
670 ip
->ip_dst
= alias_address
;
671 ud
->uh_dport
= alias_port
;
673 else if (ip
->ip_p
== IPPROTO_ICMP
)
677 struct in_addr alias_address
;
680 alias_address
= GetAliasAddress(link
);
681 alias_id
= GetAliasPort(link
);
683 /* Adjust ICMP checksum */
684 sptr
= (u_short
*) &(ip
->ip_dst
);
685 accumulate
= *sptr
++;
687 sptr
= (u_short
*) &alias_address
;
688 accumulate
-= *sptr
++;
690 accumulate
+= ic2
->icmp_id
;
691 accumulate
-= alias_id
;
692 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
695 * Alias address in IP header if it comes from the host
696 * the original ICMP message was destined for.
698 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
699 DifferentialChecksum(&pip
->ip_sum
,
700 (u_short
*) &alias_address
,
701 (u_short
*) &pip
->ip_src
,
703 pip
->ip_src
= alias_address
;
706 /* Alias address of original IP packet and sequence number of
707 embedded ICMP datagram */
708 ip
->ip_dst
= alias_address
;
709 ic2
->icmp_id
= alias_id
;
711 return(PKT_ALIAS_OK
);
713 return(PKT_ALIAS_IGNORED
);
718 IcmpAliasOut(struct ip
*pip
)
723 /* Return if proxy-only mode is enabled */
724 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
727 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
729 iresult
= PKT_ALIAS_IGNORED
;
730 switch (ic
->icmp_type
)
734 if (ic
->icmp_code
== 0)
736 iresult
= IcmpAliasOut1(pip
);
740 case ICMP_SOURCEQUENCH
:
743 iresult
= IcmpAliasOut2(pip
);
746 case ICMP_TSTAMPREPLY
:
747 iresult
= IcmpAliasOut1(pip
);
755 ProtoAliasIn(struct ip
*pip
)
758 Handle incoming IP packets. The
759 only thing which is done in this case is to alias
760 the dest IP address of the packet to our inside
763 struct alias_link
*link
;
765 /* Return if proxy-only mode is enabled */
766 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
769 link
= FindProtoIn(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
772 struct in_addr original_address
;
774 original_address
= GetOriginalAddress(link
);
776 /* Restore original IP address */
777 DifferentialChecksum(&pip
->ip_sum
,
778 (u_short
*) &original_address
,
779 (u_short
*) &pip
->ip_dst
,
781 pip
->ip_dst
= original_address
;
783 return(PKT_ALIAS_OK
);
785 return(PKT_ALIAS_IGNORED
);
790 ProtoAliasOut(struct ip
*pip
)
793 Handle outgoing IP packets. The
794 only thing which is done in this case is to alias
795 the source IP address of the packet.
797 struct alias_link
*link
;
799 /* Return if proxy-only mode is enabled */
800 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
803 link
= FindProtoOut(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
806 struct in_addr alias_address
;
808 alias_address
= GetAliasAddress(link
);
810 /* Change source address */
811 DifferentialChecksum(&pip
->ip_sum
,
812 (u_short
*) &alias_address
,
813 (u_short
*) &pip
->ip_src
,
815 pip
->ip_src
= alias_address
;
817 return(PKT_ALIAS_OK
);
819 return(PKT_ALIAS_IGNORED
);
824 UdpAliasIn(struct ip
*pip
)
827 struct alias_link
*link
;
829 /* Return if proxy-only mode is enabled */
830 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
833 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
835 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
836 ud
->uh_sport
, ud
->uh_dport
,
840 struct in_addr alias_address
;
841 struct in_addr original_address
;
847 alias_address
= GetAliasAddress(link
);
848 original_address
= GetOriginalAddress(link
);
849 alias_port
= ud
->uh_dport
;
850 ud
->uh_dport
= GetOriginalPort(link
);
852 /* Special processing for IP encoding protocols */
853 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
854 AliasHandleCUSeeMeIn(pip
, original_address
);
855 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
856 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
857 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
858 r
= AliasHandleUdpNbt(pip
, link
, &original_address
, ud
->uh_dport
);
859 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
860 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
861 r
= AliasHandleUdpNbtNS(pip
, link
, &alias_address
, &alias_port
,
862 &original_address
, &ud
->uh_dport
);
864 /* If UDP checksum is not zero, then adjust since destination port */
865 /* is being unaliased and destination address is being altered. */
868 accumulate
= alias_port
;
869 accumulate
-= ud
->uh_dport
;
870 sptr
= (u_short
*) &alias_address
;
871 accumulate
+= *sptr
++;
873 sptr
= (u_short
*) &original_address
;
874 accumulate
-= *sptr
++;
876 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
879 /* Restore original IP address */
880 DifferentialChecksum(&pip
->ip_sum
,
881 (u_short
*) &original_address
,
882 (u_short
*) &pip
->ip_dst
,
884 pip
->ip_dst
= original_address
;
887 * If we cannot figure out the packet, ignore it.
890 return(PKT_ALIAS_IGNORED
);
892 return(PKT_ALIAS_OK
);
894 return(PKT_ALIAS_IGNORED
);
898 UdpAliasOut(struct ip
*pip
)
901 struct alias_link
*link
;
903 /* Return if proxy-only mode is enabled */
904 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
907 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
909 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
910 ud
->uh_sport
, ud
->uh_dport
,
915 struct in_addr alias_address
;
917 alias_address
= GetAliasAddress(link
);
918 alias_port
= GetAliasPort(link
);
920 /* Special processing for IP encoding protocols */
921 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
922 AliasHandleCUSeeMeOut(pip
, link
);
923 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
924 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
925 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
926 AliasHandleUdpNbt(pip
, link
, &alias_address
, alias_port
);
927 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
928 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
929 AliasHandleUdpNbtNS(pip
, link
, &pip
->ip_src
, &ud
->uh_sport
,
930 &alias_address
, &alias_port
);
932 /* If UDP checksum is not zero, adjust since source port is */
933 /* being aliased and source address is being altered */
939 accumulate
= ud
->uh_sport
;
940 accumulate
-= alias_port
;
941 sptr
= (u_short
*) &(pip
->ip_src
);
942 accumulate
+= *sptr
++;
944 sptr
= (u_short
*) &alias_address
;
945 accumulate
-= *sptr
++;
947 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
950 /* Put alias port in UDP header */
951 ud
->uh_sport
= alias_port
;
953 /* Change source address */
954 DifferentialChecksum(&pip
->ip_sum
,
955 (u_short
*) &alias_address
,
956 (u_short
*) &pip
->ip_src
,
958 pip
->ip_src
= alias_address
;
960 return(PKT_ALIAS_OK
);
962 return(PKT_ALIAS_IGNORED
);
968 TcpAliasIn(struct ip
*pip
)
971 struct alias_link
*link
;
973 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
975 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
976 tc
->th_sport
, tc
->th_dport
,
978 !(packetAliasMode
& PKT_ALIAS_PROXY_ONLY
));
981 struct in_addr alias_address
;
982 struct in_addr original_address
;
983 struct in_addr proxy_address
;
989 /* Special processing for IP encoding protocols */
990 if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
991 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
992 AliasHandlePptpIn(pip
, link
);
994 alias_address
= GetAliasAddress(link
);
995 original_address
= GetOriginalAddress(link
);
996 proxy_address
= GetProxyAddress(link
);
997 alias_port
= tc
->th_dport
;
998 tc
->th_dport
= GetOriginalPort(link
);
999 proxy_port
= GetProxyPort(link
);
1001 /* Adjust TCP checksum since destination port is being unaliased */
1002 /* and destination port is being altered. */
1003 accumulate
= alias_port
;
1004 accumulate
-= tc
->th_dport
;
1005 sptr
= (u_short
*) &alias_address
;
1006 accumulate
+= *sptr
++;
1007 accumulate
+= *sptr
;
1008 sptr
= (u_short
*) &original_address
;
1009 accumulate
-= *sptr
++;
1010 accumulate
-= *sptr
;
1012 /* If this is a proxy, then modify the TCP source port and
1013 checksum accumulation */
1014 if (proxy_port
!= 0)
1016 accumulate
+= tc
->th_sport
;
1017 tc
->th_sport
= proxy_port
;
1018 accumulate
-= tc
->th_sport
;
1020 sptr
= (u_short
*) &pip
->ip_src
;
1021 accumulate
+= *sptr
++;
1022 accumulate
+= *sptr
;
1023 sptr
= (u_short
*) &proxy_address
;
1024 accumulate
-= *sptr
++;
1025 accumulate
-= *sptr
;
1028 /* See if ACK number needs to be modified */
1029 if (GetAckModified(link
) == 1)
1033 delta
= GetDeltaAckIn(pip
, link
);
1036 sptr
= (u_short
*) &tc
->th_ack
;
1037 accumulate
+= *sptr
++;
1038 accumulate
+= *sptr
;
1039 tc
->th_ack
= htonl(ntohl(tc
->th_ack
) - delta
);
1040 sptr
= (u_short
*) &tc
->th_ack
;
1041 accumulate
-= *sptr
++;
1042 accumulate
-= *sptr
;
1046 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1048 /* Restore original IP address */
1049 sptr
= (u_short
*) &pip
->ip_dst
;
1050 accumulate
= *sptr
++;
1051 accumulate
+= *sptr
;
1052 pip
->ip_dst
= original_address
;
1053 sptr
= (u_short
*) &pip
->ip_dst
;
1054 accumulate
-= *sptr
++;
1055 accumulate
-= *sptr
;
1057 /* If this is a transparent proxy packet, then modify the source
1059 if (proxy_address
.s_addr
!= 0)
1061 sptr
= (u_short
*) &pip
->ip_src
;
1062 accumulate
+= *sptr
++;
1063 accumulate
+= *sptr
;
1064 pip
->ip_src
= proxy_address
;
1065 sptr
= (u_short
*) &pip
->ip_src
;
1066 accumulate
-= *sptr
++;
1067 accumulate
-= *sptr
;
1070 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1072 /* Monitor TCP connection state */
1073 TcpMonitorIn(pip
, link
);
1075 return(PKT_ALIAS_OK
);
1077 return(PKT_ALIAS_IGNORED
);
1081 TcpAliasOut(struct ip
*pip
, int maxpacketsize
)
1085 u_short proxy_server_port
;
1086 struct in_addr dest_address
;
1087 struct in_addr proxy_server_address
;
1089 struct alias_link
*link
;
1091 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1093 proxy_type
= ProxyCheck(pip
, &proxy_server_address
, &proxy_server_port
);
1095 if (proxy_type
== 0 && (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
))
1096 return PKT_ALIAS_OK
;
1098 /* If this is a transparent proxy, save original destination,
1099 then alter the destination and adjust checksums */
1100 dest_port
= tc
->th_dport
;
1101 dest_address
= pip
->ip_dst
;
1102 if (proxy_type
!= 0)
1107 accumulate
= tc
->th_dport
;
1108 tc
->th_dport
= proxy_server_port
;
1109 accumulate
-= tc
->th_dport
;
1111 sptr
= (u_short
*) &(pip
->ip_dst
);
1112 accumulate
+= *sptr
++;
1113 accumulate
+= *sptr
;
1114 sptr
= (u_short
*) &proxy_server_address
;
1115 accumulate
-= *sptr
++;
1116 accumulate
-= *sptr
;
1118 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1120 sptr
= (u_short
*) &(pip
->ip_dst
);
1121 accumulate
= *sptr
++;
1122 accumulate
+= *sptr
;
1123 pip
->ip_dst
= proxy_server_address
;
1124 sptr
= (u_short
*) &(pip
->ip_dst
);
1125 accumulate
-= *sptr
++;
1126 accumulate
-= *sptr
;
1128 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1131 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
1132 tc
->th_sport
, tc
->th_dport
,
1137 struct in_addr alias_address
;
1141 /* Save original destination address, if this is a proxy packet.
1142 Also modify packet to include destination encoding. */
1143 if (proxy_type
!= 0)
1145 SetProxyPort(link
, dest_port
);
1146 SetProxyAddress(link
, dest_address
);
1147 ProxyModify(link
, pip
, maxpacketsize
, proxy_type
);
1150 /* Get alias address and port */
1151 alias_port
= GetAliasPort(link
);
1152 alias_address
= GetAliasAddress(link
);
1154 /* Monitor TCP connection state */
1155 TcpMonitorOut(pip
, link
);
1157 /* Special processing for IP encoding protocols */
1158 if (ntohs(tc
->th_dport
) == FTP_CONTROL_PORT_NUMBER
1159 || ntohs(tc
->th_sport
) == FTP_CONTROL_PORT_NUMBER
)
1160 AliasHandleFtpOut(pip
, link
, maxpacketsize
);
1161 else if (ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_1
1162 || ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_2
)
1163 AliasHandleIrcOut(pip
, link
, maxpacketsize
);
1164 else if (ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_1
1165 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_1
1166 || ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_2
1167 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_2
)
1168 AliasHandleRtspOut(pip
, link
, maxpacketsize
);
1169 else if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
1170 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
1171 AliasHandlePptpOut(pip
, link
);
1173 /* Adjust TCP checksum since source port is being aliased */
1174 /* and source address is being altered */
1175 accumulate
= tc
->th_sport
;
1176 tc
->th_sport
= alias_port
;
1177 accumulate
-= tc
->th_sport
;
1179 sptr
= (u_short
*) &(pip
->ip_src
);
1180 accumulate
+= *sptr
++;
1181 accumulate
+= *sptr
;
1182 sptr
= (u_short
*) &alias_address
;
1183 accumulate
-= *sptr
++;
1184 accumulate
-= *sptr
;
1186 /* Modify sequence number if necessary */
1187 if (GetAckModified(link
) == 1)
1191 delta
= GetDeltaSeqOut(pip
, link
);
1194 sptr
= (u_short
*) &tc
->th_seq
;
1195 accumulate
+= *sptr
++;
1196 accumulate
+= *sptr
;
1197 tc
->th_seq
= htonl(ntohl(tc
->th_seq
) + delta
);
1198 sptr
= (u_short
*) &tc
->th_seq
;
1199 accumulate
-= *sptr
++;
1200 accumulate
-= *sptr
;
1204 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1206 /* Change source address */
1207 sptr
= (u_short
*) &(pip
->ip_src
);
1208 accumulate
= *sptr
++;
1209 accumulate
+= *sptr
;
1210 pip
->ip_src
= alias_address
;
1211 sptr
= (u_short
*) &(pip
->ip_src
);
1212 accumulate
-= *sptr
++;
1213 accumulate
-= *sptr
;
1215 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1217 return(PKT_ALIAS_OK
);
1219 return(PKT_ALIAS_IGNORED
);
1225 /* Fragment Handling
1230 The packet aliasing module has a limited ability for handling IP
1231 fragments. If the ICMP, TCP or UDP header is in the first fragment
1232 received, then the ID number of the IP packet is saved, and other
1233 fragments are identified according to their ID number and IP address
1234 they were sent from. Pointers to unresolved fragments can also be
1235 saved and recalled when a header fragment is seen.
1238 /* Local prototypes */
1239 static int FragmentIn(struct ip
*);
1240 static int FragmentOut(struct ip
*);
1244 FragmentIn(struct ip
*pip
)
1246 struct alias_link
*link
;
1248 link
= FindFragmentIn2(pip
->ip_src
, pip
->ip_dst
, pip
->ip_id
);
1251 struct in_addr original_address
;
1253 GetFragmentAddr(link
, &original_address
);
1254 DifferentialChecksum(&pip
->ip_sum
,
1255 (u_short
*) &original_address
,
1256 (u_short
*) &pip
->ip_dst
,
1258 pip
->ip_dst
= original_address
;
1260 return(PKT_ALIAS_OK
);
1262 return(PKT_ALIAS_UNRESOLVED_FRAGMENT
);
1267 FragmentOut(struct ip
*pip
)
1269 struct in_addr alias_address
;
1271 alias_address
= FindAliasAddress(pip
->ip_src
);
1272 DifferentialChecksum(&pip
->ip_sum
,
1273 (u_short
*) &alias_address
,
1274 (u_short
*) &pip
->ip_src
,
1276 pip
->ip_src
= alias_address
;
1278 return(PKT_ALIAS_OK
);
1286 /* Outside World Access
1288 PacketAliasSaveFragment()
1289 PacketAliasGetFragment()
1290 PacketAliasFragmentIn()
1295 (prototypes in alias.h)
1300 PacketAliasSaveFragment(char *ptr
)
1303 struct alias_link
*link
;
1306 pip
= (struct ip
*) ptr
;
1307 link
= AddFragmentPtrLink(pip
->ip_src
, pip
->ip_id
);
1308 iresult
= PKT_ALIAS_ERROR
;
1311 SetFragmentPtr(link
, ptr
);
1312 iresult
= PKT_ALIAS_OK
;
1319 PacketAliasGetFragment(char *ptr
)
1321 struct alias_link
*link
;
1325 pip
= (struct ip
*) ptr
;
1326 link
= FindFragmentPtr(pip
->ip_src
, pip
->ip_id
);
1329 GetFragmentPtr(link
, &fptr
);
1330 SetFragmentPtr(link
, NULL
);
1331 SetExpire(link
, 0); /* Deletes link */
1343 PacketAliasFragmentIn(char *ptr
, /* Points to correctly de-aliased
1345 char *ptr_fragment
/* Points to fragment which must
1352 pip
= (struct ip
*) ptr
;
1353 fpip
= (struct ip
*) ptr_fragment
;
1355 DifferentialChecksum(&fpip
->ip_sum
,
1356 (u_short
*) &pip
->ip_dst
,
1357 (u_short
*) &fpip
->ip_dst
,
1359 fpip
->ip_dst
= pip
->ip_dst
;
1364 PacketAliasIn(char *ptr
, int maxpacketsize
)
1366 struct in_addr alias_addr
;
1370 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1371 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1372 iresult
= PacketAliasOut(ptr
, maxpacketsize
);
1373 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1378 ClearCheckNewLink();
1379 pip
= (struct ip
*) ptr
;
1380 alias_addr
= pip
->ip_dst
;
1382 /* Defense against mangled packets */
1383 if (ntohs(pip
->ip_len
) > maxpacketsize
1384 || (pip
->ip_hl
<<2) > maxpacketsize
)
1385 return PKT_ALIAS_IGNORED
;
1387 iresult
= PKT_ALIAS_IGNORED
;
1388 if ( (ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0 )
1393 iresult
= IcmpAliasIn(pip
);
1396 iresult
= UdpAliasIn(pip
);
1399 iresult
= TcpAliasIn(pip
);
1402 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
||
1403 AliasHandlePptpGreIn(pip
) == 0)
1404 iresult
= PKT_ALIAS_OK
;
1406 iresult
= ProtoAliasIn(pip
);
1409 iresult
= ProtoAliasIn(pip
);
1413 if (ntohs(pip
->ip_off
) & IP_MF
)
1415 struct alias_link
*link
;
1417 link
= FindFragmentIn1(pip
->ip_src
, alias_addr
, pip
->ip_id
);
1420 iresult
= PKT_ALIAS_FOUND_HEADER_FRAGMENT
;
1421 SetFragmentAddr(link
, pip
->ip_dst
);
1425 iresult
= PKT_ALIAS_ERROR
;
1431 iresult
= FragmentIn(pip
);
1439 /* Unregistered address ranges */
1441 /* 10.0.0.0 -> 10.255.255.255 */
1442 #define UNREG_ADDR_A_LOWER 0x0a000000
1443 #define UNREG_ADDR_A_UPPER 0x0affffff
1445 /* 172.16.0.0 -> 172.31.255.255 */
1446 #define UNREG_ADDR_B_LOWER 0xac100000
1447 #define UNREG_ADDR_B_UPPER 0xac1fffff
1449 /* 192.168.0.0 -> 192.168.255.255 */
1450 #define UNREG_ADDR_C_LOWER 0xc0a80000
1451 #define UNREG_ADDR_C_UPPER 0xc0a8ffff
1454 PacketAliasOut(char *ptr
, /* valid IP packet */
1455 int maxpacketsize
/* How much the packet data may grow
1456 (FTP and IRC inline changes) */
1460 struct in_addr addr_save
;
1463 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1464 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1465 iresult
= PacketAliasIn(ptr
, maxpacketsize
);
1466 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1471 ClearCheckNewLink();
1472 pip
= (struct ip
*) ptr
;
1474 /* Defense against mangled packets */
1475 if (ntohs(pip
->ip_len
) > maxpacketsize
1476 || (pip
->ip_hl
<<2) > maxpacketsize
)
1477 return PKT_ALIAS_IGNORED
;
1479 addr_save
= GetDefaultAliasAddress();
1480 if (packetAliasMode
& PKT_ALIAS_UNREGISTERED_ONLY
)
1486 addr
= ntohl(pip
->ip_src
.s_addr
);
1487 if (addr
>= UNREG_ADDR_C_LOWER
&& addr
<= UNREG_ADDR_C_UPPER
)
1489 else if (addr
>= UNREG_ADDR_B_LOWER
&& addr
<= UNREG_ADDR_B_UPPER
)
1491 else if (addr
>= UNREG_ADDR_A_LOWER
&& addr
<= UNREG_ADDR_A_UPPER
)
1496 SetDefaultAliasAddress(pip
->ip_src
);
1500 iresult
= PKT_ALIAS_IGNORED
;
1501 if ((ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0)
1506 iresult
= IcmpAliasOut(pip
);
1509 iresult
= UdpAliasOut(pip
);
1512 iresult
= TcpAliasOut(pip
, maxpacketsize
);
1515 if (AliasHandlePptpGreOut(pip
) == 0)
1516 iresult
= PKT_ALIAS_OK
;
1518 iresult
= ProtoAliasOut(pip
);
1521 iresult
= ProtoAliasOut(pip
);
1527 iresult
= FragmentOut(pip
);
1530 SetDefaultAliasAddress(addr_save
);
1535 PacketUnaliasOut(char *ptr
, /* valid IP packet */
1536 int maxpacketsize
/* for error checking */
1543 struct alias_link
*link
;
1544 int iresult
= PKT_ALIAS_IGNORED
;
1546 pip
= (struct ip
*) ptr
;
1548 /* Defense against mangled packets */
1549 if (ntohs(pip
->ip_len
) > maxpacketsize
1550 || (pip
->ip_hl
<<2) > maxpacketsize
)
1553 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1554 tc
= (struct tcphdr
*) ud
;
1555 ic
= (struct icmp
*) ud
;
1558 if (pip
->ip_p
== IPPROTO_UDP
)
1559 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1560 ud
->uh_dport
, ud
->uh_sport
,
1562 else if (pip
->ip_p
== IPPROTO_TCP
)
1563 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1564 tc
->th_dport
, tc
->th_sport
,
1566 else if (pip
->ip_p
== IPPROTO_ICMP
)
1567 link
= FindIcmpIn(pip
->ip_dst
, pip
->ip_src
, ic
->icmp_id
, 0);
1571 /* Change it from an aliased packet to an unaliased packet */
1574 if (pip
->ip_p
== IPPROTO_UDP
|| pip
->ip_p
== IPPROTO_TCP
)
1578 struct in_addr original_address
;
1579 u_short original_port
;
1581 original_address
= GetOriginalAddress(link
);
1582 original_port
= GetOriginalPort(link
);
1584 /* Adjust TCP/UDP checksum */
1585 sptr
= (u_short
*) &(pip
->ip_src
);
1586 accumulate
= *sptr
++;
1587 accumulate
+= *sptr
;
1588 sptr
= (u_short
*) &original_address
;
1589 accumulate
-= *sptr
++;
1590 accumulate
-= *sptr
;
1592 if (pip
->ip_p
== IPPROTO_UDP
) {
1593 accumulate
+= ud
->uh_sport
;
1594 accumulate
-= original_port
;
1595 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
1597 accumulate
+= tc
->th_sport
;
1598 accumulate
-= original_port
;
1599 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1602 /* Adjust IP checksum */
1603 DifferentialChecksum(&pip
->ip_sum
,
1604 (u_short
*) &original_address
,
1605 (u_short
*) &pip
->ip_src
,
1608 /* Un-alias source address and port number */
1609 pip
->ip_src
= original_address
;
1610 if (pip
->ip_p
== IPPROTO_UDP
)
1611 ud
->uh_sport
= original_port
;
1613 tc
->th_sport
= original_port
;
1615 iresult
= PKT_ALIAS_OK
;
1617 } else if (pip
->ip_p
== IPPROTO_ICMP
) {
1621 struct in_addr original_address
;
1622 u_short original_id
;
1624 original_address
= GetOriginalAddress(link
);
1625 original_id
= GetOriginalPort(link
);
1627 /* Adjust ICMP checksum */
1628 sptr
= (u_short
*) &(pip
->ip_src
);
1629 accumulate
= *sptr
++;
1630 accumulate
+= *sptr
;
1631 sptr
= (u_short
*) &original_address
;
1632 accumulate
-= *sptr
++;
1633 accumulate
-= *sptr
;
1634 accumulate
+= ic
->icmp_id
;
1635 accumulate
-= original_id
;
1636 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
1638 /* Adjust IP checksum */
1639 DifferentialChecksum(&pip
->ip_sum
,
1640 (u_short
*) &original_address
,
1641 (u_short
*) &pip
->ip_src
,
1644 /* Un-alias source address and port number */
1645 pip
->ip_src
= original_address
;
1646 ic
->icmp_id
= original_id
;
1648 iresult
= PKT_ALIAS_OK
;