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 These routines look for SYN, FIN and RST flags to determine when TCP
168 connections open and close. When a TCP connection closes, the data
169 structure containing packet aliasing information is deleted after
173 /* Local prototypes */
174 static void TcpMonitorIn(struct ip
*, struct alias_link
*);
176 static void TcpMonitorOut(struct ip
*, struct alias_link
*);
180 TcpMonitorIn(struct ip
*pip
, struct alias_link
*link
)
184 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
186 switch (GetStateIn(link
))
188 case ALIAS_TCP_STATE_NOT_CONNECTED
:
189 if (tc
->th_flags
& TH_RST
)
190 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
191 else if (tc
->th_flags
& TH_SYN
)
192 SetStateIn(link
, ALIAS_TCP_STATE_CONNECTED
);
194 case ALIAS_TCP_STATE_CONNECTED
:
195 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
196 SetStateIn(link
, ALIAS_TCP_STATE_DISCONNECTED
);
202 TcpMonitorOut(struct ip
*pip
, struct alias_link
*link
)
206 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
208 switch (GetStateOut(link
))
210 case ALIAS_TCP_STATE_NOT_CONNECTED
:
211 if (tc
->th_flags
& TH_RST
)
212 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
213 else if (tc
->th_flags
& TH_SYN
)
214 SetStateOut(link
, ALIAS_TCP_STATE_CONNECTED
);
216 case ALIAS_TCP_STATE_CONNECTED
:
217 if (tc
->th_flags
& (TH_FIN
| TH_RST
))
218 SetStateOut(link
, ALIAS_TCP_STATE_DISCONNECTED
);
227 /* Protocol Specific Packet Aliasing Routines
229 IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2()
230 IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2()
231 ProtoAliasIn(), ProtoAliasOut()
232 UdpAliasIn(), UdpAliasOut()
233 TcpAliasIn(), TcpAliasOut()
235 These routines handle protocol specific details of packet aliasing.
236 One may observe a certain amount of repetitive arithmetic in these
237 functions, the purpose of which is to compute a revised checksum
238 without actually summing over the entire data packet, which could be
239 unnecessarily time consuming.
241 The purpose of the packet aliasing routines is to replace the source
242 address of the outgoing packet and then correctly put it back for
243 any incoming packets. For TCP and UDP, ports are also re-mapped.
245 For ICMP echo/timestamp requests and replies, the following scheme
246 is used: the ID number is replaced by an alias for the outgoing
249 ICMP error messages are handled by looking at the IP fragment
250 in the data section of the message.
252 For TCP and UDP protocols, a port number is chosen for an outgoing
253 packet, and then incoming packets are identified by IP address and
254 port numbers. For TCP packets, there is additional logic in the event
255 that sequence and ACK numbers have been altered (as in the case for
256 FTP data port commands).
258 The port numbers used by the packet aliasing module are not true
259 ports in the Unix sense. No sockets are actually bound to ports.
260 They are more correctly thought of as placeholders.
262 All packets go through the aliasing mechanism, whether they come from
263 the gateway machine or other machines on a local area network.
267 /* Local prototypes */
268 static int IcmpAliasIn1(struct ip
*);
269 static int IcmpAliasIn2(struct ip
*);
270 static int IcmpAliasIn (struct ip
*);
272 static int IcmpAliasOut1(struct ip
*);
273 static int IcmpAliasOut2(struct ip
*);
274 static int IcmpAliasOut (struct ip
*);
276 static int ProtoAliasIn(struct ip
*);
277 static int ProtoAliasOut(struct ip
*);
279 static int UdpAliasOut(struct ip
*);
280 static int UdpAliasIn (struct ip
*);
282 static int TcpAliasOut(struct ip
*, int);
283 static int TcpAliasIn (struct ip
*);
287 IcmpAliasIn1(struct ip
*pip
)
290 De-alias incoming echo and timestamp replies.
291 Alias incoming echo and timestamp requests.
293 struct alias_link
*link
;
296 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
298 /* Get source address from ICMP data field and restore original data */
299 link
= FindIcmpIn(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
305 original_id
= GetOriginalPort(link
);
307 /* Adjust ICMP checksum */
308 accumulate
= ic
->icmp_id
;
309 accumulate
-= original_id
;
310 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
312 /* Put original sequence number back in */
313 ic
->icmp_id
= original_id
;
315 /* Put original address back into IP header */
317 struct in_addr original_address
;
319 original_address
= GetOriginalAddress(link
);
320 DifferentialChecksum(&pip
->ip_sum
,
321 (u_short
*) &original_address
,
322 (u_short
*) &pip
->ip_dst
,
324 pip
->ip_dst
= original_address
;
327 return(PKT_ALIAS_OK
);
329 return(PKT_ALIAS_IGNORED
);
333 IcmpAliasIn2(struct ip
*pip
)
336 Alias incoming ICMP error messages containing
337 IP header and first 64 bits of datagram.
340 struct icmp
*ic
, *ic2
;
343 struct alias_link
*link
;
345 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
348 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
349 tc
= (struct tcphdr
*) ud
;
350 ic2
= (struct icmp
*) ud
;
352 if (ip
->ip_p
== IPPROTO_UDP
)
353 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
354 ud
->uh_dport
, ud
->uh_sport
,
356 else if (ip
->ip_p
== IPPROTO_TCP
)
357 link
= FindUdpTcpIn(ip
->ip_dst
, ip
->ip_src
,
358 tc
->th_dport
, tc
->th_sport
,
360 else if (ip
->ip_p
== IPPROTO_ICMP
) {
361 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
362 link
= FindIcmpIn(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
370 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
374 struct in_addr original_address
;
375 u_short original_port
;
377 original_address
= GetOriginalAddress(link
);
378 original_port
= GetOriginalPort(link
);
380 /* Adjust ICMP checksum */
381 sptr
= (u_short
*) &(ip
->ip_src
);
382 accumulate
= *sptr
++;
384 sptr
= (u_short
*) &original_address
;
385 accumulate
-= *sptr
++;
387 accumulate
+= ud
->uh_sport
;
388 accumulate
-= original_port
;
389 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
391 /* Un-alias address in IP header */
392 DifferentialChecksum(&pip
->ip_sum
,
393 (u_short
*) &original_address
,
394 (u_short
*) &pip
->ip_dst
,
396 pip
->ip_dst
= original_address
;
398 /* Un-alias address and port number of original IP packet
399 fragment contained in ICMP data section */
400 ip
->ip_src
= original_address
;
401 ud
->uh_sport
= original_port
;
403 else if (ip
->ip_p
== IPPROTO_ICMP
)
407 struct in_addr original_address
;
410 original_address
= GetOriginalAddress(link
);
411 original_id
= GetOriginalPort(link
);
413 /* Adjust ICMP checksum */
414 sptr
= (u_short
*) &(ip
->ip_src
);
415 accumulate
= *sptr
++;
417 sptr
= (u_short
*) &original_address
;
418 accumulate
-= *sptr
++;
420 accumulate
+= ic2
->icmp_id
;
421 accumulate
-= original_id
;
422 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
424 /* Un-alias address in IP header */
425 DifferentialChecksum(&pip
->ip_sum
,
426 (u_short
*) &original_address
,
427 (u_short
*) &pip
->ip_dst
,
429 pip
->ip_dst
= original_address
;
431 /* Un-alias address of original IP packet and sequence number of
432 embedded ICMP datagram */
433 ip
->ip_src
= original_address
;
434 ic2
->icmp_id
= original_id
;
436 return(PKT_ALIAS_OK
);
438 return(PKT_ALIAS_IGNORED
);
443 IcmpAliasIn(struct ip
*pip
)
448 /* Return if proxy-only mode is enabled */
449 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
452 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
454 iresult
= PKT_ALIAS_IGNORED
;
455 switch (ic
->icmp_type
)
458 case ICMP_TSTAMPREPLY
:
459 if (ic
->icmp_code
== 0)
461 iresult
= IcmpAliasIn1(pip
);
465 case ICMP_SOURCEQUENCH
:
468 iresult
= IcmpAliasIn2(pip
);
472 iresult
= IcmpAliasIn1(pip
);
480 IcmpAliasOut1(struct ip
*pip
)
483 Alias outgoing echo and timestamp requests.
484 De-alias outgoing echo and timestamp replies.
486 struct alias_link
*link
;
489 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
491 /* Save overwritten data for when echo packet returns */
492 link
= FindIcmpOut(pip
->ip_src
, pip
->ip_dst
, ic
->icmp_id
, 1);
498 alias_id
= GetAliasPort(link
);
500 /* Since data field is being modified, adjust ICMP checksum */
501 accumulate
= ic
->icmp_id
;
502 accumulate
-= alias_id
;
503 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
505 /* Alias sequence number */
506 ic
->icmp_id
= alias_id
;
508 /* Change source address */
510 struct in_addr alias_address
;
512 alias_address
= GetAliasAddress(link
);
513 DifferentialChecksum(&pip
->ip_sum
,
514 (u_short
*) &alias_address
,
515 (u_short
*) &pip
->ip_src
,
517 pip
->ip_src
= alias_address
;
520 return(PKT_ALIAS_OK
);
522 return(PKT_ALIAS_IGNORED
);
527 IcmpAliasOut2(struct ip
*pip
)
530 Alias outgoing ICMP error messages containing
531 IP header and first 64 bits of datagram.
534 struct icmp
*ic
, *ic2
;
537 struct alias_link
*link
;
539 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
542 ud
= (struct udphdr
*) ((char *) ip
+ (ip
->ip_hl
<<2));
543 tc
= (struct tcphdr
*) ud
;
544 ic2
= (struct icmp
*) ud
;
546 if (ip
->ip_p
== IPPROTO_UDP
)
547 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
548 ud
->uh_dport
, ud
->uh_sport
,
550 else if (ip
->ip_p
== IPPROTO_TCP
)
551 link
= FindUdpTcpOut(ip
->ip_dst
, ip
->ip_src
,
552 tc
->th_dport
, tc
->th_sport
,
554 else if (ip
->ip_p
== IPPROTO_ICMP
) {
555 if (ic2
->icmp_type
== ICMP_ECHO
|| ic2
->icmp_type
== ICMP_TSTAMP
)
556 link
= FindIcmpOut(ip
->ip_dst
, ip
->ip_src
, ic2
->icmp_id
, 0);
564 if (ip
->ip_p
== IPPROTO_UDP
|| ip
->ip_p
== IPPROTO_TCP
)
568 struct in_addr alias_address
;
571 alias_address
= GetAliasAddress(link
);
572 alias_port
= GetAliasPort(link
);
574 /* Adjust ICMP checksum */
575 sptr
= (u_short
*) &(ip
->ip_dst
);
576 accumulate
= *sptr
++;
578 sptr
= (u_short
*) &alias_address
;
579 accumulate
-= *sptr
++;
581 accumulate
+= ud
->uh_dport
;
582 accumulate
-= alias_port
;
583 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
586 * Alias address in IP header if it comes from the host
587 * the original TCP/UDP packet was destined for.
589 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
590 DifferentialChecksum(&pip
->ip_sum
,
591 (u_short
*) &alias_address
,
592 (u_short
*) &pip
->ip_src
,
594 pip
->ip_src
= alias_address
;
597 /* Alias address and port number of original IP packet
598 fragment contained in ICMP data section */
599 ip
->ip_dst
= alias_address
;
600 ud
->uh_dport
= alias_port
;
602 else if (ip
->ip_p
== IPPROTO_ICMP
)
606 struct in_addr alias_address
;
609 alias_address
= GetAliasAddress(link
);
610 alias_id
= GetAliasPort(link
);
612 /* Adjust ICMP checksum */
613 sptr
= (u_short
*) &(ip
->ip_dst
);
614 accumulate
= *sptr
++;
616 sptr
= (u_short
*) &alias_address
;
617 accumulate
-= *sptr
++;
619 accumulate
+= ic2
->icmp_id
;
620 accumulate
-= alias_id
;
621 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
624 * Alias address in IP header if it comes from the host
625 * the original ICMP message was destined for.
627 if (pip
->ip_src
.s_addr
== ip
->ip_dst
.s_addr
) {
628 DifferentialChecksum(&pip
->ip_sum
,
629 (u_short
*) &alias_address
,
630 (u_short
*) &pip
->ip_src
,
632 pip
->ip_src
= alias_address
;
635 /* Alias address of original IP packet and sequence number of
636 embedded ICMP datagram */
637 ip
->ip_dst
= alias_address
;
638 ic2
->icmp_id
= alias_id
;
640 return(PKT_ALIAS_OK
);
642 return(PKT_ALIAS_IGNORED
);
647 IcmpAliasOut(struct ip
*pip
)
652 /* Return if proxy-only mode is enabled */
653 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
656 ic
= (struct icmp
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
658 iresult
= PKT_ALIAS_IGNORED
;
659 switch (ic
->icmp_type
)
663 if (ic
->icmp_code
== 0)
665 iresult
= IcmpAliasOut1(pip
);
669 case ICMP_SOURCEQUENCH
:
672 iresult
= IcmpAliasOut2(pip
);
675 case ICMP_TSTAMPREPLY
:
676 iresult
= IcmpAliasOut1(pip
);
684 ProtoAliasIn(struct ip
*pip
)
687 Handle incoming IP packets. The
688 only thing which is done in this case is to alias
689 the dest IP address of the packet to our inside
692 struct alias_link
*link
;
694 /* Return if proxy-only mode is enabled */
695 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
698 link
= FindProtoIn(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
701 struct in_addr original_address
;
703 original_address
= GetOriginalAddress(link
);
705 /* Restore original IP address */
706 DifferentialChecksum(&pip
->ip_sum
,
707 (u_short
*) &original_address
,
708 (u_short
*) &pip
->ip_dst
,
710 pip
->ip_dst
= original_address
;
712 return(PKT_ALIAS_OK
);
714 return(PKT_ALIAS_IGNORED
);
719 ProtoAliasOut(struct ip
*pip
)
722 Handle outgoing IP packets. The
723 only thing which is done in this case is to alias
724 the source IP address of the packet.
726 struct alias_link
*link
;
728 /* Return if proxy-only mode is enabled */
729 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
732 link
= FindProtoOut(pip
->ip_src
, pip
->ip_dst
, pip
->ip_p
);
735 struct in_addr alias_address
;
737 alias_address
= GetAliasAddress(link
);
739 /* Change source address */
740 DifferentialChecksum(&pip
->ip_sum
,
741 (u_short
*) &alias_address
,
742 (u_short
*) &pip
->ip_src
,
744 pip
->ip_src
= alias_address
;
746 return(PKT_ALIAS_OK
);
748 return(PKT_ALIAS_IGNORED
);
753 UdpAliasIn(struct ip
*pip
)
756 struct alias_link
*link
;
758 /* Return if proxy-only mode is enabled */
759 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
762 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
764 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
765 ud
->uh_sport
, ud
->uh_dport
,
769 struct in_addr alias_address
;
770 struct in_addr original_address
;
776 alias_address
= GetAliasAddress(link
);
777 original_address
= GetOriginalAddress(link
);
778 alias_port
= ud
->uh_dport
;
779 ud
->uh_dport
= GetOriginalPort(link
);
781 /* Special processing for IP encoding protocols */
782 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
783 AliasHandleCUSeeMeIn(pip
, original_address
);
784 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
785 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
786 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
787 r
= AliasHandleUdpNbt(pip
, link
, &original_address
, ud
->uh_dport
);
788 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
789 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
790 r
= AliasHandleUdpNbtNS(pip
, link
, &alias_address
, &alias_port
,
791 &original_address
, &ud
->uh_dport
);
793 /* If UDP checksum is not zero, then adjust since destination port */
794 /* is being unaliased and destination address is being altered. */
797 accumulate
= alias_port
;
798 accumulate
-= ud
->uh_dport
;
799 sptr
= (u_short
*) &alias_address
;
800 accumulate
+= *sptr
++;
802 sptr
= (u_short
*) &original_address
;
803 accumulate
-= *sptr
++;
805 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
808 /* Restore original IP address */
809 DifferentialChecksum(&pip
->ip_sum
,
810 (u_short
*) &original_address
,
811 (u_short
*) &pip
->ip_dst
,
813 pip
->ip_dst
= original_address
;
816 * If we cannot figure out the packet, ignore it.
819 return(PKT_ALIAS_IGNORED
);
821 return(PKT_ALIAS_OK
);
823 return(PKT_ALIAS_IGNORED
);
827 UdpAliasOut(struct ip
*pip
)
830 struct alias_link
*link
;
832 /* Return if proxy-only mode is enabled */
833 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
)
836 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
838 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
839 ud
->uh_sport
, ud
->uh_dport
,
844 struct in_addr alias_address
;
846 alias_address
= GetAliasAddress(link
);
847 alias_port
= GetAliasPort(link
);
849 /* Special processing for IP encoding protocols */
850 if (ntohs(ud
->uh_dport
) == CUSEEME_PORT_NUMBER
)
851 AliasHandleCUSeeMeOut(pip
, link
);
852 /* If NETBIOS Datagram, It should be alias address in UDP Data, too */
853 else if (ntohs(ud
->uh_dport
) == NETBIOS_DGM_PORT_NUMBER
854 || ntohs(ud
->uh_sport
) == NETBIOS_DGM_PORT_NUMBER
)
855 AliasHandleUdpNbt(pip
, link
, &alias_address
, alias_port
);
856 else if (ntohs(ud
->uh_dport
) == NETBIOS_NS_PORT_NUMBER
857 || ntohs(ud
->uh_sport
) == NETBIOS_NS_PORT_NUMBER
)
858 AliasHandleUdpNbtNS(pip
, link
, &pip
->ip_src
, &ud
->uh_sport
,
859 &alias_address
, &alias_port
);
861 /* If UDP checksum is not zero, adjust since source port is */
862 /* being aliased and source address is being altered */
868 accumulate
= ud
->uh_sport
;
869 accumulate
-= alias_port
;
870 sptr
= (u_short
*) &(pip
->ip_src
);
871 accumulate
+= *sptr
++;
873 sptr
= (u_short
*) &alias_address
;
874 accumulate
-= *sptr
++;
876 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
879 /* Put alias port in UDP header */
880 ud
->uh_sport
= alias_port
;
882 /* Change source address */
883 DifferentialChecksum(&pip
->ip_sum
,
884 (u_short
*) &alias_address
,
885 (u_short
*) &pip
->ip_src
,
887 pip
->ip_src
= alias_address
;
889 return(PKT_ALIAS_OK
);
891 return(PKT_ALIAS_IGNORED
);
897 TcpAliasIn(struct ip
*pip
)
900 struct alias_link
*link
;
902 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
904 link
= FindUdpTcpIn(pip
->ip_src
, pip
->ip_dst
,
905 tc
->th_sport
, tc
->th_dport
,
907 !(packetAliasMode
& PKT_ALIAS_PROXY_ONLY
));
910 struct in_addr alias_address
;
911 struct in_addr original_address
;
912 struct in_addr proxy_address
;
918 /* Special processing for IP encoding protocols */
919 if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
920 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
921 AliasHandlePptpIn(pip
, link
);
923 alias_address
= GetAliasAddress(link
);
924 original_address
= GetOriginalAddress(link
);
925 proxy_address
= GetProxyAddress(link
);
926 alias_port
= tc
->th_dport
;
927 tc
->th_dport
= GetOriginalPort(link
);
928 proxy_port
= GetProxyPort(link
);
930 /* Adjust TCP checksum since destination port is being unaliased */
931 /* and destination port is being altered. */
932 accumulate
= alias_port
;
933 accumulate
-= tc
->th_dport
;
934 sptr
= (u_short
*) &alias_address
;
935 accumulate
+= *sptr
++;
937 sptr
= (u_short
*) &original_address
;
938 accumulate
-= *sptr
++;
941 /* If this is a proxy, then modify the TCP source port and
942 checksum accumulation */
945 accumulate
+= tc
->th_sport
;
946 tc
->th_sport
= proxy_port
;
947 accumulate
-= tc
->th_sport
;
949 sptr
= (u_short
*) &pip
->ip_src
;
950 accumulate
+= *sptr
++;
952 sptr
= (u_short
*) &proxy_address
;
953 accumulate
-= *sptr
++;
957 /* See if ACK number needs to be modified */
958 if (GetAckModified(link
) == 1)
962 delta
= GetDeltaAckIn(pip
, link
);
965 sptr
= (u_short
*) &tc
->th_ack
;
966 accumulate
+= *sptr
++;
968 tc
->th_ack
= htonl(ntohl(tc
->th_ack
) - delta
);
969 sptr
= (u_short
*) &tc
->th_ack
;
970 accumulate
-= *sptr
++;
975 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
977 /* Restore original IP address */
978 sptr
= (u_short
*) &pip
->ip_dst
;
979 accumulate
= *sptr
++;
981 pip
->ip_dst
= original_address
;
982 sptr
= (u_short
*) &pip
->ip_dst
;
983 accumulate
-= *sptr
++;
986 /* If this is a transparent proxy packet, then modify the source
988 if (proxy_address
.s_addr
!= 0)
990 sptr
= (u_short
*) &pip
->ip_src
;
991 accumulate
+= *sptr
++;
993 pip
->ip_src
= proxy_address
;
994 sptr
= (u_short
*) &pip
->ip_src
;
995 accumulate
-= *sptr
++;
999 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1001 /* Monitor TCP connection state */
1002 TcpMonitorIn(pip
, link
);
1004 return(PKT_ALIAS_OK
);
1006 return(PKT_ALIAS_IGNORED
);
1010 TcpAliasOut(struct ip
*pip
, int maxpacketsize
)
1014 u_short proxy_server_port
;
1015 struct in_addr dest_address
;
1016 struct in_addr proxy_server_address
;
1018 struct alias_link
*link
;
1020 tc
= (struct tcphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1022 proxy_type
= ProxyCheck(pip
, &proxy_server_address
, &proxy_server_port
);
1024 if (proxy_type
== 0 && (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
))
1025 return PKT_ALIAS_OK
;
1027 /* If this is a transparent proxy, save original destination,
1028 then alter the destination and adjust checksums */
1029 dest_port
= tc
->th_dport
;
1030 dest_address
= pip
->ip_dst
;
1031 if (proxy_type
!= 0)
1036 accumulate
= tc
->th_dport
;
1037 tc
->th_dport
= proxy_server_port
;
1038 accumulate
-= tc
->th_dport
;
1040 sptr
= (u_short
*) &(pip
->ip_dst
);
1041 accumulate
+= *sptr
++;
1042 accumulate
+= *sptr
;
1043 sptr
= (u_short
*) &proxy_server_address
;
1044 accumulate
-= *sptr
++;
1045 accumulate
-= *sptr
;
1047 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1049 sptr
= (u_short
*) &(pip
->ip_dst
);
1050 accumulate
= *sptr
++;
1051 accumulate
+= *sptr
;
1052 pip
->ip_dst
= proxy_server_address
;
1053 sptr
= (u_short
*) &(pip
->ip_dst
);
1054 accumulate
-= *sptr
++;
1055 accumulate
-= *sptr
;
1057 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1060 link
= FindUdpTcpOut(pip
->ip_src
, pip
->ip_dst
,
1061 tc
->th_sport
, tc
->th_dport
,
1066 struct in_addr alias_address
;
1070 /* Save original destination address, if this is a proxy packet.
1071 Also modify packet to include destination encoding. */
1072 if (proxy_type
!= 0)
1074 SetProxyPort(link
, dest_port
);
1075 SetProxyAddress(link
, dest_address
);
1076 ProxyModify(link
, pip
, maxpacketsize
, proxy_type
);
1079 /* Get alias address and port */
1080 alias_port
= GetAliasPort(link
);
1081 alias_address
= GetAliasAddress(link
);
1083 /* Monitor TCP connection state */
1084 TcpMonitorOut(pip
, link
);
1086 /* Special processing for IP encoding protocols */
1087 if (ntohs(tc
->th_dport
) == FTP_CONTROL_PORT_NUMBER
1088 || ntohs(tc
->th_sport
) == FTP_CONTROL_PORT_NUMBER
)
1089 AliasHandleFtpOut(pip
, link
, maxpacketsize
);
1090 else if (ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_1
1091 || ntohs(tc
->th_dport
) == IRC_CONTROL_PORT_NUMBER_2
)
1092 AliasHandleIrcOut(pip
, link
, maxpacketsize
);
1093 else if (ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_1
1094 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_1
1095 || ntohs(tc
->th_dport
) == RTSP_CONTROL_PORT_NUMBER_2
1096 || ntohs(tc
->th_sport
) == RTSP_CONTROL_PORT_NUMBER_2
)
1097 AliasHandleRtspOut(pip
, link
, maxpacketsize
);
1098 else if (ntohs(tc
->th_dport
) == PPTP_CONTROL_PORT_NUMBER
1099 || ntohs(tc
->th_sport
) == PPTP_CONTROL_PORT_NUMBER
)
1100 AliasHandlePptpOut(pip
, link
);
1102 /* Adjust TCP checksum since source port is being aliased */
1103 /* and source address is being altered */
1104 accumulate
= tc
->th_sport
;
1105 tc
->th_sport
= alias_port
;
1106 accumulate
-= tc
->th_sport
;
1108 sptr
= (u_short
*) &(pip
->ip_src
);
1109 accumulate
+= *sptr
++;
1110 accumulate
+= *sptr
;
1111 sptr
= (u_short
*) &alias_address
;
1112 accumulate
-= *sptr
++;
1113 accumulate
-= *sptr
;
1115 /* Modify sequence number if necessary */
1116 if (GetAckModified(link
) == 1)
1120 delta
= GetDeltaSeqOut(pip
, link
);
1123 sptr
= (u_short
*) &tc
->th_seq
;
1124 accumulate
+= *sptr
++;
1125 accumulate
+= *sptr
;
1126 tc
->th_seq
= htonl(ntohl(tc
->th_seq
) + delta
);
1127 sptr
= (u_short
*) &tc
->th_seq
;
1128 accumulate
-= *sptr
++;
1129 accumulate
-= *sptr
;
1133 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1135 /* Change source address */
1136 sptr
= (u_short
*) &(pip
->ip_src
);
1137 accumulate
= *sptr
++;
1138 accumulate
+= *sptr
;
1139 pip
->ip_src
= alias_address
;
1140 sptr
= (u_short
*) &(pip
->ip_src
);
1141 accumulate
-= *sptr
++;
1142 accumulate
-= *sptr
;
1144 ADJUST_CHECKSUM(accumulate
, pip
->ip_sum
);
1146 return(PKT_ALIAS_OK
);
1148 return(PKT_ALIAS_IGNORED
);
1154 /* Fragment Handling
1159 The packet aliasing module has a limited ability for handling IP
1160 fragments. If the ICMP, TCP or UDP header is in the first fragment
1161 received, then the ID number of the IP packet is saved, and other
1162 fragments are identified according to their ID number and IP address
1163 they were sent from. Pointers to unresolved fragments can also be
1164 saved and recalled when a header fragment is seen.
1167 /* Local prototypes */
1168 static int FragmentIn(struct ip
*);
1169 static int FragmentOut(struct ip
*);
1173 FragmentIn(struct ip
*pip
)
1175 struct alias_link
*link
;
1177 link
= FindFragmentIn2(pip
->ip_src
, pip
->ip_dst
, pip
->ip_id
);
1180 struct in_addr original_address
;
1182 GetFragmentAddr(link
, &original_address
);
1183 DifferentialChecksum(&pip
->ip_sum
,
1184 (u_short
*) &original_address
,
1185 (u_short
*) &pip
->ip_dst
,
1187 pip
->ip_dst
= original_address
;
1189 return(PKT_ALIAS_OK
);
1191 return(PKT_ALIAS_UNRESOLVED_FRAGMENT
);
1196 FragmentOut(struct ip
*pip
)
1198 struct in_addr alias_address
;
1200 alias_address
= FindAliasAddress(pip
->ip_src
);
1201 DifferentialChecksum(&pip
->ip_sum
,
1202 (u_short
*) &alias_address
,
1203 (u_short
*) &pip
->ip_src
,
1205 pip
->ip_src
= alias_address
;
1207 return(PKT_ALIAS_OK
);
1215 /* Outside World Access
1217 PacketAliasSaveFragment()
1218 PacketAliasGetFragment()
1219 PacketAliasFragmentIn()
1224 (prototypes in alias.h)
1229 PacketAliasSaveFragment(char *ptr
)
1232 struct alias_link
*link
;
1235 pip
= (struct ip
*) ptr
;
1236 link
= AddFragmentPtrLink(pip
->ip_src
, pip
->ip_id
);
1237 iresult
= PKT_ALIAS_ERROR
;
1240 SetFragmentPtr(link
, ptr
);
1241 iresult
= PKT_ALIAS_OK
;
1248 PacketAliasGetFragment(char *ptr
)
1250 struct alias_link
*link
;
1254 pip
= (struct ip
*) ptr
;
1255 link
= FindFragmentPtr(pip
->ip_src
, pip
->ip_id
);
1258 GetFragmentPtr(link
, &fptr
);
1259 SetFragmentPtr(link
, NULL
);
1260 SetExpire(link
, 0); /* Deletes link */
1272 PacketAliasFragmentIn(char *ptr
, /* Points to correctly de-aliased
1274 char *ptr_fragment
/* Points to fragment which must
1281 pip
= (struct ip
*) ptr
;
1282 fpip
= (struct ip
*) ptr_fragment
;
1284 DifferentialChecksum(&fpip
->ip_sum
,
1285 (u_short
*) &pip
->ip_dst
,
1286 (u_short
*) &fpip
->ip_dst
,
1288 fpip
->ip_dst
= pip
->ip_dst
;
1293 PacketAliasIn(char *ptr
, int maxpacketsize
)
1295 struct in_addr alias_addr
;
1299 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1300 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1301 iresult
= PacketAliasOut(ptr
, maxpacketsize
);
1302 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1307 ClearCheckNewLink();
1308 pip
= (struct ip
*) ptr
;
1309 alias_addr
= pip
->ip_dst
;
1311 /* Defense against mangled packets */
1312 if (ntohs(pip
->ip_len
) > maxpacketsize
1313 || (pip
->ip_hl
<<2) > maxpacketsize
)
1314 return PKT_ALIAS_IGNORED
;
1316 iresult
= PKT_ALIAS_IGNORED
;
1317 if ( (ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0 )
1322 iresult
= IcmpAliasIn(pip
);
1325 iresult
= UdpAliasIn(pip
);
1328 iresult
= TcpAliasIn(pip
);
1331 if (packetAliasMode
& PKT_ALIAS_PROXY_ONLY
||
1332 AliasHandlePptpGreIn(pip
) == 0)
1333 iresult
= PKT_ALIAS_OK
;
1335 iresult
= ProtoAliasIn(pip
);
1338 iresult
= ProtoAliasIn(pip
);
1342 if (ntohs(pip
->ip_off
) & IP_MF
)
1344 struct alias_link
*link
;
1346 link
= FindFragmentIn1(pip
->ip_src
, alias_addr
, pip
->ip_id
);
1349 iresult
= PKT_ALIAS_FOUND_HEADER_FRAGMENT
;
1350 SetFragmentAddr(link
, pip
->ip_dst
);
1354 iresult
= PKT_ALIAS_ERROR
;
1360 iresult
= FragmentIn(pip
);
1368 /* Unregistered address ranges */
1370 /* 10.0.0.0 -> 10.255.255.255 */
1371 #define UNREG_ADDR_A_LOWER 0x0a000000
1372 #define UNREG_ADDR_A_UPPER 0x0affffff
1374 /* 172.16.0.0 -> 172.31.255.255 */
1375 #define UNREG_ADDR_B_LOWER 0xac100000
1376 #define UNREG_ADDR_B_UPPER 0xac1fffff
1378 /* 192.168.0.0 -> 192.168.255.255 */
1379 #define UNREG_ADDR_C_LOWER 0xc0a80000
1380 #define UNREG_ADDR_C_UPPER 0xc0a8ffff
1383 PacketAliasOut(char *ptr
, /* valid IP packet */
1384 int maxpacketsize
/* How much the packet data may grow
1385 (FTP and IRC inline changes) */
1389 struct in_addr addr_save
;
1392 if (packetAliasMode
& PKT_ALIAS_REVERSE
) {
1393 packetAliasMode
&= ~PKT_ALIAS_REVERSE
;
1394 iresult
= PacketAliasIn(ptr
, maxpacketsize
);
1395 packetAliasMode
|= PKT_ALIAS_REVERSE
;
1400 ClearCheckNewLink();
1401 pip
= (struct ip
*) ptr
;
1403 /* Defense against mangled packets */
1404 if (ntohs(pip
->ip_len
) > maxpacketsize
1405 || (pip
->ip_hl
<<2) > maxpacketsize
)
1406 return PKT_ALIAS_IGNORED
;
1408 addr_save
= GetDefaultAliasAddress();
1409 if (packetAliasMode
& PKT_ALIAS_UNREGISTERED_ONLY
)
1415 addr
= ntohl(pip
->ip_src
.s_addr
);
1416 if (addr
>= UNREG_ADDR_C_LOWER
&& addr
<= UNREG_ADDR_C_UPPER
)
1418 else if (addr
>= UNREG_ADDR_B_LOWER
&& addr
<= UNREG_ADDR_B_UPPER
)
1420 else if (addr
>= UNREG_ADDR_A_LOWER
&& addr
<= UNREG_ADDR_A_UPPER
)
1425 SetDefaultAliasAddress(pip
->ip_src
);
1429 iresult
= PKT_ALIAS_IGNORED
;
1430 if ((ntohs(pip
->ip_off
) & IP_OFFMASK
) == 0)
1435 iresult
= IcmpAliasOut(pip
);
1438 iresult
= UdpAliasOut(pip
);
1441 iresult
= TcpAliasOut(pip
, maxpacketsize
);
1444 if (AliasHandlePptpGreOut(pip
) == 0)
1445 iresult
= PKT_ALIAS_OK
;
1447 iresult
= ProtoAliasOut(pip
);
1450 iresult
= ProtoAliasOut(pip
);
1456 iresult
= FragmentOut(pip
);
1459 SetDefaultAliasAddress(addr_save
);
1464 PacketUnaliasOut(char *ptr
, /* valid IP packet */
1465 int maxpacketsize
/* for error checking */
1472 struct alias_link
*link
;
1473 int iresult
= PKT_ALIAS_IGNORED
;
1475 pip
= (struct ip
*) ptr
;
1477 /* Defense against mangled packets */
1478 if (ntohs(pip
->ip_len
) > maxpacketsize
1479 || (pip
->ip_hl
<<2) > maxpacketsize
)
1482 ud
= (struct udphdr
*) ((char *) pip
+ (pip
->ip_hl
<< 2));
1483 tc
= (struct tcphdr
*) ud
;
1484 ic
= (struct icmp
*) ud
;
1487 if (pip
->ip_p
== IPPROTO_UDP
)
1488 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1489 ud
->uh_dport
, ud
->uh_sport
,
1491 else if (pip
->ip_p
== IPPROTO_TCP
)
1492 link
= FindUdpTcpIn(pip
->ip_dst
, pip
->ip_src
,
1493 tc
->th_dport
, tc
->th_sport
,
1495 else if (pip
->ip_p
== IPPROTO_ICMP
)
1496 link
= FindIcmpIn(pip
->ip_dst
, pip
->ip_src
, ic
->icmp_id
, 0);
1500 /* Change it from an aliased packet to an unaliased packet */
1503 if (pip
->ip_p
== IPPROTO_UDP
|| pip
->ip_p
== IPPROTO_TCP
)
1507 struct in_addr original_address
;
1508 u_short original_port
;
1510 original_address
= GetOriginalAddress(link
);
1511 original_port
= GetOriginalPort(link
);
1513 /* Adjust TCP/UDP checksum */
1514 sptr
= (u_short
*) &(pip
->ip_src
);
1515 accumulate
= *sptr
++;
1516 accumulate
+= *sptr
;
1517 sptr
= (u_short
*) &original_address
;
1518 accumulate
-= *sptr
++;
1519 accumulate
-= *sptr
;
1521 if (pip
->ip_p
== IPPROTO_UDP
) {
1522 accumulate
+= ud
->uh_sport
;
1523 accumulate
-= original_port
;
1524 ADJUST_CHECKSUM(accumulate
, ud
->uh_sum
);
1526 accumulate
+= tc
->th_sport
;
1527 accumulate
-= original_port
;
1528 ADJUST_CHECKSUM(accumulate
, tc
->th_sum
);
1531 /* Adjust IP checksum */
1532 DifferentialChecksum(&pip
->ip_sum
,
1533 (u_short
*) &original_address
,
1534 (u_short
*) &pip
->ip_src
,
1537 /* Un-alias source address and port number */
1538 pip
->ip_src
= original_address
;
1539 if (pip
->ip_p
== IPPROTO_UDP
)
1540 ud
->uh_sport
= original_port
;
1542 tc
->th_sport
= original_port
;
1544 iresult
= PKT_ALIAS_OK
;
1546 } else if (pip
->ip_p
== IPPROTO_ICMP
) {
1550 struct in_addr original_address
;
1551 u_short original_id
;
1553 original_address
= GetOriginalAddress(link
);
1554 original_id
= GetOriginalPort(link
);
1556 /* Adjust ICMP checksum */
1557 sptr
= (u_short
*) &(pip
->ip_src
);
1558 accumulate
= *sptr
++;
1559 accumulate
+= *sptr
;
1560 sptr
= (u_short
*) &original_address
;
1561 accumulate
-= *sptr
++;
1562 accumulate
-= *sptr
;
1563 accumulate
+= ic
->icmp_id
;
1564 accumulate
-= original_id
;
1565 ADJUST_CHECKSUM(accumulate
, ic
->icmp_cksum
);
1567 /* Adjust IP checksum */
1568 DifferentialChecksum(&pip
->ip_sum
,
1569 (u_short
*) &original_address
,
1570 (u_short
*) &pip
->ip_src
,
1573 /* Un-alias source address and port number */
1574 pip
->ip_src
= original_address
;
1575 ic
->icmp_id
= original_id
;
1577 iresult
= PKT_ALIAS_OK
;