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 int accnetorder
= 0 ;
216 accumulate
-= packetAliasMSS
;
217 *mssPtr
= htons(packetAliasMSS
);
218 accnetorder
= htons(accumulate
);
219 ADJUST_CHECKSUM(accnetorder
, tc
->th_sum
);
234 TcpMonitorIn(struct ip
*pip
, struct alias_link
*link
)
238 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
240 switch (GetStateIn(link
))
242 case ALIAS_TCP_STATE_NOT_CONNECTED
:
243 if (tc
->th_flags
& TH_RST
)
244 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
245 else if (tc
->th_flags
& TH_SYN
)
247 SetStateIn(link
, ALIAS_TCP_STATE_CONNECTED
);
253 case ALIAS_TCP_STATE_CONNECTED
:
254 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
255 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
261 TcpMonitorOut(struct ip
*pip
, struct alias_link
*link
)
265 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
267 switch (GetStateOut(link
))
269 case ALIAS_TCP_STATE_NOT_CONNECTED
:
270 if (tc
->th_flags
& TH_RST
)
271 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
272 else if (tc
->th_flags
& TH_SYN
)
274 SetStateOut(link
, ALIAS_TCP_STATE_CONNECTED
);
280 case ALIAS_TCP_STATE_CONNECTED
:
281 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
282 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
291 /* Protocol Specific Packet Aliasing Routines
293 IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2()
294 IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2()
295 ProtoAliasIn(), ProtoAliasOut()
296 UdpAliasIn(), UdpAliasOut()
297 TcpAliasIn(), TcpAliasOut()
299 These routines handle protocol specific details of packet aliasing.
300 One may observe a certain amount of repetitive arithmetic in these
301 functions, the purpose of which is to compute a revised checksum
302 without actually summing over the entire data packet, which could be
303 unnecessarily time consuming.
305 The purpose of the packet aliasing routines is to replace the source
306 address of the outgoing packet and then correctly put it back for
307 any incoming packets. For TCP and UDP, ports are also re-mapped.
309 For ICMP echo/timestamp requests and replies, the following scheme
310 is used: the ID number is replaced by an alias for the outgoing
313 ICMP error messages are handled by looking at the IP fragment
314 in the data section of the message.
316 For TCP and UDP protocols, a port number is chosen for an outgoing
317 packet, and then incoming packets are identified by IP address and
318 port numbers. For TCP packets, there is additional logic in the event
319 that sequence and ACK numbers have been altered (as in the case for
320 FTP data port commands).
322 The port numbers used by the packet aliasing module are not true
323 ports in the Unix sense. No sockets are actually bound to ports.
324 They are more correctly thought of as placeholders.
326 All packets go through the aliasing mechanism, whether they come from
327 the gateway machine or other machines on a local area network.
331 /* Local prototypes */
332 static int IcmpAliasIn1(struct ip
*);
333 static int IcmpAliasIn2(struct ip
*);
334 static int IcmpAliasIn (struct ip
*);
336 static int IcmpAliasOut1(struct ip
*);
337 static int IcmpAliasOut2(struct ip
*);
338 static int IcmpAliasOut (struct ip
*);
340 static int ProtoAliasIn(struct ip
*);
341 static int ProtoAliasOut(struct ip
*);
343 static int UdpAliasOut(struct ip
*);
344 static int UdpAliasIn (struct ip
*);
346 static int TcpAliasOut(struct ip
*, int);
347 static int TcpAliasIn (struct ip
*);
351 IcmpAliasIn1(struct ip
*pip
)
354 De-alias incoming echo and timestamp replies.
355 Alias incoming echo and timestamp requests.
357 struct alias_link
*link
;
360 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
362 /* Get source address from ICMP data field and restore original data */
363 link
= FindIcmpIn(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
369 original_id
= GetOriginalPort(link
);
371 /* Adjust ICMP checksum */
372 accumulate
= ic
->icmp_id
;
373 accumulate
-= original_id
;
374 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
376 /* Put original sequence number back in */
377 ic
->icmp_id
= original_id
;
379 /* Put original address back into IP header */
381 struct in_addr original_address
;
383 original_address
= GetOriginalAddress(link
);
384 DifferentialChecksum(&pip
->ip_sum
,
385 (u_short
*) &original_address
,
386 (u_short
*) &pip
->ip_dst
,
388 pip
->ip_dst
= original_address
;
391 return(PKT_ALIAS_OK
);
393 return(PKT_ALIAS_IGNORED
);
397 IcmpAliasIn2(struct ip
*pip
)
400 Alias incoming ICMP error messages containing
401 IP header and first 64 bits of datagram.
404 struct icmp
*ic
, *ic2
;
407 struct alias_link
*link
;
409 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
412 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
413 tc
= (struct tcphdr
*) ud
;
414 ic2
= (struct icmp
*) ud
;
416 if (ip
->ip_p
== IPPROTO_UDP
)
417 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
418 ud
->uh_dport
, ud
->uh_sport
,
420 else if (ip
->ip_p
== IPPROTO_TCP
)
421 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
422 tc
->th_dport
, tc
->th_sport
,
424 else if (ip
->ip_p
== IPPROTO_ICMP
) {
425 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
426 link
= FindIcmpIn(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
434 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
438 struct in_addr original_address
;
439 u_short original_port
;
441 original_address
= GetOriginalAddress(link
);
442 original_port
= GetOriginalPort(link
);
444 /* Adjust ICMP checksum */
445 sptr
= (u_short
*) &(ip
->ip_src
);
446 accumulate
= *sptr
++;
448 sptr
= (u_short
*) &original_address
;
449 accumulate
-= *sptr
++;
451 accumulate
+= ud
->uh_sport
;
452 accumulate
-= original_port
;
453 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
455 /* Un-alias address in IP header */
456 DifferentialChecksum(&pip
->ip_sum
,
457 (u_short
*) &original_address
,
458 (u_short
*) &pip
->ip_dst
,
460 pip
->ip_dst
= original_address
;
462 /* Un-alias address and port number of original IP packet
463 fragment contained in ICMP data section */
464 ip
->ip_src
= original_address
;
465 ud
->uh_sport
= original_port
;
467 else if (ip
->ip_p
== IPPROTO_ICMP
)
471 struct in_addr original_address
;
474 original_address
= GetOriginalAddress(link
);
475 original_id
= GetOriginalPort(link
);
477 /* Adjust ICMP checksum */
478 sptr
= (u_short
*) &(ip
->ip_src
);
479 accumulate
= *sptr
++;
481 sptr
= (u_short
*) &original_address
;
482 accumulate
-= *sptr
++;
484 accumulate
+= ic2
->icmp_id
;
485 accumulate
-= original_id
;
486 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
488 /* Un-alias address in IP header */
489 DifferentialChecksum(&pip
->ip_sum
,
490 (u_short
*) &original_address
,
491 (u_short
*) &pip
->ip_dst
,
493 pip
->ip_dst
= original_address
;
495 /* Un-alias address of original IP packet and sequence number of
496 embedded ICMP datagram */
497 ip
->ip_src
= original_address
;
498 ic2
->icmp_id
= original_id
;
500 return(PKT_ALIAS_OK
);
502 return(PKT_ALIAS_IGNORED
);
507 IcmpAliasIn(struct ip
*pip
)
512 /* Return if proxy-only mode is enabled */
513 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
516 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
518 iresult
= PKT_ALIAS_IGNORED
;
519 switch (ic
->icmp_type
)
522 case ICMP_TSTAMPREPLY
:
523 if (ic
->icmp_code
== 0)
525 iresult
= IcmpAliasIn1(pip
);
529 case ICMP_SOURCEQUENCH
:
532 iresult
= IcmpAliasIn2(pip
);
536 iresult
= IcmpAliasIn1(pip
);
544 IcmpAliasOut1(struct ip
*pip
)
547 Alias outgoing echo and timestamp requests.
548 De-alias outgoing echo and timestamp replies.
550 struct alias_link
*link
;
553 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
555 /* Save overwritten data for when echo packet returns */
556 link
= FindIcmpOut(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
562 alias_id
= GetAliasPort(link
);
564 /* Since data field is being modified, adjust ICMP checksum */
565 accumulate
= ic
->icmp_id
;
566 accumulate
-= alias_id
;
567 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
569 /* Alias sequence number */
570 ic
->icmp_id
= alias_id
;
572 /* Change source address */
574 struct in_addr alias_address
;
576 alias_address
= GetAliasAddress(link
);
577 DifferentialChecksum(&pip
->ip_sum
,
578 (u_short
*) &alias_address
,
579 (u_short
*) &pip
->ip_src
,
581 pip
->ip_src
= alias_address
;
584 return(PKT_ALIAS_OK
);
586 return(PKT_ALIAS_IGNORED
);
591 IcmpAliasOut2(struct ip
*pip
)
594 Alias outgoing ICMP error messages containing
595 IP header and first 64 bits of datagram.
598 struct icmp
*ic
, *ic2
;
601 struct alias_link
*link
;
603 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
606 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
607 tc
= (struct tcphdr
*) ud
;
608 ic2
= (struct icmp
*) ud
;
610 if (ip
->ip_p
== IPPROTO_UDP
)
611 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
612 ud
->uh_dport
, ud
->uh_sport
,
614 else if (ip
->ip_p
== IPPROTO_TCP
)
615 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
616 tc
->th_dport
, tc
->th_sport
,
618 else if (ip
->ip_p
== IPPROTO_ICMP
) {
619 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
620 link
= FindIcmpOut(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
628 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
632 struct in_addr alias_address
;
635 alias_address
= GetAliasAddress(link
);
636 alias_port
= GetAliasPort(link
);
638 /* Adjust ICMP checksum */
639 sptr
= (u_short
*) &(ip
->ip_dst
);
640 accumulate
= *sptr
++;
642 sptr
= (u_short
*) &alias_address
;
643 accumulate
-= *sptr
++;
645 accumulate
+= ud
->uh_dport
;
646 accumulate
-= alias_port
;
647 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
650 * Alias address in IP header if it comes from the host
651 * the original TCP/UDP packet was destined for.
653 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
654 DifferentialChecksum(&pip
->ip_sum
,
655 (u_short
*) &alias_address
,
656 (u_short
*) &pip
->ip_src
,
658 pip
->ip_src
= alias_address
;
661 /* Alias address and port number of original IP packet
662 fragment contained in ICMP data section */
663 ip
->ip_dst
= alias_address
;
664 ud
->uh_dport
= alias_port
;
666 else if (ip
->ip_p
== IPPROTO_ICMP
)
670 struct in_addr alias_address
;
673 alias_address
= GetAliasAddress(link
);
674 alias_id
= GetAliasPort(link
);
676 /* Adjust ICMP checksum */
677 sptr
= (u_short
*) &(ip
->ip_dst
);
678 accumulate
= *sptr
++;
680 sptr
= (u_short
*) &alias_address
;
681 accumulate
-= *sptr
++;
683 accumulate
+= ic2
->icmp_id
;
684 accumulate
-= alias_id
;
685 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
688 * Alias address in IP header if it comes from the host
689 * the original ICMP message was destined for.
691 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
692 DifferentialChecksum(&pip
->ip_sum
,
693 (u_short
*) &alias_address
,
694 (u_short
*) &pip
->ip_src
,
696 pip
->ip_src
= alias_address
;
699 /* Alias address of original IP packet and sequence number of
700 embedded ICMP datagram */
701 ip
->ip_dst
= alias_address
;
702 ic2
->icmp_id
= alias_id
;
704 return(PKT_ALIAS_OK
);
706 return(PKT_ALIAS_IGNORED
);
711 IcmpAliasOut(struct ip
*pip
)
716 /* Return if proxy-only mode is enabled */
717 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
720 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
722 iresult
= PKT_ALIAS_IGNORED
;
723 switch (ic
->icmp_type
)
727 if (ic
->icmp_code
== 0)
729 iresult
= IcmpAliasOut1(pip
);
733 case ICMP_SOURCEQUENCH
:
736 iresult
= IcmpAliasOut2(pip
);
739 case ICMP_TSTAMPREPLY
:
740 iresult
= IcmpAliasOut1(pip
);
748 ProtoAliasIn(struct ip
*pip
)
751 Handle incoming IP packets. The
752 only thing which is done in this case is to alias
753 the dest IP address of the packet to our inside
756 struct alias_link
*link
;
758 /* Return if proxy-only mode is enabled */
759 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
762 link
= FindProtoIn(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
765 struct in_addr original_address
;
767 original_address
= GetOriginalAddress(link
);
769 /* Restore original IP address */
770 DifferentialChecksum(&pip
->ip_sum
,
771 (u_short
*) &original_address
,
772 (u_short
*) &pip
->ip_dst
,
774 pip
->ip_dst
= original_address
;
776 return(PKT_ALIAS_OK
);
778 return(PKT_ALIAS_IGNORED
);
783 ProtoAliasOut(struct ip
*pip
)
786 Handle outgoing IP packets. The
787 only thing which is done in this case is to alias
788 the source IP address of the packet.
790 struct alias_link
*link
;
792 /* Return if proxy-only mode is enabled */
793 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
796 link
= FindProtoOut(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
799 struct in_addr alias_address
;
801 alias_address
= GetAliasAddress(link
);
803 /* Change source address */
804 DifferentialChecksum(&pip
->ip_sum
,
805 (u_short
*) &alias_address
,
806 (u_short
*) &pip
->ip_src
,
808 pip
->ip_src
= alias_address
;
810 return(PKT_ALIAS_OK
);
812 return(PKT_ALIAS_IGNORED
);
817 UdpAliasIn(struct ip
*pip
)
820 struct alias_link
*link
;
822 /* Return if proxy-only mode is enabled */
823 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
826 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
828 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
829 ud
->uh_sport
, ud
->uh_dport
,
833 struct in_addr alias_address
;
834 struct in_addr original_address
;
840 alias_address
= GetAliasAddress(link
);
841 original_address
= GetOriginalAddress(link
);
842 alias_port
= ud
->uh_dport
;
843 ud
->uh_dport
= GetOriginalPort(link
);
845 /* Special processing for IP encoding protocols */
846 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
847 AliasHandleCUSeeMeIn(pip
, original_address
);
848 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
849 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
850 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
851 r
= AliasHandleUdpNbt(pip
, link
, &original_address
, ud
->uh_dport
);
852 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
853 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
854 r
= AliasHandleUdpNbtNS(pip
, link
, &alias_address
, &alias_port
,
855 &original_address
, &ud
->uh_dport
);
857 /* If UDP checksum is not zero, then adjust since destination port */
858 /* is being unaliased and destination address is being altered. */
861 accumulate
= alias_port
;
862 accumulate
-= ud
->uh_dport
;
863 sptr
= (u_short
*) &alias_address
;
864 accumulate
+= *sptr
++;
866 sptr
= (u_short
*) &original_address
;
867 accumulate
-= *sptr
++;
869 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
872 /* Restore original IP address */
873 DifferentialChecksum(&pip
->ip_sum
,
874 (u_short
*) &original_address
,
875 (u_short
*) &pip
->ip_dst
,
877 pip
->ip_dst
= original_address
;
880 * If we cannot figure out the packet, ignore it.
883 return(PKT_ALIAS_IGNORED
);
885 return(PKT_ALIAS_OK
);
887 return(PKT_ALIAS_IGNORED
);
891 UdpAliasOut(struct ip
*pip
)
894 struct alias_link
*link
;
896 /* Return if proxy-only mode is enabled */
897 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
900 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
902 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
903 ud
->uh_sport
, ud
->uh_dport
,
908 struct in_addr alias_address
;
910 alias_address
= GetAliasAddress(link
);
911 alias_port
= GetAliasPort(link
);
913 /* Special processing for IP encoding protocols */
914 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
915 AliasHandleCUSeeMeOut(pip
, link
);
916 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
917 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
918 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
919 AliasHandleUdpNbt(pip
, link
, &alias_address
, alias_port
);
920 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
921 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
922 AliasHandleUdpNbtNS(pip
, link
, &pip
->ip_src
, &ud
->uh_sport
,
923 &alias_address
, &alias_port
);
925 /* If UDP checksum is not zero, adjust since source port is */
926 /* being aliased and source address is being altered */
932 accumulate
= ud
->uh_sport
;
933 accumulate
-= alias_port
;
934 sptr
= (u_short
*) &(pip
->ip_src
);
935 accumulate
+= *sptr
++;
937 sptr
= (u_short
*) &alias_address
;
938 accumulate
-= *sptr
++;
940 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
943 /* Put alias port in UDP header */
944 ud
->uh_sport
= alias_port
;
946 /* Change source address */
947 DifferentialChecksum(&pip
->ip_sum
,
948 (u_short
*) &alias_address
,
949 (u_short
*) &pip
->ip_src
,
951 pip
->ip_src
= alias_address
;
953 return(PKT_ALIAS_OK
);
955 return(PKT_ALIAS_IGNORED
);
961 TcpAliasIn(struct ip
*pip
)
964 struct alias_link
*link
;
966 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
968 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
969 tc
->th_sport
, tc
->th_dport
,
971 !(packetAliasMode
& PKT_ALIAS_PROXY_ONLY
));
974 struct in_addr alias_address
;
975 struct in_addr original_address
;
976 struct in_addr proxy_address
;
982 /* Special processing for IP encoding protocols */
983 if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
984 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
985 AliasHandlePptpIn(pip
, link
);
987 alias_address
= GetAliasAddress(link
);
988 original_address
= GetOriginalAddress(link
);
989 proxy_address
= GetProxyAddress(link
);
990 alias_port
= tc
->th_dport
;
991 tc
->th_dport
= GetOriginalPort(link
);
992 proxy_port
= GetProxyPort(link
);
994 /* Adjust TCP checksum since destination port is being unaliased */
995 /* and destination port is being altered. */
996 accumulate
= alias_port
;
997 accumulate
-= tc
->th_dport
;
998 sptr
= (u_short
*) &alias_address
;
999 accumulate
+= *sptr
++;
1000 accumulate
+= *sptr
;
1001 sptr
= (u_short
*) &original_address
;
1002 accumulate
-= *sptr
++;
1003 accumulate
-= *sptr
;
1005 /* If this is a proxy, then modify the TCP source port and
1006 checksum accumulation */
1007 if (proxy_port
!= 0)
1009 accumulate
+= tc
->th_sport
;
1010 tc
->th_sport
= proxy_port
;
1011 accumulate
-= tc
->th_sport
;
1013 sptr
= (u_short
*) &pip
->ip_src
;
1014 accumulate
+= *sptr
++;
1015 accumulate
+= *sptr
;
1016 sptr
= (u_short
*) &proxy_address
;
1017 accumulate
-= *sptr
++;
1018 accumulate
-= *sptr
;
1021 /* See if ACK number needs to be modified */
1022 if (GetAckModified(link
) == 1)
1026 delta
= GetDeltaAckIn(pip
, link
);
1029 sptr
= (u_short
*) &tc
->th_ack
;
1030 accumulate
+= *sptr
++;
1031 accumulate
+= *sptr
;
1032 tc
->th_ack
= htonl(ntohl(tc
->th_ack
) - delta
);
1033 sptr
= (u_short
*) &tc
->th_ack
;
1034 accumulate
-= *sptr
++;
1035 accumulate
-= *sptr
;
1039 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1041 /* Restore original IP address */
1042 sptr
= (u_short
*) &pip
->ip_dst
;
1043 accumulate
= *sptr
++;
1044 accumulate
+= *sptr
;
1045 pip
->ip_dst
= original_address
;
1046 sptr
= (u_short
*) &pip
->ip_dst
;
1047 accumulate
-= *sptr
++;
1048 accumulate
-= *sptr
;
1050 /* If this is a transparent proxy packet, then modify the source
1052 if (proxy_address
.s_addr
!= 0)
1054 sptr
= (u_short
*) &pip
->ip_src
;
1055 accumulate
+= *sptr
++;
1056 accumulate
+= *sptr
;
1057 pip
->ip_src
= proxy_address
;
1058 sptr
= (u_short
*) &pip
->ip_src
;
1059 accumulate
-= *sptr
++;
1060 accumulate
-= *sptr
;
1063 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1065 /* Monitor TCP connection state */
1066 TcpMonitorIn(pip
, link
);
1068 return(PKT_ALIAS_OK
);
1070 return(PKT_ALIAS_IGNORED
);
1074 TcpAliasOut(struct ip
*pip
, int maxpacketsize
)
1078 u_short proxy_server_port
;
1079 struct in_addr dest_address
;
1080 struct in_addr proxy_server_address
;
1082 struct alias_link
*link
;
1084 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1086 proxy_type
= ProxyCheck(pip
, &proxy_server_address
, &proxy_server_port
);
1088 if (proxy_type
== 0 && (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
))
1089 return PKT_ALIAS_OK
;
1091 /* If this is a transparent proxy, save original destination,
1092 then alter the destination and adjust checksums */
1093 dest_port
= tc
->th_dport
;
1094 dest_address
= pip
->ip_dst
;
1095 if (proxy_type
!= 0)
1100 accumulate
= tc
->th_dport
;
1101 tc
->th_dport
= proxy_server_port
;
1102 accumulate
-= tc
->th_dport
;
1104 sptr
= (u_short
*) &(pip
->ip_dst
);
1105 accumulate
+= *sptr
++;
1106 accumulate
+= *sptr
;
1107 sptr
= (u_short
*) &proxy_server_address
;
1108 accumulate
-= *sptr
++;
1109 accumulate
-= *sptr
;
1111 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1113 sptr
= (u_short
*) &(pip
->ip_dst
);
1114 accumulate
= *sptr
++;
1115 accumulate
+= *sptr
;
1116 pip
->ip_dst
= proxy_server_address
;
1117 sptr
= (u_short
*) &(pip
->ip_dst
);
1118 accumulate
-= *sptr
++;
1119 accumulate
-= *sptr
;
1121 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1124 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
1125 tc
->th_sport
, tc
->th_dport
,
1130 struct in_addr alias_address
;
1134 /* Save original destination address, if this is a proxy packet.
1135 Also modify packet to include destination encoding. */
1136 if (proxy_type
!= 0)
1138 SetProxyPort(link
, dest_port
);
1139 SetProxyAddress(link
, dest_address
);
1140 ProxyModify(link
, pip
, maxpacketsize
, proxy_type
);
1143 /* Get alias address and port */
1144 alias_port
= GetAliasPort(link
);
1145 alias_address
= GetAliasAddress(link
);
1147 /* Monitor TCP connection state */
1148 TcpMonitorOut(pip
, link
);
1150 /* Special processing for IP encoding protocols */
1151 if (ntohs(tc
->th_dport
) == FTP_CONTROL_PORT_NUMBER
1152 || ntohs(tc
->th_sport
) == FTP_CONTROL_PORT_NUMBER
)
1153 AliasHandleFtpOut(pip
, link
, maxpacketsize
);
1154 else if (ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_1
1155 || ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_2
)
1156 AliasHandleIrcOut(pip
, link
, maxpacketsize
);
1157 else if (ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_1
1158 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_1
1159 || ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_2
1160 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_2
)
1161 AliasHandleRtspOut(pip
, link
, maxpacketsize
);
1162 else if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
1163 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
1164 AliasHandlePptpOut(pip
, link
);
1166 /* Adjust TCP checksum since source port is being aliased */
1167 /* and source address is being altered */
1168 accumulate
= tc
->th_sport
;
1169 tc
->th_sport
= alias_port
;
1170 accumulate
-= tc
->th_sport
;
1172 sptr
= (u_short
*) &(pip
->ip_src
);
1173 accumulate
+= *sptr
++;
1174 accumulate
+= *sptr
;
1175 sptr
= (u_short
*) &alias_address
;
1176 accumulate
-= *sptr
++;
1177 accumulate
-= *sptr
;
1179 /* Modify sequence number if necessary */
1180 if (GetAckModified(link
) == 1)
1184 delta
= GetDeltaSeqOut(pip
, link
);
1187 sptr
= (u_short
*) &tc
->th_seq
;
1188 accumulate
+= *sptr
++;
1189 accumulate
+= *sptr
;
1190 tc
->th_seq
= htonl(ntohl(tc
->th_seq
) + delta
);
1191 sptr
= (u_short
*) &tc
->th_seq
;
1192 accumulate
-= *sptr
++;
1193 accumulate
-= *sptr
;
1197 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1199 /* Change source address */
1200 sptr
= (u_short
*) &(pip
->ip_src
);
1201 accumulate
= *sptr
++;
1202 accumulate
+= *sptr
;
1203 pip
->ip_src
= alias_address
;
1204 sptr
= (u_short
*) &(pip
->ip_src
);
1205 accumulate
-= *sptr
++;
1206 accumulate
-= *sptr
;
1208 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1210 return(PKT_ALIAS_OK
);
1212 return(PKT_ALIAS_IGNORED
);
1218 /* Fragment Handling
1223 The packet aliasing module has a limited ability for handling IP
1224 fragments. If the ICMP, TCP or UDP header is in the first fragment
1225 received, then the ID number of the IP packet is saved, and other
1226 fragments are identified according to their ID number and IP address
1227 they were sent from. Pointers to unresolved fragments can also be
1228 saved and recalled when a header fragment is seen.
1231 /* Local prototypes */
1232 static int FragmentIn(struct ip
*);
1233 static int FragmentOut(struct ip
*);
1237 FragmentIn(struct ip
*pip
)
1239 struct alias_link
*link
;
1241 link
= FindFragmentIn2(pip
->ip_src
, pip
->ip_dst
, pip
->ip_id
);
1244 struct in_addr original_address
;
1246 GetFragmentAddr(link
, &original_address
);
1247 DifferentialChecksum(&pip
->ip_sum
,
1248 (u_short
*) &original_address
,
1249 (u_short
*) &pip
->ip_dst
,
1251 pip
->ip_dst
= original_address
;
1253 return(PKT_ALIAS_OK
);
1255 return(PKT_ALIAS_UNRESOLVED_FRAGMENT
);
1260 FragmentOut(struct ip
*pip
)
1262 struct in_addr alias_address
;
1264 alias_address
= FindAliasAddress(pip
->ip_src
);
1265 DifferentialChecksum(&pip
->ip_sum
,
1266 (u_short
*) &alias_address
,
1267 (u_short
*) &pip
->ip_src
,
1269 pip
->ip_src
= alias_address
;
1271 return(PKT_ALIAS_OK
);
1279 /* Outside World Access
1281 PacketAliasSaveFragment()
1282 PacketAliasGetFragment()
1283 PacketAliasFragmentIn()
1288 (prototypes in alias.h)
1293 PacketAliasSaveFragment(char *ptr
)
1296 struct alias_link
*link
;
1299 pip
= (struct ip
*) ptr
;
1300 link
= AddFragmentPtrLink(pip
->ip_src
, pip
->ip_id
);
1301 iresult
= PKT_ALIAS_ERROR
;
1304 SetFragmentPtr(link
, ptr
);
1305 iresult
= PKT_ALIAS_OK
;
1312 PacketAliasGetFragment(char *ptr
)
1314 struct alias_link
*link
;
1318 pip
= (struct ip
*) ptr
;
1319 link
= FindFragmentPtr(pip
->ip_src
, pip
->ip_id
);
1322 GetFragmentPtr(link
, &fptr
);
1323 SetFragmentPtr(link
, NULL
);
1324 SetExpire(link
, 0); /* Deletes link */
1336 PacketAliasFragmentIn(char *ptr
, /* Points to correctly de-aliased
1338 char *ptr_fragment
/* Points to fragment which must
1345 pip
= (struct ip
*) ptr
;
1346 fpip
= (struct ip
*) ptr_fragment
;
1348 DifferentialChecksum(&fpip
->ip_sum
,
1349 (u_short
*) &pip
->ip_dst
,
1350 (u_short
*) &fpip
->ip_dst
,
1352 fpip
->ip_dst
= pip
->ip_dst
;
1357 PacketAliasIn(char *ptr
, int maxpacketsize
)
1359 struct in_addr alias_addr
;
1363 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1364 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1365 iresult
= PacketAliasOut(ptr
, maxpacketsize
);
1366 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1371 ClearCheckNewLink();
1372 pip
= (struct ip
*) ptr
;
1373 alias_addr
= pip
->ip_dst
;
1375 /* Defense against mangled packets */
1376 if (ntohs(pip
->ip_len
) > maxpacketsize
1377 || (pip
->ip_hl
<<2) > maxpacketsize
)
1378 return PKT_ALIAS_IGNORED
;
1380 iresult
= PKT_ALIAS_IGNORED
;
1381 if ( (ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0 )
1386 iresult
= IcmpAliasIn(pip
);
1389 iresult
= UdpAliasIn(pip
);
1392 iresult
= TcpAliasIn(pip
);
1395 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
||
1396 AliasHandlePptpGreIn(pip
) == 0)
1397 iresult
= PKT_ALIAS_OK
;
1399 iresult
= ProtoAliasIn(pip
);
1402 iresult
= ProtoAliasIn(pip
);
1406 if (ntohs(pip
->ip_off
) & IP_MF
)
1408 struct alias_link
*link
;
1410 link
= FindFragmentIn1(pip
->ip_src
, alias_addr
, pip
->ip_id
);
1413 iresult
= PKT_ALIAS_FOUND_HEADER_FRAGMENT
;
1414 SetFragmentAddr(link
, pip
->ip_dst
);
1418 iresult
= PKT_ALIAS_ERROR
;
1424 iresult
= FragmentIn(pip
);
1432 /* Unregistered address ranges */
1434 /* 10.0.0.0 -> 10.255.255.255 */
1435 #define UNREG_ADDR_A_LOWER 0x0a000000
1436 #define UNREG_ADDR_A_UPPER 0x0affffff
1438 /* 172.16.0.0 -> 172.31.255.255 */
1439 #define UNREG_ADDR_B_LOWER 0xac100000
1440 #define UNREG_ADDR_B_UPPER 0xac1fffff
1442 /* 192.168.0.0 -> 192.168.255.255 */
1443 #define UNREG_ADDR_C_LOWER 0xc0a80000
1444 #define UNREG_ADDR_C_UPPER 0xc0a8ffff
1447 PacketAliasOut(char *ptr
, /* valid IP packet */
1448 int maxpacketsize
/* How much the packet data may grow
1449 (FTP and IRC inline changes) */
1453 struct in_addr addr_save
;
1456 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1457 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1458 iresult
= PacketAliasIn(ptr
, maxpacketsize
);
1459 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1464 ClearCheckNewLink();
1465 pip
= (struct ip
*) ptr
;
1467 /* Defense against mangled packets */
1468 if (ntohs(pip
->ip_len
) > maxpacketsize
1469 || (pip
->ip_hl
<<2) > maxpacketsize
)
1470 return PKT_ALIAS_IGNORED
;
1472 addr_save
= GetDefaultAliasAddress();
1473 if (packetAliasMode
& PKT_ALIAS_UNREGISTERED_ONLY
)
1479 addr
= ntohl(pip
->ip_src
.s_addr
);
1480 if (addr
>= UNREG_ADDR_C_LOWER
&& addr
<= UNREG_ADDR_C_UPPER
)
1482 else if (addr
>= UNREG_ADDR_B_LOWER
&& addr
<= UNREG_ADDR_B_UPPER
)
1484 else if (addr
>= UNREG_ADDR_A_LOWER
&& addr
<= UNREG_ADDR_A_UPPER
)
1489 SetDefaultAliasAddress(pip
->ip_src
);
1493 iresult
= PKT_ALIAS_IGNORED
;
1494 if ((ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0)
1499 iresult
= IcmpAliasOut(pip
);
1502 iresult
= UdpAliasOut(pip
);
1505 iresult
= TcpAliasOut(pip
, maxpacketsize
);
1508 if (AliasHandlePptpGreOut(pip
) == 0)
1509 iresult
= PKT_ALIAS_OK
;
1511 iresult
= ProtoAliasOut(pip
);
1514 iresult
= ProtoAliasOut(pip
);
1520 iresult
= FragmentOut(pip
);
1523 SetDefaultAliasAddress(addr_save
);
1528 PacketUnaliasOut(char *ptr
, /* valid IP packet */
1529 int maxpacketsize
/* for error checking */
1536 struct alias_link
*link
;
1537 int iresult
= PKT_ALIAS_IGNORED
;
1539 pip
= (struct ip
*) ptr
;
1541 /* Defense against mangled packets */
1542 if (ntohs(pip
->ip_len
) > maxpacketsize
1543 || (pip
->ip_hl
<<2) > maxpacketsize
)
1546 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1547 tc
= (struct tcphdr
*) ud
;
1548 ic
= (struct icmp
*) ud
;
1551 if (pip
->ip_p
== IPPROTO_UDP
)
1552 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1553 ud
->uh_dport
, ud
->uh_sport
,
1555 else if (pip
->ip_p
== IPPROTO_TCP
)
1556 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1557 tc
->th_dport
, tc
->th_sport
,
1559 else if (pip
->ip_p
== IPPROTO_ICMP
)
1560 link
= FindIcmpIn(pip
->ip_dst
, pip
->ip_src
, ic
->icmp_id
, 0);
1564 /* Change it from an aliased packet to an unaliased packet */
1567 if (pip
->ip_p
== IPPROTO_UDP
|| pip
->ip_p
== IPPROTO_TCP
)
1571 struct in_addr original_address
;
1572 u_short original_port
;
1574 original_address
= GetOriginalAddress(link
);
1575 original_port
= GetOriginalPort(link
);
1577 /* Adjust TCP/UDP checksum */
1578 sptr
= (u_short
*) &(pip
->ip_src
);
1579 accumulate
= *sptr
++;
1580 accumulate
+= *sptr
;
1581 sptr
= (u_short
*) &original_address
;
1582 accumulate
-= *sptr
++;
1583 accumulate
-= *sptr
;
1585 if (pip
->ip_p
== IPPROTO_UDP
) {
1586 accumulate
+= ud
->uh_sport
;
1587 accumulate
-= original_port
;
1588 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
1590 accumulate
+= tc
->th_sport
;
1591 accumulate
-= original_port
;
1592 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1595 /* Adjust IP checksum */
1596 DifferentialChecksum(&pip
->ip_sum
,
1597 (u_short
*) &original_address
,
1598 (u_short
*) &pip
->ip_src
,
1601 /* Un-alias source address and port number */
1602 pip
->ip_src
= original_address
;
1603 if (pip
->ip_p
== IPPROTO_UDP
)
1604 ud
->uh_sport
= original_port
;
1606 tc
->th_sport
= original_port
;
1608 iresult
= PKT_ALIAS_OK
;
1610 } else if (pip
->ip_p
== IPPROTO_ICMP
) {
1614 struct in_addr original_address
;
1615 u_short original_id
;
1617 original_address
= GetOriginalAddress(link
);
1618 original_id
= GetOriginalPort(link
);
1620 /* Adjust ICMP checksum */
1621 sptr
= (u_short
*) &(pip
->ip_src
);
1622 accumulate
= *sptr
++;
1623 accumulate
+= *sptr
;
1624 sptr
= (u_short
*) &original_address
;
1625 accumulate
-= *sptr
++;
1626 accumulate
-= *sptr
;
1627 accumulate
+= ic
->icmp_id
;
1628 accumulate
-= original_id
;
1629 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
1631 /* Adjust IP checksum */
1632 DifferentialChecksum(&pip
->ip_sum
,
1633 (u_short
*) &original_address
,
1634 (u_short
*) &pip
->ip_src
,
1637 /* Un-alias source address and port number */
1638 pip
->ip_src
= original_address
;
1639 ic
->icmp_id
= original_id
;
1641 iresult
= PKT_ALIAS_OK
;