1/*- 2 * Copyright (c) 2001 Charles Mott <cm@linktel.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias.c 127094 2004-03-16 21:30:41Z des $"); |
29 30/* 31 Alias.c provides supervisory control for the functions of the 32 packet aliasing software. It consists of routines to monitor 33 TCP connection state, protocol-specific aliasing routines, 34 fragment handling and the following outside world functional 35 interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn, 36 PacketAliasIn and PacketAliasOut. --- 109 unchanged lines hidden (view full) --- 146 147These routines look for SYN, FIN and RST flags to determine when TCP 148connections open and close. When a TCP connection closes, the data 149structure containing packet aliasing information is deleted after 150a timeout period. 151*/ 152 153/* Local prototypes */ |
154static void TcpMonitorIn(struct ip *, struct alias_link *); |
155 |
156static void TcpMonitorOut(struct ip *, struct alias_link *); |
157 158 159static void 160TcpMonitorIn(struct ip *pip, struct alias_link *link) 161{ |
162 struct tcphdr *tc; |
163 |
164 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); |
165 |
166 switch (GetStateIn(link)) { 167 case ALIAS_TCP_STATE_NOT_CONNECTED: 168 if (tc->th_flags & TH_RST) 169 SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED); 170 else if (tc->th_flags & TH_SYN) 171 SetStateIn(link, ALIAS_TCP_STATE_CONNECTED); 172 break; 173 case ALIAS_TCP_STATE_CONNECTED: 174 if (tc->th_flags & (TH_FIN | TH_RST)) 175 SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED); 176 break; 177 } |
178} 179 180static void 181TcpMonitorOut(struct ip *pip, struct alias_link *link) 182{ |
183 struct tcphdr *tc; |
184 |
185 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); |
186 |
187 switch (GetStateOut(link)) { 188 case ALIAS_TCP_STATE_NOT_CONNECTED: 189 if (tc->th_flags & TH_RST) 190 SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED); 191 else if (tc->th_flags & TH_SYN) 192 SetStateOut(link, ALIAS_TCP_STATE_CONNECTED); 193 break; 194 case ALIAS_TCP_STATE_CONNECTED: 195 if (tc->th_flags & (TH_FIN | TH_RST)) 196 SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED); 197 break; 198 } |
199} 200 201 202 203 204 205/* Protocol Specific Packet Aliasing Routines 206 --- 31 unchanged lines hidden (view full) --- 238They are more correctly thought of as placeholders. 239 240All packets go through the aliasing mechanism, whether they come from 241the gateway machine or other machines on a local area network. 242*/ 243 244 245/* Local prototypes */ |
246static int IcmpAliasIn1(struct libalias *, struct ip *); 247static int IcmpAliasIn2(struct libalias *, struct ip *); 248static int IcmpAliasIn(struct libalias *, struct ip *); |
249 |
250static int IcmpAliasOut1(struct libalias *, struct ip *); 251static int IcmpAliasOut2(struct libalias *, struct ip *); 252static int IcmpAliasOut(struct libalias *, struct ip *); |
253 |
254static int ProtoAliasIn(struct libalias *, struct ip *); 255static int ProtoAliasOut(struct libalias *, struct ip *); |
256 |
257static int UdpAliasOut(struct libalias *, struct ip *); 258static int UdpAliasIn(struct libalias *, struct ip *); |
259 |
260static int TcpAliasOut(struct libalias *, struct ip *, int); 261static int TcpAliasIn(struct libalias *, struct ip *); |
262 263 264static int 265IcmpAliasIn1(struct libalias *la, struct ip *pip) 266{ 267/* 268 De-alias incoming echo and timestamp replies. 269 Alias incoming echo and timestamp requests. 270*/ |
271 struct alias_link *link; 272 struct icmp *ic; |
273 |
274 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2)); |
275 276/* Get source address from ICMP data field and restore original data */ |
277 link = FindIcmpIn(la, pip->ip_src, pip->ip_dst, ic->icmp_id, 1); 278 if (link != NULL) { 279 u_short original_id; 280 int accumulate; |
281 |
282 original_id = GetOriginalPort(link); |
283 284/* Adjust ICMP checksum */ |
285 accumulate = ic->icmp_id; 286 accumulate -= original_id; 287 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); |
288 289/* Put original sequence number back in */ |
290 ic->icmp_id = original_id; |
291 292/* Put original address back into IP header */ |
293 { 294 struct in_addr original_address; |
295 |
296 original_address = GetOriginalAddress(link); 297 DifferentialChecksum(&pip->ip_sum, 298 (u_short *) & original_address, 299 (u_short *) & pip->ip_dst, 300 2); 301 pip->ip_dst = original_address; 302 } |
303 |
304 return (PKT_ALIAS_OK); 305 } 306 return (PKT_ALIAS_IGNORED); |
307} 308 309static int 310IcmpAliasIn2(struct libalias *la, struct ip *pip) 311{ 312/* 313 Alias incoming ICMP error messages containing 314 IP header and first 64 bits of datagram. 315*/ |
316 struct ip *ip; 317 struct icmp *ic, *ic2; 318 struct udphdr *ud; 319 struct tcphdr *tc; 320 struct alias_link *link; |
321 |
322 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2)); 323 ip = &ic->icmp_ip; |
324 |
325 ud = (struct udphdr *)((char *)ip + (ip->ip_hl << 2)); 326 tc = (struct tcphdr *)ud; 327 ic2 = (struct icmp *)ud; |
328 |
329 if (ip->ip_p == IPPROTO_UDP) 330 link = FindUdpTcpIn(la, ip->ip_dst, ip->ip_src, 331 ud->uh_dport, ud->uh_sport, 332 IPPROTO_UDP, 0); 333 else if (ip->ip_p == IPPROTO_TCP) 334 link = FindUdpTcpIn(la, ip->ip_dst, ip->ip_src, 335 tc->th_dport, tc->th_sport, 336 IPPROTO_TCP, 0); 337 else if (ip->ip_p == IPPROTO_ICMP) { 338 if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP) 339 link = FindIcmpIn(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0); 340 else 341 link = NULL; 342 } else 343 link = NULL; |
344 |
345 if (link != NULL) { 346 if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) { 347 u_short *sptr; 348 int accumulate, accumulate2; 349 struct in_addr original_address; 350 u_short original_port; |
351 |
352 original_address = GetOriginalAddress(link); 353 original_port = GetOriginalPort(link); |
354 355/* Adjust ICMP checksum */ |
356 sptr = (u_short *) & (ip->ip_src); 357 accumulate = *sptr++; 358 accumulate += *sptr; 359 sptr = (u_short *) & original_address; 360 accumulate -= *sptr++; 361 accumulate -= *sptr; 362 accumulate += ud->uh_sport; 363 accumulate -= original_port; 364 accumulate2 = accumulate; 365 accumulate2 += ip->ip_sum; 366 ADJUST_CHECKSUM(accumulate, ip->ip_sum); 367 accumulate2 -= ip->ip_sum; 368 ADJUST_CHECKSUM(accumulate2, ic->icmp_cksum); |
369 370/* Un-alias address in IP header */ |
371 DifferentialChecksum(&pip->ip_sum, 372 (u_short *) & original_address, 373 (u_short *) & pip->ip_dst, 374 2); 375 pip->ip_dst = original_address; |
376 377/* Un-alias address and port number of original IP packet 378fragment contained in ICMP data section */ |
379 ip->ip_src = original_address; 380 ud->uh_sport = original_port; 381 } else if (ip->ip_p == IPPROTO_ICMP) { 382 u_short *sptr; 383 int accumulate, accumulate2; 384 struct in_addr original_address; 385 u_short original_id; |
386 |
387 original_address = GetOriginalAddress(link); 388 original_id = GetOriginalPort(link); |
389 390/* Adjust ICMP checksum */ |
391 sptr = (u_short *) & (ip->ip_src); 392 accumulate = *sptr++; 393 accumulate += *sptr; 394 sptr = (u_short *) & original_address; 395 accumulate -= *sptr++; 396 accumulate -= *sptr; 397 accumulate += ic2->icmp_id; 398 accumulate -= original_id; 399 accumulate2 = accumulate; 400 accumulate2 += ip->ip_sum; 401 ADJUST_CHECKSUM(accumulate, ip->ip_sum); 402 accumulate2 -= ip->ip_sum; 403 ADJUST_CHECKSUM(accumulate2, ic->icmp_cksum); |
404 405/* Un-alias address in IP header */ |
406 DifferentialChecksum(&pip->ip_sum, 407 (u_short *) & original_address, 408 (u_short *) & pip->ip_dst, 409 2); 410 pip->ip_dst = original_address; |
411 412/* Un-alias address of original IP packet and sequence number of 413 embedded ICMP datagram */ |
414 ip->ip_src = original_address; 415 ic2->icmp_id = original_id; 416 } 417 return (PKT_ALIAS_OK); 418 } 419 return (PKT_ALIAS_IGNORED); |
420} 421 422 423static int 424IcmpAliasIn(struct libalias *la, struct ip *pip) 425{ |
426 int iresult; 427 struct icmp *ic; |
428 429/* Return if proxy-only mode is enabled */ |
430 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) 431 return PKT_ALIAS_OK; |
432 |
433 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2)); |
434 |
435 iresult = PKT_ALIAS_IGNORED; 436 switch (ic->icmp_type) { 437 case ICMP_ECHOREPLY: 438 case ICMP_TSTAMPREPLY: 439 if (ic->icmp_code == 0) { 440 iresult = IcmpAliasIn1(la, pip); 441 } 442 break; 443 case ICMP_UNREACH: 444 case ICMP_SOURCEQUENCH: 445 case ICMP_TIMXCEED: 446 case ICMP_PARAMPROB: 447 iresult = IcmpAliasIn2(la, pip); 448 break; 449 case ICMP_ECHO: 450 case ICMP_TSTAMP: 451 iresult = IcmpAliasIn1(la, pip); 452 break; 453 } 454 return (iresult); |
455} 456 457 458static int 459IcmpAliasOut1(struct libalias *la, struct ip *pip) 460{ 461/* 462 Alias outgoing echo and timestamp requests. 463 De-alias outgoing echo and timestamp replies. 464*/ |
465 struct alias_link *link; 466 struct icmp *ic; |
467 |
468 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2)); |
469 470/* Save overwritten data for when echo packet returns */ |
471 link = FindIcmpOut(la, pip->ip_src, pip->ip_dst, ic->icmp_id, 1); 472 if (link != NULL) { 473 u_short alias_id; 474 int accumulate; |
475 |
476 alias_id = GetAliasPort(link); |
477 478/* Since data field is being modified, adjust ICMP checksum */ |
479 accumulate = ic->icmp_id; 480 accumulate -= alias_id; 481 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); |
482 483/* Alias sequence number */ |
484 ic->icmp_id = alias_id; |
485 486/* Change source address */ |
487 { 488 struct in_addr alias_address; |
489 |
490 alias_address = GetAliasAddress(link); 491 DifferentialChecksum(&pip->ip_sum, 492 (u_short *) & alias_address, 493 (u_short *) & pip->ip_src, 494 2); 495 pip->ip_src = alias_address; 496 } |
497 |
498 return (PKT_ALIAS_OK); 499 } 500 return (PKT_ALIAS_IGNORED); |
501} 502 503 504static int 505IcmpAliasOut2(struct libalias *la, struct ip *pip) 506{ 507/* 508 Alias outgoing ICMP error messages containing 509 IP header and first 64 bits of datagram. 510*/ |
511 struct ip *ip; 512 struct icmp *ic, *ic2; 513 struct udphdr *ud; 514 struct tcphdr *tc; 515 struct alias_link *link; |
516 |
517 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2)); 518 ip = &ic->icmp_ip; |
519 |
520 ud = (struct udphdr *)((char *)ip + (ip->ip_hl << 2)); 521 tc = (struct tcphdr *)ud; 522 ic2 = (struct icmp *)ud; |
523 |
524 if (ip->ip_p == IPPROTO_UDP) 525 link = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src, 526 ud->uh_dport, ud->uh_sport, 527 IPPROTO_UDP, 0); 528 else if (ip->ip_p == IPPROTO_TCP) 529 link = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src, 530 tc->th_dport, tc->th_sport, 531 IPPROTO_TCP, 0); 532 else if (ip->ip_p == IPPROTO_ICMP) { 533 if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP) 534 link = FindIcmpOut(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0); 535 else 536 link = NULL; 537 } else 538 link = NULL; |
539 |
540 if (link != NULL) { 541 if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) { 542 u_short *sptr; 543 int accumulate; 544 struct in_addr alias_address; 545 u_short alias_port; |
546 |
547 alias_address = GetAliasAddress(link); 548 alias_port = GetAliasPort(link); |
549 550/* Adjust ICMP checksum */ |
551 sptr = (u_short *) & (ip->ip_dst); 552 accumulate = *sptr++; 553 accumulate += *sptr; 554 sptr = (u_short *) & alias_address; 555 accumulate -= *sptr++; 556 accumulate -= *sptr; 557 accumulate += ud->uh_dport; 558 accumulate -= alias_port; 559 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); |
560 561/* 562 * Alias address in IP header if it comes from the host 563 * the original TCP/UDP packet was destined for. 564 */ |
565 if (pip->ip_src.s_addr == ip->ip_dst.s_addr) { 566 DifferentialChecksum(&pip->ip_sum, 567 (u_short *) & alias_address, 568 (u_short *) & pip->ip_src, 569 2); 570 pip->ip_src = alias_address; 571 } |
572/* Alias address and port number of original IP packet 573fragment contained in ICMP data section */ |
574 ip->ip_dst = alias_address; 575 ud->uh_dport = alias_port; 576 } else if (ip->ip_p == IPPROTO_ICMP) { 577 u_short *sptr; 578 int accumulate; 579 struct in_addr alias_address; 580 u_short alias_id; |
581 |
582 alias_address = GetAliasAddress(link); 583 alias_id = GetAliasPort(link); |
584 585/* Adjust ICMP checksum */ |
586 sptr = (u_short *) & (ip->ip_dst); 587 accumulate = *sptr++; 588 accumulate += *sptr; 589 sptr = (u_short *) & alias_address; 590 accumulate -= *sptr++; 591 accumulate -= *sptr; 592 accumulate += ic2->icmp_id; 593 accumulate -= alias_id; 594 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); |
595 596/* 597 * Alias address in IP header if it comes from the host 598 * the original ICMP message was destined for. 599 */ |
600 if (pip->ip_src.s_addr == ip->ip_dst.s_addr) { 601 DifferentialChecksum(&pip->ip_sum, 602 (u_short *) & alias_address, 603 (u_short *) & pip->ip_src, 604 2); 605 pip->ip_src = alias_address; 606 } |
607/* Alias address of original IP packet and sequence number of 608 embedded ICMP datagram */ |
609 ip->ip_dst = alias_address; 610 ic2->icmp_id = alias_id; 611 } 612 return (PKT_ALIAS_OK); 613 } 614 return (PKT_ALIAS_IGNORED); |
615} 616 617 618static int 619IcmpAliasOut(struct libalias *la, struct ip *pip) 620{ |
621 int iresult; 622 struct icmp *ic; |
623 624/* Return if proxy-only mode is enabled */ |
625 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) 626 return PKT_ALIAS_OK; |
627 |
628 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2)); |
629 |
630 iresult = PKT_ALIAS_IGNORED; 631 switch (ic->icmp_type) { 632 case ICMP_ECHO: 633 case ICMP_TSTAMP: 634 if (ic->icmp_code == 0) { 635 iresult = IcmpAliasOut1(la, pip); 636 } 637 break; 638 case ICMP_UNREACH: 639 case ICMP_SOURCEQUENCH: 640 case ICMP_TIMXCEED: 641 case ICMP_PARAMPROB: 642 iresult = IcmpAliasOut2(la, pip); 643 break; 644 case ICMP_ECHOREPLY: 645 case ICMP_TSTAMPREPLY: 646 iresult = IcmpAliasOut1(la, pip); 647 } 648 return (iresult); |
649} 650 651 652 653static int 654ProtoAliasIn(struct libalias *la, struct ip *pip) 655{ 656/* 657 Handle incoming IP packets. The 658 only thing which is done in this case is to alias 659 the dest IP address of the packet to our inside 660 machine. 661*/ |
662 struct alias_link *link; |
663 664/* Return if proxy-only mode is enabled */ |
665 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) 666 return PKT_ALIAS_OK; |
667 |
668 link = FindProtoIn(la, pip->ip_src, pip->ip_dst, pip->ip_p); 669 if (link != NULL) { 670 struct in_addr original_address; |
671 |
672 original_address = GetOriginalAddress(link); |
673 674/* Restore original IP address */ |
675 DifferentialChecksum(&pip->ip_sum, 676 (u_short *) & original_address, 677 (u_short *) & pip->ip_dst, 678 2); 679 pip->ip_dst = original_address; |
680 |
681 return (PKT_ALIAS_OK); 682 } 683 return (PKT_ALIAS_IGNORED); |
684} 685 686 687static int 688ProtoAliasOut(struct libalias *la, struct ip *pip) 689{ 690/* 691 Handle outgoing IP packets. The 692 only thing which is done in this case is to alias 693 the source IP address of the packet. 694*/ |
695 struct alias_link *link; |
696 697/* Return if proxy-only mode is enabled */ |
698 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) 699 return PKT_ALIAS_OK; |
700 |
701 link = FindProtoOut(la, pip->ip_src, pip->ip_dst, pip->ip_p); 702 if (link != NULL) { 703 struct in_addr alias_address; |
704 |
705 alias_address = GetAliasAddress(link); |
706 707/* Change source address */ |
708 DifferentialChecksum(&pip->ip_sum, 709 (u_short *) & alias_address, 710 (u_short *) & pip->ip_src, 711 2); 712 pip->ip_src = alias_address; |
713 |
714 return (PKT_ALIAS_OK); 715 } 716 return (PKT_ALIAS_IGNORED); |
717} 718 719 720static int 721UdpAliasIn(struct libalias *la, struct ip *pip) 722{ |
723 struct udphdr *ud; 724 struct alias_link *link; |
725 726/* Return if proxy-only mode is enabled */ |
727 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) 728 return PKT_ALIAS_OK; |
729 |
730 ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2)); |
731 |
732 link = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, 733 ud->uh_sport, ud->uh_dport, 734 IPPROTO_UDP, 1); 735 if (link != NULL) { 736 struct in_addr alias_address; 737 struct in_addr original_address; 738 u_short alias_port; 739 int accumulate; 740 u_short *sptr; 741 int r = 0; |
742 |
743 alias_address = GetAliasAddress(link); 744 original_address = GetOriginalAddress(link); 745 alias_port = ud->uh_dport; 746 ud->uh_dport = GetOriginalPort(link); |
747 748/* Special processing for IP encoding protocols */ |
749 if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) 750 AliasHandleCUSeeMeIn(la, pip, original_address); |
751/* If NETBIOS Datagram, It should be alias address in UDP Data, too */ |
752 else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER 753 || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) 754 r = AliasHandleUdpNbt(la, pip, link, &original_address, ud->uh_dport); 755 else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER 756 || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) 757 r = AliasHandleUdpNbtNS(la, pip, link, &alias_address, &alias_port, 758 &original_address, &ud->uh_dport); |
759 760/* If UDP checksum is not zero, then adjust since destination port */ 761/* is being unaliased and destination address is being altered. */ |
762 if (ud->uh_sum != 0) { 763 accumulate = alias_port; 764 accumulate -= ud->uh_dport; 765 sptr = (u_short *) & alias_address; 766 accumulate += *sptr++; 767 accumulate += *sptr; 768 sptr = (u_short *) & original_address; 769 accumulate -= *sptr++; 770 accumulate -= *sptr; 771 ADJUST_CHECKSUM(accumulate, ud->uh_sum); 772 } |
773/* Restore original IP address */ |
774 DifferentialChecksum(&pip->ip_sum, 775 (u_short *) & original_address, 776 (u_short *) & pip->ip_dst, 777 2); 778 pip->ip_dst = original_address; |
779 |
780 /* 781 * If we cannot figure out the packet, ignore it. 782 */ 783 if (r < 0) 784 return (PKT_ALIAS_IGNORED); 785 else 786 return (PKT_ALIAS_OK); 787 } 788 return (PKT_ALIAS_IGNORED); |
789} 790 791static int 792UdpAliasOut(struct libalias *la, struct ip *pip) 793{ |
794 struct udphdr *ud; 795 struct alias_link *link; |
796 797/* Return if proxy-only mode is enabled */ |
798 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) 799 return PKT_ALIAS_OK; |
800 |
801 ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2)); |
802 |
803 link = FindUdpTcpOut(la, pip->ip_src, pip->ip_dst, 804 ud->uh_sport, ud->uh_dport, 805 IPPROTO_UDP, 1); 806 if (link != NULL) { 807 u_short alias_port; 808 struct in_addr alias_address; |
809 |
810 alias_address = GetAliasAddress(link); 811 alias_port = GetAliasPort(link); |
812 813/* Special processing for IP encoding protocols */ |
814 if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) 815 AliasHandleCUSeeMeOut(la, pip, link); |
816/* If NETBIOS Datagram, It should be alias address in UDP Data, too */ |
817 else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER 818 || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) 819 AliasHandleUdpNbt(la, pip, link, &alias_address, alias_port); 820 else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER 821 || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) 822 AliasHandleUdpNbtNS(la, pip, link, &pip->ip_src, &ud->uh_sport, 823 &alias_address, &alias_port); |
824/* 825 * We don't know in advance what TID the TFTP server will choose, 826 * so we create a wilcard link (destination port is unspecified) 827 * that will match any TID from a given destination. 828 */ |
829 else if (ntohs(ud->uh_dport) == TFTP_PORT_NUMBER) 830 FindRtspOut(la, pip->ip_src, pip->ip_dst, 831 ud->uh_sport, alias_port, IPPROTO_UDP); |
832 833/* If UDP checksum is not zero, adjust since source port is */ 834/* being aliased and source address is being altered */ |
835 if (ud->uh_sum != 0) { 836 int accumulate; 837 u_short *sptr; |
838 |
839 accumulate = ud->uh_sport; 840 accumulate -= alias_port; 841 sptr = (u_short *) & (pip->ip_src); 842 accumulate += *sptr++; 843 accumulate += *sptr; 844 sptr = (u_short *) & alias_address; 845 accumulate -= *sptr++; 846 accumulate -= *sptr; 847 ADJUST_CHECKSUM(accumulate, ud->uh_sum); 848 } |
849/* Put alias port in UDP header */ |
850 ud->uh_sport = alias_port; |
851 852/* Change source address */ |
853 DifferentialChecksum(&pip->ip_sum, 854 (u_short *) & alias_address, 855 (u_short *) & pip->ip_src, 856 2); 857 pip->ip_src = alias_address; |
858 |
859 return (PKT_ALIAS_OK); 860 } 861 return (PKT_ALIAS_IGNORED); |
862} 863 864 865 866static int 867TcpAliasIn(struct libalias *la, struct ip *pip) 868{ |
869 struct tcphdr *tc; 870 struct alias_link *link; |
871 |
872 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); |
873 |
874 link = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, 875 tc->th_sport, tc->th_dport, 876 IPPROTO_TCP, 877 !(la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)); 878 if (link != NULL) { 879 struct in_addr alias_address; 880 struct in_addr original_address; 881 struct in_addr proxy_address; 882 u_short alias_port; 883 u_short proxy_port; 884 int accumulate; 885 u_short *sptr; |
886 887/* Special processing for IP encoding protocols */ |
888 if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER 889 || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) 890 AliasHandlePptpIn(la, pip, link); 891 else if (la->skinnyPort != 0 && (ntohs(tc->th_dport) == la->skinnyPort 892 || ntohs(tc->th_sport) == la->skinnyPort)) 893 AliasHandleSkinny(la, pip, link); |
894 |
895 alias_address = GetAliasAddress(link); 896 original_address = GetOriginalAddress(link); 897 proxy_address = GetProxyAddress(link); 898 alias_port = tc->th_dport; 899 tc->th_dport = GetOriginalPort(link); 900 proxy_port = GetProxyPort(link); |
901 902/* Adjust TCP checksum since destination port is being unaliased */ 903/* and destination port is being altered. */ |
904 accumulate = alias_port; 905 accumulate -= tc->th_dport; 906 sptr = (u_short *) & alias_address; 907 accumulate += *sptr++; 908 accumulate += *sptr; 909 sptr = (u_short *) & original_address; 910 accumulate -= *sptr++; 911 accumulate -= *sptr; |
912 913/* If this is a proxy, then modify the TCP source port and 914 checksum accumulation */ |
915 if (proxy_port != 0) { 916 accumulate += tc->th_sport; 917 tc->th_sport = proxy_port; 918 accumulate -= tc->th_sport; |
919 |
920 sptr = (u_short *) & pip->ip_src; 921 accumulate += *sptr++; 922 accumulate += *sptr; 923 sptr = (u_short *) & proxy_address; 924 accumulate -= *sptr++; 925 accumulate -= *sptr; 926 } |
927/* See if ACK number needs to be modified */ |
928 if (GetAckModified(link) == 1) { 929 int delta; |
930 |
931 delta = GetDeltaAckIn(pip, link); 932 if (delta != 0) { 933 sptr = (u_short *) & tc->th_ack; 934 accumulate += *sptr++; 935 accumulate += *sptr; 936 tc->th_ack = htonl(ntohl(tc->th_ack) - delta); 937 sptr = (u_short *) & tc->th_ack; 938 accumulate -= *sptr++; 939 accumulate -= *sptr; 940 } 941 } 942 ADJUST_CHECKSUM(accumulate, tc->th_sum); |
943 |
944/* Restore original IP address */ |
945 sptr = (u_short *) & pip->ip_dst; 946 accumulate = *sptr++; 947 accumulate += *sptr; 948 pip->ip_dst = original_address; 949 sptr = (u_short *) & pip->ip_dst; 950 accumulate -= *sptr++; 951 accumulate -= *sptr; |
952 953/* If this is a transparent proxy packet, then modify the source 954 address */ |
955 if (proxy_address.s_addr != 0) { 956 sptr = (u_short *) & pip->ip_src; 957 accumulate += *sptr++; 958 accumulate += *sptr; 959 pip->ip_src = proxy_address; 960 sptr = (u_short *) & pip->ip_src; 961 accumulate -= *sptr++; 962 accumulate -= *sptr; 963 } 964 ADJUST_CHECKSUM(accumulate, pip->ip_sum); |
965 |
966/* Monitor TCP connection state */ |
967 TcpMonitorIn(pip, link); |
968 |
969 return (PKT_ALIAS_OK); 970 } 971 return (PKT_ALIAS_IGNORED); |
972} 973 974static int 975TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize) 976{ |
977 int proxy_type; 978 u_short dest_port; 979 u_short proxy_server_port; 980 struct in_addr dest_address; 981 struct in_addr proxy_server_address; 982 struct tcphdr *tc; 983 struct alias_link *link; |
984 |
985 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); |
986 |
987 proxy_type = ProxyCheck(la, pip, &proxy_server_address, &proxy_server_port); |
988 |
989 if (proxy_type == 0 && (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)) 990 return PKT_ALIAS_OK; |
991 992/* If this is a transparent proxy, save original destination, 993 then alter the destination and adjust checksums */ |
994 dest_port = tc->th_dport; 995 dest_address = pip->ip_dst; 996 if (proxy_type != 0) { 997 int accumulate; 998 u_short *sptr; |
999 |
1000 accumulate = tc->th_dport; 1001 tc->th_dport = proxy_server_port; 1002 accumulate -= tc->th_dport; |
1003 |
1004 sptr = (u_short *) & (pip->ip_dst); 1005 accumulate += *sptr++; 1006 accumulate += *sptr; 1007 sptr = (u_short *) & proxy_server_address; 1008 accumulate -= *sptr++; 1009 accumulate -= *sptr; |
1010 |
1011 ADJUST_CHECKSUM(accumulate, tc->th_sum); |
1012 |
1013 sptr = (u_short *) & (pip->ip_dst); 1014 accumulate = *sptr++; 1015 accumulate += *sptr; 1016 pip->ip_dst = proxy_server_address; 1017 sptr = (u_short *) & (pip->ip_dst); 1018 accumulate -= *sptr++; 1019 accumulate -= *sptr; |
1020 |
1021 ADJUST_CHECKSUM(accumulate, pip->ip_sum); 1022 } 1023 link = FindUdpTcpOut(la, pip->ip_src, pip->ip_dst, 1024 tc->th_sport, tc->th_dport, 1025 IPPROTO_TCP, 1); 1026 if (link != NULL) { 1027 u_short alias_port; 1028 struct in_addr alias_address; 1029 int accumulate; 1030 u_short *sptr; |
1031 |
1032/* Save original destination address, if this is a proxy packet. 1033 Also modify packet to include destination encoding. This may 1034 change the size of IP header. */ |
1035 if (proxy_type != 0) { 1036 SetProxyPort(link, dest_port); 1037 SetProxyAddress(link, dest_address); 1038 ProxyModify(la, link, pip, maxpacketsize, proxy_type); 1039 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); 1040 } |
1041/* Get alias address and port */ |
1042 alias_port = GetAliasPort(link); 1043 alias_address = GetAliasAddress(link); |
1044 1045/* Monitor TCP connection state */ |
1046 TcpMonitorOut(pip, link); |
1047 1048/* Special processing for IP encoding protocols */ |
1049 if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER 1050 || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER) 1051 AliasHandleFtpOut(la, pip, link, maxpacketsize); 1052 else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1 1053 || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2) 1054 AliasHandleIrcOut(la, pip, link, maxpacketsize); 1055 else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1 1056 || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1 1057 || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2 1058 || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2) 1059 AliasHandleRtspOut(la, pip, link, maxpacketsize); 1060 else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER 1061 || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) 1062 AliasHandlePptpOut(la, pip, link); 1063 else if (la->skinnyPort != 0 && (ntohs(tc->th_sport) == la->skinnyPort 1064 || ntohs(tc->th_dport) == la->skinnyPort)) 1065 AliasHandleSkinny(la, pip, link); |
1066 1067/* Adjust TCP checksum since source port is being aliased */ 1068/* and source address is being altered */ |
1069 accumulate = tc->th_sport; 1070 tc->th_sport = alias_port; 1071 accumulate -= tc->th_sport; |
1072 |
1073 sptr = (u_short *) & (pip->ip_src); 1074 accumulate += *sptr++; 1075 accumulate += *sptr; 1076 sptr = (u_short *) & alias_address; 1077 accumulate -= *sptr++; 1078 accumulate -= *sptr; |
1079 1080/* Modify sequence number if necessary */ |
1081 if (GetAckModified(link) == 1) { 1082 int delta; |
1083 |
1084 delta = GetDeltaSeqOut(pip, link); 1085 if (delta != 0) { 1086 sptr = (u_short *) & tc->th_seq; 1087 accumulate += *sptr++; 1088 accumulate += *sptr; 1089 tc->th_seq = htonl(ntohl(tc->th_seq) + delta); 1090 sptr = (u_short *) & tc->th_seq; 1091 accumulate -= *sptr++; 1092 accumulate -= *sptr; 1093 } 1094 } 1095 ADJUST_CHECKSUM(accumulate, tc->th_sum); |
1096 |
1097/* Change source address */ |
1098 sptr = (u_short *) & (pip->ip_src); 1099 accumulate = *sptr++; 1100 accumulate += *sptr; 1101 pip->ip_src = alias_address; 1102 sptr = (u_short *) & (pip->ip_src); 1103 accumulate -= *sptr++; 1104 accumulate -= *sptr; |
1105 |
1106 ADJUST_CHECKSUM(accumulate, pip->ip_sum); |
1107 |
1108 return (PKT_ALIAS_OK); 1109 } 1110 return (PKT_ALIAS_IGNORED); |
1111} 1112 1113 1114 1115 1116/* Fragment Handling 1117 1118 FragmentIn() 1119 FragmentOut() 1120 1121The packet aliasing module has a limited ability for handling IP 1122fragments. If the ICMP, TCP or UDP header is in the first fragment 1123received, then the ID number of the IP packet is saved, and other 1124fragments are identified according to their ID number and IP address 1125they were sent from. Pointers to unresolved fragments can also be 1126saved and recalled when a header fragment is seen. 1127*/ 1128 1129/* Local prototypes */ |
1130static int FragmentIn(struct libalias *, struct ip *); 1131static int FragmentOut(struct libalias *, struct ip *); |
1132 1133 1134static int 1135FragmentIn(struct libalias *la, struct ip *pip) 1136{ |
1137 struct alias_link *link; |
1138 |
1139 link = FindFragmentIn2(la, pip->ip_src, pip->ip_dst, pip->ip_id); 1140 if (link != NULL) { 1141 struct in_addr original_address; |
1142 |
1143 GetFragmentAddr(link, &original_address); 1144 DifferentialChecksum(&pip->ip_sum, 1145 (u_short *) & original_address, 1146 (u_short *) & pip->ip_dst, 1147 2); 1148 pip->ip_dst = original_address; |
1149 |
1150 return (PKT_ALIAS_OK); 1151 } 1152 return (PKT_ALIAS_UNRESOLVED_FRAGMENT); |
1153} 1154 1155 1156static int 1157FragmentOut(struct libalias *la, struct ip *pip) 1158{ |
1159 struct in_addr alias_address; |
1160 |
1161 alias_address = FindAliasAddress(la, pip->ip_src); 1162 DifferentialChecksum(&pip->ip_sum, 1163 (u_short *) & alias_address, 1164 (u_short *) & pip->ip_src, 1165 2); 1166 pip->ip_src = alias_address; |
1167 |
1168 return (PKT_ALIAS_OK); |
1169} 1170 1171 1172 1173 1174 1175 1176/* Outside World Access --- 7 unchanged lines hidden (view full) --- 1184 1185(prototypes in alias.h) 1186*/ 1187 1188 1189int 1190LibAliasSaveFragment(struct libalias *la, char *ptr) 1191{ |
1192 int iresult; 1193 struct alias_link *link; 1194 struct ip *pip; |
1195 |
1196 pip = (struct ip *)ptr; 1197 link = AddFragmentPtrLink(la, pip->ip_src, pip->ip_id); 1198 iresult = PKT_ALIAS_ERROR; 1199 if (link != NULL) { 1200 SetFragmentPtr(link, ptr); 1201 iresult = PKT_ALIAS_OK; 1202 } 1203 return (iresult); |
1204} 1205 1206 |
1207char * |
1208LibAliasGetFragment(struct libalias *la, char *ptr) 1209{ |
1210 struct alias_link *link; 1211 char *fptr; 1212 struct ip *pip; |
1213 |
1214 pip = (struct ip *)ptr; 1215 link = FindFragmentPtr(la, pip->ip_src, pip->ip_id); 1216 if (link != NULL) { 1217 GetFragmentPtr(link, &fptr); 1218 SetFragmentPtr(link, NULL); 1219 SetExpire(link, 0); /* Deletes link */ |
1220 |
1221 return (fptr); 1222 } else { 1223 return (NULL); 1224 } |
1225} 1226 1227 1228void |
1229LibAliasFragmentIn(struct libalias *la, char *ptr, /* Points to correctly 1230 * de-aliased header 1231 * fragment */ 1232 char *ptr_fragment /* Points to fragment which must be 1233 * de-aliased */ 1234) |
1235{ |
1236 struct ip *pip; 1237 struct ip *fpip; |
1238 |
1239 pip = (struct ip *)ptr; 1240 fpip = (struct ip *)ptr_fragment; |
1241 |
1242 DifferentialChecksum(&fpip->ip_sum, 1243 (u_short *) & pip->ip_dst, 1244 (u_short *) & fpip->ip_dst, 1245 2); 1246 fpip->ip_dst = pip->ip_dst; |
1247} 1248 1249 1250int 1251LibAliasIn(struct libalias *la, char *ptr, int maxpacketsize) 1252{ |
1253 struct in_addr alias_addr; 1254 struct ip *pip; 1255 int iresult; |
1256 |
1257 if (la->packetAliasMode & PKT_ALIAS_REVERSE) { 1258 la->packetAliasMode &= ~PKT_ALIAS_REVERSE; 1259 iresult = PacketAliasOut(ptr, maxpacketsize); 1260 la->packetAliasMode |= PKT_ALIAS_REVERSE; 1261 return iresult; 1262 } 1263 HouseKeeping(la); 1264 ClearCheckNewLink(la); 1265 pip = (struct ip *)ptr; 1266 alias_addr = pip->ip_dst; |
1267 |
1268 /* Defense against mangled packets */ 1269 if (ntohs(pip->ip_len) > maxpacketsize 1270 || (pip->ip_hl << 2) > maxpacketsize) 1271 return PKT_ALIAS_IGNORED; |
1272 |
1273 iresult = PKT_ALIAS_IGNORED; 1274 if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) { 1275 switch (pip->ip_p) { 1276 case IPPROTO_ICMP: 1277 iresult = IcmpAliasIn(la, pip); 1278 break; 1279 case IPPROTO_UDP: 1280 iresult = UdpAliasIn(la, pip); 1281 break; 1282 case IPPROTO_TCP: 1283 iresult = TcpAliasIn(la, pip); 1284 break; 1285 case IPPROTO_GRE: 1286 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY || 1287 AliasHandlePptpGreIn(la, pip) == 0) 1288 iresult = PKT_ALIAS_OK; 1289 else 1290 iresult = ProtoAliasIn(la, pip); 1291 break; 1292 default: 1293 iresult = ProtoAliasIn(la, pip); 1294 break; 1295 } |
1296 |
1297 if (ntohs(pip->ip_off) & IP_MF) { 1298 struct alias_link *link; |
1299 |
1300 link = FindFragmentIn1(la, pip->ip_src, alias_addr, pip->ip_id); 1301 if (link != NULL) { 1302 iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT; 1303 SetFragmentAddr(link, pip->ip_dst); 1304 } else { 1305 iresult = PKT_ALIAS_ERROR; 1306 } 1307 } 1308 } else { 1309 iresult = FragmentIn(la, pip); 1310 } |
1311 |
1312 return (iresult); |
1313} 1314 1315 1316 1317/* Unregistered address ranges */ 1318 1319/* 10.0.0.0 -> 10.255.255.255 */ 1320#define UNREG_ADDR_A_LOWER 0x0a000000 1321#define UNREG_ADDR_A_UPPER 0x0affffff 1322 1323/* 172.16.0.0 -> 172.31.255.255 */ 1324#define UNREG_ADDR_B_LOWER 0xac100000 1325#define UNREG_ADDR_B_UPPER 0xac1fffff 1326 1327/* 192.168.0.0 -> 192.168.255.255 */ 1328#define UNREG_ADDR_C_LOWER 0xc0a80000 1329#define UNREG_ADDR_C_UPPER 0xc0a8ffff 1330 1331int |
1332LibAliasOut(struct libalias *la, char *ptr, /* valid IP packet */ 1333 int maxpacketsize /* How much the packet data may grow (FTP 1334 * and IRC inline changes) */ 1335) |
1336{ |
1337 int iresult; 1338 struct in_addr addr_save; 1339 struct ip *pip; |
1340 |
1341 if (la->packetAliasMode & PKT_ALIAS_REVERSE) { 1342 la->packetAliasMode &= ~PKT_ALIAS_REVERSE; 1343 iresult = PacketAliasIn(ptr, maxpacketsize); 1344 la->packetAliasMode |= PKT_ALIAS_REVERSE; 1345 return iresult; 1346 } 1347 HouseKeeping(la); 1348 ClearCheckNewLink(la); 1349 pip = (struct ip *)ptr; |
1350 |
1351 /* Defense against mangled packets */ 1352 if (ntohs(pip->ip_len) > maxpacketsize 1353 || (pip->ip_hl << 2) > maxpacketsize) 1354 return PKT_ALIAS_IGNORED; |
1355 |
1356 addr_save = GetDefaultAliasAddress(la); 1357 if (la->packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY) { 1358 u_long addr; 1359 int iclass; |
1360 |
1361 iclass = 0; 1362 addr = ntohl(pip->ip_src.s_addr); 1363 if (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER) 1364 iclass = 3; 1365 else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER) 1366 iclass = 2; 1367 else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER) 1368 iclass = 1; |
1369 |
1370 if (iclass == 0) { 1371 SetDefaultAliasAddress(la, pip->ip_src); 1372 } 1373 } else if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) { 1374 SetDefaultAliasAddress(la, pip->ip_src); 1375 } 1376 iresult = PKT_ALIAS_IGNORED; 1377 if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) { 1378 switch (pip->ip_p) { 1379 case IPPROTO_ICMP: 1380 iresult = IcmpAliasOut(la, pip); 1381 break; 1382 case IPPROTO_UDP: 1383 iresult = UdpAliasOut(la, pip); 1384 break; 1385 case IPPROTO_TCP: 1386 iresult = TcpAliasOut(la, pip, maxpacketsize); 1387 break; 1388 case IPPROTO_GRE: 1389 if (AliasHandlePptpGreOut(la, pip) == 0) 1390 iresult = PKT_ALIAS_OK; 1391 else 1392 iresult = ProtoAliasOut(la, pip); 1393 break; 1394 default: 1395 iresult = ProtoAliasOut(la, pip); 1396 break; 1397 } 1398 } else { 1399 iresult = FragmentOut(la, pip); 1400 } |
1401 |
1402 SetDefaultAliasAddress(la, addr_save); 1403 return (iresult); |
1404} 1405 1406int |
1407LibAliasUnaliasOut(struct libalias *la, char *ptr, /* valid IP packet */ 1408 int maxpacketsize /* for error checking */ 1409) |
1410{ |
1411 struct ip *pip; 1412 struct icmp *ic; 1413 struct udphdr *ud; 1414 struct tcphdr *tc; 1415 struct alias_link *link; 1416 int iresult = PKT_ALIAS_IGNORED; |
1417 |
1418 pip = (struct ip *)ptr; |
1419 |
1420 /* Defense against mangled packets */ 1421 if (ntohs(pip->ip_len) > maxpacketsize 1422 || (pip->ip_hl << 2) > maxpacketsize) 1423 return (iresult); |
1424 |
1425 ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2)); 1426 tc = (struct tcphdr *)ud; 1427 ic = (struct icmp *)ud; |
1428 |
1429 /* Find a link */ 1430 if (pip->ip_p == IPPROTO_UDP) 1431 link = FindUdpTcpIn(la, pip->ip_dst, pip->ip_src, 1432 ud->uh_dport, ud->uh_sport, 1433 IPPROTO_UDP, 0); 1434 else if (pip->ip_p == IPPROTO_TCP) 1435 link = FindUdpTcpIn(la, pip->ip_dst, pip->ip_src, 1436 tc->th_dport, tc->th_sport, 1437 IPPROTO_TCP, 0); 1438 else if (pip->ip_p == IPPROTO_ICMP) 1439 link = FindIcmpIn(la, pip->ip_dst, pip->ip_src, ic->icmp_id, 0); 1440 else 1441 link = NULL; |
1442 |
1443 /* Change it from an aliased packet to an unaliased packet */ 1444 if (link != NULL) { 1445 if (pip->ip_p == IPPROTO_UDP || pip->ip_p == IPPROTO_TCP) { 1446 u_short *sptr; 1447 int accumulate; 1448 struct in_addr original_address; 1449 u_short original_port; |
1450 |
1451 original_address = GetOriginalAddress(link); 1452 original_port = GetOriginalPort(link); |
1453 |
1454 /* Adjust TCP/UDP checksum */ 1455 sptr = (u_short *) & (pip->ip_src); 1456 accumulate = *sptr++; 1457 accumulate += *sptr; 1458 sptr = (u_short *) & original_address; 1459 accumulate -= *sptr++; 1460 accumulate -= *sptr; |
1461 |
1462 if (pip->ip_p == IPPROTO_UDP) { 1463 accumulate += ud->uh_sport; 1464 accumulate -= original_port; 1465 ADJUST_CHECKSUM(accumulate, ud->uh_sum); 1466 } else { 1467 accumulate += tc->th_sport; 1468 accumulate -= original_port; 1469 ADJUST_CHECKSUM(accumulate, tc->th_sum); 1470 } |
1471 |
1472 /* Adjust IP checksum */ 1473 DifferentialChecksum(&pip->ip_sum, 1474 (u_short *) & original_address, 1475 (u_short *) & pip->ip_src, 1476 2); |
1477 |
1478 /* Un-alias source address and port number */ 1479 pip->ip_src = original_address; 1480 if (pip->ip_p == IPPROTO_UDP) 1481 ud->uh_sport = original_port; 1482 else 1483 tc->th_sport = original_port; |
1484 |
1485 iresult = PKT_ALIAS_OK; |
1486 |
1487 } else if (pip->ip_p == IPPROTO_ICMP) { |
1488 |
1489 u_short *sptr; 1490 int accumulate; 1491 struct in_addr original_address; 1492 u_short original_id; |
1493 |
1494 original_address = GetOriginalAddress(link); 1495 original_id = GetOriginalPort(link); |
1496 |
1497 /* Adjust ICMP checksum */ 1498 sptr = (u_short *) & (pip->ip_src); 1499 accumulate = *sptr++; 1500 accumulate += *sptr; 1501 sptr = (u_short *) & original_address; 1502 accumulate -= *sptr++; 1503 accumulate -= *sptr; 1504 accumulate += ic->icmp_id; 1505 accumulate -= original_id; 1506 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum); |
1507 |
1508 /* Adjust IP checksum */ 1509 DifferentialChecksum(&pip->ip_sum, 1510 (u_short *) & original_address, 1511 (u_short *) & pip->ip_src, 1512 2); |
1513 |
1514 /* Un-alias source address and port number */ 1515 pip->ip_src = original_address; 1516 ic->icmp_id = original_id; |
1517 |
1518 iresult = PKT_ALIAS_OK; 1519 } 1520 } 1521 return (iresult); |
1522 1523} |