Deleted Added
sdiff udiff text old ( 124621 ) new ( 127094 )
full compact
1/* -*- mode: c; tab-width: 8; c-basic-indent: 4; -*- */
2
3/*-
4 * Copyright (c) 2001 Charles Mott <cm@linktel.net>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias.c 124621 2004-01-17 10:52:21Z phk $");
31
32/*
33 Alias.c provides supervisory control for the functions of the
34 packet aliasing software. It consists of routines to monitor
35 TCP connection state, protocol-specific aliasing routines,
36 fragment handling and the following outside world functional
37 interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn,
38 PacketAliasIn and PacketAliasOut.

--- 109 unchanged lines hidden (view full) ---

148
149These routines look for SYN, FIN and RST flags to determine when TCP
150connections open and close. When a TCP connection closes, the data
151structure containing packet aliasing information is deleted after
152a timeout period.
153*/
154
155/* Local prototypes */
156static void TcpMonitorIn(struct ip *, struct alias_link *);
157
158static void TcpMonitorOut(struct ip *, struct alias_link *);
159
160
161static void
162TcpMonitorIn(struct ip *pip, struct alias_link *link)
163{
164 struct tcphdr *tc;
165
166 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
167
168 switch (GetStateIn(link))
169 {
170 case ALIAS_TCP_STATE_NOT_CONNECTED:
171 if (tc->th_flags & TH_RST)
172 SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
173 else if (tc->th_flags & TH_SYN)
174 SetStateIn(link, ALIAS_TCP_STATE_CONNECTED);
175 break;
176 case ALIAS_TCP_STATE_CONNECTED:
177 if (tc->th_flags & (TH_FIN | TH_RST))
178 SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
179 break;
180 }
181}
182
183static void
184TcpMonitorOut(struct ip *pip, struct alias_link *link)
185{
186 struct tcphdr *tc;
187
188 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
189
190 switch (GetStateOut(link))
191 {
192 case ALIAS_TCP_STATE_NOT_CONNECTED:
193 if (tc->th_flags & TH_RST)
194 SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
195 else if (tc->th_flags & TH_SYN)
196 SetStateOut(link, ALIAS_TCP_STATE_CONNECTED);
197 break;
198 case ALIAS_TCP_STATE_CONNECTED:
199 if (tc->th_flags & (TH_FIN | TH_RST))
200 SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
201 break;
202 }
203}
204
205
206
207
208
209/* Protocol Specific Packet Aliasing Routines
210

--- 31 unchanged lines hidden (view full) ---

242They are more correctly thought of as placeholders.
243
244All packets go through the aliasing mechanism, whether they come from
245the gateway machine or other machines on a local area network.
246*/
247
248
249/* Local prototypes */
250static int IcmpAliasIn1(struct libalias *, struct ip *);
251static int IcmpAliasIn2(struct libalias *, struct ip *);
252static int IcmpAliasIn (struct libalias *, struct ip *);
253
254static int IcmpAliasOut1(struct libalias *, struct ip *);
255static int IcmpAliasOut2(struct libalias *, struct ip *);
256static int IcmpAliasOut (struct libalias *, struct ip *);
257
258static int ProtoAliasIn(struct libalias *, struct ip *);
259static int ProtoAliasOut(struct libalias *, struct ip *);
260
261static int UdpAliasOut(struct libalias *, struct ip *);
262static int UdpAliasIn (struct libalias *, struct ip *);
263
264static int TcpAliasOut(struct libalias *, struct ip *, int);
265static int TcpAliasIn (struct libalias *, struct ip *);
266
267
268static int
269IcmpAliasIn1(struct libalias *la, struct ip *pip)
270{
271/*
272 De-alias incoming echo and timestamp replies.
273 Alias incoming echo and timestamp requests.
274*/
275 struct alias_link *link;
276 struct icmp *ic;
277
278 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
279
280/* Get source address from ICMP data field and restore original data */
281 link = FindIcmpIn(la, pip->ip_src, pip->ip_dst, ic->icmp_id, 1);
282 if (link != NULL)
283 {
284 u_short original_id;
285 int accumulate;
286
287 original_id = GetOriginalPort(link);
288
289/* Adjust ICMP checksum */
290 accumulate = ic->icmp_id;
291 accumulate -= original_id;
292 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
293
294/* Put original sequence number back in */
295 ic->icmp_id = original_id;
296
297/* Put original address back into IP header */
298 {
299 struct in_addr original_address;
300
301 original_address = GetOriginalAddress(link);
302 DifferentialChecksum(&pip->ip_sum,
303 (u_short *) &original_address,
304 (u_short *) &pip->ip_dst,
305 2);
306 pip->ip_dst = original_address;
307 }
308
309 return(PKT_ALIAS_OK);
310 }
311 return(PKT_ALIAS_IGNORED);
312}
313
314static int
315IcmpAliasIn2(struct libalias *la, struct ip *pip)
316{
317/*
318 Alias incoming ICMP error messages containing
319 IP header and first 64 bits of datagram.
320*/
321 struct ip *ip;
322 struct icmp *ic, *ic2;
323 struct udphdr *ud;
324 struct tcphdr *tc;
325 struct alias_link *link;
326
327 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
328 ip = &ic->icmp_ip;
329
330 ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2));
331 tc = (struct tcphdr *) ud;
332 ic2 = (struct icmp *) ud;
333
334 if (ip->ip_p == IPPROTO_UDP)
335 link = FindUdpTcpIn(la, ip->ip_dst, ip->ip_src,
336 ud->uh_dport, ud->uh_sport,
337 IPPROTO_UDP, 0);
338 else if (ip->ip_p == IPPROTO_TCP)
339 link = FindUdpTcpIn(la, ip->ip_dst, ip->ip_src,
340 tc->th_dport, tc->th_sport,
341 IPPROTO_TCP, 0);
342 else if (ip->ip_p == IPPROTO_ICMP) {
343 if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
344 link = FindIcmpIn(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0);
345 else
346 link = NULL;
347 } else
348 link = NULL;
349
350 if (link != NULL)
351 {
352 if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP)
353 {
354 u_short *sptr;
355 int accumulate, accumulate2;
356 struct in_addr original_address;
357 u_short original_port;
358
359 original_address = GetOriginalAddress(link);
360 original_port = GetOriginalPort(link);
361
362/* Adjust ICMP checksum */
363 sptr = (u_short *) &(ip->ip_src);
364 accumulate = *sptr++;
365 accumulate += *sptr;
366 sptr = (u_short *) &original_address;
367 accumulate -= *sptr++;
368 accumulate -= *sptr;
369 accumulate += ud->uh_sport;
370 accumulate -= original_port;
371 accumulate2 = accumulate;
372 accumulate2 += ip->ip_sum;
373 ADJUST_CHECKSUM(accumulate, ip->ip_sum);
374 accumulate2 -= ip->ip_sum;
375 ADJUST_CHECKSUM(accumulate2, ic->icmp_cksum);
376
377/* Un-alias address in IP header */
378 DifferentialChecksum(&pip->ip_sum,
379 (u_short *) &original_address,
380 (u_short *) &pip->ip_dst,
381 2);
382 pip->ip_dst = original_address;
383
384/* Un-alias address and port number of original IP packet
385fragment contained in ICMP data section */
386 ip->ip_src = original_address;
387 ud->uh_sport = original_port;
388 }
389 else if (ip->ip_p == IPPROTO_ICMP)
390 {
391 u_short *sptr;
392 int accumulate, accumulate2;
393 struct in_addr original_address;
394 u_short original_id;
395
396 original_address = GetOriginalAddress(link);
397 original_id = GetOriginalPort(link);
398
399/* Adjust ICMP checksum */
400 sptr = (u_short *) &(ip->ip_src);
401 accumulate = *sptr++;
402 accumulate += *sptr;
403 sptr = (u_short *) &original_address;
404 accumulate -= *sptr++;
405 accumulate -= *sptr;
406 accumulate += ic2->icmp_id;
407 accumulate -= original_id;
408 accumulate2 = accumulate;
409 accumulate2 += ip->ip_sum;
410 ADJUST_CHECKSUM(accumulate, ip->ip_sum);
411 accumulate2 -= ip->ip_sum;
412 ADJUST_CHECKSUM(accumulate2, ic->icmp_cksum);
413
414/* Un-alias address in IP header */
415 DifferentialChecksum(&pip->ip_sum,
416 (u_short *) &original_address,
417 (u_short *) &pip->ip_dst,
418 2);
419 pip->ip_dst = original_address;
420
421/* Un-alias address of original IP packet and sequence number of
422 embedded ICMP datagram */
423 ip->ip_src = original_address;
424 ic2->icmp_id = original_id;
425 }
426 return(PKT_ALIAS_OK);
427 }
428 return(PKT_ALIAS_IGNORED);
429}
430
431
432static int
433IcmpAliasIn(struct libalias *la, struct ip *pip)
434{
435 int iresult;
436 struct icmp *ic;
437
438/* Return if proxy-only mode is enabled */
439 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
440 return PKT_ALIAS_OK;
441
442 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
443
444 iresult = PKT_ALIAS_IGNORED;
445 switch (ic->icmp_type)
446 {
447 case ICMP_ECHOREPLY:
448 case ICMP_TSTAMPREPLY:
449 if (ic->icmp_code == 0)
450 {
451 iresult = IcmpAliasIn1(la, pip);
452 }
453 break;
454 case ICMP_UNREACH:
455 case ICMP_SOURCEQUENCH:
456 case ICMP_TIMXCEED:
457 case ICMP_PARAMPROB:
458 iresult = IcmpAliasIn2(la, pip);
459 break;
460 case ICMP_ECHO:
461 case ICMP_TSTAMP:
462 iresult = IcmpAliasIn1(la, pip);
463 break;
464 }
465 return(iresult);
466}
467
468
469static int
470IcmpAliasOut1(struct libalias *la, struct ip *pip)
471{
472/*
473 Alias outgoing echo and timestamp requests.
474 De-alias outgoing echo and timestamp replies.
475*/
476 struct alias_link *link;
477 struct icmp *ic;
478
479 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
480
481/* Save overwritten data for when echo packet returns */
482 link = FindIcmpOut(la, pip->ip_src, pip->ip_dst, ic->icmp_id, 1);
483 if (link != NULL)
484 {
485 u_short alias_id;
486 int accumulate;
487
488 alias_id = GetAliasPort(link);
489
490/* Since data field is being modified, adjust ICMP checksum */
491 accumulate = ic->icmp_id;
492 accumulate -= alias_id;
493 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
494
495/* Alias sequence number */
496 ic->icmp_id = alias_id;
497
498/* Change source address */
499 {
500 struct in_addr alias_address;
501
502 alias_address = GetAliasAddress(link);
503 DifferentialChecksum(&pip->ip_sum,
504 (u_short *) &alias_address,
505 (u_short *) &pip->ip_src,
506 2);
507 pip->ip_src = alias_address;
508 }
509
510 return(PKT_ALIAS_OK);
511 }
512 return(PKT_ALIAS_IGNORED);
513}
514
515
516static int
517IcmpAliasOut2(struct libalias *la, struct ip *pip)
518{
519/*
520 Alias outgoing ICMP error messages containing
521 IP header and first 64 bits of datagram.
522*/
523 struct ip *ip;
524 struct icmp *ic, *ic2;
525 struct udphdr *ud;
526 struct tcphdr *tc;
527 struct alias_link *link;
528
529 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
530 ip = &ic->icmp_ip;
531
532 ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2));
533 tc = (struct tcphdr *) ud;
534 ic2 = (struct icmp *) ud;
535
536 if (ip->ip_p == IPPROTO_UDP)
537 link = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src,
538 ud->uh_dport, ud->uh_sport,
539 IPPROTO_UDP, 0);
540 else if (ip->ip_p == IPPROTO_TCP)
541 link = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src,
542 tc->th_dport, tc->th_sport,
543 IPPROTO_TCP, 0);
544 else if (ip->ip_p == IPPROTO_ICMP) {
545 if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
546 link = FindIcmpOut(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0);
547 else
548 link = NULL;
549 } else
550 link = NULL;
551
552 if (link != NULL)
553 {
554 if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP)
555 {
556 u_short *sptr;
557 int accumulate;
558 struct in_addr alias_address;
559 u_short alias_port;
560
561 alias_address = GetAliasAddress(link);
562 alias_port = GetAliasPort(link);
563
564/* Adjust ICMP checksum */
565 sptr = (u_short *) &(ip->ip_dst);
566 accumulate = *sptr++;
567 accumulate += *sptr;
568 sptr = (u_short *) &alias_address;
569 accumulate -= *sptr++;
570 accumulate -= *sptr;
571 accumulate += ud->uh_dport;
572 accumulate -= alias_port;
573 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
574
575/*
576 * Alias address in IP header if it comes from the host
577 * the original TCP/UDP packet was destined for.
578 */
579 if (pip->ip_src.s_addr == ip->ip_dst.s_addr) {
580 DifferentialChecksum(&pip->ip_sum,
581 (u_short *) &alias_address,
582 (u_short *) &pip->ip_src,
583 2);
584 pip->ip_src = alias_address;
585 }
586
587/* Alias address and port number of original IP packet
588fragment contained in ICMP data section */
589 ip->ip_dst = alias_address;
590 ud->uh_dport = alias_port;
591 }
592 else if (ip->ip_p == IPPROTO_ICMP)
593 {
594 u_short *sptr;
595 int accumulate;
596 struct in_addr alias_address;
597 u_short alias_id;
598
599 alias_address = GetAliasAddress(link);
600 alias_id = GetAliasPort(link);
601
602/* Adjust ICMP checksum */
603 sptr = (u_short *) &(ip->ip_dst);
604 accumulate = *sptr++;
605 accumulate += *sptr;
606 sptr = (u_short *) &alias_address;
607 accumulate -= *sptr++;
608 accumulate -= *sptr;
609 accumulate += ic2->icmp_id;
610 accumulate -= alias_id;
611 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
612
613/*
614 * Alias address in IP header if it comes from the host
615 * the original ICMP message was destined for.
616 */
617 if (pip->ip_src.s_addr == ip->ip_dst.s_addr) {
618 DifferentialChecksum(&pip->ip_sum,
619 (u_short *) &alias_address,
620 (u_short *) &pip->ip_src,
621 2);
622 pip->ip_src = alias_address;
623 }
624
625/* Alias address of original IP packet and sequence number of
626 embedded ICMP datagram */
627 ip->ip_dst = alias_address;
628 ic2->icmp_id = alias_id;
629 }
630 return(PKT_ALIAS_OK);
631 }
632 return(PKT_ALIAS_IGNORED);
633}
634
635
636static int
637IcmpAliasOut(struct libalias *la, struct ip *pip)
638{
639 int iresult;
640 struct icmp *ic;
641
642/* Return if proxy-only mode is enabled */
643 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
644 return PKT_ALIAS_OK;
645
646 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
647
648 iresult = PKT_ALIAS_IGNORED;
649 switch (ic->icmp_type)
650 {
651 case ICMP_ECHO:
652 case ICMP_TSTAMP:
653 if (ic->icmp_code == 0)
654 {
655 iresult = IcmpAliasOut1(la, pip);
656 }
657 break;
658 case ICMP_UNREACH:
659 case ICMP_SOURCEQUENCH:
660 case ICMP_TIMXCEED:
661 case ICMP_PARAMPROB:
662 iresult = IcmpAliasOut2(la, pip);
663 break;
664 case ICMP_ECHOREPLY:
665 case ICMP_TSTAMPREPLY:
666 iresult = IcmpAliasOut1(la, pip);
667 }
668 return(iresult);
669}
670
671
672
673static int
674ProtoAliasIn(struct libalias *la, struct ip *pip)
675{
676/*
677 Handle incoming IP packets. The
678 only thing which is done in this case is to alias
679 the dest IP address of the packet to our inside
680 machine.
681*/
682 struct alias_link *link;
683
684/* Return if proxy-only mode is enabled */
685 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
686 return PKT_ALIAS_OK;
687
688 link = FindProtoIn(la, pip->ip_src, pip->ip_dst, pip->ip_p);
689 if (link != NULL)
690 {
691 struct in_addr original_address;
692
693 original_address = GetOriginalAddress(link);
694
695/* Restore original IP address */
696 DifferentialChecksum(&pip->ip_sum,
697 (u_short *) &original_address,
698 (u_short *) &pip->ip_dst,
699 2);
700 pip->ip_dst = original_address;
701
702 return(PKT_ALIAS_OK);
703 }
704 return(PKT_ALIAS_IGNORED);
705}
706
707
708static int
709ProtoAliasOut(struct libalias *la, struct ip *pip)
710{
711/*
712 Handle outgoing IP packets. The
713 only thing which is done in this case is to alias
714 the source IP address of the packet.
715*/
716 struct alias_link *link;
717
718/* Return if proxy-only mode is enabled */
719 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
720 return PKT_ALIAS_OK;
721
722 link = FindProtoOut(la, pip->ip_src, pip->ip_dst, pip->ip_p);
723 if (link != NULL)
724 {
725 struct in_addr alias_address;
726
727 alias_address = GetAliasAddress(link);
728
729/* Change source address */
730 DifferentialChecksum(&pip->ip_sum,
731 (u_short *) &alias_address,
732 (u_short *) &pip->ip_src,
733 2);
734 pip->ip_src = alias_address;
735
736 return(PKT_ALIAS_OK);
737 }
738 return(PKT_ALIAS_IGNORED);
739}
740
741
742static int
743UdpAliasIn(struct libalias *la, struct ip *pip)
744{
745 struct udphdr *ud;
746 struct alias_link *link;
747
748/* Return if proxy-only mode is enabled */
749 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
750 return PKT_ALIAS_OK;
751
752 ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
753
754 link = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst,
755 ud->uh_sport, ud->uh_dport,
756 IPPROTO_UDP, 1);
757 if (link != NULL)
758 {
759 struct in_addr alias_address;
760 struct in_addr original_address;
761 u_short alias_port;
762 int accumulate;
763 u_short *sptr;
764 int r = 0;
765
766 alias_address = GetAliasAddress(link);
767 original_address = GetOriginalAddress(link);
768 alias_port = ud->uh_dport;
769 ud->uh_dport = GetOriginalPort(link);
770
771/* Special processing for IP encoding protocols */
772 if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
773 AliasHandleCUSeeMeIn(la, pip, original_address);
774/* If NETBIOS Datagram, It should be alias address in UDP Data, too */
775 else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
776 || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER)
777 r = AliasHandleUdpNbt(la, pip, link, &original_address, ud->uh_dport);
778 else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
779 || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER)
780 r = AliasHandleUdpNbtNS(la, pip, link, &alias_address, &alias_port,
781 &original_address, &ud->uh_dport);
782
783/* If UDP checksum is not zero, then adjust since destination port */
784/* is being unaliased and destination address is being altered. */
785 if (ud->uh_sum != 0)
786 {
787 accumulate = alias_port;
788 accumulate -= ud->uh_dport;
789 sptr = (u_short *) &alias_address;
790 accumulate += *sptr++;
791 accumulate += *sptr;
792 sptr = (u_short *) &original_address;
793 accumulate -= *sptr++;
794 accumulate -= *sptr;
795 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
796 }
797
798/* Restore original IP address */
799 DifferentialChecksum(&pip->ip_sum,
800 (u_short *) &original_address,
801 (u_short *) &pip->ip_dst,
802 2);
803 pip->ip_dst = original_address;
804
805 /*
806 * If we cannot figure out the packet, ignore it.
807 */
808 if (r < 0)
809 return(PKT_ALIAS_IGNORED);
810 else
811 return(PKT_ALIAS_OK);
812 }
813 return(PKT_ALIAS_IGNORED);
814}
815
816static int
817UdpAliasOut(struct libalias *la, struct ip *pip)
818{
819 struct udphdr *ud;
820 struct alias_link *link;
821
822/* Return if proxy-only mode is enabled */
823 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
824 return PKT_ALIAS_OK;
825
826 ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
827
828 link = FindUdpTcpOut(la, pip->ip_src, pip->ip_dst,
829 ud->uh_sport, ud->uh_dport,
830 IPPROTO_UDP, 1);
831 if (link != NULL)
832 {
833 u_short alias_port;
834 struct in_addr alias_address;
835
836 alias_address = GetAliasAddress(link);
837 alias_port = GetAliasPort(link);
838
839/* Special processing for IP encoding protocols */
840 if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
841 AliasHandleCUSeeMeOut(la, pip, link);
842/* If NETBIOS Datagram, It should be alias address in UDP Data, too */
843 else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
844 || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER)
845 AliasHandleUdpNbt(la, pip, link, &alias_address, alias_port);
846 else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
847 || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER)
848 AliasHandleUdpNbtNS(la, pip, link, &pip->ip_src, &ud->uh_sport,
849 &alias_address, &alias_port);
850/*
851 * We don't know in advance what TID the TFTP server will choose,
852 * so we create a wilcard link (destination port is unspecified)
853 * that will match any TID from a given destination.
854 */
855 else if (ntohs(ud->uh_dport) == TFTP_PORT_NUMBER)
856 FindRtspOut(la, pip->ip_src, pip->ip_dst,
857 ud->uh_sport, alias_port, IPPROTO_UDP);
858
859/* If UDP checksum is not zero, adjust since source port is */
860/* being aliased and source address is being altered */
861 if (ud->uh_sum != 0)
862 {
863 int accumulate;
864 u_short *sptr;
865
866 accumulate = ud->uh_sport;
867 accumulate -= alias_port;
868 sptr = (u_short *) &(pip->ip_src);
869 accumulate += *sptr++;
870 accumulate += *sptr;
871 sptr = (u_short *) &alias_address;
872 accumulate -= *sptr++;
873 accumulate -= *sptr;
874 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
875 }
876
877/* Put alias port in UDP header */
878 ud->uh_sport = alias_port;
879
880/* Change source address */
881 DifferentialChecksum(&pip->ip_sum,
882 (u_short *) &alias_address,
883 (u_short *) &pip->ip_src,
884 2);
885 pip->ip_src = alias_address;
886
887 return(PKT_ALIAS_OK);
888 }
889 return(PKT_ALIAS_IGNORED);
890}
891
892
893
894static int
895TcpAliasIn(struct libalias *la, struct ip *pip)
896{
897 struct tcphdr *tc;
898 struct alias_link *link;
899
900 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
901
902 link = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst,
903 tc->th_sport, tc->th_dport,
904 IPPROTO_TCP,
905 !(la->packetAliasMode & PKT_ALIAS_PROXY_ONLY));
906 if (link != NULL)
907 {
908 struct in_addr alias_address;
909 struct in_addr original_address;
910 struct in_addr proxy_address;
911 u_short alias_port;
912 u_short proxy_port;
913 int accumulate;
914 u_short *sptr;
915
916/* Special processing for IP encoding protocols */
917 if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
918 || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
919 AliasHandlePptpIn(la, pip, link);
920 else if (la->skinnyPort != 0 && (ntohs(tc->th_dport) == la->skinnyPort
921 || ntohs(tc->th_sport) == la->skinnyPort))
922 AliasHandleSkinny(la, pip, link);
923
924 alias_address = GetAliasAddress(link);
925 original_address = GetOriginalAddress(link);
926 proxy_address = GetProxyAddress(link);
927 alias_port = tc->th_dport;
928 tc->th_dport = GetOriginalPort(link);
929 proxy_port = GetProxyPort(link);
930
931/* Adjust TCP checksum since destination port is being unaliased */
932/* and destination port is being altered. */
933 accumulate = alias_port;
934 accumulate -= tc->th_dport;
935 sptr = (u_short *) &alias_address;
936 accumulate += *sptr++;
937 accumulate += *sptr;
938 sptr = (u_short *) &original_address;
939 accumulate -= *sptr++;
940 accumulate -= *sptr;
941
942/* If this is a proxy, then modify the TCP source port and
943 checksum accumulation */
944 if (proxy_port != 0)
945 {
946 accumulate += tc->th_sport;
947 tc->th_sport = proxy_port;
948 accumulate -= tc->th_sport;
949
950 sptr = (u_short *) &pip->ip_src;
951 accumulate += *sptr++;
952 accumulate += *sptr;
953 sptr = (u_short *) &proxy_address;
954 accumulate -= *sptr++;
955 accumulate -= *sptr;
956 }
957
958/* See if ACK number needs to be modified */
959 if (GetAckModified(link) == 1)
960 {
961 int delta;
962
963 delta = GetDeltaAckIn(pip, link);
964 if (delta != 0)
965 {
966 sptr = (u_short *) &tc->th_ack;
967 accumulate += *sptr++;
968 accumulate += *sptr;
969 tc->th_ack = htonl(ntohl(tc->th_ack) - delta);
970 sptr = (u_short *) &tc->th_ack;
971 accumulate -= *sptr++;
972 accumulate -= *sptr;
973 }
974 }
975
976 ADJUST_CHECKSUM(accumulate, tc->th_sum);
977
978/* Restore original IP address */
979 sptr = (u_short *) &pip->ip_dst;
980 accumulate = *sptr++;
981 accumulate += *sptr;
982 pip->ip_dst = original_address;
983 sptr = (u_short *) &pip->ip_dst;
984 accumulate -= *sptr++;
985 accumulate -= *sptr;
986
987/* If this is a transparent proxy packet, then modify the source
988 address */
989 if (proxy_address.s_addr != 0)
990 {
991 sptr = (u_short *) &pip->ip_src;
992 accumulate += *sptr++;
993 accumulate += *sptr;
994 pip->ip_src = proxy_address;
995 sptr = (u_short *) &pip->ip_src;
996 accumulate -= *sptr++;
997 accumulate -= *sptr;
998 }
999
1000 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1001
1002/* Monitor TCP connection state */
1003 TcpMonitorIn(pip, link);
1004
1005 return(PKT_ALIAS_OK);
1006 }
1007 return(PKT_ALIAS_IGNORED);
1008}
1009
1010static int
1011TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize)
1012{
1013 int proxy_type;
1014 u_short dest_port;
1015 u_short proxy_server_port;
1016 struct in_addr dest_address;
1017 struct in_addr proxy_server_address;
1018 struct tcphdr *tc;
1019 struct alias_link *link;
1020
1021 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
1022
1023 proxy_type = ProxyCheck(la, pip, &proxy_server_address, &proxy_server_port);
1024
1025 if (proxy_type == 0 && (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY))
1026 return PKT_ALIAS_OK;
1027
1028/* If this is a transparent proxy, save original destination,
1029 then alter the destination and adjust checksums */
1030 dest_port = tc->th_dport;
1031 dest_address = pip->ip_dst;
1032 if (proxy_type != 0)
1033 {
1034 int accumulate;
1035 u_short *sptr;
1036
1037 accumulate = tc->th_dport;
1038 tc->th_dport = proxy_server_port;
1039 accumulate -= tc->th_dport;
1040
1041 sptr = (u_short *) &(pip->ip_dst);
1042 accumulate += *sptr++;
1043 accumulate += *sptr;
1044 sptr = (u_short *) &proxy_server_address;
1045 accumulate -= *sptr++;
1046 accumulate -= *sptr;
1047
1048 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1049
1050 sptr = (u_short *) &(pip->ip_dst);
1051 accumulate = *sptr++;
1052 accumulate += *sptr;
1053 pip->ip_dst = proxy_server_address;
1054 sptr = (u_short *) &(pip->ip_dst);
1055 accumulate -= *sptr++;
1056 accumulate -= *sptr;
1057
1058 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1059 }
1060
1061 link = FindUdpTcpOut(la, pip->ip_src, pip->ip_dst,
1062 tc->th_sport, tc->th_dport,
1063 IPPROTO_TCP, 1);
1064 if (link !=NULL)
1065 {
1066 u_short alias_port;
1067 struct in_addr alias_address;
1068 int accumulate;
1069 u_short *sptr;
1070
1071/* Save original destination address, if this is a proxy packet.
1072 Also modify packet to include destination encoding. This may
1073 change the size of IP header. */
1074 if (proxy_type != 0)
1075 {
1076 SetProxyPort(link, dest_port);
1077 SetProxyAddress(link, dest_address);
1078 ProxyModify(la, link, pip, maxpacketsize, proxy_type);
1079 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
1080 }
1081
1082/* Get alias address and port */
1083 alias_port = GetAliasPort(link);
1084 alias_address = GetAliasAddress(link);
1085
1086/* Monitor TCP connection state */
1087 TcpMonitorOut(pip, link);
1088
1089/* Special processing for IP encoding protocols */
1090 if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER
1091 || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER)
1092 AliasHandleFtpOut(la, pip, link, maxpacketsize);
1093 else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1
1094 || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2)
1095 AliasHandleIrcOut(la, pip, link, maxpacketsize);
1096 else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1
1097 || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1
1098 || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2
1099 || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2)
1100 AliasHandleRtspOut(la, pip, link, maxpacketsize);
1101 else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
1102 || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
1103 AliasHandlePptpOut(la, pip, link);
1104 else if (la->skinnyPort != 0 && (ntohs(tc->th_sport) == la->skinnyPort
1105 || ntohs(tc->th_dport) == la->skinnyPort))
1106 AliasHandleSkinny(la, pip, link);
1107
1108/* Adjust TCP checksum since source port is being aliased */
1109/* and source address is being altered */
1110 accumulate = tc->th_sport;
1111 tc->th_sport = alias_port;
1112 accumulate -= tc->th_sport;
1113
1114 sptr = (u_short *) &(pip->ip_src);
1115 accumulate += *sptr++;
1116 accumulate += *sptr;
1117 sptr = (u_short *) &alias_address;
1118 accumulate -= *sptr++;
1119 accumulate -= *sptr;
1120
1121/* Modify sequence number if necessary */
1122 if (GetAckModified(link) == 1)
1123 {
1124 int delta;
1125
1126 delta = GetDeltaSeqOut(pip, link);
1127 if (delta != 0)
1128 {
1129 sptr = (u_short *) &tc->th_seq;
1130 accumulate += *sptr++;
1131 accumulate += *sptr;
1132 tc->th_seq = htonl(ntohl(tc->th_seq) + delta);
1133 sptr = (u_short *) &tc->th_seq;
1134 accumulate -= *sptr++;
1135 accumulate -= *sptr;
1136 }
1137 }
1138
1139 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1140
1141/* Change source address */
1142 sptr = (u_short *) &(pip->ip_src);
1143 accumulate = *sptr++;
1144 accumulate += *sptr;
1145 pip->ip_src = alias_address;
1146 sptr = (u_short *) &(pip->ip_src);
1147 accumulate -= *sptr++;
1148 accumulate -= *sptr;
1149
1150 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1151
1152 return(PKT_ALIAS_OK);
1153 }
1154 return(PKT_ALIAS_IGNORED);
1155}
1156
1157
1158
1159
1160/* Fragment Handling
1161
1162 FragmentIn()
1163 FragmentOut()
1164
1165The packet aliasing module has a limited ability for handling IP
1166fragments. If the ICMP, TCP or UDP header is in the first fragment
1167received, then the ID number of the IP packet is saved, and other
1168fragments are identified according to their ID number and IP address
1169they were sent from. Pointers to unresolved fragments can also be
1170saved and recalled when a header fragment is seen.
1171*/
1172
1173/* Local prototypes */
1174static int FragmentIn(struct libalias *, struct ip *);
1175static int FragmentOut(struct libalias *, struct ip *);
1176
1177
1178static int
1179FragmentIn(struct libalias *la, struct ip *pip)
1180{
1181 struct alias_link *link;
1182
1183 link = FindFragmentIn2(la, pip->ip_src, pip->ip_dst, pip->ip_id);
1184 if (link != NULL)
1185 {
1186 struct in_addr original_address;
1187
1188 GetFragmentAddr(link, &original_address);
1189 DifferentialChecksum(&pip->ip_sum,
1190 (u_short *) &original_address,
1191 (u_short *) &pip->ip_dst,
1192 2);
1193 pip->ip_dst = original_address;
1194
1195 return(PKT_ALIAS_OK);
1196 }
1197 return(PKT_ALIAS_UNRESOLVED_FRAGMENT);
1198}
1199
1200
1201static int
1202FragmentOut(struct libalias *la, struct ip *pip)
1203{
1204 struct in_addr alias_address;
1205
1206 alias_address = FindAliasAddress(la, pip->ip_src);
1207 DifferentialChecksum(&pip->ip_sum,
1208 (u_short *) &alias_address,
1209 (u_short *) &pip->ip_src,
1210 2);
1211 pip->ip_src = alias_address;
1212
1213 return(PKT_ALIAS_OK);
1214}
1215
1216
1217
1218
1219
1220
1221/* Outside World Access

--- 7 unchanged lines hidden (view full) ---

1229
1230(prototypes in alias.h)
1231*/
1232
1233
1234int
1235LibAliasSaveFragment(struct libalias *la, char *ptr)
1236{
1237 int iresult;
1238 struct alias_link *link;
1239 struct ip *pip;
1240
1241 pip = (struct ip *) ptr;
1242 link = AddFragmentPtrLink(la, pip->ip_src, pip->ip_id);
1243 iresult = PKT_ALIAS_ERROR;
1244 if (link != NULL)
1245 {
1246 SetFragmentPtr(link, ptr);
1247 iresult = PKT_ALIAS_OK;
1248 }
1249 return(iresult);
1250}
1251
1252
1253char *
1254LibAliasGetFragment(struct libalias *la, char *ptr)
1255{
1256 struct alias_link *link;
1257 char *fptr;
1258 struct ip *pip;
1259
1260 pip = (struct ip *) ptr;
1261 link = FindFragmentPtr(la, pip->ip_src, pip->ip_id);
1262 if (link != NULL)
1263 {
1264 GetFragmentPtr(link, &fptr);
1265 SetFragmentPtr(link, NULL);
1266 SetExpire(link, 0); /* Deletes link */
1267
1268 return(fptr);
1269 }
1270 else
1271 {
1272 return(NULL);
1273 }
1274}
1275
1276
1277void
1278LibAliasFragmentIn(struct libalias *la, char *ptr, /* Points to correctly de-aliased
1279 header fragment */
1280 char *ptr_fragment /* Points to fragment which must
1281 be de-aliased */
1282 )
1283{
1284 struct ip *pip;
1285 struct ip *fpip;
1286
1287 pip = (struct ip *) ptr;
1288 fpip = (struct ip *) ptr_fragment;
1289
1290 DifferentialChecksum(&fpip->ip_sum,
1291 (u_short *) &pip->ip_dst,
1292 (u_short *) &fpip->ip_dst,
1293 2);
1294 fpip->ip_dst = pip->ip_dst;
1295}
1296
1297
1298int
1299LibAliasIn(struct libalias *la, char *ptr, int maxpacketsize)
1300{
1301 struct in_addr alias_addr;
1302 struct ip *pip;
1303 int iresult;
1304
1305 if (la->packetAliasMode & PKT_ALIAS_REVERSE) {
1306 la->packetAliasMode &= ~PKT_ALIAS_REVERSE;
1307 iresult = PacketAliasOut(ptr, maxpacketsize);
1308 la->packetAliasMode |= PKT_ALIAS_REVERSE;
1309 return iresult;
1310 }
1311
1312 HouseKeeping(la);
1313 ClearCheckNewLink(la);
1314 pip = (struct ip *) ptr;
1315 alias_addr = pip->ip_dst;
1316
1317 /* Defense against mangled packets */
1318 if (ntohs(pip->ip_len) > maxpacketsize
1319 || (pip->ip_hl<<2) > maxpacketsize)
1320 return PKT_ALIAS_IGNORED;
1321
1322 iresult = PKT_ALIAS_IGNORED;
1323 if ( (ntohs(pip->ip_off) & IP_OFFMASK) == 0 )
1324 {
1325 switch (pip->ip_p)
1326 {
1327 case IPPROTO_ICMP:
1328 iresult = IcmpAliasIn(la, pip);
1329 break;
1330 case IPPROTO_UDP:
1331 iresult = UdpAliasIn(la, pip);
1332 break;
1333 case IPPROTO_TCP:
1334 iresult = TcpAliasIn(la, pip);
1335 break;
1336 case IPPROTO_GRE:
1337 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY ||
1338 AliasHandlePptpGreIn(la, pip) == 0)
1339 iresult = PKT_ALIAS_OK;
1340 else
1341 iresult = ProtoAliasIn(la, pip);
1342 break;
1343 default:
1344 iresult = ProtoAliasIn(la, pip);
1345 break;
1346 }
1347
1348 if (ntohs(pip->ip_off) & IP_MF)
1349 {
1350 struct alias_link *link;
1351
1352 link = FindFragmentIn1(la, pip->ip_src, alias_addr, pip->ip_id);
1353 if (link != NULL)
1354 {
1355 iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT;
1356 SetFragmentAddr(link, pip->ip_dst);
1357 }
1358 else
1359 {
1360 iresult = PKT_ALIAS_ERROR;
1361 }
1362 }
1363 }
1364 else
1365 {
1366 iresult = FragmentIn(la, pip);
1367 }
1368
1369 return(iresult);
1370}
1371
1372
1373
1374/* Unregistered address ranges */
1375
1376/* 10.0.0.0 -> 10.255.255.255 */
1377#define UNREG_ADDR_A_LOWER 0x0a000000
1378#define UNREG_ADDR_A_UPPER 0x0affffff
1379
1380/* 172.16.0.0 -> 172.31.255.255 */
1381#define UNREG_ADDR_B_LOWER 0xac100000
1382#define UNREG_ADDR_B_UPPER 0xac1fffff
1383
1384/* 192.168.0.0 -> 192.168.255.255 */
1385#define UNREG_ADDR_C_LOWER 0xc0a80000
1386#define UNREG_ADDR_C_UPPER 0xc0a8ffff
1387
1388int
1389LibAliasOut(struct libalias *la, char *ptr, /* valid IP packet */
1390 int maxpacketsize /* How much the packet data may grow
1391 (FTP and IRC inline changes) */
1392 )
1393{
1394 int iresult;
1395 struct in_addr addr_save;
1396 struct ip *pip;
1397
1398 if (la->packetAliasMode & PKT_ALIAS_REVERSE) {
1399 la->packetAliasMode &= ~PKT_ALIAS_REVERSE;
1400 iresult = PacketAliasIn(ptr, maxpacketsize);
1401 la->packetAliasMode |= PKT_ALIAS_REVERSE;
1402 return iresult;
1403 }
1404
1405 HouseKeeping(la);
1406 ClearCheckNewLink(la);
1407 pip = (struct ip *) ptr;
1408
1409 /* Defense against mangled packets */
1410 if (ntohs(pip->ip_len) > maxpacketsize
1411 || (pip->ip_hl<<2) > maxpacketsize)
1412 return PKT_ALIAS_IGNORED;
1413
1414 addr_save = GetDefaultAliasAddress(la);
1415 if (la->packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY)
1416 {
1417 u_long addr;
1418 int iclass;
1419
1420 iclass = 0;
1421 addr = ntohl(pip->ip_src.s_addr);
1422 if (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER)
1423 iclass = 3;
1424 else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER)
1425 iclass = 2;
1426 else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER)
1427 iclass = 1;
1428
1429 if (iclass == 0)
1430 {
1431 SetDefaultAliasAddress(la, pip->ip_src);
1432 }
1433 }
1434 else if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
1435 {
1436 SetDefaultAliasAddress(la, pip->ip_src);
1437 }
1438
1439 iresult = PKT_ALIAS_IGNORED;
1440 if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0)
1441 {
1442 switch (pip->ip_p)
1443 {
1444 case IPPROTO_ICMP:
1445 iresult = IcmpAliasOut(la, pip);
1446 break;
1447 case IPPROTO_UDP:
1448 iresult = UdpAliasOut(la, pip);
1449 break;
1450 case IPPROTO_TCP:
1451 iresult = TcpAliasOut(la, pip, maxpacketsize);
1452 break;
1453 case IPPROTO_GRE:
1454 if (AliasHandlePptpGreOut(la, pip) == 0)
1455 iresult = PKT_ALIAS_OK;
1456 else
1457 iresult = ProtoAliasOut(la, pip);
1458 break;
1459 default:
1460 iresult = ProtoAliasOut(la, pip);
1461 break;
1462 }
1463 }
1464 else
1465 {
1466 iresult = FragmentOut(la, pip);
1467 }
1468
1469 SetDefaultAliasAddress(la, addr_save);
1470 return(iresult);
1471}
1472
1473int
1474LibAliasUnaliasOut(struct libalias *la, char *ptr, /* valid IP packet */
1475 int maxpacketsize /* for error checking */
1476 )
1477{
1478 struct ip *pip;
1479 struct icmp *ic;
1480 struct udphdr *ud;
1481 struct tcphdr *tc;
1482 struct alias_link *link;
1483 int iresult = PKT_ALIAS_IGNORED;
1484
1485 pip = (struct ip *) ptr;
1486
1487 /* Defense against mangled packets */
1488 if (ntohs(pip->ip_len) > maxpacketsize
1489 || (pip->ip_hl<<2) > maxpacketsize)
1490 return(iresult);
1491
1492 ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
1493 tc = (struct tcphdr *) ud;
1494 ic = (struct icmp *) ud;
1495
1496 /* Find a link */
1497 if (pip->ip_p == IPPROTO_UDP)
1498 link = FindUdpTcpIn(la, pip->ip_dst, pip->ip_src,
1499 ud->uh_dport, ud->uh_sport,
1500 IPPROTO_UDP, 0);
1501 else if (pip->ip_p == IPPROTO_TCP)
1502 link = FindUdpTcpIn(la, pip->ip_dst, pip->ip_src,
1503 tc->th_dport, tc->th_sport,
1504 IPPROTO_TCP, 0);
1505 else if (pip->ip_p == IPPROTO_ICMP)
1506 link = FindIcmpIn(la, pip->ip_dst, pip->ip_src, ic->icmp_id, 0);
1507 else
1508 link = NULL;
1509
1510 /* Change it from an aliased packet to an unaliased packet */
1511 if (link != NULL)
1512 {
1513 if (pip->ip_p == IPPROTO_UDP || pip->ip_p == IPPROTO_TCP)
1514 {
1515 u_short *sptr;
1516 int accumulate;
1517 struct in_addr original_address;
1518 u_short original_port;
1519
1520 original_address = GetOriginalAddress(link);
1521 original_port = GetOriginalPort(link);
1522
1523 /* Adjust TCP/UDP checksum */
1524 sptr = (u_short *) &(pip->ip_src);
1525 accumulate = *sptr++;
1526 accumulate += *sptr;
1527 sptr = (u_short *) &original_address;
1528 accumulate -= *sptr++;
1529 accumulate -= *sptr;
1530
1531 if (pip->ip_p == IPPROTO_UDP) {
1532 accumulate += ud->uh_sport;
1533 accumulate -= original_port;
1534 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
1535 } else {
1536 accumulate += tc->th_sport;
1537 accumulate -= original_port;
1538 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1539 }
1540
1541 /* Adjust IP checksum */
1542 DifferentialChecksum(&pip->ip_sum,
1543 (u_short *) &original_address,
1544 (u_short *) &pip->ip_src,
1545 2);
1546
1547 /* Un-alias source address and port number */
1548 pip->ip_src = original_address;
1549 if (pip->ip_p == IPPROTO_UDP)
1550 ud->uh_sport = original_port;
1551 else
1552 tc->th_sport = original_port;
1553
1554 iresult = PKT_ALIAS_OK;
1555
1556 } else if (pip->ip_p == IPPROTO_ICMP) {
1557
1558 u_short *sptr;
1559 int accumulate;
1560 struct in_addr original_address;
1561 u_short original_id;
1562
1563 original_address = GetOriginalAddress(link);
1564 original_id = GetOriginalPort(link);
1565
1566 /* Adjust ICMP checksum */
1567 sptr = (u_short *) &(pip->ip_src);
1568 accumulate = *sptr++;
1569 accumulate += *sptr;
1570 sptr = (u_short *) &original_address;
1571 accumulate -= *sptr++;
1572 accumulate -= *sptr;
1573 accumulate += ic->icmp_id;
1574 accumulate -= original_id;
1575 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
1576
1577 /* Adjust IP checksum */
1578 DifferentialChecksum(&pip->ip_sum,
1579 (u_short *) &original_address,
1580 (u_short *) &pip->ip_src,
1581 2);
1582
1583 /* Un-alias source address and port number */
1584 pip->ip_src = original_address;
1585 ic->icmp_id = original_id;
1586
1587 iresult = PKT_ALIAS_OK;
1588 }
1589 }
1590 return(iresult);
1591
1592}