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 #define TEST_5618045 0
196 if ((ntohs(tc
->th_dport
) == 8080 || ntohs(tc
->th_sport
) == 8080) && tc
->th_off
> 5) {
202 while (optionEnd
> option
)
204 /* Bounds checking to avoid infinite loops */
205 if (option
[0] == TCPOPT_EOL
)
208 if (option
[0] == TCPOPT_NOP
) {
212 if (optionEnd
- option
< 2)
214 if (option
[1] < 2 || option
+ option
[1] >= optionEnd
)
223 u_short
*mssPtr
= (u_short
*) option
+ 1;
224 u_short mssVal
= ntohs(*mssPtr
);
226 if (packetAliasMSS
< mssVal
)
228 int accumulate
= mssVal
;
229 int accnetorder
= 0 ;
231 accumulate
-= packetAliasMSS
;
232 *mssPtr
= htons(packetAliasMSS
);
233 accnetorder
= htons(accumulate
);
234 ADJUST_CHECKSUM(accnetorder
, tc
->th_sum
);
249 TcpMonitorIn(struct ip
*pip
, struct alias_link
*link
)
253 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
255 switch (GetStateIn(link
))
257 case ALIAS_TCP_STATE_NOT_CONNECTED
:
258 if (tc
->th_flags
& TH_RST
)
259 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
260 else if (tc
->th_flags
& TH_SYN
)
262 SetStateIn(link
, ALIAS_TCP_STATE_CONNECTED
);
268 case ALIAS_TCP_STATE_CONNECTED
:
269 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
270 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
276 TcpMonitorOut(struct ip
*pip
, struct alias_link
*link
)
280 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
282 switch (GetStateOut(link
))
284 case ALIAS_TCP_STATE_NOT_CONNECTED
:
285 if (tc
->th_flags
& TH_RST
)
286 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
287 else if (tc
->th_flags
& TH_SYN
)
289 SetStateOut(link
, ALIAS_TCP_STATE_CONNECTED
);
295 case ALIAS_TCP_STATE_CONNECTED
:
296 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
297 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
306 /* Protocol Specific Packet Aliasing Routines
308 IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2()
309 IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2()
310 ProtoAliasIn(), ProtoAliasOut()
311 UdpAliasIn(), UdpAliasOut()
312 TcpAliasIn(), TcpAliasOut()
314 These routines handle protocol specific details of packet aliasing.
315 One may observe a certain amount of repetitive arithmetic in these
316 functions, the purpose of which is to compute a revised checksum
317 without actually summing over the entire data packet, which could be
318 unnecessarily time consuming.
320 The purpose of the packet aliasing routines is to replace the source
321 address of the outgoing packet and then correctly put it back for
322 any incoming packets. For TCP and UDP, ports are also re-mapped.
324 For ICMP echo/timestamp requests and replies, the following scheme
325 is used: the ID number is replaced by an alias for the outgoing
328 ICMP error messages are handled by looking at the IP fragment
329 in the data section of the message.
331 For TCP and UDP protocols, a port number is chosen for an outgoing
332 packet, and then incoming packets are identified by IP address and
333 port numbers. For TCP packets, there is additional logic in the event
334 that sequence and ACK numbers have been altered (as in the case for
335 FTP data port commands).
337 The port numbers used by the packet aliasing module are not true
338 ports in the Unix sense. No sockets are actually bound to ports.
339 They are more correctly thought of as placeholders.
341 All packets go through the aliasing mechanism, whether they come from
342 the gateway machine or other machines on a local area network.
346 /* Local prototypes */
347 static int IcmpAliasIn1(struct ip
*);
348 static int IcmpAliasIn2(struct ip
*);
349 static int IcmpAliasIn (struct ip
*);
351 static int IcmpAliasOut1(struct ip
*);
352 static int IcmpAliasOut2(struct ip
*);
353 static int IcmpAliasOut (struct ip
*);
355 static int ProtoAliasIn(struct ip
*);
356 static int ProtoAliasOut(struct ip
*);
358 static int UdpAliasOut(struct ip
*);
359 static int UdpAliasIn (struct ip
*);
361 static int TcpAliasOut(struct ip
*, int);
362 static int TcpAliasIn (struct ip
*);
366 IcmpAliasIn1(struct ip
*pip
)
369 De-alias incoming echo and timestamp replies.
370 Alias incoming echo and timestamp requests.
372 struct alias_link
*link
;
375 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
377 /* Get source address from ICMP data field and restore original data */
378 link
= FindIcmpIn(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
384 original_id
= GetOriginalPort(link
);
386 /* Adjust ICMP checksum */
387 accumulate
= ic
->icmp_id
;
388 accumulate
-= original_id
;
389 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
391 /* Put original sequence number back in */
392 ic
->icmp_id
= original_id
;
394 /* Put original address back into IP header */
396 struct in_addr original_address
;
398 original_address
= GetOriginalAddress(link
);
399 DifferentialChecksum(&pip
->ip_sum
,
400 (u_short
*) &original_address
,
401 (u_short
*) &pip
->ip_dst
,
403 pip
->ip_dst
= original_address
;
406 return(PKT_ALIAS_OK
);
408 return(PKT_ALIAS_IGNORED
);
412 IcmpAliasIn2(struct ip
*pip
)
415 Alias incoming ICMP error messages containing
416 IP header and first 64 bits of datagram.
419 struct icmp
*ic
, *ic2
;
422 struct alias_link
*link
;
424 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
427 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
428 tc
= (struct tcphdr
*) ud
;
429 ic2
= (struct icmp
*) ud
;
431 if (ip
->ip_p
== IPPROTO_UDP
)
432 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
433 ud
->uh_dport
, ud
->uh_sport
,
435 else if (ip
->ip_p
== IPPROTO_TCP
)
436 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
437 tc
->th_dport
, tc
->th_sport
,
439 else if (ip
->ip_p
== IPPROTO_ICMP
) {
440 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
441 link
= FindIcmpIn(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
449 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
453 struct in_addr original_address
;
454 u_short original_port
;
456 original_address
= GetOriginalAddress(link
);
457 original_port
= GetOriginalPort(link
);
459 /* Adjust ICMP checksum */
460 sptr
= (u_short
*) &(ip
->ip_src
);
461 accumulate
= *sptr
++;
463 sptr
= (u_short
*) &original_address
;
464 accumulate
-= *sptr
++;
466 accumulate
+= ud
->uh_sport
;
467 accumulate
-= original_port
;
468 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
470 /* Un-alias address in IP header */
471 DifferentialChecksum(&pip
->ip_sum
,
472 (u_short
*) &original_address
,
473 (u_short
*) &pip
->ip_dst
,
475 pip
->ip_dst
= original_address
;
477 /* Un-alias address and port number of original IP packet
478 fragment contained in ICMP data section */
479 ip
->ip_src
= original_address
;
480 ud
->uh_sport
= original_port
;
482 else if (ip
->ip_p
== IPPROTO_ICMP
)
486 struct in_addr original_address
;
489 original_address
= GetOriginalAddress(link
);
490 original_id
= GetOriginalPort(link
);
492 /* Adjust ICMP checksum */
493 sptr
= (u_short
*) &(ip
->ip_src
);
494 accumulate
= *sptr
++;
496 sptr
= (u_short
*) &original_address
;
497 accumulate
-= *sptr
++;
499 accumulate
+= ic2
->icmp_id
;
500 accumulate
-= original_id
;
501 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
503 /* Un-alias address in IP header */
504 DifferentialChecksum(&pip
->ip_sum
,
505 (u_short
*) &original_address
,
506 (u_short
*) &pip
->ip_dst
,
508 pip
->ip_dst
= original_address
;
510 /* Un-alias address of original IP packet and sequence number of
511 embedded ICMP datagram */
512 ip
->ip_src
= original_address
;
513 ic2
->icmp_id
= original_id
;
515 return(PKT_ALIAS_OK
);
517 return(PKT_ALIAS_IGNORED
);
522 IcmpAliasIn(struct ip
*pip
)
527 /* Return if proxy-only mode is enabled */
528 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
531 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
533 iresult
= PKT_ALIAS_IGNORED
;
534 switch (ic
->icmp_type
)
537 case ICMP_TSTAMPREPLY
:
538 if (ic
->icmp_code
== 0)
540 iresult
= IcmpAliasIn1(pip
);
544 case ICMP_SOURCEQUENCH
:
547 iresult
= IcmpAliasIn2(pip
);
551 iresult
= IcmpAliasIn1(pip
);
559 IcmpAliasOut1(struct ip
*pip
)
562 Alias outgoing echo and timestamp requests.
563 De-alias outgoing echo and timestamp replies.
565 struct alias_link
*link
;
568 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
570 /* Save overwritten data for when echo packet returns */
571 link
= FindIcmpOut(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
577 alias_id
= GetAliasPort(link
);
579 /* Since data field is being modified, adjust ICMP checksum */
580 accumulate
= ic
->icmp_id
;
581 accumulate
-= alias_id
;
582 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
584 /* Alias sequence number */
585 ic
->icmp_id
= alias_id
;
587 /* Change source address */
589 struct in_addr alias_address
;
591 alias_address
= GetAliasAddress(link
);
592 DifferentialChecksum(&pip
->ip_sum
,
593 (u_short
*) &alias_address
,
594 (u_short
*) &pip
->ip_src
,
596 pip
->ip_src
= alias_address
;
599 return(PKT_ALIAS_OK
);
601 return(PKT_ALIAS_IGNORED
);
606 IcmpAliasOut2(struct ip
*pip
)
609 Alias outgoing ICMP error messages containing
610 IP header and first 64 bits of datagram.
613 struct icmp
*ic
, *ic2
;
616 struct alias_link
*link
;
618 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
621 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
622 tc
= (struct tcphdr
*) ud
;
623 ic2
= (struct icmp
*) ud
;
625 if (ip
->ip_p
== IPPROTO_UDP
)
626 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
627 ud
->uh_dport
, ud
->uh_sport
,
629 else if (ip
->ip_p
== IPPROTO_TCP
)
630 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
631 tc
->th_dport
, tc
->th_sport
,
633 else if (ip
->ip_p
== IPPROTO_ICMP
) {
634 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
635 link
= FindIcmpOut(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
643 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
647 struct in_addr alias_address
;
650 alias_address
= GetAliasAddress(link
);
651 alias_port
= GetAliasPort(link
);
653 /* Adjust ICMP checksum */
654 sptr
= (u_short
*) &(ip
->ip_dst
);
655 accumulate
= *sptr
++;
657 sptr
= (u_short
*) &alias_address
;
658 accumulate
-= *sptr
++;
660 accumulate
+= ud
->uh_dport
;
661 accumulate
-= alias_port
;
662 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
665 * Alias address in IP header if it comes from the host
666 * the original TCP/UDP packet was destined for.
668 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
669 DifferentialChecksum(&pip
->ip_sum
,
670 (u_short
*) &alias_address
,
671 (u_short
*) &pip
->ip_src
,
673 pip
->ip_src
= alias_address
;
676 /* Alias address and port number of original IP packet
677 fragment contained in ICMP data section */
678 ip
->ip_dst
= alias_address
;
679 ud
->uh_dport
= alias_port
;
681 else if (ip
->ip_p
== IPPROTO_ICMP
)
685 struct in_addr alias_address
;
688 alias_address
= GetAliasAddress(link
);
689 alias_id
= GetAliasPort(link
);
691 /* Adjust ICMP checksum */
692 sptr
= (u_short
*) &(ip
->ip_dst
);
693 accumulate
= *sptr
++;
695 sptr
= (u_short
*) &alias_address
;
696 accumulate
-= *sptr
++;
698 accumulate
+= ic2
->icmp_id
;
699 accumulate
-= alias_id
;
700 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
703 * Alias address in IP header if it comes from the host
704 * the original ICMP message was destined for.
706 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
707 DifferentialChecksum(&pip
->ip_sum
,
708 (u_short
*) &alias_address
,
709 (u_short
*) &pip
->ip_src
,
711 pip
->ip_src
= alias_address
;
714 /* Alias address of original IP packet and sequence number of
715 embedded ICMP datagram */
716 ip
->ip_dst
= alias_address
;
717 ic2
->icmp_id
= alias_id
;
719 return(PKT_ALIAS_OK
);
721 return(PKT_ALIAS_IGNORED
);
726 IcmpAliasOut(struct ip
*pip
)
731 /* Return if proxy-only mode is enabled */
732 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
735 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
737 iresult
= PKT_ALIAS_IGNORED
;
738 switch (ic
->icmp_type
)
742 if (ic
->icmp_code
== 0)
744 iresult
= IcmpAliasOut1(pip
);
748 case ICMP_SOURCEQUENCH
:
751 iresult
= IcmpAliasOut2(pip
);
754 case ICMP_TSTAMPREPLY
:
755 iresult
= IcmpAliasOut1(pip
);
763 ProtoAliasIn(struct ip
*pip
)
766 Handle incoming IP packets. The
767 only thing which is done in this case is to alias
768 the dest IP address of the packet to our inside
771 struct alias_link
*link
;
773 /* Return if proxy-only mode is enabled */
774 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
777 link
= FindProtoIn(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
780 struct in_addr original_address
;
782 original_address
= GetOriginalAddress(link
);
784 /* Restore original IP address */
785 DifferentialChecksum(&pip
->ip_sum
,
786 (u_short
*) &original_address
,
787 (u_short
*) &pip
->ip_dst
,
789 pip
->ip_dst
= original_address
;
791 return(PKT_ALIAS_OK
);
793 return(PKT_ALIAS_IGNORED
);
798 ProtoAliasOut(struct ip
*pip
)
801 Handle outgoing IP packets. The
802 only thing which is done in this case is to alias
803 the source IP address of the packet.
805 struct alias_link
*link
;
807 /* Return if proxy-only mode is enabled */
808 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
811 link
= FindProtoOut(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
814 struct in_addr alias_address
;
816 alias_address
= GetAliasAddress(link
);
818 /* Change source address */
819 DifferentialChecksum(&pip
->ip_sum
,
820 (u_short
*) &alias_address
,
821 (u_short
*) &pip
->ip_src
,
823 pip
->ip_src
= alias_address
;
825 return(PKT_ALIAS_OK
);
827 return(PKT_ALIAS_IGNORED
);
832 UdpAliasIn(struct ip
*pip
)
835 struct alias_link
*link
;
837 /* Return if proxy-only mode is enabled */
838 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
841 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
843 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
844 ud
->uh_sport
, ud
->uh_dport
,
848 struct in_addr alias_address
;
849 struct in_addr original_address
;
855 alias_address
= GetAliasAddress(link
);
856 original_address
= GetOriginalAddress(link
);
857 alias_port
= ud
->uh_dport
;
858 ud
->uh_dport
= GetOriginalPort(link
);
860 /* Special processing for IP encoding protocols */
861 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
862 AliasHandleCUSeeMeIn(pip
, original_address
);
863 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
864 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
865 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
866 r
= AliasHandleUdpNbt(pip
, link
, &original_address
, ud
->uh_dport
);
867 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
868 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
869 r
= AliasHandleUdpNbtNS(pip
, link
, &alias_address
, &alias_port
,
870 &original_address
, &ud
->uh_dport
);
872 /* If UDP checksum is not zero, then adjust since destination port */
873 /* is being unaliased and destination address is being altered. */
876 accumulate
= alias_port
;
877 accumulate
-= ud
->uh_dport
;
878 sptr
= (u_short
*) &alias_address
;
879 accumulate
+= *sptr
++;
881 sptr
= (u_short
*) &original_address
;
882 accumulate
-= *sptr
++;
884 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
887 /* Restore original IP address */
888 DifferentialChecksum(&pip
->ip_sum
,
889 (u_short
*) &original_address
,
890 (u_short
*) &pip
->ip_dst
,
892 pip
->ip_dst
= original_address
;
895 * If we cannot figure out the packet, ignore it.
898 return(PKT_ALIAS_IGNORED
);
900 return(PKT_ALIAS_OK
);
902 return(PKT_ALIAS_IGNORED
);
906 UdpAliasOut(struct ip
*pip
)
909 struct alias_link
*link
;
911 /* Return if proxy-only mode is enabled */
912 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
915 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
917 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
918 ud
->uh_sport
, ud
->uh_dport
,
923 struct in_addr alias_address
;
925 alias_address
= GetAliasAddress(link
);
926 alias_port
= GetAliasPort(link
);
928 /* Special processing for IP encoding protocols */
929 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
930 AliasHandleCUSeeMeOut(pip
, link
);
931 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
932 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
933 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
934 AliasHandleUdpNbt(pip
, link
, &alias_address
, alias_port
);
935 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
936 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
937 AliasHandleUdpNbtNS(pip
, link
, &pip
->ip_src
, &ud
->uh_sport
,
938 &alias_address
, &alias_port
);
940 /* If UDP checksum is not zero, adjust since source port is */
941 /* being aliased and source address is being altered */
947 accumulate
= ud
->uh_sport
;
948 accumulate
-= alias_port
;
949 sptr
= (u_short
*) &(pip
->ip_src
);
950 accumulate
+= *sptr
++;
952 sptr
= (u_short
*) &alias_address
;
953 accumulate
-= *sptr
++;
955 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
958 /* Put alias port in UDP header */
959 ud
->uh_sport
= alias_port
;
961 /* Change source address */
962 DifferentialChecksum(&pip
->ip_sum
,
963 (u_short
*) &alias_address
,
964 (u_short
*) &pip
->ip_src
,
966 pip
->ip_src
= alias_address
;
968 return(PKT_ALIAS_OK
);
970 return(PKT_ALIAS_IGNORED
);
976 TcpAliasIn(struct ip
*pip
)
979 struct alias_link
*link
;
981 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
983 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
984 tc
->th_sport
, tc
->th_dport
,
986 !(packetAliasMode
& PKT_ALIAS_PROXY_ONLY
));
989 struct in_addr alias_address
;
990 struct in_addr original_address
;
991 struct in_addr proxy_address
;
997 /* Special processing for IP encoding protocols */
998 if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
999 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
1000 AliasHandlePptpIn(pip
, link
);
1002 alias_address
= GetAliasAddress(link
);
1003 original_address
= GetOriginalAddress(link
);
1004 proxy_address
= GetProxyAddress(link
);
1005 alias_port
= tc
->th_dport
;
1006 tc
->th_dport
= GetOriginalPort(link
);
1007 proxy_port
= GetProxyPort(link
);
1009 /* Adjust TCP checksum since destination port is being unaliased */
1010 /* and destination port is being altered. */
1011 accumulate
= alias_port
;
1012 accumulate
-= tc
->th_dport
;
1013 sptr
= (u_short
*) &alias_address
;
1014 accumulate
+= *sptr
++;
1015 accumulate
+= *sptr
;
1016 sptr
= (u_short
*) &original_address
;
1017 accumulate
-= *sptr
++;
1018 accumulate
-= *sptr
;
1020 /* If this is a proxy, then modify the TCP source port and
1021 checksum accumulation */
1022 if (proxy_port
!= 0)
1024 accumulate
+= tc
->th_sport
;
1025 tc
->th_sport
= proxy_port
;
1026 accumulate
-= tc
->th_sport
;
1028 sptr
= (u_short
*) &pip
->ip_src
;
1029 accumulate
+= *sptr
++;
1030 accumulate
+= *sptr
;
1031 sptr
= (u_short
*) &proxy_address
;
1032 accumulate
-= *sptr
++;
1033 accumulate
-= *sptr
;
1036 /* See if ACK number needs to be modified */
1037 if (GetAckModified(link
) == 1)
1041 delta
= GetDeltaAckIn(pip
, link
);
1044 sptr
= (u_short
*) &tc
->th_ack
;
1045 accumulate
+= *sptr
++;
1046 accumulate
+= *sptr
;
1047 tc
->th_ack
= htonl(ntohl(tc
->th_ack
) - delta
);
1048 sptr
= (u_short
*) &tc
->th_ack
;
1049 accumulate
-= *sptr
++;
1050 accumulate
-= *sptr
;
1054 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1056 /* Restore original IP address */
1057 sptr
= (u_short
*) &pip
->ip_dst
;
1058 accumulate
= *sptr
++;
1059 accumulate
+= *sptr
;
1060 pip
->ip_dst
= original_address
;
1061 sptr
= (u_short
*) &pip
->ip_dst
;
1062 accumulate
-= *sptr
++;
1063 accumulate
-= *sptr
;
1065 /* If this is a transparent proxy packet, then modify the source
1067 if (proxy_address
.s_addr
!= 0)
1069 sptr
= (u_short
*) &pip
->ip_src
;
1070 accumulate
+= *sptr
++;
1071 accumulate
+= *sptr
;
1072 pip
->ip_src
= proxy_address
;
1073 sptr
= (u_short
*) &pip
->ip_src
;
1074 accumulate
-= *sptr
++;
1075 accumulate
-= *sptr
;
1078 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1080 /* Monitor TCP connection state */
1081 TcpMonitorIn(pip
, link
);
1083 return(PKT_ALIAS_OK
);
1085 return(PKT_ALIAS_IGNORED
);
1089 TcpAliasOut(struct ip
*pip
, int maxpacketsize
)
1093 u_short proxy_server_port
;
1094 struct in_addr dest_address
;
1095 struct in_addr proxy_server_address
;
1097 struct alias_link
*link
;
1099 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1101 proxy_type
= ProxyCheck(pip
, &proxy_server_address
, &proxy_server_port
);
1103 if (proxy_type
== 0 && (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
))
1104 return PKT_ALIAS_OK
;
1106 /* If this is a transparent proxy, save original destination,
1107 then alter the destination and adjust checksums */
1108 dest_port
= tc
->th_dport
;
1109 dest_address
= pip
->ip_dst
;
1110 if (proxy_type
!= 0)
1115 accumulate
= tc
->th_dport
;
1116 tc
->th_dport
= proxy_server_port
;
1117 accumulate
-= tc
->th_dport
;
1119 sptr
= (u_short
*) &(pip
->ip_dst
);
1120 accumulate
+= *sptr
++;
1121 accumulate
+= *sptr
;
1122 sptr
= (u_short
*) &proxy_server_address
;
1123 accumulate
-= *sptr
++;
1124 accumulate
-= *sptr
;
1126 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1128 sptr
= (u_short
*) &(pip
->ip_dst
);
1129 accumulate
= *sptr
++;
1130 accumulate
+= *sptr
;
1131 pip
->ip_dst
= proxy_server_address
;
1132 sptr
= (u_short
*) &(pip
->ip_dst
);
1133 accumulate
-= *sptr
++;
1134 accumulate
-= *sptr
;
1136 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1139 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
1140 tc
->th_sport
, tc
->th_dport
,
1145 struct in_addr alias_address
;
1149 /* Save original destination address, if this is a proxy packet.
1150 Also modify packet to include destination encoding. */
1151 if (proxy_type
!= 0)
1153 SetProxyPort(link
, dest_port
);
1154 SetProxyAddress(link
, dest_address
);
1155 ProxyModify(link
, pip
, maxpacketsize
, proxy_type
);
1158 /* Get alias address and port */
1159 alias_port
= GetAliasPort(link
);
1160 alias_address
= GetAliasAddress(link
);
1162 /* Monitor TCP connection state */
1163 TcpMonitorOut(pip
, link
);
1165 /* Special processing for IP encoding protocols */
1166 if (ntohs(tc
->th_dport
) == FTP_CONTROL_PORT_NUMBER
1167 || ntohs(tc
->th_sport
) == FTP_CONTROL_PORT_NUMBER
)
1168 AliasHandleFtpOut(pip
, link
, maxpacketsize
);
1169 else if (ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_1
1170 || ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_2
)
1171 AliasHandleIrcOut(pip
, link
, maxpacketsize
);
1172 else if (ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_1
1173 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_1
1174 || ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_2
1175 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_2
)
1176 AliasHandleRtspOut(pip
, link
, maxpacketsize
);
1177 else if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
1178 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
1179 AliasHandlePptpOut(pip
, link
);
1181 /* Adjust TCP checksum since source port is being aliased */
1182 /* and source address is being altered */
1183 accumulate
= tc
->th_sport
;
1184 tc
->th_sport
= alias_port
;
1185 accumulate
-= tc
->th_sport
;
1187 sptr
= (u_short
*) &(pip
->ip_src
);
1188 accumulate
+= *sptr
++;
1189 accumulate
+= *sptr
;
1190 sptr
= (u_short
*) &alias_address
;
1191 accumulate
-= *sptr
++;
1192 accumulate
-= *sptr
;
1194 /* Modify sequence number if necessary */
1195 if (GetAckModified(link
) == 1)
1199 delta
= GetDeltaSeqOut(pip
, link
);
1202 sptr
= (u_short
*) &tc
->th_seq
;
1203 accumulate
+= *sptr
++;
1204 accumulate
+= *sptr
;
1205 tc
->th_seq
= htonl(ntohl(tc
->th_seq
) + delta
);
1206 sptr
= (u_short
*) &tc
->th_seq
;
1207 accumulate
-= *sptr
++;
1208 accumulate
-= *sptr
;
1212 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1214 /* Change source address */
1215 sptr
= (u_short
*) &(pip
->ip_src
);
1216 accumulate
= *sptr
++;
1217 accumulate
+= *sptr
;
1218 pip
->ip_src
= alias_address
;
1219 sptr
= (u_short
*) &(pip
->ip_src
);
1220 accumulate
-= *sptr
++;
1221 accumulate
-= *sptr
;
1223 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1225 return(PKT_ALIAS_OK
);
1227 return(PKT_ALIAS_IGNORED
);
1233 /* Fragment Handling
1238 The packet aliasing module has a limited ability for handling IP
1239 fragments. If the ICMP, TCP or UDP header is in the first fragment
1240 received, then the ID number of the IP packet is saved, and other
1241 fragments are identified according to their ID number and IP address
1242 they were sent from. Pointers to unresolved fragments can also be
1243 saved and recalled when a header fragment is seen.
1246 /* Local prototypes */
1247 static int FragmentIn(struct ip
*);
1248 static int FragmentOut(struct ip
*);
1252 FragmentIn(struct ip
*pip
)
1254 struct alias_link
*link
;
1256 link
= FindFragmentIn2(pip
->ip_src
, pip
->ip_dst
, pip
->ip_id
);
1259 struct in_addr original_address
;
1261 GetFragmentAddr(link
, &original_address
);
1262 DifferentialChecksum(&pip
->ip_sum
,
1263 (u_short
*) &original_address
,
1264 (u_short
*) &pip
->ip_dst
,
1266 pip
->ip_dst
= original_address
;
1268 return(PKT_ALIAS_OK
);
1270 return(PKT_ALIAS_UNRESOLVED_FRAGMENT
);
1275 FragmentOut(struct ip
*pip
)
1277 struct in_addr alias_address
;
1279 alias_address
= FindAliasAddress(pip
->ip_src
);
1280 DifferentialChecksum(&pip
->ip_sum
,
1281 (u_short
*) &alias_address
,
1282 (u_short
*) &pip
->ip_src
,
1284 pip
->ip_src
= alias_address
;
1286 return(PKT_ALIAS_OK
);
1294 /* Outside World Access
1296 PacketAliasSaveFragment()
1297 PacketAliasGetFragment()
1298 PacketAliasFragmentIn()
1303 (prototypes in alias.h)
1308 PacketAliasSaveFragment(char *ptr
)
1311 struct alias_link
*link
;
1314 pip
= (struct ip
*) ptr
;
1315 link
= AddFragmentPtrLink(pip
->ip_src
, pip
->ip_id
);
1316 iresult
= PKT_ALIAS_ERROR
;
1319 SetFragmentPtr(link
, ptr
);
1320 iresult
= PKT_ALIAS_OK
;
1327 PacketAliasGetFragment(char *ptr
)
1329 struct alias_link
*link
;
1333 pip
= (struct ip
*) ptr
;
1334 link
= FindFragmentPtr(pip
->ip_src
, pip
->ip_id
);
1337 GetFragmentPtr(link
, &fptr
);
1338 SetFragmentPtr(link
, NULL
);
1339 SetExpire(link
, 0); /* Deletes link */
1351 PacketAliasFragmentIn(char *ptr
, /* Points to correctly de-aliased
1353 char *ptr_fragment
/* Points to fragment which must
1360 pip
= (struct ip
*) ptr
;
1361 fpip
= (struct ip
*) ptr_fragment
;
1363 DifferentialChecksum(&fpip
->ip_sum
,
1364 (u_short
*) &pip
->ip_dst
,
1365 (u_short
*) &fpip
->ip_dst
,
1367 fpip
->ip_dst
= pip
->ip_dst
;
1372 PacketAliasIn(char *ptr
, int maxpacketsize
)
1374 struct in_addr alias_addr
;
1378 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1379 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1380 iresult
= PacketAliasOut(ptr
, maxpacketsize
);
1381 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1386 ClearCheckNewLink();
1387 pip
= (struct ip
*) ptr
;
1388 alias_addr
= pip
->ip_dst
;
1390 /* Defense against mangled packets */
1391 if (ntohs(pip
->ip_len
) > maxpacketsize
1392 || (pip
->ip_hl
<<2) > maxpacketsize
)
1393 return PKT_ALIAS_IGNORED
;
1395 iresult
= PKT_ALIAS_IGNORED
;
1396 if ( (ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0 )
1401 iresult
= IcmpAliasIn(pip
);
1404 iresult
= UdpAliasIn(pip
);
1407 iresult
= TcpAliasIn(pip
);
1410 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
||
1411 AliasHandlePptpGreIn(pip
) == 0)
1412 iresult
= PKT_ALIAS_OK
;
1414 iresult
= ProtoAliasIn(pip
);
1417 iresult
= ProtoAliasIn(pip
);
1421 if (ntohs(pip
->ip_off
) & IP_MF
)
1423 struct alias_link
*link
;
1425 link
= FindFragmentIn1(pip
->ip_src
, alias_addr
, pip
->ip_id
);
1428 iresult
= PKT_ALIAS_FOUND_HEADER_FRAGMENT
;
1429 SetFragmentAddr(link
, pip
->ip_dst
);
1433 iresult
= PKT_ALIAS_ERROR
;
1439 iresult
= FragmentIn(pip
);
1447 /* Unregistered address ranges */
1449 /* 10.0.0.0 -> 10.255.255.255 */
1450 #define UNREG_ADDR_A_LOWER 0x0a000000
1451 #define UNREG_ADDR_A_UPPER 0x0affffff
1453 /* 172.16.0.0 -> 172.31.255.255 */
1454 #define UNREG_ADDR_B_LOWER 0xac100000
1455 #define UNREG_ADDR_B_UPPER 0xac1fffff
1457 /* 192.168.0.0 -> 192.168.255.255 */
1458 #define UNREG_ADDR_C_LOWER 0xc0a80000
1459 #define UNREG_ADDR_C_UPPER 0xc0a8ffff
1462 PacketAliasOut(char *ptr
, /* valid IP packet */
1463 int maxpacketsize
/* How much the packet data may grow
1464 (FTP and IRC inline changes) */
1468 struct in_addr addr_save
;
1471 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1472 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1473 iresult
= PacketAliasIn(ptr
, maxpacketsize
);
1474 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1479 ClearCheckNewLink();
1480 pip
= (struct ip
*) ptr
;
1482 /* Defense against mangled packets */
1483 if (ntohs(pip
->ip_len
) > maxpacketsize
1484 || (pip
->ip_hl
<<2) > maxpacketsize
)
1485 return PKT_ALIAS_IGNORED
;
1487 addr_save
= GetDefaultAliasAddress();
1488 if (packetAliasMode
& PKT_ALIAS_UNREGISTERED_ONLY
)
1494 addr
= ntohl(pip
->ip_src
.s_addr
);
1495 if (addr
>= UNREG_ADDR_C_LOWER
&& addr
<= UNREG_ADDR_C_UPPER
)
1497 else if (addr
>= UNREG_ADDR_B_LOWER
&& addr
<= UNREG_ADDR_B_UPPER
)
1499 else if (addr
>= UNREG_ADDR_A_LOWER
&& addr
<= UNREG_ADDR_A_UPPER
)
1504 SetDefaultAliasAddress(pip
->ip_src
);
1508 iresult
= PKT_ALIAS_IGNORED
;
1509 if ((ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0)
1514 iresult
= IcmpAliasOut(pip
);
1517 iresult
= UdpAliasOut(pip
);
1520 iresult
= TcpAliasOut(pip
, maxpacketsize
);
1523 if (AliasHandlePptpGreOut(pip
) == 0)
1524 iresult
= PKT_ALIAS_OK
;
1526 iresult
= ProtoAliasOut(pip
);
1529 iresult
= ProtoAliasOut(pip
);
1535 iresult
= FragmentOut(pip
);
1538 SetDefaultAliasAddress(addr_save
);
1543 PacketUnaliasOut(char *ptr
, /* valid IP packet */
1544 int maxpacketsize
/* for error checking */
1551 struct alias_link
*link
;
1552 int iresult
= PKT_ALIAS_IGNORED
;
1554 pip
= (struct ip
*) ptr
;
1556 /* Defense against mangled packets */
1557 if (ntohs(pip
->ip_len
) > maxpacketsize
1558 || (pip
->ip_hl
<<2) > maxpacketsize
)
1561 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1562 tc
= (struct tcphdr
*) ud
;
1563 ic
= (struct icmp
*) ud
;
1566 if (pip
->ip_p
== IPPROTO_UDP
)
1567 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1568 ud
->uh_dport
, ud
->uh_sport
,
1570 else if (pip
->ip_p
== IPPROTO_TCP
)
1571 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1572 tc
->th_dport
, tc
->th_sport
,
1574 else if (pip
->ip_p
== IPPROTO_ICMP
)
1575 link
= FindIcmpIn(pip
->ip_dst
, pip
->ip_src
, ic
->icmp_id
, 0);
1579 /* Change it from an aliased packet to an unaliased packet */
1582 if (pip
->ip_p
== IPPROTO_UDP
|| pip
->ip_p
== IPPROTO_TCP
)
1586 struct in_addr original_address
;
1587 u_short original_port
;
1589 original_address
= GetOriginalAddress(link
);
1590 original_port
= GetOriginalPort(link
);
1592 /* Adjust TCP/UDP checksum */
1593 sptr
= (u_short
*) &(pip
->ip_src
);
1594 accumulate
= *sptr
++;
1595 accumulate
+= *sptr
;
1596 sptr
= (u_short
*) &original_address
;
1597 accumulate
-= *sptr
++;
1598 accumulate
-= *sptr
;
1600 if (pip
->ip_p
== IPPROTO_UDP
) {
1601 accumulate
+= ud
->uh_sport
;
1602 accumulate
-= original_port
;
1603 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
1605 accumulate
+= tc
->th_sport
;
1606 accumulate
-= original_port
;
1607 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1610 /* Adjust IP checksum */
1611 DifferentialChecksum(&pip
->ip_sum
,
1612 (u_short
*) &original_address
,
1613 (u_short
*) &pip
->ip_src
,
1616 /* Un-alias source address and port number */
1617 pip
->ip_src
= original_address
;
1618 if (pip
->ip_p
== IPPROTO_UDP
)
1619 ud
->uh_sport
= original_port
;
1621 tc
->th_sport
= original_port
;
1623 iresult
= PKT_ALIAS_OK
;
1625 } else if (pip
->ip_p
== IPPROTO_ICMP
) {
1629 struct in_addr original_address
;
1630 u_short original_id
;
1632 original_address
= GetOriginalAddress(link
);
1633 original_id
= GetOriginalPort(link
);
1635 /* Adjust ICMP checksum */
1636 sptr
= (u_short
*) &(pip
->ip_src
);
1637 accumulate
= *sptr
++;
1638 accumulate
+= *sptr
;
1639 sptr
= (u_short
*) &original_address
;
1640 accumulate
-= *sptr
++;
1641 accumulate
-= *sptr
;
1642 accumulate
+= ic
->icmp_id
;
1643 accumulate
-= original_id
;
1644 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
1646 /* Adjust IP checksum */
1647 DifferentialChecksum(&pip
->ip_sum
,
1648 (u_short
*) &original_address
,
1649 (u_short
*) &pip
->ip_src
,
1652 /* Un-alias source address and port number */
1653 pip
->ip_src
= original_address
;
1654 ic
->icmp_id
= original_id
;
1656 iresult
= PKT_ALIAS_OK
;