Deleted Added
full compact
1/* -*- mode: c; tab-width: 8; c-basic-indent: 4; -*- */
2
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>
30__FBSDID("$FreeBSD: head/sys/netinet/libalias/alias.c 124621 2004-01-17 10:52:21Z phk $");
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 */
156static void TcpMonitorIn(struct ip *, struct alias_link *);
154static void TcpMonitorIn(struct ip *, struct alias_link *);
155
158static void TcpMonitorOut(struct ip *, struct alias_link *);
156static void TcpMonitorOut(struct ip *, struct alias_link *);
157
158
159static void
160TcpMonitorIn(struct ip *pip, struct alias_link *link)
161{
164 struct tcphdr *tc;
162 struct tcphdr *tc;
163
166 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
164 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
165
168 switch (GetStateIn(link))
169 {
170 case ALIAS_TCP_STATE_NOT_CONNECTED:
171 if (tc->th_flags & TH_RST)
172 SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
173 else if (tc->th_flags & TH_SYN)
174 SetStateIn(link, ALIAS_TCP_STATE_CONNECTED);
175 break;
176 case ALIAS_TCP_STATE_CONNECTED:
177 if (tc->th_flags & (TH_FIN | TH_RST))
178 SetStateIn(link, ALIAS_TCP_STATE_DISCONNECTED);
179 break;
180 }
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{
186 struct tcphdr *tc;
183 struct tcphdr *tc;
184
188 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
185 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
186
190 switch (GetStateOut(link))
191 {
192 case ALIAS_TCP_STATE_NOT_CONNECTED:
193 if (tc->th_flags & TH_RST)
194 SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
195 else if (tc->th_flags & TH_SYN)
196 SetStateOut(link, ALIAS_TCP_STATE_CONNECTED);
197 break;
198 case ALIAS_TCP_STATE_CONNECTED:
199 if (tc->th_flags & (TH_FIN | TH_RST))
200 SetStateOut(link, ALIAS_TCP_STATE_DISCONNECTED);
201 break;
202 }
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 */
250static int IcmpAliasIn1(struct libalias *, struct ip *);
251static int IcmpAliasIn2(struct libalias *, struct ip *);
252static int IcmpAliasIn (struct libalias *, struct ip *);
246static int IcmpAliasIn1(struct libalias *, struct ip *);
247static int IcmpAliasIn2(struct libalias *, struct ip *);
248static int IcmpAliasIn(struct libalias *, struct ip *);
249
254static int IcmpAliasOut1(struct libalias *, struct ip *);
255static int IcmpAliasOut2(struct libalias *, struct ip *);
256static int IcmpAliasOut (struct libalias *, struct ip *);
250static int IcmpAliasOut1(struct libalias *, struct ip *);
251static int IcmpAliasOut2(struct libalias *, struct ip *);
252static int IcmpAliasOut(struct libalias *, struct ip *);
253
258static int ProtoAliasIn(struct libalias *, struct ip *);
259static int ProtoAliasOut(struct libalias *, struct ip *);
254static int ProtoAliasIn(struct libalias *, struct ip *);
255static int ProtoAliasOut(struct libalias *, struct ip *);
256
261static int UdpAliasOut(struct libalias *, struct ip *);
262static int UdpAliasIn (struct libalias *, struct ip *);
257static int UdpAliasOut(struct libalias *, struct ip *);
258static int UdpAliasIn(struct libalias *, struct ip *);
259
264static int TcpAliasOut(struct libalias *, struct ip *, int);
265static int TcpAliasIn (struct libalias *, struct ip *);
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*/
275 struct alias_link *link;
276 struct icmp *ic;
271 struct alias_link *link;
272 struct icmp *ic;
273
278 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
274 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2));
275
276/* Get source address from ICMP data field and restore original data */
281 link = FindIcmpIn(la, pip->ip_src, pip->ip_dst, ic->icmp_id, 1);
282 if (link != NULL)
283 {
284 u_short original_id;
285 int accumulate;
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
287 original_id = GetOriginalPort(link);
282 original_id = GetOriginalPort(link);
283
284/* Adjust ICMP checksum */
290 accumulate = ic->icmp_id;
291 accumulate -= original_id;
292 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
285 accumulate = ic->icmp_id;
286 accumulate -= original_id;
287 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
288
289/* Put original sequence number back in */
295 ic->icmp_id = original_id;
290 ic->icmp_id = original_id;
291
292/* Put original address back into IP header */
298 {
299 struct in_addr original_address;
293 {
294 struct in_addr original_address;
295
301 original_address = GetOriginalAddress(link);
302 DifferentialChecksum(&pip->ip_sum,
303 (u_short *) &original_address,
304 (u_short *) &pip->ip_dst,
305 2);
306 pip->ip_dst = original_address;
307 }
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
309 return(PKT_ALIAS_OK);
310 }
311 return(PKT_ALIAS_IGNORED);
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*/
321 struct ip *ip;
322 struct icmp *ic, *ic2;
323 struct udphdr *ud;
324 struct tcphdr *tc;
325 struct alias_link *link;
316 struct ip *ip;
317 struct icmp *ic, *ic2;
318 struct udphdr *ud;
319 struct tcphdr *tc;
320 struct alias_link *link;
321
327 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
328 ip = &ic->icmp_ip;
322 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2));
323 ip = &ic->icmp_ip;
324
330 ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2));
331 tc = (struct tcphdr *) ud;
332 ic2 = (struct icmp *) ud;
325 ud = (struct udphdr *)((char *)ip + (ip->ip_hl << 2));
326 tc = (struct tcphdr *)ud;
327 ic2 = (struct icmp *)ud;
328
334 if (ip->ip_p == IPPROTO_UDP)
335 link = FindUdpTcpIn(la, ip->ip_dst, ip->ip_src,
336 ud->uh_dport, ud->uh_sport,
337 IPPROTO_UDP, 0);
338 else if (ip->ip_p == IPPROTO_TCP)
339 link = FindUdpTcpIn(la, ip->ip_dst, ip->ip_src,
340 tc->th_dport, tc->th_sport,
341 IPPROTO_TCP, 0);
342 else if (ip->ip_p == IPPROTO_ICMP) {
343 if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
344 link = FindIcmpIn(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0);
345 else
346 link = NULL;
347 } else
348 link = NULL;
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
350 if (link != NULL)
351 {
352 if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP)
353 {
354 u_short *sptr;
355 int accumulate, accumulate2;
356 struct in_addr original_address;
357 u_short original_port;
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
359 original_address = GetOriginalAddress(link);
360 original_port = GetOriginalPort(link);
352 original_address = GetOriginalAddress(link);
353 original_port = GetOriginalPort(link);
354
355/* Adjust ICMP checksum */
363 sptr = (u_short *) &(ip->ip_src);
364 accumulate = *sptr++;
365 accumulate += *sptr;
366 sptr = (u_short *) &original_address;
367 accumulate -= *sptr++;
368 accumulate -= *sptr;
369 accumulate += ud->uh_sport;
370 accumulate -= original_port;
371 accumulate2 = accumulate;
372 accumulate2 += ip->ip_sum;
373 ADJUST_CHECKSUM(accumulate, ip->ip_sum);
374 accumulate2 -= ip->ip_sum;
375 ADJUST_CHECKSUM(accumulate2, ic->icmp_cksum);
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 */
378 DifferentialChecksum(&pip->ip_sum,
379 (u_short *) &original_address,
380 (u_short *) &pip->ip_dst,
381 2);
382 pip->ip_dst = original_address;
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 */
386 ip->ip_src = original_address;
387 ud->uh_sport = original_port;
388 }
389 else if (ip->ip_p == IPPROTO_ICMP)
390 {
391 u_short *sptr;
392 int accumulate, accumulate2;
393 struct in_addr original_address;
394 u_short original_id;
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
396 original_address = GetOriginalAddress(link);
397 original_id = GetOriginalPort(link);
387 original_address = GetOriginalAddress(link);
388 original_id = GetOriginalPort(link);
389
390/* Adjust ICMP checksum */
400 sptr = (u_short *) &(ip->ip_src);
401 accumulate = *sptr++;
402 accumulate += *sptr;
403 sptr = (u_short *) &original_address;
404 accumulate -= *sptr++;
405 accumulate -= *sptr;
406 accumulate += ic2->icmp_id;
407 accumulate -= original_id;
408 accumulate2 = accumulate;
409 accumulate2 += ip->ip_sum;
410 ADJUST_CHECKSUM(accumulate, ip->ip_sum);
411 accumulate2 -= ip->ip_sum;
412 ADJUST_CHECKSUM(accumulate2, ic->icmp_cksum);
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 */
415 DifferentialChecksum(&pip->ip_sum,
416 (u_short *) &original_address,
417 (u_short *) &pip->ip_dst,
418 2);
419 pip->ip_dst = original_address;
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 */
423 ip->ip_src = original_address;
424 ic2->icmp_id = original_id;
425 }
426 return(PKT_ALIAS_OK);
427 }
428 return(PKT_ALIAS_IGNORED);
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{
435 int iresult;
436 struct icmp *ic;
426 int iresult;
427 struct icmp *ic;
428
429/* Return if proxy-only mode is enabled */
439 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
440 return PKT_ALIAS_OK;
430 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
431 return PKT_ALIAS_OK;
432
442 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
433 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2));
434
444 iresult = PKT_ALIAS_IGNORED;
445 switch (ic->icmp_type)
446 {
447 case ICMP_ECHOREPLY:
448 case ICMP_TSTAMPREPLY:
449 if (ic->icmp_code == 0)
450 {
451 iresult = IcmpAliasIn1(la, pip);
452 }
453 break;
454 case ICMP_UNREACH:
455 case ICMP_SOURCEQUENCH:
456 case ICMP_TIMXCEED:
457 case ICMP_PARAMPROB:
458 iresult = IcmpAliasIn2(la, pip);
459 break;
460 case ICMP_ECHO:
461 case ICMP_TSTAMP:
462 iresult = IcmpAliasIn1(la, pip);
463 break;
464 }
465 return(iresult);
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*/
476 struct alias_link *link;
477 struct icmp *ic;
465 struct alias_link *link;
466 struct icmp *ic;
467
479 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
468 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2));
469
470/* Save overwritten data for when echo packet returns */
482 link = FindIcmpOut(la, pip->ip_src, pip->ip_dst, ic->icmp_id, 1);
483 if (link != NULL)
484 {
485 u_short alias_id;
486 int accumulate;
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
488 alias_id = GetAliasPort(link);
476 alias_id = GetAliasPort(link);
477
478/* Since data field is being modified, adjust ICMP checksum */
491 accumulate = ic->icmp_id;
492 accumulate -= alias_id;
493 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
479 accumulate = ic->icmp_id;
480 accumulate -= alias_id;
481 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
482
483/* Alias sequence number */
496 ic->icmp_id = alias_id;
484 ic->icmp_id = alias_id;
485
486/* Change source address */
499 {
500 struct in_addr alias_address;
487 {
488 struct in_addr alias_address;
489
502 alias_address = GetAliasAddress(link);
503 DifferentialChecksum(&pip->ip_sum,
504 (u_short *) &alias_address,
505 (u_short *) &pip->ip_src,
506 2);
507 pip->ip_src = alias_address;
508 }
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
510 return(PKT_ALIAS_OK);
511 }
512 return(PKT_ALIAS_IGNORED);
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*/
523 struct ip *ip;
524 struct icmp *ic, *ic2;
525 struct udphdr *ud;
526 struct tcphdr *tc;
527 struct alias_link *link;
511 struct ip *ip;
512 struct icmp *ic, *ic2;
513 struct udphdr *ud;
514 struct tcphdr *tc;
515 struct alias_link *link;
516
529 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
530 ip = &ic->icmp_ip;
517 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2));
518 ip = &ic->icmp_ip;
519
532 ud = (struct udphdr *) ((char *) ip + (ip->ip_hl <<2));
533 tc = (struct tcphdr *) ud;
534 ic2 = (struct icmp *) ud;
520 ud = (struct udphdr *)((char *)ip + (ip->ip_hl << 2));
521 tc = (struct tcphdr *)ud;
522 ic2 = (struct icmp *)ud;
523
536 if (ip->ip_p == IPPROTO_UDP)
537 link = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src,
538 ud->uh_dport, ud->uh_sport,
539 IPPROTO_UDP, 0);
540 else if (ip->ip_p == IPPROTO_TCP)
541 link = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src,
542 tc->th_dport, tc->th_sport,
543 IPPROTO_TCP, 0);
544 else if (ip->ip_p == IPPROTO_ICMP) {
545 if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
546 link = FindIcmpOut(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0);
547 else
548 link = NULL;
549 } else
550 link = NULL;
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
552 if (link != NULL)
553 {
554 if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP)
555 {
556 u_short *sptr;
557 int accumulate;
558 struct in_addr alias_address;
559 u_short alias_port;
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
561 alias_address = GetAliasAddress(link);
562 alias_port = GetAliasPort(link);
547 alias_address = GetAliasAddress(link);
548 alias_port = GetAliasPort(link);
549
550/* Adjust ICMP checksum */
565 sptr = (u_short *) &(ip->ip_dst);
566 accumulate = *sptr++;
567 accumulate += *sptr;
568 sptr = (u_short *) &alias_address;
569 accumulate -= *sptr++;
570 accumulate -= *sptr;
571 accumulate += ud->uh_dport;
572 accumulate -= alias_port;
573 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
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 */
579 if (pip->ip_src.s_addr == ip->ip_dst.s_addr) {
580 DifferentialChecksum(&pip->ip_sum,
581 (u_short *) &alias_address,
582 (u_short *) &pip->ip_src,
583 2);
584 pip->ip_src = alias_address;
585 }
586
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 */
589 ip->ip_dst = alias_address;
590 ud->uh_dport = alias_port;
591 }
592 else if (ip->ip_p == IPPROTO_ICMP)
593 {
594 u_short *sptr;
595 int accumulate;
596 struct in_addr alias_address;
597 u_short alias_id;
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
599 alias_address = GetAliasAddress(link);
600 alias_id = GetAliasPort(link);
582 alias_address = GetAliasAddress(link);
583 alias_id = GetAliasPort(link);
584
585/* Adjust ICMP checksum */
603 sptr = (u_short *) &(ip->ip_dst);
604 accumulate = *sptr++;
605 accumulate += *sptr;
606 sptr = (u_short *) &alias_address;
607 accumulate -= *sptr++;
608 accumulate -= *sptr;
609 accumulate += ic2->icmp_id;
610 accumulate -= alias_id;
611 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
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 */
617 if (pip->ip_src.s_addr == ip->ip_dst.s_addr) {
618 DifferentialChecksum(&pip->ip_sum,
619 (u_short *) &alias_address,
620 (u_short *) &pip->ip_src,
621 2);
622 pip->ip_src = alias_address;
623 }
624
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 */
627 ip->ip_dst = alias_address;
628 ic2->icmp_id = alias_id;
629 }
630 return(PKT_ALIAS_OK);
631 }
632 return(PKT_ALIAS_IGNORED);
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{
639 int iresult;
640 struct icmp *ic;
621 int iresult;
622 struct icmp *ic;
623
624/* Return if proxy-only mode is enabled */
643 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
644 return PKT_ALIAS_OK;
625 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
626 return PKT_ALIAS_OK;
627
646 ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));
628 ic = (struct icmp *)((char *)pip + (pip->ip_hl << 2));
629
648 iresult = PKT_ALIAS_IGNORED;
649 switch (ic->icmp_type)
650 {
651 case ICMP_ECHO:
652 case ICMP_TSTAMP:
653 if (ic->icmp_code == 0)
654 {
655 iresult = IcmpAliasOut1(la, pip);
656 }
657 break;
658 case ICMP_UNREACH:
659 case ICMP_SOURCEQUENCH:
660 case ICMP_TIMXCEED:
661 case ICMP_PARAMPROB:
662 iresult = IcmpAliasOut2(la, pip);
663 break;
664 case ICMP_ECHOREPLY:
665 case ICMP_TSTAMPREPLY:
666 iresult = IcmpAliasOut1(la, pip);
667 }
668 return(iresult);
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*/
682 struct alias_link *link;
662 struct alias_link *link;
663
664/* Return if proxy-only mode is enabled */
685 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
686 return PKT_ALIAS_OK;
665 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
666 return PKT_ALIAS_OK;
667
688 link = FindProtoIn(la, pip->ip_src, pip->ip_dst, pip->ip_p);
689 if (link != NULL)
690 {
691 struct in_addr original_address;
668 link = FindProtoIn(la, pip->ip_src, pip->ip_dst, pip->ip_p);
669 if (link != NULL) {
670 struct in_addr original_address;
671
693 original_address = GetOriginalAddress(link);
672 original_address = GetOriginalAddress(link);
673
674/* Restore original IP address */
696 DifferentialChecksum(&pip->ip_sum,
697 (u_short *) &original_address,
698 (u_short *) &pip->ip_dst,
699 2);
700 pip->ip_dst = original_address;
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
702 return(PKT_ALIAS_OK);
703 }
704 return(PKT_ALIAS_IGNORED);
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*/
716 struct alias_link *link;
695 struct alias_link *link;
696
697/* Return if proxy-only mode is enabled */
719 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
720 return PKT_ALIAS_OK;
698 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
699 return PKT_ALIAS_OK;
700
722 link = FindProtoOut(la, pip->ip_src, pip->ip_dst, pip->ip_p);
723 if (link != NULL)
724 {
725 struct in_addr alias_address;
701 link = FindProtoOut(la, pip->ip_src, pip->ip_dst, pip->ip_p);
702 if (link != NULL) {
703 struct in_addr alias_address;
704
727 alias_address = GetAliasAddress(link);
705 alias_address = GetAliasAddress(link);
706
707/* Change source address */
730 DifferentialChecksum(&pip->ip_sum,
731 (u_short *) &alias_address,
732 (u_short *) &pip->ip_src,
733 2);
734 pip->ip_src = alias_address;
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
736 return(PKT_ALIAS_OK);
737 }
738 return(PKT_ALIAS_IGNORED);
714 return (PKT_ALIAS_OK);
715 }
716 return (PKT_ALIAS_IGNORED);
717}
718
719
720static int
721UdpAliasIn(struct libalias *la, struct ip *pip)
722{
745 struct udphdr *ud;
746 struct alias_link *link;
723 struct udphdr *ud;
724 struct alias_link *link;
725
726/* Return if proxy-only mode is enabled */
749 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
750 return PKT_ALIAS_OK;
727 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
728 return PKT_ALIAS_OK;
729
752 ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
730 ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
731
754 link = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst,
755 ud->uh_sport, ud->uh_dport,
756 IPPROTO_UDP, 1);
757 if (link != NULL)
758 {
759 struct in_addr alias_address;
760 struct in_addr original_address;
761 u_short alias_port;
762 int accumulate;
763 u_short *sptr;
764 int r = 0;
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
766 alias_address = GetAliasAddress(link);
767 original_address = GetOriginalAddress(link);
768 alias_port = ud->uh_dport;
769 ud->uh_dport = GetOriginalPort(link);
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 */
772 if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
773 AliasHandleCUSeeMeIn(la, pip, original_address);
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 */
775 else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
776 || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER)
777 r = AliasHandleUdpNbt(la, pip, link, &original_address, ud->uh_dport);
778 else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
779 || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER)
780 r = AliasHandleUdpNbtNS(la, pip, link, &alias_address, &alias_port,
781 &original_address, &ud->uh_dport);
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. */
785 if (ud->uh_sum != 0)
786 {
787 accumulate = alias_port;
788 accumulate -= ud->uh_dport;
789 sptr = (u_short *) &alias_address;
790 accumulate += *sptr++;
791 accumulate += *sptr;
792 sptr = (u_short *) &original_address;
793 accumulate -= *sptr++;
794 accumulate -= *sptr;
795 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
796 }
797
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 */
799 DifferentialChecksum(&pip->ip_sum,
800 (u_short *) &original_address,
801 (u_short *) &pip->ip_dst,
802 2);
803 pip->ip_dst = original_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
805 /*
806 * If we cannot figure out the packet, ignore it.
807 */
808 if (r < 0)
809 return(PKT_ALIAS_IGNORED);
810 else
811 return(PKT_ALIAS_OK);
812 }
813 return(PKT_ALIAS_IGNORED);
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{
819 struct udphdr *ud;
820 struct alias_link *link;
794 struct udphdr *ud;
795 struct alias_link *link;
796
797/* Return if proxy-only mode is enabled */
823 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
824 return PKT_ALIAS_OK;
798 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
799 return PKT_ALIAS_OK;
800
826 ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
801 ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
802
828 link = FindUdpTcpOut(la, pip->ip_src, pip->ip_dst,
829 ud->uh_sport, ud->uh_dport,
830 IPPROTO_UDP, 1);
831 if (link != NULL)
832 {
833 u_short alias_port;
834 struct in_addr alias_address;
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
836 alias_address = GetAliasAddress(link);
837 alias_port = GetAliasPort(link);
810 alias_address = GetAliasAddress(link);
811 alias_port = GetAliasPort(link);
812
813/* Special processing for IP encoding protocols */
840 if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)
841 AliasHandleCUSeeMeOut(la, pip, link);
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 */
843 else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER
844 || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER)
845 AliasHandleUdpNbt(la, pip, link, &alias_address, alias_port);
846 else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER
847 || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER)
848 AliasHandleUdpNbtNS(la, pip, link, &pip->ip_src, &ud->uh_sport,
849 &alias_address, &alias_port);
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 */
855 else if (ntohs(ud->uh_dport) == TFTP_PORT_NUMBER)
856 FindRtspOut(la, pip->ip_src, pip->ip_dst,
857 ud->uh_sport, alias_port, IPPROTO_UDP);
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 */
861 if (ud->uh_sum != 0)
862 {
863 int accumulate;
864 u_short *sptr;
835 if (ud->uh_sum != 0) {
836 int accumulate;
837 u_short *sptr;
838
866 accumulate = ud->uh_sport;
867 accumulate -= alias_port;
868 sptr = (u_short *) &(pip->ip_src);
869 accumulate += *sptr++;
870 accumulate += *sptr;
871 sptr = (u_short *) &alias_address;
872 accumulate -= *sptr++;
873 accumulate -= *sptr;
874 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
875 }
876
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 */
878 ud->uh_sport = alias_port;
850 ud->uh_sport = alias_port;
851
852/* Change source address */
881 DifferentialChecksum(&pip->ip_sum,
882 (u_short *) &alias_address,
883 (u_short *) &pip->ip_src,
884 2);
885 pip->ip_src = alias_address;
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
887 return(PKT_ALIAS_OK);
888 }
889 return(PKT_ALIAS_IGNORED);
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{
897 struct tcphdr *tc;
898 struct alias_link *link;
869 struct tcphdr *tc;
870 struct alias_link *link;
871
900 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
872 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
873
902 link = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst,
903 tc->th_sport, tc->th_dport,
904 IPPROTO_TCP,
905 !(la->packetAliasMode & PKT_ALIAS_PROXY_ONLY));
906 if (link != NULL)
907 {
908 struct in_addr alias_address;
909 struct in_addr original_address;
910 struct in_addr proxy_address;
911 u_short alias_port;
912 u_short proxy_port;
913 int accumulate;
914 u_short *sptr;
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 */
917 if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
918 || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
919 AliasHandlePptpIn(la, pip, link);
920 else if (la->skinnyPort != 0 && (ntohs(tc->th_dport) == la->skinnyPort
921 || ntohs(tc->th_sport) == la->skinnyPort))
922 AliasHandleSkinny(la, pip, link);
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
924 alias_address = GetAliasAddress(link);
925 original_address = GetOriginalAddress(link);
926 proxy_address = GetProxyAddress(link);
927 alias_port = tc->th_dport;
928 tc->th_dport = GetOriginalPort(link);
929 proxy_port = GetProxyPort(link);
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. */
933 accumulate = alias_port;
934 accumulate -= tc->th_dport;
935 sptr = (u_short *) &alias_address;
936 accumulate += *sptr++;
937 accumulate += *sptr;
938 sptr = (u_short *) &original_address;
939 accumulate -= *sptr++;
940 accumulate -= *sptr;
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 */
944 if (proxy_port != 0)
945 {
946 accumulate += tc->th_sport;
947 tc->th_sport = proxy_port;
948 accumulate -= tc->th_sport;
915 if (proxy_port != 0) {
916 accumulate += tc->th_sport;
917 tc->th_sport = proxy_port;
918 accumulate -= tc->th_sport;
919
950 sptr = (u_short *) &pip->ip_src;
951 accumulate += *sptr++;
952 accumulate += *sptr;
953 sptr = (u_short *) &proxy_address;
954 accumulate -= *sptr++;
955 accumulate -= *sptr;
956 }
957
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 */
959 if (GetAckModified(link) == 1)
960 {
961 int delta;
928 if (GetAckModified(link) == 1) {
929 int delta;
930
963 delta = GetDeltaAckIn(pip, link);
964 if (delta != 0)
965 {
966 sptr = (u_short *) &tc->th_ack;
967 accumulate += *sptr++;
968 accumulate += *sptr;
969 tc->th_ack = htonl(ntohl(tc->th_ack) - delta);
970 sptr = (u_short *) &tc->th_ack;
971 accumulate -= *sptr++;
972 accumulate -= *sptr;
973 }
974 }
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
976 ADJUST_CHECKSUM(accumulate, tc->th_sum);
977
944/* Restore original IP address */
979 sptr = (u_short *) &pip->ip_dst;
980 accumulate = *sptr++;
981 accumulate += *sptr;
982 pip->ip_dst = original_address;
983 sptr = (u_short *) &pip->ip_dst;
984 accumulate -= *sptr++;
985 accumulate -= *sptr;
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 */
989 if (proxy_address.s_addr != 0)
990 {
991 sptr = (u_short *) &pip->ip_src;
992 accumulate += *sptr++;
993 accumulate += *sptr;
994 pip->ip_src = proxy_address;
995 sptr = (u_short *) &pip->ip_src;
996 accumulate -= *sptr++;
997 accumulate -= *sptr;
998 }
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
1000 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1001
966/* Monitor TCP connection state */
1003 TcpMonitorIn(pip, link);
967 TcpMonitorIn(pip, link);
968
1005 return(PKT_ALIAS_OK);
1006 }
1007 return(PKT_ALIAS_IGNORED);
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{
1013 int proxy_type;
1014 u_short dest_port;
1015 u_short proxy_server_port;
1016 struct in_addr dest_address;
1017 struct in_addr proxy_server_address;
1018 struct tcphdr *tc;
1019 struct alias_link *link;
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
1021 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
985 tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
986
1023 proxy_type = ProxyCheck(la, pip, &proxy_server_address, &proxy_server_port);
987 proxy_type = ProxyCheck(la, pip, &proxy_server_address, &proxy_server_port);
988
1025 if (proxy_type == 0 && (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY))
1026 return PKT_ALIAS_OK;
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 */
1030 dest_port = tc->th_dport;
1031 dest_address = pip->ip_dst;
1032 if (proxy_type != 0)
1033 {
1034 int accumulate;
1035 u_short *sptr;
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
1037 accumulate = tc->th_dport;
1038 tc->th_dport = proxy_server_port;
1039 accumulate -= tc->th_dport;
1000 accumulate = tc->th_dport;
1001 tc->th_dport = proxy_server_port;
1002 accumulate -= tc->th_dport;
1003
1041 sptr = (u_short *) &(pip->ip_dst);
1042 accumulate += *sptr++;
1043 accumulate += *sptr;
1044 sptr = (u_short *) &proxy_server_address;
1045 accumulate -= *sptr++;
1046 accumulate -= *sptr;
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
1048 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1011 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1012
1050 sptr = (u_short *) &(pip->ip_dst);
1051 accumulate = *sptr++;
1052 accumulate += *sptr;
1053 pip->ip_dst = proxy_server_address;
1054 sptr = (u_short *) &(pip->ip_dst);
1055 accumulate -= *sptr++;
1056 accumulate -= *sptr;
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
1058 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1059 }
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
1061 link = FindUdpTcpOut(la, pip->ip_src, pip->ip_dst,
1062 tc->th_sport, tc->th_dport,
1063 IPPROTO_TCP, 1);
1064 if (link !=NULL)
1065 {
1066 u_short alias_port;
1067 struct in_addr alias_address;
1068 int accumulate;
1069 u_short *sptr;
1070
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. */
1074 if (proxy_type != 0)
1075 {
1076 SetProxyPort(link, dest_port);
1077 SetProxyAddress(link, dest_address);
1078 ProxyModify(la, link, pip, maxpacketsize, proxy_type);
1079 tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
1080 }
1081
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 */
1083 alias_port = GetAliasPort(link);
1084 alias_address = GetAliasAddress(link);
1042 alias_port = GetAliasPort(link);
1043 alias_address = GetAliasAddress(link);
1044
1045/* Monitor TCP connection state */
1087 TcpMonitorOut(pip, link);
1046 TcpMonitorOut(pip, link);
1047
1048/* Special processing for IP encoding protocols */
1090 if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER
1091 || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER)
1092 AliasHandleFtpOut(la, pip, link, maxpacketsize);
1093 else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1
1094 || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2)
1095 AliasHandleIrcOut(la, pip, link, maxpacketsize);
1096 else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1
1097 || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1
1098 || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2
1099 || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2)
1100 AliasHandleRtspOut(la, pip, link, maxpacketsize);
1101 else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
1102 || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
1103 AliasHandlePptpOut(la, pip, link);
1104 else if (la->skinnyPort != 0 && (ntohs(tc->th_sport) == la->skinnyPort
1105 || ntohs(tc->th_dport) == la->skinnyPort))
1106 AliasHandleSkinny(la, pip, link);
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 */
1110 accumulate = tc->th_sport;
1111 tc->th_sport = alias_port;
1112 accumulate -= tc->th_sport;
1069 accumulate = tc->th_sport;
1070 tc->th_sport = alias_port;
1071 accumulate -= tc->th_sport;
1072
1114 sptr = (u_short *) &(pip->ip_src);
1115 accumulate += *sptr++;
1116 accumulate += *sptr;
1117 sptr = (u_short *) &alias_address;
1118 accumulate -= *sptr++;
1119 accumulate -= *sptr;
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 */
1122 if (GetAckModified(link) == 1)
1123 {
1124 int delta;
1081 if (GetAckModified(link) == 1) {
1082 int delta;
1083
1126 delta = GetDeltaSeqOut(pip, link);
1127 if (delta != 0)
1128 {
1129 sptr = (u_short *) &tc->th_seq;
1130 accumulate += *sptr++;
1131 accumulate += *sptr;
1132 tc->th_seq = htonl(ntohl(tc->th_seq) + delta);
1133 sptr = (u_short *) &tc->th_seq;
1134 accumulate -= *sptr++;
1135 accumulate -= *sptr;
1136 }
1137 }
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
1139 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1140
1097/* Change source address */
1142 sptr = (u_short *) &(pip->ip_src);
1143 accumulate = *sptr++;
1144 accumulate += *sptr;
1145 pip->ip_src = alias_address;
1146 sptr = (u_short *) &(pip->ip_src);
1147 accumulate -= *sptr++;
1148 accumulate -= *sptr;
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
1150 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1106 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1107
1152 return(PKT_ALIAS_OK);
1153 }
1154 return(PKT_ALIAS_IGNORED);
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 */
1174static int FragmentIn(struct libalias *, struct ip *);
1175static int FragmentOut(struct libalias *, struct ip *);
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{
1181 struct alias_link *link;
1137 struct alias_link *link;
1138
1183 link = FindFragmentIn2(la, pip->ip_src, pip->ip_dst, pip->ip_id);
1184 if (link != NULL)
1185 {
1186 struct in_addr original_address;
1139 link = FindFragmentIn2(la, pip->ip_src, pip->ip_dst, pip->ip_id);
1140 if (link != NULL) {
1141 struct in_addr original_address;
1142
1188 GetFragmentAddr(link, &original_address);
1189 DifferentialChecksum(&pip->ip_sum,
1190 (u_short *) &original_address,
1191 (u_short *) &pip->ip_dst,
1192 2);
1193 pip->ip_dst = original_address;
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
1195 return(PKT_ALIAS_OK);
1196 }
1197 return(PKT_ALIAS_UNRESOLVED_FRAGMENT);
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{
1204 struct in_addr alias_address;
1159 struct in_addr alias_address;
1160
1206 alias_address = FindAliasAddress(la, pip->ip_src);
1207 DifferentialChecksum(&pip->ip_sum,
1208 (u_short *) &alias_address,
1209 (u_short *) &pip->ip_src,
1210 2);
1211 pip->ip_src = alias_address;
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
1213 return(PKT_ALIAS_OK);
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{
1237 int iresult;
1238 struct alias_link *link;
1239 struct ip *pip;
1192 int iresult;
1193 struct alias_link *link;
1194 struct ip *pip;
1195
1241 pip = (struct ip *) ptr;
1242 link = AddFragmentPtrLink(la, pip->ip_src, pip->ip_id);
1243 iresult = PKT_ALIAS_ERROR;
1244 if (link != NULL)
1245 {
1246 SetFragmentPtr(link, ptr);
1247 iresult = PKT_ALIAS_OK;
1248 }
1249 return(iresult);
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
1253char *
1207char *
1208LibAliasGetFragment(struct libalias *la, char *ptr)
1209{
1256 struct alias_link *link;
1257 char *fptr;
1258 struct ip *pip;
1210 struct alias_link *link;
1211 char *fptr;
1212 struct ip *pip;
1213
1260 pip = (struct ip *) ptr;
1261 link = FindFragmentPtr(la, pip->ip_src, pip->ip_id);
1262 if (link != NULL)
1263 {
1264 GetFragmentPtr(link, &fptr);
1265 SetFragmentPtr(link, NULL);
1266 SetExpire(link, 0); /* Deletes link */
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
1268 return(fptr);
1269 }
1270 else
1271 {
1272 return(NULL);
1273 }
1221 return (fptr);
1222 } else {
1223 return (NULL);
1224 }
1225}
1226
1227
1228void
1278LibAliasFragmentIn(struct libalias *la, char *ptr, /* Points to correctly de-aliased
1279 header fragment */
1280 char *ptr_fragment /* Points to fragment which must
1281 be de-aliased */
1282 )
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{
1284 struct ip *pip;
1285 struct ip *fpip;
1236 struct ip *pip;
1237 struct ip *fpip;
1238
1287 pip = (struct ip *) ptr;
1288 fpip = (struct ip *) ptr_fragment;
1239 pip = (struct ip *)ptr;
1240 fpip = (struct ip *)ptr_fragment;
1241
1290 DifferentialChecksum(&fpip->ip_sum,
1291 (u_short *) &pip->ip_dst,
1292 (u_short *) &fpip->ip_dst,
1293 2);
1294 fpip->ip_dst = pip->ip_dst;
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{
1301 struct in_addr alias_addr;
1302 struct ip *pip;
1303 int iresult;
1253 struct in_addr alias_addr;
1254 struct ip *pip;
1255 int iresult;
1256
1305 if (la->packetAliasMode & PKT_ALIAS_REVERSE) {
1306 la->packetAliasMode &= ~PKT_ALIAS_REVERSE;
1307 iresult = PacketAliasOut(ptr, maxpacketsize);
1308 la->packetAliasMode |= PKT_ALIAS_REVERSE;
1309 return iresult;
1310 }
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
1312 HouseKeeping(la);
1313 ClearCheckNewLink(la);
1314 pip = (struct ip *) ptr;
1315 alias_addr = pip->ip_dst;
1268 /* Defense against mangled packets */
1269 if (ntohs(pip->ip_len) > maxpacketsize
1270 || (pip->ip_hl << 2) > maxpacketsize)
1271 return PKT_ALIAS_IGNORED;
1272
1317 /* Defense against mangled packets */
1318 if (ntohs(pip->ip_len) > maxpacketsize
1319 || (pip->ip_hl<<2) > maxpacketsize)
1320 return PKT_ALIAS_IGNORED;
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
1322 iresult = PKT_ALIAS_IGNORED;
1323 if ( (ntohs(pip->ip_off) & IP_OFFMASK) == 0 )
1324 {
1325 switch (pip->ip_p)
1326 {
1327 case IPPROTO_ICMP:
1328 iresult = IcmpAliasIn(la, pip);
1329 break;
1330 case IPPROTO_UDP:
1331 iresult = UdpAliasIn(la, pip);
1332 break;
1333 case IPPROTO_TCP:
1334 iresult = TcpAliasIn(la, pip);
1335 break;
1336 case IPPROTO_GRE:
1337 if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY ||
1338 AliasHandlePptpGreIn(la, pip) == 0)
1339 iresult = PKT_ALIAS_OK;
1340 else
1341 iresult = ProtoAliasIn(la, pip);
1342 break;
1343 default:
1344 iresult = ProtoAliasIn(la, pip);
1345 break;
1346 }
1297 if (ntohs(pip->ip_off) & IP_MF) {
1298 struct alias_link *link;
1299
1348 if (ntohs(pip->ip_off) & IP_MF)
1349 {
1350 struct alias_link *link;
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
1352 link = FindFragmentIn1(la, pip->ip_src, alias_addr, pip->ip_id);
1353 if (link != NULL)
1354 {
1355 iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT;
1356 SetFragmentAddr(link, pip->ip_dst);
1357 }
1358 else
1359 {
1360 iresult = PKT_ALIAS_ERROR;
1361 }
1362 }
1363 }
1364 else
1365 {
1366 iresult = FragmentIn(la, pip);
1367 }
1368
1369 return(iresult);
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
1389LibAliasOut(struct libalias *la, char *ptr, /* valid IP packet */
1390 int maxpacketsize /* How much the packet data may grow
1391 (FTP and IRC inline changes) */
1392 )
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{
1394 int iresult;
1395 struct in_addr addr_save;
1396 struct ip *pip;
1337 int iresult;
1338 struct in_addr addr_save;
1339 struct ip *pip;
1340
1398 if (la->packetAliasMode & PKT_ALIAS_REVERSE) {
1399 la->packetAliasMode &= ~PKT_ALIAS_REVERSE;
1400 iresult = PacketAliasIn(ptr, maxpacketsize);
1401 la->packetAliasMode |= PKT_ALIAS_REVERSE;
1402 return iresult;
1403 }
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
1405 HouseKeeping(la);
1406 ClearCheckNewLink(la);
1407 pip = (struct ip *) ptr;
1351 /* Defense against mangled packets */
1352 if (ntohs(pip->ip_len) > maxpacketsize
1353 || (pip->ip_hl << 2) > maxpacketsize)
1354 return PKT_ALIAS_IGNORED;
1355
1409 /* Defense against mangled packets */
1410 if (ntohs(pip->ip_len) > maxpacketsize
1411 || (pip->ip_hl<<2) > maxpacketsize)
1412 return PKT_ALIAS_IGNORED;
1356 addr_save = GetDefaultAliasAddress(la);
1357 if (la->packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY) {
1358 u_long addr;
1359 int iclass;
1360
1414 addr_save = GetDefaultAliasAddress(la);
1415 if (la->packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY)
1416 {
1417 u_long addr;
1418 int iclass;
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
1420 iclass = 0;
1421 addr = ntohl(pip->ip_src.s_addr);
1422 if (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER)
1423 iclass = 3;
1424 else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER)
1425 iclass = 2;
1426 else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER)
1427 iclass = 1;
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
1429 if (iclass == 0)
1430 {
1431 SetDefaultAliasAddress(la, pip->ip_src);
1432 }
1433 }
1434 else if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)
1435 {
1436 SetDefaultAliasAddress(la, pip->ip_src);
1437 }
1438
1439 iresult = PKT_ALIAS_IGNORED;
1440 if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0)
1441 {
1442 switch (pip->ip_p)
1443 {
1444 case IPPROTO_ICMP:
1445 iresult = IcmpAliasOut(la, pip);
1446 break;
1447 case IPPROTO_UDP:
1448 iresult = UdpAliasOut(la, pip);
1449 break;
1450 case IPPROTO_TCP:
1451 iresult = TcpAliasOut(la, pip, maxpacketsize);
1452 break;
1453 case IPPROTO_GRE:
1454 if (AliasHandlePptpGreOut(la, pip) == 0)
1455 iresult = PKT_ALIAS_OK;
1456 else
1457 iresult = ProtoAliasOut(la, pip);
1458 break;
1459 default:
1460 iresult = ProtoAliasOut(la, pip);
1461 break;
1462 }
1463 }
1464 else
1465 {
1466 iresult = FragmentOut(la, pip);
1467 }
1468
1469 SetDefaultAliasAddress(la, addr_save);
1470 return(iresult);
1402 SetDefaultAliasAddress(la, addr_save);
1403 return (iresult);
1404}
1405
1406int
1474LibAliasUnaliasOut(struct libalias *la, char *ptr, /* valid IP packet */
1475 int maxpacketsize /* for error checking */
1476 )
1407LibAliasUnaliasOut(struct libalias *la, char *ptr, /* valid IP packet */
1408 int maxpacketsize /* for error checking */
1409)
1410{
1478 struct ip *pip;
1479 struct icmp *ic;
1480 struct udphdr *ud;
1481 struct tcphdr *tc;
1482 struct alias_link *link;
1483 int iresult = PKT_ALIAS_IGNORED;
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
1485 pip = (struct ip *) ptr;
1418 pip = (struct ip *)ptr;
1419
1487 /* Defense against mangled packets */
1488 if (ntohs(pip->ip_len) > maxpacketsize
1489 || (pip->ip_hl<<2) > maxpacketsize)
1490 return(iresult);
1420 /* Defense against mangled packets */
1421 if (ntohs(pip->ip_len) > maxpacketsize
1422 || (pip->ip_hl << 2) > maxpacketsize)
1423 return (iresult);
1424
1492 ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
1493 tc = (struct tcphdr *) ud;
1494 ic = (struct icmp *) ud;
1425 ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
1426 tc = (struct tcphdr *)ud;
1427 ic = (struct icmp *)ud;
1428
1496 /* Find a link */
1497 if (pip->ip_p == IPPROTO_UDP)
1498 link = FindUdpTcpIn(la, pip->ip_dst, pip->ip_src,
1499 ud->uh_dport, ud->uh_sport,
1500 IPPROTO_UDP, 0);
1501 else if (pip->ip_p == IPPROTO_TCP)
1502 link = FindUdpTcpIn(la, pip->ip_dst, pip->ip_src,
1503 tc->th_dport, tc->th_sport,
1504 IPPROTO_TCP, 0);
1505 else if (pip->ip_p == IPPROTO_ICMP)
1506 link = FindIcmpIn(la, pip->ip_dst, pip->ip_src, ic->icmp_id, 0);
1507 else
1508 link = NULL;
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
1510 /* Change it from an aliased packet to an unaliased packet */
1511 if (link != NULL)
1512 {
1513 if (pip->ip_p == IPPROTO_UDP || pip->ip_p == IPPROTO_TCP)
1514 {
1515 u_short *sptr;
1516 int accumulate;
1517 struct in_addr original_address;
1518 u_short original_port;
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
1520 original_address = GetOriginalAddress(link);
1521 original_port = GetOriginalPort(link);
1451 original_address = GetOriginalAddress(link);
1452 original_port = GetOriginalPort(link);
1453
1523 /* Adjust TCP/UDP checksum */
1524 sptr = (u_short *) &(pip->ip_src);
1525 accumulate = *sptr++;
1526 accumulate += *sptr;
1527 sptr = (u_short *) &original_address;
1528 accumulate -= *sptr++;
1529 accumulate -= *sptr;
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
1531 if (pip->ip_p == IPPROTO_UDP) {
1532 accumulate += ud->uh_sport;
1533 accumulate -= original_port;
1534 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
1535 } else {
1536 accumulate += tc->th_sport;
1537 accumulate -= original_port;
1538 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1539 }
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
1541 /* Adjust IP checksum */
1542 DifferentialChecksum(&pip->ip_sum,
1543 (u_short *) &original_address,
1544 (u_short *) &pip->ip_src,
1545 2);
1472 /* Adjust IP checksum */
1473 DifferentialChecksum(&pip->ip_sum,
1474 (u_short *) & original_address,
1475 (u_short *) & pip->ip_src,
1476 2);
1477
1547 /* Un-alias source address and port number */
1548 pip->ip_src = original_address;
1549 if (pip->ip_p == IPPROTO_UDP)
1550 ud->uh_sport = original_port;
1551 else
1552 tc->th_sport = original_port;
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
1554 iresult = PKT_ALIAS_OK;
1485 iresult = PKT_ALIAS_OK;
1486
1556 } else if (pip->ip_p == IPPROTO_ICMP) {
1487 } else if (pip->ip_p == IPPROTO_ICMP) {
1488
1558 u_short *sptr;
1559 int accumulate;
1560 struct in_addr original_address;
1561 u_short original_id;
1489 u_short *sptr;
1490 int accumulate;
1491 struct in_addr original_address;
1492 u_short original_id;
1493
1563 original_address = GetOriginalAddress(link);
1564 original_id = GetOriginalPort(link);
1494 original_address = GetOriginalAddress(link);
1495 original_id = GetOriginalPort(link);
1496
1566 /* Adjust ICMP checksum */
1567 sptr = (u_short *) &(pip->ip_src);
1568 accumulate = *sptr++;
1569 accumulate += *sptr;
1570 sptr = (u_short *) &original_address;
1571 accumulate -= *sptr++;
1572 accumulate -= *sptr;
1573 accumulate += ic->icmp_id;
1574 accumulate -= original_id;
1575 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
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
1577 /* Adjust IP checksum */
1578 DifferentialChecksum(&pip->ip_sum,
1579 (u_short *) &original_address,
1580 (u_short *) &pip->ip_src,
1581 2);
1508 /* Adjust IP checksum */
1509 DifferentialChecksum(&pip->ip_sum,
1510 (u_short *) & original_address,
1511 (u_short *) & pip->ip_src,
1512 2);
1513
1583 /* Un-alias source address and port number */
1584 pip->ip_src = original_address;
1585 ic->icmp_id = original_id;
1514 /* Un-alias source address and port number */
1515 pip->ip_src = original_address;
1516 ic->icmp_id = original_id;
1517
1587 iresult = PKT_ALIAS_OK;
1588 }
1589 }
1590 return(iresult);
1518 iresult = PKT_ALIAS_OK;
1519 }
1520 }
1521 return (iresult);
1522
1523}