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
)
209 u_short
*mssPtr
= (u_short
*) option
+ 1;
210 u_short mssVal
= ntohs(*mssPtr
);
212 if (packetAliasMSS
< mssVal
)
214 int accumulate
= mssVal
;
215 accumulate
-= packetAliasMSS
;
216 *mssPtr
= htons(packetAliasMSS
);
217 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
232 TcpMonitorIn(struct ip
*pip
, struct alias_link
*link
)
236 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
238 switch (GetStateIn(link
))
240 case ALIAS_TCP_STATE_NOT_CONNECTED
:
241 if (tc
->th_flags
& TH_RST
)
242 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
243 else if (tc
->th_flags
& TH_SYN
)
245 SetStateIn(link
, ALIAS_TCP_STATE_CONNECTED
);
251 case ALIAS_TCP_STATE_CONNECTED
:
252 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
253 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
259 TcpMonitorOut(struct ip
*pip
, struct alias_link
*link
)
263 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
265 switch (GetStateOut(link
))
267 case ALIAS_TCP_STATE_NOT_CONNECTED
:
268 if (tc
->th_flags
& TH_RST
)
269 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
270 else if (tc
->th_flags
& TH_SYN
)
272 SetStateOut(link
, ALIAS_TCP_STATE_CONNECTED
);
278 case ALIAS_TCP_STATE_CONNECTED
:
279 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
280 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
289 /* Protocol Specific Packet Aliasing Routines
291 IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2()
292 IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2()
293 ProtoAliasIn(), ProtoAliasOut()
294 UdpAliasIn(), UdpAliasOut()
295 TcpAliasIn(), TcpAliasOut()
297 These routines handle protocol specific details of packet aliasing.
298 One may observe a certain amount of repetitive arithmetic in these
299 functions, the purpose of which is to compute a revised checksum
300 without actually summing over the entire data packet, which could be
301 unnecessarily time consuming.
303 The purpose of the packet aliasing routines is to replace the source
304 address of the outgoing packet and then correctly put it back for
305 any incoming packets. For TCP and UDP, ports are also re-mapped.
307 For ICMP echo/timestamp requests and replies, the following scheme
308 is used: the ID number is replaced by an alias for the outgoing
311 ICMP error messages are handled by looking at the IP fragment
312 in the data section of the message.
314 For TCP and UDP protocols, a port number is chosen for an outgoing
315 packet, and then incoming packets are identified by IP address and
316 port numbers. For TCP packets, there is additional logic in the event
317 that sequence and ACK numbers have been altered (as in the case for
318 FTP data port commands).
320 The port numbers used by the packet aliasing module are not true
321 ports in the Unix sense. No sockets are actually bound to ports.
322 They are more correctly thought of as placeholders.
324 All packets go through the aliasing mechanism, whether they come from
325 the gateway machine or other machines on a local area network.
329 /* Local prototypes */
330 static int IcmpAliasIn1(struct ip
*);
331 static int IcmpAliasIn2(struct ip
*);
332 static int IcmpAliasIn (struct ip
*);
334 static int IcmpAliasOut1(struct ip
*);
335 static int IcmpAliasOut2(struct ip
*);
336 static int IcmpAliasOut (struct ip
*);
338 static int ProtoAliasIn(struct ip
*);
339 static int ProtoAliasOut(struct ip
*);
341 static int UdpAliasOut(struct ip
*);
342 static int UdpAliasIn (struct ip
*);
344 static int TcpAliasOut(struct ip
*, int);
345 static int TcpAliasIn (struct ip
*);
349 IcmpAliasIn1(struct ip
*pip
)
352 De-alias incoming echo and timestamp replies.
353 Alias incoming echo and timestamp requests.
355 struct alias_link
*link
;
358 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
360 /* Get source address from ICMP data field and restore original data */
361 link
= FindIcmpIn(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
367 original_id
= GetOriginalPort(link
);
369 /* Adjust ICMP checksum */
370 accumulate
= ic
->icmp_id
;
371 accumulate
-= original_id
;
372 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
374 /* Put original sequence number back in */
375 ic
->icmp_id
= original_id
;
377 /* Put original address back into IP header */
379 struct in_addr original_address
;
381 original_address
= GetOriginalAddress(link
);
382 DifferentialChecksum(&pip
->ip_sum
,
383 (u_short
*) &original_address
,
384 (u_short
*) &pip
->ip_dst
,
386 pip
->ip_dst
= original_address
;
389 return(PKT_ALIAS_OK
);
391 return(PKT_ALIAS_IGNORED
);
395 IcmpAliasIn2(struct ip
*pip
)
398 Alias incoming ICMP error messages containing
399 IP header and first 64 bits of datagram.
402 struct icmp
*ic
, *ic2
;
405 struct alias_link
*link
;
407 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
410 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
411 tc
= (struct tcphdr
*) ud
;
412 ic2
= (struct icmp
*) ud
;
414 if (ip
->ip_p
== IPPROTO_UDP
)
415 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
416 ud
->uh_dport
, ud
->uh_sport
,
418 else if (ip
->ip_p
== IPPROTO_TCP
)
419 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
420 tc
->th_dport
, tc
->th_sport
,
422 else if (ip
->ip_p
== IPPROTO_ICMP
) {
423 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
424 link
= FindIcmpIn(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
432 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
436 struct in_addr original_address
;
437 u_short original_port
;
439 original_address
= GetOriginalAddress(link
);
440 original_port
= GetOriginalPort(link
);
442 /* Adjust ICMP checksum */
443 sptr
= (u_short
*) &(ip
->ip_src
);
444 accumulate
= *sptr
++;
446 sptr
= (u_short
*) &original_address
;
447 accumulate
-= *sptr
++;
449 accumulate
+= ud
->uh_sport
;
450 accumulate
-= original_port
;
451 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
453 /* Un-alias address in IP header */
454 DifferentialChecksum(&pip
->ip_sum
,
455 (u_short
*) &original_address
,
456 (u_short
*) &pip
->ip_dst
,
458 pip
->ip_dst
= original_address
;
460 /* Un-alias address and port number of original IP packet
461 fragment contained in ICMP data section */
462 ip
->ip_src
= original_address
;
463 ud
->uh_sport
= original_port
;
465 else if (ip
->ip_p
== IPPROTO_ICMP
)
469 struct in_addr original_address
;
472 original_address
= GetOriginalAddress(link
);
473 original_id
= GetOriginalPort(link
);
475 /* Adjust ICMP checksum */
476 sptr
= (u_short
*) &(ip
->ip_src
);
477 accumulate
= *sptr
++;
479 sptr
= (u_short
*) &original_address
;
480 accumulate
-= *sptr
++;
482 accumulate
+= ic2
->icmp_id
;
483 accumulate
-= original_id
;
484 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
486 /* Un-alias address in IP header */
487 DifferentialChecksum(&pip
->ip_sum
,
488 (u_short
*) &original_address
,
489 (u_short
*) &pip
->ip_dst
,
491 pip
->ip_dst
= original_address
;
493 /* Un-alias address of original IP packet and sequence number of
494 embedded ICMP datagram */
495 ip
->ip_src
= original_address
;
496 ic2
->icmp_id
= original_id
;
498 return(PKT_ALIAS_OK
);
500 return(PKT_ALIAS_IGNORED
);
505 IcmpAliasIn(struct ip
*pip
)
510 /* Return if proxy-only mode is enabled */
511 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
514 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
516 iresult
= PKT_ALIAS_IGNORED
;
517 switch (ic
->icmp_type
)
520 case ICMP_TSTAMPREPLY
:
521 if (ic
->icmp_code
== 0)
523 iresult
= IcmpAliasIn1(pip
);
527 case ICMP_SOURCEQUENCH
:
530 iresult
= IcmpAliasIn2(pip
);
534 iresult
= IcmpAliasIn1(pip
);
542 IcmpAliasOut1(struct ip
*pip
)
545 Alias outgoing echo and timestamp requests.
546 De-alias outgoing echo and timestamp replies.
548 struct alias_link
*link
;
551 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
553 /* Save overwritten data for when echo packet returns */
554 link
= FindIcmpOut(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
560 alias_id
= GetAliasPort(link
);
562 /* Since data field is being modified, adjust ICMP checksum */
563 accumulate
= ic
->icmp_id
;
564 accumulate
-= alias_id
;
565 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
567 /* Alias sequence number */
568 ic
->icmp_id
= alias_id
;
570 /* Change source address */
572 struct in_addr alias_address
;
574 alias_address
= GetAliasAddress(link
);
575 DifferentialChecksum(&pip
->ip_sum
,
576 (u_short
*) &alias_address
,
577 (u_short
*) &pip
->ip_src
,
579 pip
->ip_src
= alias_address
;
582 return(PKT_ALIAS_OK
);
584 return(PKT_ALIAS_IGNORED
);
589 IcmpAliasOut2(struct ip
*pip
)
592 Alias outgoing ICMP error messages containing
593 IP header and first 64 bits of datagram.
596 struct icmp
*ic
, *ic2
;
599 struct alias_link
*link
;
601 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
604 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
605 tc
= (struct tcphdr
*) ud
;
606 ic2
= (struct icmp
*) ud
;
608 if (ip
->ip_p
== IPPROTO_UDP
)
609 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
610 ud
->uh_dport
, ud
->uh_sport
,
612 else if (ip
->ip_p
== IPPROTO_TCP
)
613 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
614 tc
->th_dport
, tc
->th_sport
,
616 else if (ip
->ip_p
== IPPROTO_ICMP
) {
617 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
618 link
= FindIcmpOut(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
626 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
630 struct in_addr alias_address
;
633 alias_address
= GetAliasAddress(link
);
634 alias_port
= GetAliasPort(link
);
636 /* Adjust ICMP checksum */
637 sptr
= (u_short
*) &(ip
->ip_dst
);
638 accumulate
= *sptr
++;
640 sptr
= (u_short
*) &alias_address
;
641 accumulate
-= *sptr
++;
643 accumulate
+= ud
->uh_dport
;
644 accumulate
-= alias_port
;
645 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
648 * Alias address in IP header if it comes from the host
649 * the original TCP/UDP packet was destined for.
651 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
652 DifferentialChecksum(&pip
->ip_sum
,
653 (u_short
*) &alias_address
,
654 (u_short
*) &pip
->ip_src
,
656 pip
->ip_src
= alias_address
;
659 /* Alias address and port number of original IP packet
660 fragment contained in ICMP data section */
661 ip
->ip_dst
= alias_address
;
662 ud
->uh_dport
= alias_port
;
664 else if (ip
->ip_p
== IPPROTO_ICMP
)
668 struct in_addr alias_address
;
671 alias_address
= GetAliasAddress(link
);
672 alias_id
= GetAliasPort(link
);
674 /* Adjust ICMP checksum */
675 sptr
= (u_short
*) &(ip
->ip_dst
);
676 accumulate
= *sptr
++;
678 sptr
= (u_short
*) &alias_address
;
679 accumulate
-= *sptr
++;
681 accumulate
+= ic2
->icmp_id
;
682 accumulate
-= alias_id
;
683 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
686 * Alias address in IP header if it comes from the host
687 * the original ICMP message was destined for.
689 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
690 DifferentialChecksum(&pip
->ip_sum
,
691 (u_short
*) &alias_address
,
692 (u_short
*) &pip
->ip_src
,
694 pip
->ip_src
= alias_address
;
697 /* Alias address of original IP packet and sequence number of
698 embedded ICMP datagram */
699 ip
->ip_dst
= alias_address
;
700 ic2
->icmp_id
= alias_id
;
702 return(PKT_ALIAS_OK
);
704 return(PKT_ALIAS_IGNORED
);
709 IcmpAliasOut(struct ip
*pip
)
714 /* Return if proxy-only mode is enabled */
715 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
718 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
720 iresult
= PKT_ALIAS_IGNORED
;
721 switch (ic
->icmp_type
)
725 if (ic
->icmp_code
== 0)
727 iresult
= IcmpAliasOut1(pip
);
731 case ICMP_SOURCEQUENCH
:
734 iresult
= IcmpAliasOut2(pip
);
737 case ICMP_TSTAMPREPLY
:
738 iresult
= IcmpAliasOut1(pip
);
746 ProtoAliasIn(struct ip
*pip
)
749 Handle incoming IP packets. The
750 only thing which is done in this case is to alias
751 the dest IP address of the packet to our inside
754 struct alias_link
*link
;
756 /* Return if proxy-only mode is enabled */
757 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
760 link
= FindProtoIn(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
763 struct in_addr original_address
;
765 original_address
= GetOriginalAddress(link
);
767 /* Restore original IP address */
768 DifferentialChecksum(&pip
->ip_sum
,
769 (u_short
*) &original_address
,
770 (u_short
*) &pip
->ip_dst
,
772 pip
->ip_dst
= original_address
;
774 return(PKT_ALIAS_OK
);
776 return(PKT_ALIAS_IGNORED
);
781 ProtoAliasOut(struct ip
*pip
)
784 Handle outgoing IP packets. The
785 only thing which is done in this case is to alias
786 the source IP address of the packet.
788 struct alias_link
*link
;
790 /* Return if proxy-only mode is enabled */
791 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
794 link
= FindProtoOut(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
797 struct in_addr alias_address
;
799 alias_address
= GetAliasAddress(link
);
801 /* Change source address */
802 DifferentialChecksum(&pip
->ip_sum
,
803 (u_short
*) &alias_address
,
804 (u_short
*) &pip
->ip_src
,
806 pip
->ip_src
= alias_address
;
808 return(PKT_ALIAS_OK
);
810 return(PKT_ALIAS_IGNORED
);
815 UdpAliasIn(struct ip
*pip
)
818 struct alias_link
*link
;
820 /* Return if proxy-only mode is enabled */
821 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
824 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
826 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
827 ud
->uh_sport
, ud
->uh_dport
,
831 struct in_addr alias_address
;
832 struct in_addr original_address
;
838 alias_address
= GetAliasAddress(link
);
839 original_address
= GetOriginalAddress(link
);
840 alias_port
= ud
->uh_dport
;
841 ud
->uh_dport
= GetOriginalPort(link
);
843 /* Special processing for IP encoding protocols */
844 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
845 AliasHandleCUSeeMeIn(pip
, original_address
);
846 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
847 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
848 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
849 r
= AliasHandleUdpNbt(pip
, link
, &original_address
, ud
->uh_dport
);
850 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
851 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
852 r
= AliasHandleUdpNbtNS(pip
, link
, &alias_address
, &alias_port
,
853 &original_address
, &ud
->uh_dport
);
855 /* If UDP checksum is not zero, then adjust since destination port */
856 /* is being unaliased and destination address is being altered. */
859 accumulate
= alias_port
;
860 accumulate
-= ud
->uh_dport
;
861 sptr
= (u_short
*) &alias_address
;
862 accumulate
+= *sptr
++;
864 sptr
= (u_short
*) &original_address
;
865 accumulate
-= *sptr
++;
867 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
870 /* Restore original IP address */
871 DifferentialChecksum(&pip
->ip_sum
,
872 (u_short
*) &original_address
,
873 (u_short
*) &pip
->ip_dst
,
875 pip
->ip_dst
= original_address
;
878 * If we cannot figure out the packet, ignore it.
881 return(PKT_ALIAS_IGNORED
);
883 return(PKT_ALIAS_OK
);
885 return(PKT_ALIAS_IGNORED
);
889 UdpAliasOut(struct ip
*pip
)
892 struct alias_link
*link
;
894 /* Return if proxy-only mode is enabled */
895 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
898 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
900 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
901 ud
->uh_sport
, ud
->uh_dport
,
906 struct in_addr alias_address
;
908 alias_address
= GetAliasAddress(link
);
909 alias_port
= GetAliasPort(link
);
911 /* Special processing for IP encoding protocols */
912 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
913 AliasHandleCUSeeMeOut(pip
, link
);
914 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
915 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
916 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
917 AliasHandleUdpNbt(pip
, link
, &alias_address
, alias_port
);
918 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
919 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
920 AliasHandleUdpNbtNS(pip
, link
, &pip
->ip_src
, &ud
->uh_sport
,
921 &alias_address
, &alias_port
);
923 /* If UDP checksum is not zero, adjust since source port is */
924 /* being aliased and source address is being altered */
930 accumulate
= ud
->uh_sport
;
931 accumulate
-= alias_port
;
932 sptr
= (u_short
*) &(pip
->ip_src
);
933 accumulate
+= *sptr
++;
935 sptr
= (u_short
*) &alias_address
;
936 accumulate
-= *sptr
++;
938 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
941 /* Put alias port in UDP header */
942 ud
->uh_sport
= alias_port
;
944 /* Change source address */
945 DifferentialChecksum(&pip
->ip_sum
,
946 (u_short
*) &alias_address
,
947 (u_short
*) &pip
->ip_src
,
949 pip
->ip_src
= alias_address
;
951 return(PKT_ALIAS_OK
);
953 return(PKT_ALIAS_IGNORED
);
959 TcpAliasIn(struct ip
*pip
)
962 struct alias_link
*link
;
964 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
966 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
967 tc
->th_sport
, tc
->th_dport
,
969 !(packetAliasMode
& PKT_ALIAS_PROXY_ONLY
));
972 struct in_addr alias_address
;
973 struct in_addr original_address
;
974 struct in_addr proxy_address
;
980 /* Special processing for IP encoding protocols */
981 if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
982 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
983 AliasHandlePptpIn(pip
, link
);
985 alias_address
= GetAliasAddress(link
);
986 original_address
= GetOriginalAddress(link
);
987 proxy_address
= GetProxyAddress(link
);
988 alias_port
= tc
->th_dport
;
989 tc
->th_dport
= GetOriginalPort(link
);
990 proxy_port
= GetProxyPort(link
);
992 /* Adjust TCP checksum since destination port is being unaliased */
993 /* and destination port is being altered. */
994 accumulate
= alias_port
;
995 accumulate
-= tc
->th_dport
;
996 sptr
= (u_short
*) &alias_address
;
997 accumulate
+= *sptr
++;
999 sptr
= (u_short
*) &original_address
;
1000 accumulate
-= *sptr
++;
1001 accumulate
-= *sptr
;
1003 /* If this is a proxy, then modify the TCP source port and
1004 checksum accumulation */
1005 if (proxy_port
!= 0)
1007 accumulate
+= tc
->th_sport
;
1008 tc
->th_sport
= proxy_port
;
1009 accumulate
-= tc
->th_sport
;
1011 sptr
= (u_short
*) &pip
->ip_src
;
1012 accumulate
+= *sptr
++;
1013 accumulate
+= *sptr
;
1014 sptr
= (u_short
*) &proxy_address
;
1015 accumulate
-= *sptr
++;
1016 accumulate
-= *sptr
;
1019 /* See if ACK number needs to be modified */
1020 if (GetAckModified(link
) == 1)
1024 delta
= GetDeltaAckIn(pip
, link
);
1027 sptr
= (u_short
*) &tc
->th_ack
;
1028 accumulate
+= *sptr
++;
1029 accumulate
+= *sptr
;
1030 tc
->th_ack
= htonl(ntohl(tc
->th_ack
) - delta
);
1031 sptr
= (u_short
*) &tc
->th_ack
;
1032 accumulate
-= *sptr
++;
1033 accumulate
-= *sptr
;
1037 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1039 /* Restore original IP address */
1040 sptr
= (u_short
*) &pip
->ip_dst
;
1041 accumulate
= *sptr
++;
1042 accumulate
+= *sptr
;
1043 pip
->ip_dst
= original_address
;
1044 sptr
= (u_short
*) &pip
->ip_dst
;
1045 accumulate
-= *sptr
++;
1046 accumulate
-= *sptr
;
1048 /* If this is a transparent proxy packet, then modify the source
1050 if (proxy_address
.s_addr
!= 0)
1052 sptr
= (u_short
*) &pip
->ip_src
;
1053 accumulate
+= *sptr
++;
1054 accumulate
+= *sptr
;
1055 pip
->ip_src
= proxy_address
;
1056 sptr
= (u_short
*) &pip
->ip_src
;
1057 accumulate
-= *sptr
++;
1058 accumulate
-= *sptr
;
1061 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1063 /* Monitor TCP connection state */
1064 TcpMonitorIn(pip
, link
);
1066 return(PKT_ALIAS_OK
);
1068 return(PKT_ALIAS_IGNORED
);
1072 TcpAliasOut(struct ip
*pip
, int maxpacketsize
)
1076 u_short proxy_server_port
;
1077 struct in_addr dest_address
;
1078 struct in_addr proxy_server_address
;
1080 struct alias_link
*link
;
1082 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1084 proxy_type
= ProxyCheck(pip
, &proxy_server_address
, &proxy_server_port
);
1086 if (proxy_type
== 0 && (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
))
1087 return PKT_ALIAS_OK
;
1089 /* If this is a transparent proxy, save original destination,
1090 then alter the destination and adjust checksums */
1091 dest_port
= tc
->th_dport
;
1092 dest_address
= pip
->ip_dst
;
1093 if (proxy_type
!= 0)
1098 accumulate
= tc
->th_dport
;
1099 tc
->th_dport
= proxy_server_port
;
1100 accumulate
-= tc
->th_dport
;
1102 sptr
= (u_short
*) &(pip
->ip_dst
);
1103 accumulate
+= *sptr
++;
1104 accumulate
+= *sptr
;
1105 sptr
= (u_short
*) &proxy_server_address
;
1106 accumulate
-= *sptr
++;
1107 accumulate
-= *sptr
;
1109 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1111 sptr
= (u_short
*) &(pip
->ip_dst
);
1112 accumulate
= *sptr
++;
1113 accumulate
+= *sptr
;
1114 pip
->ip_dst
= proxy_server_address
;
1115 sptr
= (u_short
*) &(pip
->ip_dst
);
1116 accumulate
-= *sptr
++;
1117 accumulate
-= *sptr
;
1119 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1122 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
1123 tc
->th_sport
, tc
->th_dport
,
1128 struct in_addr alias_address
;
1132 /* Save original destination address, if this is a proxy packet.
1133 Also modify packet to include destination encoding. */
1134 if (proxy_type
!= 0)
1136 SetProxyPort(link
, dest_port
);
1137 SetProxyAddress(link
, dest_address
);
1138 ProxyModify(link
, pip
, maxpacketsize
, proxy_type
);
1141 /* Get alias address and port */
1142 alias_port
= GetAliasPort(link
);
1143 alias_address
= GetAliasAddress(link
);
1145 /* Monitor TCP connection state */
1146 TcpMonitorOut(pip
, link
);
1148 /* Special processing for IP encoding protocols */
1149 if (ntohs(tc
->th_dport
) == FTP_CONTROL_PORT_NUMBER
1150 || ntohs(tc
->th_sport
) == FTP_CONTROL_PORT_NUMBER
)
1151 AliasHandleFtpOut(pip
, link
, maxpacketsize
);
1152 else if (ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_1
1153 || ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_2
)
1154 AliasHandleIrcOut(pip
, link
, maxpacketsize
);
1155 else if (ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_1
1156 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_1
1157 || ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_2
1158 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_2
)
1159 AliasHandleRtspOut(pip
, link
, maxpacketsize
);
1160 else if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
1161 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
1162 AliasHandlePptpOut(pip
, link
);
1164 /* Adjust TCP checksum since source port is being aliased */
1165 /* and source address is being altered */
1166 accumulate
= tc
->th_sport
;
1167 tc
->th_sport
= alias_port
;
1168 accumulate
-= tc
->th_sport
;
1170 sptr
= (u_short
*) &(pip
->ip_src
);
1171 accumulate
+= *sptr
++;
1172 accumulate
+= *sptr
;
1173 sptr
= (u_short
*) &alias_address
;
1174 accumulate
-= *sptr
++;
1175 accumulate
-= *sptr
;
1177 /* Modify sequence number if necessary */
1178 if (GetAckModified(link
) == 1)
1182 delta
= GetDeltaSeqOut(pip
, link
);
1185 sptr
= (u_short
*) &tc
->th_seq
;
1186 accumulate
+= *sptr
++;
1187 accumulate
+= *sptr
;
1188 tc
->th_seq
= htonl(ntohl(tc
->th_seq
) + delta
);
1189 sptr
= (u_short
*) &tc
->th_seq
;
1190 accumulate
-= *sptr
++;
1191 accumulate
-= *sptr
;
1195 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1197 /* Change source address */
1198 sptr
= (u_short
*) &(pip
->ip_src
);
1199 accumulate
= *sptr
++;
1200 accumulate
+= *sptr
;
1201 pip
->ip_src
= alias_address
;
1202 sptr
= (u_short
*) &(pip
->ip_src
);
1203 accumulate
-= *sptr
++;
1204 accumulate
-= *sptr
;
1206 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1208 return(PKT_ALIAS_OK
);
1210 return(PKT_ALIAS_IGNORED
);
1216 /* Fragment Handling
1221 The packet aliasing module has a limited ability for handling IP
1222 fragments. If the ICMP, TCP or UDP header is in the first fragment
1223 received, then the ID number of the IP packet is saved, and other
1224 fragments are identified according to their ID number and IP address
1225 they were sent from. Pointers to unresolved fragments can also be
1226 saved and recalled when a header fragment is seen.
1229 /* Local prototypes */
1230 static int FragmentIn(struct ip
*);
1231 static int FragmentOut(struct ip
*);
1235 FragmentIn(struct ip
*pip
)
1237 struct alias_link
*link
;
1239 link
= FindFragmentIn2(pip
->ip_src
, pip
->ip_dst
, pip
->ip_id
);
1242 struct in_addr original_address
;
1244 GetFragmentAddr(link
, &original_address
);
1245 DifferentialChecksum(&pip
->ip_sum
,
1246 (u_short
*) &original_address
,
1247 (u_short
*) &pip
->ip_dst
,
1249 pip
->ip_dst
= original_address
;
1251 return(PKT_ALIAS_OK
);
1253 return(PKT_ALIAS_UNRESOLVED_FRAGMENT
);
1258 FragmentOut(struct ip
*pip
)
1260 struct in_addr alias_address
;
1262 alias_address
= FindAliasAddress(pip
->ip_src
);
1263 DifferentialChecksum(&pip
->ip_sum
,
1264 (u_short
*) &alias_address
,
1265 (u_short
*) &pip
->ip_src
,
1267 pip
->ip_src
= alias_address
;
1269 return(PKT_ALIAS_OK
);
1277 /* Outside World Access
1279 PacketAliasSaveFragment()
1280 PacketAliasGetFragment()
1281 PacketAliasFragmentIn()
1286 (prototypes in alias.h)
1291 PacketAliasSaveFragment(char *ptr
)
1294 struct alias_link
*link
;
1297 pip
= (struct ip
*) ptr
;
1298 link
= AddFragmentPtrLink(pip
->ip_src
, pip
->ip_id
);
1299 iresult
= PKT_ALIAS_ERROR
;
1302 SetFragmentPtr(link
, ptr
);
1303 iresult
= PKT_ALIAS_OK
;
1310 PacketAliasGetFragment(char *ptr
)
1312 struct alias_link
*link
;
1316 pip
= (struct ip
*) ptr
;
1317 link
= FindFragmentPtr(pip
->ip_src
, pip
->ip_id
);
1320 GetFragmentPtr(link
, &fptr
);
1321 SetFragmentPtr(link
, NULL
);
1322 SetExpire(link
, 0); /* Deletes link */
1334 PacketAliasFragmentIn(char *ptr
, /* Points to correctly de-aliased
1336 char *ptr_fragment
/* Points to fragment which must
1343 pip
= (struct ip
*) ptr
;
1344 fpip
= (struct ip
*) ptr_fragment
;
1346 DifferentialChecksum(&fpip
->ip_sum
,
1347 (u_short
*) &pip
->ip_dst
,
1348 (u_short
*) &fpip
->ip_dst
,
1350 fpip
->ip_dst
= pip
->ip_dst
;
1355 PacketAliasIn(char *ptr
, int maxpacketsize
)
1357 struct in_addr alias_addr
;
1361 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1362 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1363 iresult
= PacketAliasOut(ptr
, maxpacketsize
);
1364 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1369 ClearCheckNewLink();
1370 pip
= (struct ip
*) ptr
;
1371 alias_addr
= pip
->ip_dst
;
1373 /* Defense against mangled packets */
1374 if (ntohs(pip
->ip_len
) > maxpacketsize
1375 || (pip
->ip_hl
<<2) > maxpacketsize
)
1376 return PKT_ALIAS_IGNORED
;
1378 iresult
= PKT_ALIAS_IGNORED
;
1379 if ( (ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0 )
1384 iresult
= IcmpAliasIn(pip
);
1387 iresult
= UdpAliasIn(pip
);
1390 iresult
= TcpAliasIn(pip
);
1393 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
||
1394 AliasHandlePptpGreIn(pip
) == 0)
1395 iresult
= PKT_ALIAS_OK
;
1397 iresult
= ProtoAliasIn(pip
);
1400 iresult
= ProtoAliasIn(pip
);
1404 if (ntohs(pip
->ip_off
) & IP_MF
)
1406 struct alias_link
*link
;
1408 link
= FindFragmentIn1(pip
->ip_src
, alias_addr
, pip
->ip_id
);
1411 iresult
= PKT_ALIAS_FOUND_HEADER_FRAGMENT
;
1412 SetFragmentAddr(link
, pip
->ip_dst
);
1416 iresult
= PKT_ALIAS_ERROR
;
1422 iresult
= FragmentIn(pip
);
1430 /* Unregistered address ranges */
1432 /* 10.0.0.0 -> 10.255.255.255 */
1433 #define UNREG_ADDR_A_LOWER 0x0a000000
1434 #define UNREG_ADDR_A_UPPER 0x0affffff
1436 /* 172.16.0.0 -> 172.31.255.255 */
1437 #define UNREG_ADDR_B_LOWER 0xac100000
1438 #define UNREG_ADDR_B_UPPER 0xac1fffff
1440 /* 192.168.0.0 -> 192.168.255.255 */
1441 #define UNREG_ADDR_C_LOWER 0xc0a80000
1442 #define UNREG_ADDR_C_UPPER 0xc0a8ffff
1445 PacketAliasOut(char *ptr
, /* valid IP packet */
1446 int maxpacketsize
/* How much the packet data may grow
1447 (FTP and IRC inline changes) */
1451 struct in_addr addr_save
;
1454 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1455 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1456 iresult
= PacketAliasIn(ptr
, maxpacketsize
);
1457 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1462 ClearCheckNewLink();
1463 pip
= (struct ip
*) ptr
;
1465 /* Defense against mangled packets */
1466 if (ntohs(pip
->ip_len
) > maxpacketsize
1467 || (pip
->ip_hl
<<2) > maxpacketsize
)
1468 return PKT_ALIAS_IGNORED
;
1470 addr_save
= GetDefaultAliasAddress();
1471 if (packetAliasMode
& PKT_ALIAS_UNREGISTERED_ONLY
)
1477 addr
= ntohl(pip
->ip_src
.s_addr
);
1478 if (addr
>= UNREG_ADDR_C_LOWER
&& addr
<= UNREG_ADDR_C_UPPER
)
1480 else if (addr
>= UNREG_ADDR_B_LOWER
&& addr
<= UNREG_ADDR_B_UPPER
)
1482 else if (addr
>= UNREG_ADDR_A_LOWER
&& addr
<= UNREG_ADDR_A_UPPER
)
1487 SetDefaultAliasAddress(pip
->ip_src
);
1491 iresult
= PKT_ALIAS_IGNORED
;
1492 if ((ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0)
1497 iresult
= IcmpAliasOut(pip
);
1500 iresult
= UdpAliasOut(pip
);
1503 iresult
= TcpAliasOut(pip
, maxpacketsize
);
1506 if (AliasHandlePptpGreOut(pip
) == 0)
1507 iresult
= PKT_ALIAS_OK
;
1509 iresult
= ProtoAliasOut(pip
);
1512 iresult
= ProtoAliasOut(pip
);
1518 iresult
= FragmentOut(pip
);
1521 SetDefaultAliasAddress(addr_save
);
1526 PacketUnaliasOut(char *ptr
, /* valid IP packet */
1527 int maxpacketsize
/* for error checking */
1534 struct alias_link
*link
;
1535 int iresult
= PKT_ALIAS_IGNORED
;
1537 pip
= (struct ip
*) ptr
;
1539 /* Defense against mangled packets */
1540 if (ntohs(pip
->ip_len
) > maxpacketsize
1541 || (pip
->ip_hl
<<2) > maxpacketsize
)
1544 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1545 tc
= (struct tcphdr
*) ud
;
1546 ic
= (struct icmp
*) ud
;
1549 if (pip
->ip_p
== IPPROTO_UDP
)
1550 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1551 ud
->uh_dport
, ud
->uh_sport
,
1553 else if (pip
->ip_p
== IPPROTO_TCP
)
1554 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1555 tc
->th_dport
, tc
->th_sport
,
1557 else if (pip
->ip_p
== IPPROTO_ICMP
)
1558 link
= FindIcmpIn(pip
->ip_dst
, pip
->ip_src
, ic
->icmp_id
, 0);
1562 /* Change it from an aliased packet to an unaliased packet */
1565 if (pip
->ip_p
== IPPROTO_UDP
|| pip
->ip_p
== IPPROTO_TCP
)
1569 struct in_addr original_address
;
1570 u_short original_port
;
1572 original_address
= GetOriginalAddress(link
);
1573 original_port
= GetOriginalPort(link
);
1575 /* Adjust TCP/UDP checksum */
1576 sptr
= (u_short
*) &(pip
->ip_src
);
1577 accumulate
= *sptr
++;
1578 accumulate
+= *sptr
;
1579 sptr
= (u_short
*) &original_address
;
1580 accumulate
-= *sptr
++;
1581 accumulate
-= *sptr
;
1583 if (pip
->ip_p
== IPPROTO_UDP
) {
1584 accumulate
+= ud
->uh_sport
;
1585 accumulate
-= original_port
;
1586 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
1588 accumulate
+= tc
->th_sport
;
1589 accumulate
-= original_port
;
1590 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1593 /* Adjust IP checksum */
1594 DifferentialChecksum(&pip
->ip_sum
,
1595 (u_short
*) &original_address
,
1596 (u_short
*) &pip
->ip_src
,
1599 /* Un-alias source address and port number */
1600 pip
->ip_src
= original_address
;
1601 if (pip
->ip_p
== IPPROTO_UDP
)
1602 ud
->uh_sport
= original_port
;
1604 tc
->th_sport
= original_port
;
1606 iresult
= PKT_ALIAS_OK
;
1608 } else if (pip
->ip_p
== IPPROTO_ICMP
) {
1612 struct in_addr original_address
;
1613 u_short original_id
;
1615 original_address
= GetOriginalAddress(link
);
1616 original_id
= GetOriginalPort(link
);
1618 /* Adjust ICMP checksum */
1619 sptr
= (u_short
*) &(pip
->ip_src
);
1620 accumulate
= *sptr
++;
1621 accumulate
+= *sptr
;
1622 sptr
= (u_short
*) &original_address
;
1623 accumulate
-= *sptr
++;
1624 accumulate
-= *sptr
;
1625 accumulate
+= ic
->icmp_id
;
1626 accumulate
-= original_id
;
1627 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
1629 /* Adjust IP checksum */
1630 DifferentialChecksum(&pip
->ip_sum
,
1631 (u_short
*) &original_address
,
1632 (u_short
*) &pip
->ip_src
,
1635 /* Un-alias source address and port number */
1636 pip
->ip_src
= original_address
;
1637 ic
->icmp_id
= original_id
;
1639 iresult
= PKT_ALIAS_OK
;