alias.c revision 67980
1265555Sambrisko/* -*- mode: c; tab-width: 8; c-basic-indent: 4; -*- */ 2282531Skadesai/* 3272744Skadesai Alias.c provides supervisory control for the functions of the 4282531Skadesai packet aliasing software. It consists of routines to monitor 5265555Sambrisko TCP connection state, protocol-specific aliasing routines, 6265555Sambrisko fragment handling and the following outside world functional 7272744Skadesai interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn, 8272744Skadesai PacketAliasIn and PacketAliasOut. 9265555Sambrisko 10272744Skadesai The other C program files are briefly described. The data 11272744Skadesai structure framework which holds information needed to translate 12272744Skadesai packets is encapsulated in alias_db.c. Data is accessed by 13272744Skadesai function calls, so other segments of the program need not know 14272744Skadesai about the underlying data structures. Alias_ftp.c contains 15272744Skadesai special code for modifying the ftp PORT command used to establish 16272744Skadesai data connections, while alias_irc.c does the same for IRC 17272744Skadesai DCC. Alias_util.c contains a few utility routines. 18265555Sambrisko 19272744Skadesai This software is placed into the public domain with no restrictions 20272744Skadesai on its distribution. 21272744Skadesai 22272744Skadesai Version 1.0 August, 1996 (cjm) 23272744Skadesai 24272744Skadesai Version 1.1 August 20, 1996 (cjm) 25272744Skadesai PPP host accepts incoming connections for ports 0 to 1023. 26272744Skadesai (Gary Roberts pointed out the need to handle incoming 27272744Skadesai connections.) 28272744Skadesai 29265555Sambrisko Version 1.2 September 7, 1996 (cjm) 30265555Sambrisko Fragment handling error in alias_db.c corrected. 31272744Skadesai (Tom Torrance helped fix this problem.) 32272744Skadesai 33265555Sambrisko Version 1.4 September 16, 1996 (cjm) 34265555Sambrisko - A more generalized method for handling incoming 35282531Skadesai connections, without the 0-1023 restriction, is 36272744Skadesai implemented in alias_db.c 37265555Sambrisko - Improved ICMP support in alias.c. Traceroute 38265555Sambrisko packet streams can now be correctly aliased. 39265555Sambrisko - TCP connection closing logic simplified in 40265555Sambrisko alias.c and now allows for additional 1 minute 41265555Sambrisko "grace period" after FIN or RST is observed. 42265555Sambrisko 43265555Sambrisko Version 1.5 September 17, 1996 (cjm) 44265555Sambrisko Corrected error in handling incoming UDP packets with 0 checksum. 45265555Sambrisko (Tom Torrance helped fix this problem.) 46265555Sambrisko 47265555Sambrisko Version 1.6 September 18, 1996 (cjm) 48265555Sambrisko Simplified ICMP aliasing scheme. Should now support 49265555Sambrisko traceroute from Win95 as well as FreeBSD. 50265555Sambrisko 51265555Sambrisko Version 1.7 January 9, 1997 (cjm) 52265555Sambrisko - Out-of-order fragment handling. 53265555Sambrisko - IP checksum error fixed for ftp transfers 54265555Sambrisko from aliasing host. 55265555Sambrisko - Integer return codes added to all 56265555Sambrisko aliasing/de-aliasing functions. 57265555Sambrisko - Some obsolete comments cleaned up. 58272744Skadesai - Differential checksum computations for 59282533Skadesai IP header (TCP, UDP and ICMP were already 60282533Skadesai differential). 61282533Skadesai 62272744Skadesai Version 2.1 May 1997 (cjm) 63272744Skadesai - Added support for outgoing ICMP error 64272744Skadesai messages. 65282533Skadesai - Added two functions PacketAliasIn2() 66272744Skadesai and PacketAliasOut2() for dynamic address 67272744Skadesai control (e.g. round-robin allocation of 68272744Skadesai incoming packets). 69272744Skadesai 70272744Skadesai Version 2.2 July 1997 (cjm) 71272744Skadesai - Rationalized API function names to begin 72272744Skadesai with "PacketAlias..." 73282533Skadesai - Eliminated PacketAliasIn2() and 74282533Skadesai PacketAliasOut2() as poorly conceived. 75282533Skadesai 76265555Sambrisko Version 2.3 Dec 1998 (dillon) 77282533Skadesai - Major bounds checking additions, see FreeBSD/CVS 78272744Skadesai 79272744Skadesai Version 3.1 May, 2000 (salander) 80265555Sambrisko - Added hooks to handle PPTP. 81272744Skadesai 82282533Skadesai Version 3.2 July, 2000 (salander and satoh) 83282533Skadesai - Added PacketUnaliasOut routine. 84282533Skadesai - Added hooks to handle RTSP/RTP. 85272744Skadesai 86272744Skadesai See HISTORY file for additional revisions. 87272744Skadesai 88272744Skadesai $FreeBSD: head/sys/netinet/libalias/alias.c 67980 2000-10-30 17:24:12Z ru $ 89282533Skadesai*/ 90272744Skadesai 91272744Skadesai#include <sys/types.h> 92272744Skadesai 93282533Skadesai#include <netinet/in_systm.h> 94272744Skadesai#include <netinet/in.h> 95272744Skadesai#include <netinet/ip.h> 96272744Skadesai#include <netinet/ip_icmp.h> 97272744Skadesai#include <netinet/tcp.h> 98272744Skadesai#include <netinet/udp.h> 99282533Skadesai 100272744Skadesai#include "alias_local.h" 101272744Skadesai#include "alias.h" 102272744Skadesai 103272744Skadesai#define NETBIOS_NS_PORT_NUMBER 137 104272744Skadesai#define NETBIOS_DGM_PORT_NUMBER 138 105272744Skadesai#define FTP_CONTROL_PORT_NUMBER 21 106272744Skadesai#define IRC_CONTROL_PORT_NUMBER_1 6667 107265555Sambrisko#define IRC_CONTROL_PORT_NUMBER_2 6668 108272735Skadesai#define CUSEEME_PORT_NUMBER 7648 109265555Sambrisko#define RTSP_CONTROL_PORT_NUMBER_1 554 110272744Skadesai#define RTSP_CONTROL_PORT_NUMBER_2 7070 111272744Skadesai#define PPTP_CONTROL_PORT_NUMBER 1723 112265555Sambrisko 113272744Skadesai 114272744Skadesai 115272744Skadesai 116272744Skadesai/* TCP Handling Routines 117272744Skadesai 118272744Skadesai TcpMonitorIn() -- These routines monitor TCP connections, and 119272744Skadesai TcpMonitorOut() delete a link when a connection is closed. 120272744Skadesai 121272744SkadesaiThese routines look for SYN, FIN and RST flags to determine when TCP 122272744Skadesaiconnections open and close. When a TCP connection closes, the data 123272744Skadesaistructure containing packet aliasing information is deleted after 124272744Skadesaia timeout period. 125272744Skadesai*/ 126272744Skadesai 127272744Skadesai/* Local prototypes */ 128265555Sambriskostatic void TcpMonitorIn(struct ip *, struct alias_link *); 129265555Sambrisko 130265555Sambriskostatic void TcpMonitorOut(struct ip *, struct alias_link *); 131272744Skadesai 132265555Sambrisko 133272744Skadesaistatic void 134272744SkadesaiTcpMonitorIn(struct ip *pip, struct alias_link *link) 135272744Skadesai{ 136272744Skadesai struct tcphdr *tc; 137272744Skadesai 138265555Sambrisko tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); 139265555Sambrisko 140265555Sambrisko switch (GetStateIn(link)) 141265555Sambrisko { 142265555Sambrisko case ALIAS_TCP_STATE_NOT_CONNECTED: 143272744Skadesai if (tc->th_flags & TH_RST) 144272744Skadesai SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED); 145265555Sambrisko else if (tc->th_flags & TH_SYN) 146272744Skadesai SetStateIn(link, ALIAS_TCP_STATE_CONNECTED); 147272744Skadesai break; 148272744Skadesai case ALIAS_TCP_STATE_CONNECTED: 149265555Sambrisko if (tc->th_flags & (TH_FIN | TH_RST)) 150282533Skadesai SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED); 151265555Sambrisko break; 152282527Skadesai } 153265555Sambrisko} 154265555Sambrisko 155265555Sambriskostatic void 156265555SambriskoTcpMonitorOut(struct ip *pip, struct alias_link *link) 157272744Skadesai{ 158265555Sambrisko struct tcphdr *tc; 159272744Skadesai 160265555Sambrisko tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); 161265555Sambrisko 162265555Sambrisko switch (GetStateOut(link)) 163265555Sambrisko { 164265555Sambrisko case ALIAS_TCP_STATE_NOT_CONNECTED: 165265555Sambrisko if (tc->th_flags & TH_RST) 166265555Sambrisko SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED); 167265555Sambrisko else if (tc->th_flags & TH_SYN) 168272744Skadesai SetStateOut(link, ALIAS_TCP_STATE_CONNECTED); 169272744Skadesai break; 170272744Skadesai case ALIAS_TCP_STATE_CONNECTED: 171272744Skadesai if (tc->th_flags & (TH_FIN | TH_RST)) 172272744Skadesai SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED); 173272744Skadesai break; 174265555Sambrisko } 175265555Sambrisko} 176272744Skadesai 177265555Sambrisko 178265555Sambrisko 179265555Sambrisko 180265555Sambrisko 181272744Skadesai/* Protocol Specific Packet Aliasing Routines 182265555Sambrisko 183265555Sambrisko IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2() 184265555Sambrisko IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2() 185265555Sambrisko ProtoAliasIn(), ProtoAliasOut() 186265555Sambrisko UdpAliasIn(), UdpAliasOut() 187265555Sambrisko TcpAliasIn(), TcpAliasOut() 188265555Sambrisko 189272744SkadesaiThese routines handle protocol specific details of packet aliasing. 190265555SambriskoOne may observe a certain amount of repetitive arithmetic in these 191265555Sambriskofunctions, the purpose of which is to compute a revised checksum 192272744Skadesaiwithout actually summing over the entire data packet, which could be 193272744Skadesaiunnecessarily time consuming. 194265555Sambrisko 195272744SkadesaiThe purpose of the packet aliasing routines is to replace the source 196265555Sambriskoaddress of the outgoing packet and then correctly put it back for 197265555Sambriskoany incoming packets. For TCP and UDP, ports are also re-mapped. 198272744Skadesai 199272744SkadesaiFor ICMP echo/timestamp requests and replies, the following scheme 200265555Sambriskois used: the ID number is replaced by an alias for the outgoing 201272744Skadesaipacket. 202265555Sambrisko 203265555SambriskoICMP error messages are handled by looking at the IP fragment 204272744Skadesaiin the data section of the message. 205272744Skadesai 206265555SambriskoFor TCP and UDP protocols, a port number is chosen for an outgoing 207272744Skadesaipacket, and then incoming packets are identified by IP address and 208265555Sambriskoport numbers. For TCP packets, there is additional logic in the event 209265555Sambriskothat sequence and ACK numbers have been altered (as in the case for 210272744SkadesaiFTP data port commands). 211272744Skadesai 212265555SambriskoThe port numbers used by the packet aliasing module are not true 213272744Skadesaiports in the Unix sense. No sockets are actually bound to ports. 214265555SambriskoThey are more correctly thought of as placeholders. 215265555Sambrisko 216272744SkadesaiAll packets go through the aliasing mechanism, whether they come from 217272744Skadesaithe gateway machine or other machines on a local area network. 218265555Sambrisko*/ 219272744Skadesai 220265555Sambrisko 221265555Sambrisko/* Local prototypes */ 222272744Skadesaistatic int IcmpAliasIn1(struct ip *); 223272744Skadesaistatic int IcmpAliasIn2(struct ip *); 224265555Sambriskostatic int IcmpAliasIn (struct ip *); 225272744Skadesai 226265555Sambriskostatic int IcmpAliasOut1(struct ip *); 227265555Sambriskostatic int IcmpAliasOut2(struct ip *); 228272744Skadesaistatic int IcmpAliasOut (struct ip *); 229272744Skadesai 230265555Sambriskostatic int ProtoAliasIn(struct ip *); 231272744Skadesaistatic int ProtoAliasOut(struct ip *); 232265555Sambrisko 233265555Sambriskostatic int UdpAliasOut(struct ip *); 234272744Skadesaistatic int UdpAliasIn (struct ip *); 235272744Skadesai 236265555Sambriskostatic int TcpAliasOut(struct ip *, int); 237272744Skadesaistatic int TcpAliasIn (struct ip *); 238265555Sambrisko 239265555Sambrisko 240272744Skadesaistatic int 241272744SkadesaiIcmpAliasIn1(struct ip *pip) 242265555Sambrisko{ 243272744Skadesai/* 244265555Sambrisko De-alias incoming echo and timestamp replies. 245265555Sambrisko Alias incoming echo and timestamp requests. 246272744Skadesai*/ 247272744Skadesai struct alias_link *link; 248265555Sambrisko struct icmp *ic; 249272744Skadesai 250272744Skadesai ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); 251265555Sambrisko 252272744Skadesai/* Get source address from ICMP data field and restore original data */ 253265555Sambrisko link = FindIcmpIn(pip->ip_src, pip->ip_dst, ic->icmp_id, 1); 254272744Skadesai if (link != NULL) 255272744Skadesai { 256272744Skadesai u_short original_id; 257272744Skadesai int accumulate; 258272744Skadesai 259265555Sambrisko original_id = GetOriginalPort(link); 260272744Skadesai 261272744Skadesai/* Adjust ICMP checksum */ 262272744Skadesai accumulate = ic->icmp_id; 263272744Skadesai accumulate -= original_id; 264265555Sambrisko ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) 265272744Skadesai 266265555Sambrisko/* Put original sequence number back in */ 267265555Sambrisko ic->icmp_id = original_id; 268272735Skadesai 269272735Skadesai/* Put original address back into IP header */ 270272735Skadesai { 271272744Skadesai struct in_addr original_address; 272272744Skadesai 273272735Skadesai original_address = GetOriginalAddress(link); 274272744Skadesai DifferentialChecksum(&pip->ip_sum, 275272744Skadesai (u_short *) &original_address, 276272735Skadesai (u_short *) &pip->ip_dst, 277272735Skadesai 2); 278272735Skadesai pip->ip_dst = original_address; 279272735Skadesai } 280272735Skadesai 281272744Skadesai return(PKT_ALIAS_OK); 282272735Skadesai } 283272744Skadesai return(PKT_ALIAS_IGNORED); 284272744Skadesai} 285272744Skadesai 286272744Skadesaistatic int 287272744SkadesaiIcmpAliasIn2(struct ip *pip) 288272735Skadesai{ 289272744Skadesai/* 290272735Skadesai Alias incoming ICMP error messages containing 291272744Skadesai IP header and first 64 bits of datagram. 292272735Skadesai*/ 293272735Skadesai struct ip *ip; 294272735Skadesai struct icmp *ic, *ic2; 295272735Skadesai struct udphdr *ud; 296272735Skadesai struct tcphdr *tc; 297272744Skadesai struct alias_link *link; 298272744Skadesai 299272744Skadesai ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); 300272744Skadesai ip = &ic->icmp_ip; 301272735Skadesai 302272735Skadesai ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2)); 303272735Skadesai tc = (struct tcphdr *) ud; 304272735Skadesai ic2 = (struct icmp *) ud; 305272735Skadesai 306272735Skadesai if (ip->ip_p == IPPROTO_UDP) 307272735Skadesai link = FindUdpTcpIn(ip->ip_dst, ip->ip_src, 308272744Skadesai ud->uh_dport, ud->uh_sport, 309272735Skadesai IPPROTO_UDP, 0); 310272744Skadesai else if (ip->ip_p == IPPROTO_TCP) 311272735Skadesai link = FindUdpTcpIn(ip->ip_dst, ip->ip_src, 312272744Skadesai tc->th_dport, tc->th_sport, 313272735Skadesai IPPROTO_TCP, 0); 314272735Skadesai else if (ip->ip_p == IPPROTO_ICMP) { 315272744Skadesai if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP) 316272735Skadesai link = FindIcmpIn(ip->ip_dst, ip->ip_src, ic2->icmp_id, 0); 317272744Skadesai else 318272735Skadesai link = NULL; 319272735Skadesai } else 320272744Skadesai link = NULL; 321272744Skadesai 322272744Skadesai if (link != NULL) 323272744Skadesai { 324272744Skadesai if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) 325272744Skadesai { 326272744Skadesai u_short *sptr; 327272744Skadesai int accumulate; 328272744Skadesai struct in_addr original_address; 329272744Skadesai u_short original_port; 330272744Skadesai 331272744Skadesai original_address = GetOriginalAddress(link); 332272744Skadesai original_port = GetOriginalPort(link); 333272735Skadesai 334272735Skadesai/* Adjust ICMP checksum */ 335272735Skadesai sptr = (u_short *) &(ip->ip_src); 336272735Skadesai accumulate = *sptr++; 337272744Skadesai accumulate += *sptr; 338272735Skadesai sptr = (u_short *) &original_address; 339272744Skadesai accumulate -= *sptr++; 340272744Skadesai accumulate -= *sptr; 341272735Skadesai accumulate += ud->uh_sport; 342272735Skadesai accumulate -= original_port; 343272735Skadesai ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) 344272744Skadesai 345272744Skadesai/* Un-alias address in IP header */ 346272744Skadesai DifferentialChecksum(&pip->ip_sum, 347265555Sambrisko (u_short *) &original_address, 348272744Skadesai (u_short *) &pip->ip_dst, 349265555Sambrisko 2); 350265555Sambrisko pip->ip_dst = original_address; 351272744Skadesai 352272744Skadesai/* Un-alias address and port number of original IP packet 353265555Sambriskofragment contained in ICMP data section */ 354265555Sambrisko ip->ip_src = original_address; 355265555Sambrisko ud->uh_sport = original_port; 356265555Sambrisko } 357272744Skadesai else if (ip->ip_p == IPPROTO_ICMP) 358272735Skadesai { 359272744Skadesai u_short *sptr; 360272744Skadesai int accumulate; 361272735Skadesai struct in_addr original_address; 362272744Skadesai u_short original_id; 363272735Skadesai 364272744Skadesai original_address = GetOriginalAddress(link); 365272744Skadesai original_id = GetOriginalPort(link); 366272744Skadesai 367265555Sambrisko/* Adjust ICMP checksum */ 368272744Skadesai sptr = (u_short *) &(ip->ip_src); 369272744Skadesai accumulate = *sptr++; 370272744Skadesai accumulate += *sptr; 371272744Skadesai sptr = (u_short *) &original_address; 372272744Skadesai accumulate -= *sptr++; 373272744Skadesai accumulate -= *sptr; 374265555Sambrisko accumulate += ic2->icmp_id; 375272744Skadesai accumulate -= original_id; 376272744Skadesai ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) 377272744Skadesai 378272744Skadesai/* Un-alias address in IP header */ 379272744Skadesai DifferentialChecksum(&pip->ip_sum, 380265555Sambrisko (u_short *) &original_address, 381272744Skadesai (u_short *) &pip->ip_dst, 382272744Skadesai 2); 383272744Skadesai pip->ip_dst = original_address; 384282527Skadesai 385265555Sambrisko/* Un-alias address of original IP packet and sequence number of 386272744Skadesai embedded ICMP datagram */ 387265555Sambrisko ip->ip_src = original_address; 388265555Sambrisko ic2->icmp_id = original_id; 389265555Sambrisko } 390272744Skadesai return(PKT_ALIAS_OK); 391272744Skadesai } 392272744Skadesai return(PKT_ALIAS_IGNORED); 393272744Skadesai} 394272744Skadesai 395272744Skadesai 396272744Skadesaistatic int 397272744SkadesaiIcmpAliasIn(struct ip *pip) 398265555Sambrisko{ 399272744Skadesai int iresult; 400272744Skadesai struct icmp *ic; 401265555Sambrisko 402265555Sambrisko/* Return if proxy-only mode is enabled */ 403272744Skadesai if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) 404272744Skadesai return PKT_ALIAS_OK; 405272744Skadesai 406272744Skadesai ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); 407272744Skadesai 408272744Skadesai iresult = PKT_ALIAS_IGNORED; 409272744Skadesai switch (ic->icmp_type) 410265555Sambrisko { 411272744Skadesai case ICMP_ECHOREPLY: 412272744Skadesai case ICMP_TSTAMPREPLY: 413272744Skadesai if (ic->icmp_code == 0) 414272744Skadesai { 415272744Skadesai iresult = IcmpAliasIn1(pip); 416272744Skadesai } 417272744Skadesai break; 418272744Skadesai case ICMP_UNREACH: 419272744Skadesai case ICMP_SOURCEQUENCH: 420272744Skadesai case ICMP_TIMXCEED: 421272744Skadesai case ICMP_PARAMPROB: 422272744Skadesai iresult = IcmpAliasIn2(pip); 423272744Skadesai break; 424272744Skadesai case ICMP_ECHO: 425272744Skadesai case ICMP_TSTAMP: 426265555Sambrisko iresult = IcmpAliasIn1(pip); 427272744Skadesai break; 428272744Skadesai } 429272744Skadesai return(iresult); 430272744Skadesai} 431272744Skadesai 432272744Skadesai 433272744Skadesaistatic int 434272744SkadesaiIcmpAliasOut1(struct ip *pip) 435272744Skadesai{ 436272744Skadesai/* 437272744Skadesai Alias outgoing echo and timestamp requests. 438272744Skadesai De-alias outgoing echo and timestamp replies. 439272744Skadesai*/ 440272744Skadesai struct alias_link *link; 441272744Skadesai struct icmp *ic; 442272744Skadesai 443272744Skadesai ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); 444272744Skadesai 445272744Skadesai/* Save overwritten data for when echo packet returns */ 446272744Skadesai link = FindIcmpOut(pip->ip_src, pip->ip_dst, ic->icmp_id, 1); 447272744Skadesai if (link != NULL) 448272744Skadesai { 449272744Skadesai u_short alias_id; 450272744Skadesai int accumulate; 451272744Skadesai 452272744Skadesai alias_id = GetAliasPort(link); 453272744Skadesai 454272744Skadesai/* Since data field is being modified, adjust ICMP checksum */ 455272744Skadesai accumulate = ic->icmp_id; 456272744Skadesai accumulate -= alias_id; 457272744Skadesai ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) 458272744Skadesai 459272744Skadesai/* Alias sequence number */ 460272744Skadesai ic->icmp_id = alias_id; 461265555Sambrisko 462272744Skadesai/* Change source address */ 463265555Sambrisko { 464265555Sambrisko struct in_addr alias_address; 465272744Skadesai 466272744Skadesai alias_address = GetAliasAddress(link); 467272744Skadesai DifferentialChecksum(&pip->ip_sum, 468272744Skadesai (u_short *) &alias_address, 469272744Skadesai (u_short *) &pip->ip_src, 470272744Skadesai 2); 471272744Skadesai pip->ip_src = alias_address; 472272744Skadesai } 473272744Skadesai 474272744Skadesai return(PKT_ALIAS_OK); 475272744Skadesai } 476272744Skadesai return(PKT_ALIAS_IGNORED); 477265555Sambrisko} 478272744Skadesai 479272744Skadesai 480272744Skadesaistatic int 481265555SambriskoIcmpAliasOut2(struct ip *pip) 482272744Skadesai{ 483272744Skadesai/* 484272744Skadesai Alias outgoing ICMP error messages containing 485272744Skadesai IP header and first 64 bits of datagram. 486272744Skadesai*/ 487265555Sambrisko struct ip *ip; 488272744Skadesai struct icmp *ic, *ic2; 489272744Skadesai struct udphdr *ud; 490265555Sambrisko struct tcphdr *tc; 491272744Skadesai struct alias_link *link; 492272744Skadesai 493272744Skadesai ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); 494272744Skadesai ip = &ic->icmp_ip; 495265555Sambrisko 496272744Skadesai ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2)); 497272744Skadesai tc = (struct tcphdr *) ud; 498272744Skadesai ic2 = (struct icmp *) ud; 499272744Skadesai 500272744Skadesai if (ip->ip_p == IPPROTO_UDP) 501272744Skadesai link = FindUdpTcpOut(ip->ip_dst, ip->ip_src, 502272744Skadesai ud->uh_dport, ud->uh_sport, 503272744Skadesai IPPROTO_UDP, 0); 504272744Skadesai else if (ip->ip_p == IPPROTO_TCP) 505272744Skadesai link = FindUdpTcpOut(ip->ip_dst, ip->ip_src, 506272744Skadesai tc->th_dport, tc->th_sport, 507272744Skadesai IPPROTO_TCP, 0); 508272744Skadesai else if (ip->ip_p == IPPROTO_ICMP) { 509272744Skadesai if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP) 510272744Skadesai link = FindIcmpOut(ip->ip_dst, ip->ip_src, ic2->icmp_id, 0); 511272744Skadesai else 512272744Skadesai link = NULL; 513272744Skadesai } else 514272744Skadesai link = NULL; 515272744Skadesai 516272744Skadesai if (link != NULL) 517272744Skadesai { 518272744Skadesai if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) 519272744Skadesai { 520272744Skadesai u_short *sptr; 521272744Skadesai int accumulate; 522272744Skadesai struct in_addr alias_address; 523272744Skadesai u_short alias_port; 524272744Skadesai 525265555Sambrisko alias_address = GetAliasAddress(link); 526265555Sambrisko alias_port = GetAliasPort(link); 527265555Sambrisko 528272744Skadesai/* Adjust ICMP checksum */ 529272744Skadesai sptr = (u_short *) &(ip->ip_dst); 530272744Skadesai accumulate = *sptr++; 531272744Skadesai accumulate += *sptr; 532272744Skadesai sptr = (u_short *) &alias_address; 533272744Skadesai accumulate -= *sptr++; 534272744Skadesai accumulate -= *sptr; 535272744Skadesai accumulate += ud->uh_dport; 536272744Skadesai accumulate -= alias_port; 537272744Skadesai ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) 538265555Sambrisko 539272744Skadesai/* 540272744Skadesai * Alias address in IP header if it comes from the host 541272744Skadesai * the original TCP/UDP packet was destined for. 542265555Sambrisko */ 543272744Skadesai if (pip->ip_src.s_addr == ip->ip_dst.s_addr) { 544272744Skadesai DifferentialChecksum(&pip->ip_sum, 545272744Skadesai (u_short *) &alias_address, 546272744Skadesai (u_short *) &pip->ip_src, 547272744Skadesai 2); 548265555Sambrisko pip->ip_src = alias_address; 549272744Skadesai } 550272744Skadesai 551265555Sambrisko/* Alias address and port number of original IP packet 552272744Skadesaifragment contained in ICMP data section */ 553272744Skadesai ip->ip_dst = alias_address; 554272744Skadesai ud->uh_dport = alias_port; 555272744Skadesai } 556265555Sambrisko else if (ip->ip_p == IPPROTO_ICMP) 557272744Skadesai { 558272744Skadesai u_short *sptr; 559272744Skadesai int accumulate; 560272744Skadesai struct in_addr alias_address; 561272744Skadesai u_short alias_id; 562272744Skadesai 563272744Skadesai alias_address = GetAliasAddress(link); 564272744Skadesai alias_id = GetAliasPort(link); 565272744Skadesai 566272744Skadesai/* Adjust ICMP checksum */ 567272744Skadesai sptr = (u_short *) &(ip->ip_dst); 568272744Skadesai accumulate = *sptr++; 569272744Skadesai accumulate += *sptr; 570272744Skadesai sptr = (u_short *) &alias_address; 571282531Skadesai accumulate -= *sptr++; 572272744Skadesai accumulate -= *sptr; 573272744Skadesai accumulate += ic2->icmp_id; 574272744Skadesai accumulate -= alias_id; 575272744Skadesai ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) 576282531Skadesai 577272744Skadesai/* 578272744Skadesai * Alias address in IP header if it comes from the host 579272744Skadesai * the original ICMP message was destined for. 580272744Skadesai */ 581272744Skadesai if (pip->ip_src.s_addr == ip->ip_dst.s_addr) { 582265555Sambrisko DifferentialChecksum(&pip->ip_sum, 583265555Sambrisko (u_short *) &alias_address, 584265555Sambrisko (u_short *) &pip->ip_src, 585265555Sambrisko 2); 586272744Skadesai pip->ip_src = alias_address; 587272744Skadesai } 588272744Skadesai 589272744Skadesai/* Alias address of original IP packet and sequence number of 590272744Skadesai embedded ICMP datagram */ 591272744Skadesai ip->ip_dst = alias_address; 592272744Skadesai ic2->icmp_id = alias_id; 593272744Skadesai } 594272744Skadesai return(PKT_ALIAS_OK); 595272744Skadesai } 596265555Sambrisko return(PKT_ALIAS_IGNORED); 597272744Skadesai} 598272744Skadesai 599272744Skadesai 600265555Sambriskostatic int 601272744SkadesaiIcmpAliasOut(struct ip *pip) 602272744Skadesai{ 603272744Skadesai int iresult; 604272744Skadesai struct icmp *ic; 605272744Skadesai 606272744Skadesai/* Return if proxy-only mode is enabled */ 607265555Sambrisko if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) 608272744Skadesai return PKT_ALIAS_OK; 609272744Skadesai 610265555Sambrisko ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); 611272744Skadesai 612272744Skadesai iresult = PKT_ALIAS_IGNORED; 613272744Skadesai switch (ic->icmp_type) 614272744Skadesai { 615265555Sambrisko case ICMP_ECHO: 616272744Skadesai case ICMP_TSTAMP: 617272744Skadesai if (ic->icmp_code == 0) 618272744Skadesai { 619272744Skadesai iresult = IcmpAliasOut1(pip); 620272744Skadesai } 621272744Skadesai break; 622272744Skadesai case ICMP_UNREACH: 623272744Skadesai case ICMP_SOURCEQUENCH: 624272744Skadesai case ICMP_TIMXCEED: 625272744Skadesai case ICMP_PARAMPROB: 626272744Skadesai iresult = IcmpAliasOut2(pip); 627272744Skadesai break; 628272744Skadesai case ICMP_ECHOREPLY: 629272744Skadesai case ICMP_TSTAMPREPLY: 630272744Skadesai iresult = IcmpAliasOut1(pip); 631272744Skadesai } 632272744Skadesai return(iresult); 633272744Skadesai} 634272744Skadesai 635272744Skadesai 636282531Skadesai 637272744Skadesaistatic int 638272744SkadesaiProtoAliasIn(struct ip *pip) 639265555Sambrisko{ 640265555Sambrisko/* 641265555Sambrisko Handle incoming IP packets. The 642272744Skadesai only thing which is done in this case is to alias 643272744Skadesai the dest IP address of the packet to our inside 644272744Skadesai machine. 645272744Skadesai*/ 646272744Skadesai struct alias_link *link; 647272744Skadesai 648272744Skadesai/* Return if proxy-only mode is enabled */ 649272744Skadesai if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) 650272744Skadesai return PKT_ALIAS_OK; 651272744Skadesai 652272744Skadesai link = FindProtoIn(pip->ip_src, pip->ip_dst, pip->ip_p); 653272744Skadesai if (link != NULL) 654265555Sambrisko { 655272744Skadesai struct in_addr original_address; 656272744Skadesai 657272744Skadesai original_address = GetOriginalAddress(link); 658265555Sambrisko 659272744Skadesai/* Restore original IP address */ 660272744Skadesai DifferentialChecksum(&pip->ip_sum, 661272744Skadesai (u_short *) &original_address, 662272744Skadesai (u_short *) &pip->ip_dst, 663265555Sambrisko 2); 664272744Skadesai pip->ip_dst = original_address; 665272744Skadesai 666265555Sambrisko return(PKT_ALIAS_OK); 667272744Skadesai } 668272744Skadesai return(PKT_ALIAS_IGNORED); 669272744Skadesai} 670272744Skadesai 671265555Sambrisko 672272744Skadesaistatic int 673272744SkadesaiProtoAliasOut(struct ip *pip) 674272744Skadesai{ 675265555Sambrisko/* 676272744Skadesai Handle outgoing IP packets. The 677272744Skadesai only thing which is done in this case is to alias 678272744Skadesai the source IP address of the packet. 679272744Skadesai*/ 680272744Skadesai struct alias_link *link; 681272744Skadesai 682272744Skadesai/* Return if proxy-only mode is enabled */ 683272744Skadesai if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) 684282531Skadesai return PKT_ALIAS_OK; 685272744Skadesai 686272744Skadesai link = FindProtoOut(pip->ip_src, pip->ip_dst, pip->ip_p); 687272744Skadesai if (link != NULL) 688272744Skadesai { 689265555Sambrisko struct in_addr alias_address; 690282531Skadesai 691272744Skadesai alias_address = GetAliasAddress(link); 692265555Sambrisko 693272744Skadesai/* Change source address */ 694265555Sambrisko DifferentialChecksum(&pip->ip_sum, 695265555Sambrisko (u_short *) &alias_address, 696265555Sambrisko (u_short *) &pip->ip_src, 697265555Sambrisko 2); 698272744Skadesai pip->ip_src = alias_address; 699272744Skadesai 700272744Skadesai return(PKT_ALIAS_OK); 701265555Sambrisko } 702272744Skadesai return(PKT_ALIAS_IGNORED); 703265555Sambrisko} 704272744Skadesai 705272744Skadesai 706265555Sambriskostatic int 707272744SkadesaiUdpAliasIn(struct ip *pip) 708272744Skadesai{ 709272744Skadesai struct udphdr *ud; 710272744Skadesai struct alias_link *link; 711272744Skadesai 712272744Skadesai/* Return if proxy-only mode is enabled */ 713272744Skadesai if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) 714272744Skadesai return PKT_ALIAS_OK; 715272744Skadesai 716272744Skadesai ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 717272744Skadesai 718272744Skadesai link = FindUdpTcpIn(pip->ip_src, pip->ip_dst, 719265555Sambrisko ud->uh_sport, ud->uh_dport, 720272744Skadesai IPPROTO_UDP, 1); 721265555Sambrisko if (link != NULL) 722265555Sambrisko { 723265555Sambrisko struct in_addr alias_address; 724272744Skadesai struct in_addr original_address; 725272744Skadesai u_short alias_port; 726272744Skadesai int accumulate; 727272744Skadesai u_short *sptr; 728282527Skadesai int r = 0; 729282527Skadesai 730282527Skadesai alias_address = GetAliasAddress(link); 731282527Skadesai original_address = GetOriginalAddress(link); 732282527Skadesai alias_port = ud->uh_dport; 733272744Skadesai ud->uh_dport = GetOriginalPort(link); 734272744Skadesai 735272744Skadesai/* Special processing for IP encoding protocols */ 736272744Skadesai if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) 737272744Skadesai AliasHandleCUSeeMeIn(pip, original_address); 738272744Skadesai/* If NETBIOS Datagram, It should be alias address in UDP Data, too */ 739272744Skadesai else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER 740272744Skadesai || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) 741265555Sambrisko r = AliasHandleUdpNbt(pip, link, &original_address, ud->uh_dport); 742272744Skadesai else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER 743272744Skadesai || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) 744272744Skadesai r = AliasHandleUdpNbtNS(pip, link, &alias_address, &alias_port, 745272744Skadesai &original_address, &ud->uh_dport); 746272744Skadesai 747272744Skadesai/* If UDP checksum is not zero, then adjust since destination port */ 748272744Skadesai/* is being unaliased and destination address is being altered. */ 749272744Skadesai if (ud->uh_sum != 0) 750272744Skadesai { 751265555Sambrisko accumulate = alias_port; 752299670Skadesai accumulate -= ud->uh_dport; 753299670Skadesai sptr = (u_short *) &alias_address; 754299670Skadesai accumulate += *sptr++; 755301203Skadesai accumulate += *sptr; 756301203Skadesai sptr = (u_short *) &original_address; 757301203Skadesai accumulate -= *sptr++; 758272744Skadesai accumulate -= *sptr; 759265555Sambrisko ADJUST_CHECKSUM(accumulate, ud->uh_sum) 760272744Skadesai } 761272744Skadesai 762272744Skadesai/* Restore original IP address */ 763265555Sambrisko DifferentialChecksum(&pip->ip_sum, 764265555Sambrisko (u_short *) &original_address, 765272744Skadesai (u_short *) &pip->ip_dst, 766272744Skadesai 2); 767272744Skadesai pip->ip_dst = original_address; 768272744Skadesai 769272744Skadesai /* 770272744Skadesai * If we cannot figure out the packet, ignore it. 771272744Skadesai */ 772272744Skadesai if (r < 0) 773272744Skadesai return(PKT_ALIAS_IGNORED); 774272744Skadesai else 775272744Skadesai return(PKT_ALIAS_OK); 776265555Sambrisko } 777265555Sambrisko return(PKT_ALIAS_IGNORED); 778272744Skadesai} 779272744Skadesai 780265555Sambriskostatic int 781272744SkadesaiUdpAliasOut(struct ip *pip) 782272744Skadesai{ 783272744Skadesai struct udphdr *ud; 784272744Skadesai struct alias_link *link; 785272744Skadesai 786272744Skadesai/* Return if proxy-only mode is enabled */ 787272744Skadesai if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) 788272744Skadesai return PKT_ALIAS_OK; 789272744Skadesai 790272744Skadesai ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 791272744Skadesai 792272744Skadesai link = FindUdpTcpOut(pip->ip_src, pip->ip_dst, 793272744Skadesai ud->uh_sport, ud->uh_dport, 794272744Skadesai IPPROTO_UDP, 1); 795272744Skadesai if (link != NULL) 796272744Skadesai { 797282527Skadesai u_short alias_port; 798272744Skadesai struct in_addr alias_address; 799265555Sambrisko 800265555Sambrisko alias_address = GetAliasAddress(link); 801272744Skadesai alias_port = GetAliasPort(link); 802272744Skadesai 803272744Skadesai/* Special processing for IP encoding protocols */ 804272744Skadesai if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) 805272744Skadesai AliasHandleCUSeeMeOut(pip, link); 806272744Skadesai/* If NETBIOS Datagram, It should be alias address in UDP Data, too */ 807272744Skadesai else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER 808272744Skadesai || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) 809265555Sambrisko AliasHandleUdpNbt(pip, link, &alias_address, alias_port); 810272744Skadesai else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER 811265555Sambrisko || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) 812272744Skadesai AliasHandleUdpNbtNS(pip, link, &pip->ip_src, &ud->uh_sport, 813272744Skadesai &alias_address, &alias_port); 814272744Skadesai 815272744Skadesai/* If UDP checksum is not zero, adjust since source port is */ 816272744Skadesai/* being aliased and source address is being altered */ 817272744Skadesai if (ud->uh_sum != 0) 818272744Skadesai { 819272744Skadesai int accumulate; 820272744Skadesai u_short *sptr; 821272744Skadesai 822272744Skadesai accumulate = ud->uh_sport; 823265555Sambrisko accumulate -= alias_port; 824272744Skadesai sptr = (u_short *) &(pip->ip_src); 825272744Skadesai accumulate += *sptr++; 826265555Sambrisko accumulate += *sptr; 827272744Skadesai sptr = (u_short *) &alias_address; 828272744Skadesai accumulate -= *sptr++; 829272744Skadesai accumulate -= *sptr; 830272744Skadesai ADJUST_CHECKSUM(accumulate, ud->uh_sum) 831272744Skadesai } 832265555Sambrisko 833272744Skadesai/* Put alias port in UDP header */ 834265555Sambrisko ud->uh_sport = alias_port; 835272744Skadesai 836272744Skadesai/* Change source address */ 837265555Sambrisko DifferentialChecksum(&pip->ip_sum, 838272744Skadesai (u_short *) &alias_address, 839272744Skadesai (u_short *) &pip->ip_src, 840272744Skadesai 2); 841272744Skadesai pip->ip_src = alias_address; 842272744Skadesai 843272744Skadesai return(PKT_ALIAS_OK); 844282531Skadesai } 845272744Skadesai return(PKT_ALIAS_IGNORED); 846272744Skadesai} 847272744Skadesai 848272744Skadesai 849265555Sambrisko 850272744Skadesaistatic int 851272744SkadesaiTcpAliasIn(struct ip *pip) 852272744Skadesai{ 853272744Skadesai struct tcphdr *tc; 854272744Skadesai struct alias_link *link; 855272744Skadesai 856272744Skadesai tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); 857272744Skadesai 858272744Skadesai link = FindUdpTcpIn(pip->ip_src, pip->ip_dst, 859272744Skadesai tc->th_sport, tc->th_dport, 860272744Skadesai IPPROTO_TCP, 861272744Skadesai !(packetAliasMode & PKT_ALIAS_PROXY_ONLY)); 862272744Skadesai if (link != NULL) 863272744Skadesai { 864272744Skadesai struct in_addr alias_address; 865272744Skadesai struct in_addr original_address; 866272744Skadesai struct in_addr proxy_address; 867272744Skadesai u_short alias_port; 868272744Skadesai u_short proxy_port; 869272744Skadesai int accumulate; 870272744Skadesai u_short *sptr; 871282531Skadesai 872272744Skadesai/* Special processing for IP encoding protocols */ 873272744Skadesai if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER 874272744Skadesai || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) 875272744Skadesai AliasHandlePptpIn(pip, link); 876272744Skadesai 877282531Skadesai alias_address = GetAliasAddress(link); 878272744Skadesai original_address = GetOriginalAddress(link); 879272744Skadesai proxy_address = GetProxyAddress(link); 880272744Skadesai alias_port = tc->th_dport; 881272744Skadesai tc->th_dport = GetOriginalPort(link); 882272744Skadesai proxy_port = GetProxyPort(link); 883272744Skadesai 884272744Skadesai/* Adjust TCP checksum since destination port is being unaliased */ 885272744Skadesai/* and destination port is being altered. */ 886282531Skadesai accumulate = alias_port; 887272744Skadesai accumulate -= tc->th_dport; 888272744Skadesai sptr = (u_short *) &alias_address; 889272744Skadesai accumulate += *sptr++; 890272744Skadesai accumulate += *sptr; 891282531Skadesai sptr = (u_short *) &original_address; 892272744Skadesai accumulate -= *sptr++; 893272744Skadesai accumulate -= *sptr; 894272744Skadesai 895272744Skadesai/* If this is a proxy, then modify the TCP source port and 896272744Skadesai checksum accumulation */ 897265555Sambrisko if (proxy_port != 0) 898272744Skadesai { 899265555Sambrisko accumulate += tc->th_sport; 900272744Skadesai tc->th_sport = proxy_port; 901272744Skadesai accumulate -= tc->th_sport; 902272744Skadesai 903272744Skadesai sptr = (u_short *) &pip->ip_src; 904272744Skadesai accumulate += *sptr++; 905272744Skadesai accumulate += *sptr; 906265555Sambrisko sptr = (u_short *) &proxy_address; 907272744Skadesai accumulate -= *sptr++; 908272744Skadesai accumulate -= *sptr; 909272744Skadesai } 910272744Skadesai 911272744Skadesai/* See if ACK number needs to be modified */ 912272744Skadesai if (GetAckModified(link) == 1) 913272744Skadesai { 914272744Skadesai int delta; 915272744Skadesai 916272744Skadesai delta = GetDeltaAckIn(pip, link); 917272744Skadesai if (delta != 0) 918272744Skadesai { 919265555Sambrisko sptr = (u_short *) &tc->th_ack; 920272744Skadesai accumulate += *sptr++; 921272744Skadesai accumulate += *sptr; 922272744Skadesai tc->th_ack = htonl(ntohl(tc->th_ack) - delta); 923272744Skadesai sptr = (u_short *) &tc->th_ack; 924272744Skadesai accumulate -= *sptr++; 925272744Skadesai accumulate -= *sptr; 926272744Skadesai } 927272744Skadesai } 928272744Skadesai 929272744Skadesai ADJUST_CHECKSUM(accumulate, tc->th_sum); 930272744Skadesai 931272744Skadesai/* Restore original IP address */ 932272744Skadesai sptr = (u_short *) &pip->ip_dst; 933272744Skadesai accumulate = *sptr++; 934272744Skadesai accumulate += *sptr; 935272744Skadesai pip->ip_dst = original_address; 936272744Skadesai sptr = (u_short *) &pip->ip_dst; 937272744Skadesai accumulate -= *sptr++; 938272744Skadesai accumulate -= *sptr; 939265555Sambrisko 940272744Skadesai/* If this is a transparent proxy packet, then modify the source 941265555Sambrisko address */ 942272744Skadesai if (proxy_address.s_addr != 0) 943272744Skadesai { 944272744Skadesai sptr = (u_short *) &pip->ip_src; 945272744Skadesai accumulate += *sptr++; 946272744Skadesai accumulate += *sptr; 947272744Skadesai pip->ip_src = proxy_address; 948272744Skadesai sptr = (u_short *) &pip->ip_src; 949272744Skadesai accumulate -= *sptr++; 950272744Skadesai accumulate -= *sptr; 951272744Skadesai } 952272744Skadesai 953272744Skadesai ADJUST_CHECKSUM(accumulate, pip->ip_sum); 954272744Skadesai 955265555Sambrisko/* Monitor TCP connection state */ 956272744Skadesai TcpMonitorIn(pip, link); 957272744Skadesai 958272744Skadesai return(PKT_ALIAS_OK); 959272744Skadesai } 960265555Sambrisko return(PKT_ALIAS_IGNORED); 961272744Skadesai} 962272744Skadesai 963272744Skadesaistatic int 964272744SkadesaiTcpAliasOut(struct ip *pip, int maxpacketsize) 965272744Skadesai{ 966272744Skadesai int proxy_type; 967272744Skadesai u_short dest_port; 968299670Skadesai u_short proxy_server_port; 969299670Skadesai struct in_addr dest_address; 970299670Skadesai struct in_addr proxy_server_address; 971301203Skadesai struct tcphdr *tc; 972301203Skadesai struct alias_link *link; 973301203Skadesai 974272744Skadesai tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); 975272744Skadesai 976272744Skadesai proxy_type = ProxyCheck(pip, &proxy_server_address, &proxy_server_port); 977272744Skadesai 978272744Skadesai if (proxy_type == 0 && (packetAliasMode & PKT_ALIAS_PROXY_ONLY)) 979272744Skadesai return PKT_ALIAS_OK; 980272744Skadesai 981265555Sambrisko/* If this is a transparent proxy, save original destination, 982272744Skadesai then alter the destination and adjust checksums */ 983272744Skadesai dest_port = tc->th_dport; 984272744Skadesai dest_address = pip->ip_dst; 985272744Skadesai if (proxy_type != 0) 986272744Skadesai { 987272744Skadesai int accumulate; 988272744Skadesai u_short *sptr; 989272744Skadesai 990272744Skadesai accumulate = tc->th_dport; 991272744Skadesai tc->th_dport = proxy_server_port; 992272744Skadesai accumulate -= tc->th_dport; 993272744Skadesai 994272744Skadesai sptr = (u_short *) &(pip->ip_dst); 995272744Skadesai accumulate += *sptr++; 996272744Skadesai accumulate += *sptr; 997272744Skadesai sptr = (u_short *) &proxy_server_address; 998272744Skadesai accumulate -= *sptr++; 999272744Skadesai accumulate -= *sptr; 1000272744Skadesai 1001272744Skadesai ADJUST_CHECKSUM(accumulate, tc->th_sum); 1002272744Skadesai 1003272744Skadesai sptr = (u_short *) &(pip->ip_dst); 1004272744Skadesai accumulate = *sptr++; 1005272744Skadesai accumulate += *sptr; 1006272744Skadesai pip->ip_dst = proxy_server_address; 1007265555Sambrisko sptr = (u_short *) &(pip->ip_dst); 1008272744Skadesai accumulate -= *sptr++; 1009272744Skadesai accumulate -= *sptr; 1010265555Sambrisko 1011272744Skadesai ADJUST_CHECKSUM(accumulate, pip->ip_sum); 1012265555Sambrisko } 1013265555Sambrisko 1014265555Sambrisko link = FindUdpTcpOut(pip->ip_src, pip->ip_dst, 1015272744Skadesai tc->th_sport, tc->th_dport, 1016272744Skadesai IPPROTO_TCP, 1); 1017272744Skadesai if (link !=NULL) 1018272744Skadesai { 1019272744Skadesai u_short alias_port; 1020272744Skadesai struct in_addr alias_address; 1021272744Skadesai int accumulate; 1022272744Skadesai u_short *sptr; 1023272744Skadesai 1024272744Skadesai/* Save original destination address, if this is a proxy packet. 1025265555Sambrisko Also modify packet to include destination encoding. */ 1026272744Skadesai if (proxy_type != 0) 1027272744Skadesai { 1028272744Skadesai SetProxyPort(link, dest_port); 1029272744Skadesai SetProxyAddress(link, dest_address); 1030272744Skadesai ProxyModify(link, pip, maxpacketsize, proxy_type); 1031272744Skadesai } 1032272744Skadesai 1033272744Skadesai/* Get alias address and port */ 1034272735Skadesai alias_port = GetAliasPort(link); 1035272744Skadesai alias_address = GetAliasAddress(link); 1036272744Skadesai 1037272744Skadesai/* Monitor TCP connection state */ 1038272744Skadesai TcpMonitorOut(pip, link); 1039272744Skadesai 1040272744Skadesai/* Special processing for IP encoding protocols */ 1041272744Skadesai if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER 1042272744Skadesai || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER) 1043272744Skadesai AliasHandleFtpOut(pip, link, maxpacketsize); 1044272744Skadesai else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1 1045272744Skadesai || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2) 1046272744Skadesai AliasHandleIrcOut(pip, link, maxpacketsize); 1047272744Skadesai else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1 1048272744Skadesai || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1 1049265555Sambrisko || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2 1050272744Skadesai || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2) 1051265555Sambrisko AliasHandleRtspOut(pip, link, maxpacketsize); 1052272744Skadesai else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER 1053272744Skadesai || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) 1054272744Skadesai AliasHandlePptpOut(pip, link); 1055272744Skadesai 1056272744Skadesai/* Adjust TCP checksum since source port is being aliased */ 1057272744Skadesai/* and source address is being altered */ 1058272744Skadesai accumulate = tc->th_sport; 1059265555Sambrisko tc->th_sport = alias_port; 1060282531Skadesai accumulate -= tc->th_sport; 1061272744Skadesai 1062265555Sambrisko sptr = (u_short *) &(pip->ip_src); 1063272744Skadesai accumulate += *sptr++; 1064272744Skadesai accumulate += *sptr; 1065265555Sambrisko sptr = (u_short *) &alias_address; 1066272744Skadesai accumulate -= *sptr++; 1067272744Skadesai accumulate -= *sptr; 1068272744Skadesai 1069265555Sambrisko/* Modify sequence number if necessary */ 1070272744Skadesai if (GetAckModified(link) == 1) 1071272744Skadesai { 1072272744Skadesai int delta; 1073272744Skadesai 1074265555Sambrisko delta = GetDeltaSeqOut(pip, link); 1075272744Skadesai if (delta != 0) 1076272744Skadesai { 1077265555Sambrisko sptr = (u_short *) &tc->th_seq; 1078272744Skadesai accumulate += *sptr++; 1079272744Skadesai accumulate += *sptr; 1080265555Sambrisko tc->th_seq = htonl(ntohl(tc->th_seq) + delta); 1081272744Skadesai sptr = (u_short *) &tc->th_seq; 1082272744Skadesai accumulate -= *sptr++; 1083272744Skadesai accumulate -= *sptr; 1084272744Skadesai } 1085272744Skadesai } 1086272744Skadesai 1087272744Skadesai ADJUST_CHECKSUM(accumulate, tc->th_sum) 1088265555Sambrisko 1089272744Skadesai/* Change source address */ 1090272744Skadesai sptr = (u_short *) &(pip->ip_src); 1091272744Skadesai accumulate = *sptr++; 1092272744Skadesai accumulate += *sptr; 1093272744Skadesai pip->ip_src = alias_address; 1094272744Skadesai sptr = (u_short *) &(pip->ip_src); 1095272744Skadesai accumulate -= *sptr++; 1096272744Skadesai accumulate -= *sptr; 1097272744Skadesai 1098272744Skadesai ADJUST_CHECKSUM(accumulate, pip->ip_sum) 1099272744Skadesai 1100272744Skadesai return(PKT_ALIAS_OK); 1101272744Skadesai } 1102272744Skadesai return(PKT_ALIAS_IGNORED); 1103272744Skadesai} 1104272744Skadesai 1105272744Skadesai 1106272744Skadesai 1107272744Skadesai 1108265555Sambrisko/* Fragment Handling 1109272744Skadesai 1110265555Sambrisko FragmentIn() 1111265555Sambrisko FragmentOut() 1112265555Sambrisko 1113272744SkadesaiThe packet aliasing module has a limited ability for handling IP 1114272744Skadesaifragments. If the ICMP, TCP or UDP header is in the first fragment 1115282527Skadesaireceived, then the ID number of the IP packet is saved, and other 1116282527Skadesaifragments are identified according to their ID number and IP address 1117282527Skadesaithey were sent from. Pointers to unresolved fragments can also be 1118282527Skadesaisaved and recalled when a header fragment is seen. 1119265555Sambrisko*/ 1120272744Skadesai 1121272744Skadesai/* Local prototypes */ 1122265555Sambriskostatic int FragmentIn(struct ip *); 1123282533Skadesaistatic int FragmentOut(struct ip *); 1124282527Skadesai 1125282533Skadesai 1126265555Sambriskostatic int 1127272744SkadesaiFragmentIn(struct ip *pip) 1128272744Skadesai{ 1129272744Skadesai struct alias_link *link; 1130265555Sambrisko 1131282533Skadesai link = FindFragmentIn2(pip->ip_src, pip->ip_dst, pip->ip_id); 1132282533Skadesai if (link != NULL) 1133282527Skadesai { 1134282527Skadesai struct in_addr original_address; 1135282527Skadesai 1136282527Skadesai GetFragmentAddr(link, &original_address); 1137272744Skadesai DifferentialChecksum(&pip->ip_sum, 1138272744Skadesai (u_short *) &original_address, 1139272744Skadesai (u_short *) &pip->ip_dst, 1140282527Skadesai 2); 1141282527Skadesai pip->ip_dst = original_address; 1142282533Skadesai 1143272744Skadesai return(PKT_ALIAS_OK); 1144282527Skadesai } 1145282527Skadesai return(PKT_ALIAS_UNRESOLVED_FRAGMENT); 1146282527Skadesai} 1147272744Skadesai 1148265555Sambrisko 1149265555Sambriskostatic int 1150265555SambriskoFragmentOut(struct ip *pip) 1151272744Skadesai{ 1152272744Skadesai struct in_addr alias_address; 1153272744Skadesai 1154272744Skadesai alias_address = FindAliasAddress(pip->ip_src); 1155272744Skadesai DifferentialChecksum(&pip->ip_sum, 1156272744Skadesai (u_short *) &alias_address, 1157272744Skadesai (u_short *) &pip->ip_src, 1158272744Skadesai 2); 1159265555Sambrisko pip->ip_src = alias_address; 1160265555Sambrisko 1161265555Sambrisko return(PKT_ALIAS_OK); 1162282533Skadesai} 1163272744Skadesai 1164265555Sambrisko 1165272744Skadesai 1166265555Sambrisko 1167265555Sambrisko 1168272744Skadesai 1169272744Skadesai/* Outside World Access 1170272744Skadesai 1171272744Skadesai PacketAliasSaveFragment() 1172272744Skadesai PacketAliasGetFragment() 1173272744Skadesai PacketAliasFragmentIn() 1174272744Skadesai PacketAliasIn() 1175265555Sambrisko PacketAliasOut() 1176272744Skadesai PacketUnaliasOut() 1177272744Skadesai 1178272744Skadesai(prototypes in alias.h) 1179272744Skadesai*/ 1180272744Skadesai 1181272744Skadesai 1182272744Skadesaiint 1183265555SambriskoPacketAliasSaveFragment(char *ptr) 1184272744Skadesai{ 1185272744Skadesai int iresult; 1186272744Skadesai struct alias_link *link; 1187272744Skadesai struct ip *pip; 1188272744Skadesai 1189265555Sambrisko pip = (struct ip *) ptr; 1190272744Skadesai link = AddFragmentPtrLink(pip->ip_src, pip->ip_id); 1191272744Skadesai iresult = PKT_ALIAS_ERROR; 1192272744Skadesai if (link != NULL) 1193272744Skadesai { 1194272744Skadesai SetFragmentPtr(link, ptr); 1195272744Skadesai iresult = PKT_ALIAS_OK; 1196272744Skadesai } 1197272744Skadesai return(iresult); 1198272744Skadesai} 1199265555Sambrisko 1200272744Skadesai 1201272744Skadesaichar * 1202272744SkadesaiPacketAliasGetFragment(char *ptr) 1203272744Skadesai{ 1204265555Sambrisko struct alias_link *link; 1205272744Skadesai char *fptr; 1206272744Skadesai struct ip *pip; 1207272744Skadesai 1208272744Skadesai pip = (struct ip *) ptr; 1209272744Skadesai link = FindFragmentPtr(pip->ip_src, pip->ip_id); 1210265555Sambrisko if (link != NULL) 1211272744Skadesai { 1212272744Skadesai GetFragmentPtr(link, &fptr); 1213272744Skadesai SetFragmentPtr(link, NULL); 1214272744Skadesai SetExpire(link, 0); /* Deletes link */ 1215272744Skadesai 1216272744Skadesai return(fptr); 1217272744Skadesai } 1218272744Skadesai else 1219272744Skadesai { 1220272744Skadesai return(NULL); 1221272744Skadesai } 1222272744Skadesai} 1223272744Skadesai 1224272744Skadesai 1225272744Skadesaivoid 1226272744SkadesaiPacketAliasFragmentIn(char *ptr, /* Points to correctly de-aliased 1227272744Skadesai header fragment */ 1228272744Skadesai char *ptr_fragment /* Points to fragment which must 1229272744Skadesai be de-aliased */ 1230272744Skadesai ) 1231272744Skadesai{ 1232272744Skadesai struct ip *pip; 1233272744Skadesai struct ip *fpip; 1234272744Skadesai 1235272744Skadesai pip = (struct ip *) ptr; 1236272744Skadesai fpip = (struct ip *) ptr_fragment; 1237272744Skadesai 1238272744Skadesai DifferentialChecksum(&fpip->ip_sum, 1239272744Skadesai (u_short *) &pip->ip_dst, 1240272744Skadesai (u_short *) &fpip->ip_dst, 1241265555Sambrisko 2); 1242272744Skadesai fpip->ip_dst = pip->ip_dst; 1243265555Sambrisko} 1244272744Skadesai 1245272744Skadesai 1246272744Skadesaiint 1247272744SkadesaiPacketAliasIn(char *ptr, int maxpacketsize) 1248265555Sambrisko{ 1249272744Skadesai struct in_addr alias_addr; 1250272744Skadesai struct ip *pip; 1251272744Skadesai int iresult; 1252265555Sambrisko 1253272744Skadesai if (packetAliasMode & PKT_ALIAS_REVERSE) { 1254272744Skadesai packetAliasMode &= ~PKT_ALIAS_REVERSE; 1255272744Skadesai iresult = PacketAliasOut(ptr, maxpacketsize); 1256272744Skadesai packetAliasMode |= PKT_ALIAS_REVERSE; 1257272744Skadesai return iresult; 1258272744Skadesai } 1259272744Skadesai 1260272744Skadesai HouseKeeping(); 1261272744Skadesai ClearCheckNewLink(); 1262272744Skadesai pip = (struct ip *) ptr; 1263272744Skadesai alias_addr = pip->ip_dst; 1264272744Skadesai 1265272744Skadesai /* Defense against mangled packets */ 1266272744Skadesai if (ntohs(pip->ip_len) > maxpacketsize 1267272744Skadesai || (pip->ip_hl<<2) > maxpacketsize) 1268272744Skadesai return PKT_ALIAS_IGNORED; 1269272744Skadesai 1270272744Skadesai iresult = PKT_ALIAS_IGNORED; 1271272744Skadesai if ( (ntohs(pip->ip_off) & IP_OFFMASK) == 0 ) 1272272744Skadesai { 1273272744Skadesai switch (pip->ip_p) 1274272744Skadesai { 1275265555Sambrisko case IPPROTO_ICMP: 1276272744Skadesai iresult = IcmpAliasIn(pip); 1277265555Sambrisko break; 1278272744Skadesai case IPPROTO_UDP: 1279272744Skadesai iresult = UdpAliasIn(pip); 1280272744Skadesai break; 1281272744Skadesai case IPPROTO_TCP: 1282265555Sambrisko iresult = TcpAliasIn(pip); 1283272744Skadesai break; 1284272744Skadesai case IPPROTO_GRE: 1285272744Skadesai if (packetAliasMode & PKT_ALIAS_PROXY_ONLY || 1286272744Skadesai AliasHandlePptpGreIn(pip) == 0) 1287272744Skadesai iresult = PKT_ALIAS_OK; 1288265555Sambrisko else 1289272744Skadesai iresult = ProtoAliasIn(pip); 1290272744Skadesai break; 1291272744Skadesai default: 1292272744Skadesai iresult = ProtoAliasIn(pip); 1293272744Skadesai break; 1294272744Skadesai } 1295265555Sambrisko 1296272744Skadesai if (ntohs(pip->ip_off) & IP_MF) 1297272744Skadesai { 1298272744Skadesai struct alias_link *link; 1299265555Sambrisko 1300272744Skadesai link = FindFragmentIn1(pip->ip_src, alias_addr, pip->ip_id); 1301272744Skadesai if (link != NULL) 1302272744Skadesai { 1303272744Skadesai iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT; 1304272744Skadesai SetFragmentAddr(link, pip->ip_dst); 1305272744Skadesai } 1306272744Skadesai else 1307272744Skadesai { 1308272744Skadesai iresult = PKT_ALIAS_ERROR; 1309282533Skadesai } 1310272744Skadesai } 1311272744Skadesai } 1312272744Skadesai else 1313272744Skadesai { 1314272744Skadesai iresult = FragmentIn(pip); 1315272744Skadesai } 1316272744Skadesai 1317272744Skadesai return(iresult); 1318272744Skadesai} 1319272744Skadesai 1320272744Skadesai 1321272744Skadesai 1322272744Skadesai/* Unregistered address ranges */ 1323272744Skadesai 1324272744Skadesai/* 10.0.0.0 -> 10.255.255.255 */ 1325272744Skadesai#define UNREG_ADDR_A_LOWER 0x0a000000 1326272744Skadesai#define UNREG_ADDR_A_UPPER 0x0affffff 1327272744Skadesai 1328272744Skadesai/* 172.16.0.0 -> 172.31.255.255 */ 1329272744Skadesai#define UNREG_ADDR_B_LOWER 0xac100000 1330272744Skadesai#define UNREG_ADDR_B_UPPER 0xac1fffff 1331272744Skadesai 1332272744Skadesai/* 192.168.0.0 -> 192.168.255.255 */ 1333265555Sambrisko#define UNREG_ADDR_C_LOWER 0xc0a80000 1334265555Sambrisko#define UNREG_ADDR_C_UPPER 0xc0a8ffff 1335265555Sambrisko 1336272744Skadesaiint 1337282527SkadesaiPacketAliasOut(char *ptr, /* valid IP packet */ 1338282527Skadesai int maxpacketsize /* How much the packet data may grow 1339282527Skadesai (FTP and IRC inline changes) */ 1340282527Skadesai ) 1341282527Skadesai{ 1342265555Sambrisko int iresult; 1343265555Sambrisko struct in_addr addr_save; 1344265555Sambrisko struct ip *pip; 1345265555Sambrisko 1346282533Skadesai if (packetAliasMode & PKT_ALIAS_REVERSE) { 1347282533Skadesai packetAliasMode &= ~PKT_ALIAS_REVERSE; 1348282533Skadesai iresult = PacketAliasIn(ptr, maxpacketsize); 1349265555Sambrisko packetAliasMode |= PKT_ALIAS_REVERSE; 1350282533Skadesai return iresult; 1351282527Skadesai } 1352282527Skadesai 1353272744Skadesai HouseKeeping(); 1354282527Skadesai ClearCheckNewLink(); 1355282527Skadesai pip = (struct ip *) ptr; 1356265555Sambrisko 1357282527Skadesai /* Defense against mangled packets */ 1358282527Skadesai if (ntohs(pip->ip_len) > maxpacketsize 1359282527Skadesai || (pip->ip_hl<<2) > maxpacketsize) 1360282527Skadesai return PKT_ALIAS_IGNORED; 1361282533Skadesai 1362282527Skadesai addr_save = GetDefaultAliasAddress(); 1363282527Skadesai if (packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY) 1364282527Skadesai { 1365282527Skadesai u_long addr; 1366282527Skadesai int iclass; 1367282527Skadesai 1368282533Skadesai iclass = 0; 1369282527Skadesai addr = ntohl(pip->ip_src.s_addr); 1370282533Skadesai if (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER) 1371282533Skadesai iclass = 3; 1372282533Skadesai else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER) 1373282533Skadesai iclass = 2; 1374282527Skadesai else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER) 1375272744Skadesai iclass = 1; 1376282527Skadesai 1377282527Skadesai if (iclass == 0) 1378265555Sambrisko { 1379272744Skadesai SetDefaultAliasAddress(pip->ip_src); 1380282527Skadesai } 1381282527Skadesai } 1382282527Skadesai 1383265555Sambrisko iresult = PKT_ALIAS_IGNORED; 1384282527Skadesai if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) 1385282533Skadesai { 1386272744Skadesai switch (pip->ip_p) 1387265555Sambrisko { 1388272744Skadesai case IPPROTO_ICMP: 1389282533Skadesai iresult = IcmpAliasOut(pip); 1390282527Skadesai break; 1391282533Skadesai case IPPROTO_UDP: 1392282527Skadesai iresult = UdpAliasOut(pip); 1393282533Skadesai break; 1394282533Skadesai case IPPROTO_TCP: 1395282533Skadesai iresult = TcpAliasOut(pip, maxpacketsize); 1396282533Skadesai break; 1397282527Skadesai case IPPROTO_GRE: 1398265555Sambrisko if (AliasHandlePptpGreOut(pip) == 0) 1399282527Skadesai iresult = PKT_ALIAS_OK; 1400265555Sambrisko else 1401265555Sambrisko iresult = ProtoAliasOut(pip); 1402272744Skadesai break; 1403272744Skadesai default: 1404282527Skadesai iresult = ProtoAliasOut(pip); 1405282527Skadesai break; 1406282527Skadesai } 1407282527Skadesai } 1408265555Sambrisko else 1409265555Sambrisko { 1410265555Sambrisko iresult = FragmentOut(pip); 1411282533Skadesai } 1412282533Skadesai 1413282533Skadesai SetDefaultAliasAddress(addr_save); 1414265555Sambrisko return(iresult); 1415282527Skadesai} 1416272744Skadesai 1417282527Skadesaiint 1418265555SambriskoPacketUnaliasOut(char *ptr, /* valid IP packet */ 1419282527Skadesai int maxpacketsize /* for error checking */ 1420265555Sambrisko ) 1421272744Skadesai{ 1422282533Skadesai struct ip *pip; 1423282527Skadesai struct icmp *ic; 1424282527Skadesai struct udphdr *ud; 1425265555Sambrisko struct tcphdr *tc; 1426272744Skadesai struct alias_link *link; 1427265555Sambrisko int iresult = PKT_ALIAS_IGNORED; 1428265555Sambrisko 1429272744Skadesai pip = (struct ip *) ptr; 1430272744Skadesai 1431272744Skadesai /* Defense against mangled packets */ 1432272744Skadesai if (ntohs(pip->ip_len) > maxpacketsize 1433272744Skadesai || (pip->ip_hl<<2) > maxpacketsize) 1434272744Skadesai return(iresult); 1435265555Sambrisko 1436272744Skadesai ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); 1437272744Skadesai tc = (struct tcphdr *) ud; 1438272744Skadesai ic = (struct icmp *) ud; 1439272744Skadesai 1440265555Sambrisko /* Find a link */ 1441272744Skadesai if (pip->ip_p == IPPROTO_UDP) 1442272744Skadesai link = FindUdpTcpIn(pip->ip_dst, pip->ip_src, 1443272744Skadesai ud->uh_dport, ud->uh_sport, 1444272744Skadesai IPPROTO_UDP, 0); 1445272744Skadesai else if (pip->ip_p == IPPROTO_TCP) 1446265555Sambrisko link = FindUdpTcpIn(pip->ip_dst, pip->ip_src, 1447272744Skadesai tc->th_dport, tc->th_sport, 1448272744Skadesai IPPROTO_TCP, 0); 1449272744Skadesai else if (pip->ip_p == IPPROTO_ICMP) 1450272744Skadesai link = FindIcmpIn(pip->ip_dst, pip->ip_src, ic->icmp_id, 0); 1451272744Skadesai else 1452272744Skadesai link = NULL; 1453265555Sambrisko 1454272744Skadesai /* Change it from an aliased packet to an unaliased packet */ 1455272744Skadesai if (link != NULL) 1456265555Sambrisko { 1457265555Sambrisko if (pip->ip_p == IPPROTO_UDP || pip->ip_p == IPPROTO_TCP) 1458299670Skadesai { 1459299670Skadesai u_short *sptr; 1460299670Skadesai int accumulate; 1461301203Skadesai struct in_addr original_address; 1462301203Skadesai u_short original_port; 1463301203Skadesai 1464265555Sambrisko original_address = GetOriginalAddress(link); 1465265555Sambrisko original_port = GetOriginalPort(link); 1466272744Skadesai 1467265555Sambrisko /* Adjust TCP/UDP checksum */ 1468272744Skadesai sptr = (u_short *) &(pip->ip_src); 1469272744Skadesai accumulate = *sptr++; 1470272744Skadesai accumulate += *sptr; 1471272744Skadesai sptr = (u_short *) &original_address; 1472272744Skadesai accumulate -= *sptr++; 1473272744Skadesai accumulate -= *sptr; 1474272744Skadesai 1475272744Skadesai if (pip->ip_p == IPPROTO_UDP) { 1476272744Skadesai accumulate += ud->uh_sport; 1477272744Skadesai accumulate -= original_port; 1478272744Skadesai ADJUST_CHECKSUM(accumulate, ud->uh_sum) 1479272744Skadesai } else { 1480272744Skadesai accumulate += tc->th_sport; 1481272744Skadesai accumulate -= original_port; 1482272744Skadesai ADJUST_CHECKSUM(accumulate, tc->th_sum) 1483272744Skadesai } 1484265555Sambrisko 1485272744Skadesai /* Adjust IP checksum */ 1486272744Skadesai DifferentialChecksum(&pip->ip_sum, 1487272744Skadesai (u_short *) &original_address, 1488272744Skadesai (u_short *) &pip->ip_src, 1489272744Skadesai 2); 1490272744Skadesai 1491272744Skadesai /* Un-alias source address and port number */ 1492272744Skadesai pip->ip_src = original_address; 1493265555Sambrisko if (pip->ip_p == IPPROTO_UDP) 1494272744Skadesai ud->uh_sport = original_port; 1495272744Skadesai else 1496265555Sambrisko tc->th_sport = original_port; 1497272744Skadesai 1498265555Sambrisko iresult = PKT_ALIAS_OK; 1499272744Skadesai 1500272744Skadesai } else if (pip->ip_p == IPPROTO_ICMP) { 1501272744Skadesai 1502272744Skadesai u_short *sptr; 1503272744Skadesai int accumulate; 1504272744Skadesai struct in_addr original_address; 1505272744Skadesai u_short original_id; 1506272744Skadesai 1507272744Skadesai original_address = GetOriginalAddress(link); 1508272744Skadesai original_id = GetOriginalPort(link); 1509272744Skadesai 1510272744Skadesai /* Adjust ICMP checksum */ 1511272744Skadesai sptr = (u_short *) &(pip->ip_src); 1512272744Skadesai accumulate = *sptr++; 1513272744Skadesai accumulate += *sptr; 1514272744Skadesai sptr = (u_short *) &original_address; 1515265555Sambrisko accumulate -= *sptr++; 1516272744Skadesai accumulate -= *sptr; 1517272744Skadesai accumulate += ic->icmp_id; 1518282527Skadesai accumulate -= original_id; 1519272744Skadesai ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) 1520265555Sambrisko 1521265555Sambrisko /* Adjust IP checksum */ 1522272744Skadesai DifferentialChecksum(&pip->ip_sum, 1523272744Skadesai (u_short *) &original_address, 1524272744Skadesai (u_short *) &pip->ip_src, 1525272744Skadesai 2); 1526272744Skadesai 1527272744Skadesai /* Un-alias source address and port number */ 1528265555Sambrisko pip->ip_src = original_address; 1529272744Skadesai ic->icmp_id = original_id; 1530272744Skadesai 1531272744Skadesai iresult = PKT_ALIAS_OK; 1532265555Sambrisko } 1533272744Skadesai } 1534272744Skadesai return(iresult); 1535272744Skadesai 1536265555Sambrisko} 1537272744Skadesai