FreeBSD kernel IPv4 code
alias.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2001 Charles Mott <cm@linktel.net>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31
32/*
33 Alias.c provides supervisory control for the functions of the
34 packet aliasing software. It consists of routines to monitor
35 TCP connection state, protocol-specific aliasing routines,
36 fragment handling and the following outside world functional
37 interfaces: SaveFragmentPtr, GetFragmentPtr, FragmentAliasIn,
38 PacketAliasIn and PacketAliasOut.
39
40 The other C program files are briefly described. The data
41 structure framework which holds information needed to translate
42 packets is encapsulated in alias_db.c. Data is accessed by
43 function calls, so other segments of the program need not know
44 about the underlying data structures. Alias_ftp.c contains
45 special code for modifying the ftp PORT command used to establish
46 data connections, while alias_irc.c does the same for IRC
47 DCC. Alias_util.c contains a few utility routines.
48
49 Version 1.0 August, 1996 (cjm)
50
51 Version 1.1 August 20, 1996 (cjm)
52 PPP host accepts incoming connections for ports 0 to 1023.
53 (Gary Roberts pointed out the need to handle incoming
54 connections.)
55
56 Version 1.2 September 7, 1996 (cjm)
57 Fragment handling error in alias_db.c corrected.
58 (Tom Torrance helped fix this problem.)
59
60 Version 1.4 September 16, 1996 (cjm)
61 - A more generalized method for handling incoming
62 connections, without the 0-1023 restriction, is
63 implemented in alias_db.c
64 - Improved ICMP support in alias.c. Traceroute
65 packet streams can now be correctly aliased.
66 - TCP connection closing logic simplified in
67 alias.c and now allows for additional 1 minute
68 "grace period" after FIN or RST is observed.
69
70 Version 1.5 September 17, 1996 (cjm)
71 Corrected error in handling incoming UDP packets with 0 checksum.
72 (Tom Torrance helped fix this problem.)
73
74 Version 1.6 September 18, 1996 (cjm)
75 Simplified ICMP aliasing scheme. Should now support
76 traceroute from Win95 as well as FreeBSD.
77
78 Version 1.7 January 9, 1997 (cjm)
79 - Out-of-order fragment handling.
80 - IP checksum error fixed for ftp transfers
81 from aliasing host.
82 - Integer return codes added to all
83 aliasing/de-aliasing functions.
84 - Some obsolete comments cleaned up.
85 - Differential checksum computations for
86 IP header (TCP, UDP and ICMP were already
87 differential).
88
89 Version 2.1 May 1997 (cjm)
90 - Added support for outgoing ICMP error
91 messages.
92 - Added two functions PacketAliasIn2()
93 and PacketAliasOut2() for dynamic address
94 control (e.g. round-robin allocation of
95 incoming packets).
96
97 Version 2.2 July 1997 (cjm)
98 - Rationalized API function names to begin
99 with "PacketAlias..."
100 - Eliminated PacketAliasIn2() and
101 PacketAliasOut2() as poorly conceived.
102
103 Version 2.3 Dec 1998 (dillon)
104 - Major bounds checking additions, see FreeBSD/CVS
105
106 Version 3.1 May, 2000 (salander)
107 - Added hooks to handle PPTP.
108
109 Version 3.2 July, 2000 (salander and satoh)
110 - Added PacketUnaliasOut routine.
111 - Added hooks to handle RTSP/RTP.
112
113 See HISTORY file for additional revisions.
114*/
115
116#ifdef _KERNEL
117#include <sys/param.h>
118#include <sys/systm.h>
119#include <sys/mbuf.h>
120#include <sys/sysctl.h>
121#else
122#include <sys/types.h>
123#include <stdlib.h>
124#include <stdio.h>
125#include <ctype.h>
126#include <dlfcn.h>
127#include <errno.h>
128#include <string.h>
129#endif
130
131#include <netinet/in_systm.h>
132#include <netinet/in.h>
133#include <netinet/ip.h>
134#include <netinet/ip_icmp.h>
135#include <netinet/tcp.h>
136#include <netinet/udp.h>
137
138#ifdef _KERNEL
142#else
143#include <err.h>
144#include "alias.h"
145#include "alias_local.h"
146#include "alias_mod.h"
147#endif
148
149/*
150 * Define libalias SYSCTL Node
151 */
152#ifdef SYSCTL_NODE
153
154SYSCTL_DECL(_net_inet);
155SYSCTL_DECL(_net_inet_ip);
156SYSCTL_NODE(_net_inet_ip, OID_AUTO, alias, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
157 "Libalias sysctl API");
158
159#endif
160
161static __inline int
162twowords(void *p)
163{
164 uint8_t *c = p;
165
166#if BYTE_ORDER == LITTLE_ENDIAN
167 uint16_t s1 = ((uint16_t)c[1] << 8) + (uint16_t)c[0];
168 uint16_t s2 = ((uint16_t)c[3] << 8) + (uint16_t)c[2];
169#else
170 uint16_t s1 = ((uint16_t)c[0] << 8) + (uint16_t)c[1];
171 uint16_t s2 = ((uint16_t)c[2] << 8) + (uint16_t)c[3];
172#endif
173 return (s1 + s2);
174}
175
176/* TCP Handling Routines
177
178 TcpMonitorIn() -- These routines monitor TCP connections, and
179 TcpMonitorOut() delete a link when a connection is closed.
180
181These routines look for SYN, FIN and RST flags to determine when TCP
182connections open and close. When a TCP connection closes, the data
183structure containing packet aliasing information is deleted after
184a timeout period.
185*/
186
187/* Local prototypes */
188static void TcpMonitorIn(u_char, struct alias_link *);
189
190static void TcpMonitorOut(u_char, struct alias_link *);
191
192static void
193TcpMonitorIn(u_char th_flags, struct alias_link *lnk)
194{
195 switch (GetStateIn(lnk)) {
197 if (th_flags & TH_RST)
199 else if (th_flags & TH_SYN)
201 break;
203 if (th_flags & (TH_FIN | TH_RST))
205 break;
206 }
207}
208
209static void
210TcpMonitorOut(u_char th_flags, struct alias_link *lnk)
211{
212 switch (GetStateOut(lnk)) {
214 if (th_flags & TH_RST)
216 else if (th_flags & TH_SYN)
218 break;
220 if (th_flags & (TH_FIN | TH_RST))
222 break;
223 }
224}
225
226/* Protocol Specific Packet Aliasing Routines
227
228 IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2()
229 IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2()
230 ProtoAliasIn(), ProtoAliasOut()
231 UdpAliasIn(), UdpAliasOut()
232 TcpAliasIn(), TcpAliasOut()
233
234These routines handle protocol specific details of packet aliasing.
235One may observe a certain amount of repetitive arithmetic in these
236functions, the purpose of which is to compute a revised checksum
237without actually summing over the entire data packet, which could be
238unnecessarily time consuming.
239
240The purpose of the packet aliasing routines is to replace the source
241address of the outgoing packet and then correctly put it back for
242any incoming packets. For TCP and UDP, ports are also re-mapped.
243
244For ICMP echo/timestamp requests and replies, the following scheme
245is used: the ID number is replaced by an alias for the outgoing
246packet.
247
248ICMP error messages are handled by looking at the IP fragment
249in the data section of the message.
250
251For TCP and UDP protocols, a port number is chosen for an outgoing
252packet, and then incoming packets are identified by IP address and
253port numbers. For TCP packets, there is additional logic in the event
254that sequence and ACK numbers have been altered (as in the case for
255FTP data port commands).
256
257The port numbers used by the packet aliasing module are not true
258ports in the Unix sense. No sockets are actually bound to ports.
259They are more correctly thought of as placeholders.
260
261All packets go through the aliasing mechanism, whether they come from
262the gateway machine or other machines on a local area network.
263*/
264
265/* Local prototypes */
266static int IcmpAliasIn1(struct libalias *, struct ip *);
267static int IcmpAliasIn2(struct libalias *, struct ip *);
268static int IcmpAliasIn(struct libalias *, struct ip *);
269
270static int IcmpAliasOut1(struct libalias *, struct ip *, int create);
271static int IcmpAliasOut2(struct libalias *, struct ip *);
272static int IcmpAliasOut(struct libalias *, struct ip *, int create);
273
274static int ProtoAliasIn(struct libalias *la, struct in_addr ip_src,
275 struct ip *pip, u_char ip_p, u_short *ip_sum);
276static int ProtoAliasOut(struct libalias *la, struct ip *pip,
277 struct in_addr ip_dst, u_char ip_p, u_short *ip_sum,
278 int create);
279
280static int UdpAliasIn(struct libalias *, struct ip *);
281static int UdpAliasOut(struct libalias *, struct ip *, int, int create);
282
283static int TcpAliasIn(struct libalias *, struct ip *);
284static int TcpAliasOut(struct libalias *, struct ip *, int, int create);
285
286/*
287 De-alias incoming echo and timestamp replies.
288 Alias incoming echo and timestamp requests.
289*/
290static int
291IcmpAliasIn1(struct libalias *la, struct ip *pip)
292{
293 struct alias_link *lnk;
294 struct icmp *ic;
295
297 ic = (struct icmp *)ip_next(pip);
298
299 /* Get source address from ICMP data field and restore original data */
300 lnk = FindIcmpIn(la, pip->ip_src, pip->ip_dst, ic->icmp_id, 1);
301 if (lnk != NULL) {
302 u_short original_id;
303 int accumulate;
304
305 original_id = GetOriginalPort(lnk);
306
307 /* Adjust ICMP checksum */
308 accumulate = ic->icmp_id;
309 accumulate -= original_id;
310 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
311
312 /* Put original sequence number back in */
313 ic->icmp_id = original_id;
314
315 /* Put original address back into IP header */
316 {
317 struct in_addr original_address;
318
319 original_address = GetOriginalAddress(lnk);
321 &original_address, &pip->ip_dst, 2);
322 pip->ip_dst = original_address;
323 }
324
325 return (PKT_ALIAS_OK);
326 }
327 return (PKT_ALIAS_IGNORED);
328}
329
330/*
331 Alias incoming ICMP error messages containing
332 IP header and first 64 bits of datagram.
333*/
334static int
335IcmpAliasIn2(struct libalias *la, struct ip *pip)
336{
337 struct ip *ip;
338 struct icmp *ic, *ic2;
339 struct udphdr *ud;
340 struct tcphdr *tc;
341 struct alias_link *lnk;
342
344 ic = (struct icmp *)ip_next(pip);
345 ip = &ic->icmp_ip;
346
347 ud = (struct udphdr *)ip_next(ip);
348 tc = (struct tcphdr *)ip_next(ip);
349 ic2 = (struct icmp *)ip_next(ip);
350
351 if (ip->ip_p == IPPROTO_UDP)
352 lnk = FindUdpTcpIn(la, ip->ip_dst, ip->ip_src,
353 ud->uh_dport, ud->uh_sport,
354 IPPROTO_UDP, 0);
355 else if (ip->ip_p == IPPROTO_TCP)
356 lnk = FindUdpTcpIn(la, ip->ip_dst, ip->ip_src,
357 tc->th_dport, tc->th_sport,
358 IPPROTO_TCP, 0);
359 else if (ip->ip_p == IPPROTO_ICMP) {
360 if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
361 lnk = FindIcmpIn(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0);
362 else
363 lnk = NULL;
364 } else
365 lnk = NULL;
366
367 if (lnk != NULL) {
368 if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) {
369 int accumulate, accumulate2;
370 struct in_addr original_address;
371 u_short original_port;
372
373 original_address = GetOriginalAddress(lnk);
374 original_port = GetOriginalPort(lnk);
375
376 /* Adjust ICMP checksum */
377 accumulate = twowords(&ip->ip_src);
378 accumulate -= twowords(&original_address);
379 accumulate += ud->uh_sport;
380 accumulate -= original_port;
381 accumulate2 = accumulate;
382 accumulate2 += ip->ip_sum;
383 ADJUST_CHECKSUM(accumulate, ip->ip_sum);
384 accumulate2 -= ip->ip_sum;
385 ADJUST_CHECKSUM(accumulate2, ic->icmp_cksum);
386
387 /* Un-alias address in IP header */
389 &original_address, &pip->ip_dst, 2);
390 pip->ip_dst = original_address;
391
392 /* Un-alias address and port number of
393 * original IP packet fragment contained
394 * in ICMP data section */
395 ip->ip_src = original_address;
396 ud->uh_sport = original_port;
397 } else if (ip->ip_p == IPPROTO_ICMP) {
398 int accumulate, accumulate2;
399 struct in_addr original_address;
400 u_short original_id;
401
402 original_address = GetOriginalAddress(lnk);
403 original_id = GetOriginalPort(lnk);
404
405 /* Adjust ICMP checksum */
406 accumulate = twowords(&ip->ip_src);
407 accumulate -= twowords(&original_address);
408 accumulate += ic2->icmp_id;
409 accumulate -= original_id;
410 accumulate2 = accumulate;
411 accumulate2 += ip->ip_sum;
412 ADJUST_CHECKSUM(accumulate, ip->ip_sum);
413 accumulate2 -= ip->ip_sum;
414 ADJUST_CHECKSUM(accumulate2, ic->icmp_cksum);
415
416 /* Un-alias address in IP header */
418 &original_address, &pip->ip_dst, 2);
419 pip->ip_dst = original_address;
420
421 /* Un-alias address of original IP packet and
422 * sequence number of embedded ICMP datagram */
423 ip->ip_src = original_address;
424 ic2->icmp_id = original_id;
425 }
426 return (PKT_ALIAS_OK);
427 }
428 return (PKT_ALIAS_IGNORED);
429}
430
431static int
432IcmpAliasIn(struct libalias *la, struct ip *pip)
433{
434 struct icmp *ic;
435 int iresult;
436 size_t dlen;
437
439
440 dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2);
441 if (dlen < ICMP_MINLEN)
442 return (PKT_ALIAS_IGNORED);
443
444 /* Return if proxy-only mode is enabled */
446 return (PKT_ALIAS_OK);
447
448 ic = (struct icmp *)ip_next(pip);
449
450 iresult = PKT_ALIAS_IGNORED;
451 switch (ic->icmp_type) {
452 case ICMP_ECHOREPLY:
453 case ICMP_TSTAMPREPLY:
454 if (ic->icmp_code == 0) {
455 iresult = IcmpAliasIn1(la, pip);
456 }
457 break;
458 case ICMP_UNREACH:
460 case ICMP_TIMXCEED:
461 case ICMP_PARAMPROB:
462 if (dlen < ICMP_ADVLENMIN ||
463 dlen < (size_t)ICMP_ADVLEN(ic))
464 return (PKT_ALIAS_IGNORED);
465 iresult = IcmpAliasIn2(la, pip);
466 break;
467 case ICMP_ECHO:
468 case ICMP_TSTAMP:
469 iresult = IcmpAliasIn1(la, pip);
470 break;
471 }
472 return (iresult);
473}
474
475/*
476 Alias outgoing echo and timestamp requests.
477 De-alias outgoing echo and timestamp replies.
478*/
479static int
480IcmpAliasOut1(struct libalias *la, struct ip *pip, int create)
481{
482 struct alias_link *lnk;
483 struct icmp *ic;
484
486 ic = (struct icmp *)ip_next(pip);
487
488 /* Save overwritten data for when echo packet returns */
489 lnk = FindIcmpOut(la, pip->ip_src, pip->ip_dst, ic->icmp_id, create);
490 if (lnk != NULL) {
491 u_short alias_id;
492 int accumulate;
493
494 alias_id = GetAliasPort(lnk);
495
496 /* Since data field is being modified, adjust ICMP checksum */
497 accumulate = ic->icmp_id;
498 accumulate -= alias_id;
499 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
500
501 /* Alias sequence number */
502 ic->icmp_id = alias_id;
503
504 /* Change source address */
505 {
506 struct in_addr alias_address;
507
508 alias_address = GetAliasAddress(lnk);
510 &alias_address, &pip->ip_src, 2);
511 pip->ip_src = alias_address;
512 }
513
514 return (PKT_ALIAS_OK);
515 }
516 return (PKT_ALIAS_IGNORED);
517}
518
519/*
520 Alias outgoing ICMP error messages containing
521 IP header and first 64 bits of datagram.
522*/
523static int
524IcmpAliasOut2(struct libalias *la, struct ip *pip)
525{
526 struct ip *ip;
527 struct icmp *ic, *ic2;
528 struct udphdr *ud;
529 struct tcphdr *tc;
530 struct alias_link *lnk;
531
533 ic = (struct icmp *)ip_next(pip);
534 ip = &ic->icmp_ip;
535
536 ud = (struct udphdr *)ip_next(ip);
537 tc = (struct tcphdr *)ip_next(ip);
538 ic2 = (struct icmp *)ip_next(ip);
539
540 if (ip->ip_p == IPPROTO_UDP)
541 lnk = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src,
542 ud->uh_dport, ud->uh_sport,
543 IPPROTO_UDP, 0);
544 else if (ip->ip_p == IPPROTO_TCP)
545 lnk = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src,
546 tc->th_dport, tc->th_sport,
547 IPPROTO_TCP, 0);
548 else if (ip->ip_p == IPPROTO_ICMP) {
549 if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
550 lnk = FindIcmpOut(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0);
551 else
552 lnk = NULL;
553 } else
554 lnk = NULL;
555
556 if (lnk != NULL) {
557 if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) {
558 int accumulate;
559 struct in_addr alias_address;
560 u_short alias_port;
561
562 alias_address = GetAliasAddress(lnk);
563 alias_port = GetAliasPort(lnk);
564
565 /* Adjust ICMP checksum */
566 accumulate = twowords(&ip->ip_dst);
567 accumulate -= twowords(&alias_address);
568 accumulate += ud->uh_dport;
569 accumulate -= alias_port;
570 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
571
572 /*
573 * Alias address in IP header if it comes from the host
574 * the original TCP/UDP packet was destined for.
575 */
576 if (pip->ip_src.s_addr == ip->ip_dst.s_addr) {
578 &alias_address, &pip->ip_src, 2);
579 pip->ip_src = alias_address;
580 }
581 /* Alias address and port number of original IP packet
582 * fragment contained in ICMP data section */
583 ip->ip_dst = alias_address;
584 ud->uh_dport = alias_port;
585 } else if (ip->ip_p == IPPROTO_ICMP) {
586 int accumulate;
587 struct in_addr alias_address;
588 u_short alias_id;
589
590 alias_address = GetAliasAddress(lnk);
591 alias_id = GetAliasPort(lnk);
592
593 /* Adjust ICMP checksum */
594 accumulate = twowords(&ip->ip_dst);
595 accumulate -= twowords(&alias_address);
596 accumulate += ic2->icmp_id;
597 accumulate -= alias_id;
598 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
599
600 /*
601 * Alias address in IP header if it comes from the host
602 * the original ICMP message was destined for.
603 */
604 if (pip->ip_src.s_addr == ip->ip_dst.s_addr) {
606 &alias_address, &pip->ip_src, 2);
607 pip->ip_src = alias_address;
608 }
609 /* Alias address of original IP packet and
610 * sequence number of embedded ICMP datagram */
611 ip->ip_dst = alias_address;
612 ic2->icmp_id = alias_id;
613 }
614 return (PKT_ALIAS_OK);
615 }
616 return (PKT_ALIAS_IGNORED);
617}
618
619static int
620IcmpAliasOut(struct libalias *la, struct ip *pip, int create)
621{
622 int iresult;
623 struct icmp *ic;
624
626 (void)create;
627
628 /* Return if proxy-only mode is enabled */
630 return (PKT_ALIAS_OK);
631
632 ic = (struct icmp *)ip_next(pip);
633
634 iresult = PKT_ALIAS_IGNORED;
635 switch (ic->icmp_type) {
636 case ICMP_ECHO:
637 case ICMP_TSTAMP:
638 if (ic->icmp_code == 0) {
639 iresult = IcmpAliasOut1(la, pip, create);
640 }
641 break;
642 case ICMP_UNREACH:
644 case ICMP_TIMXCEED:
645 case ICMP_PARAMPROB:
646 iresult = IcmpAliasOut2(la, pip);
647 break;
648 case ICMP_ECHOREPLY:
649 case ICMP_TSTAMPREPLY:
650 iresult = IcmpAliasOut1(la, pip, create);
651 }
652 return (iresult);
653}
654
655/*
656 Handle incoming IP packets. The
657 only thing which is done in this case is to alias
658 the dest IP address of the packet to our inside
659 machine.
660*/
661static int
662ProtoAliasIn(struct libalias *la, struct in_addr ip_src,
663 struct ip *pip, u_char ip_p, u_short *ip_sum)
664{
665 struct alias_link *lnk;
666
668 /* Return if proxy-only mode is enabled */
670 return (PKT_ALIAS_OK);
671
672 lnk = FindProtoIn(la, ip_src, pip->ip_dst, ip_p);
673 if (lnk != NULL) {
674 struct in_addr original_address;
675
676 original_address = GetOriginalAddress(lnk);
677
678 /* Restore original IP address */
680 &original_address, &pip->ip_dst, 2);
681 pip->ip_dst = original_address;
682
683 return (PKT_ALIAS_OK);
684 }
685 return (PKT_ALIAS_IGNORED);
686}
687
688/*
689 Handle outgoing IP packets. The
690 only thing which is done in this case is to alias
691 the source IP address of the packet.
692*/
693static int
694ProtoAliasOut(struct libalias *la, struct ip *pip,
695 struct in_addr ip_dst, u_char ip_p, u_short *ip_sum, int create)
696{
697 struct alias_link *lnk;
698
700
701 /* Return if proxy-only mode is enabled */
703 return (PKT_ALIAS_OK);
704
705 if (!create)
706 return (PKT_ALIAS_IGNORED);
707
708 lnk = FindProtoOut(la, pip->ip_src, ip_dst, ip_p);
709 if (lnk != NULL) {
710 struct in_addr alias_address;
711
712 alias_address = GetAliasAddress(lnk);
713
714 /* Change source address */
716 &alias_address, &pip->ip_src, 2);
717 pip->ip_src = alias_address;
718
719 return (PKT_ALIAS_OK);
720 }
721 return (PKT_ALIAS_IGNORED);
722}
723
724#define MF_ISSET(_pip) (ntohs((_pip)->ip_off) & IP_MF)
725#define FRAG_NO_HDR(_pip) (ntohs((_pip)->ip_off) & IP_OFFMASK)
726
727static struct udphdr *
729{
730 struct udphdr *ud;
731 size_t dlen;
732
733#ifdef _KERNEL
734 KASSERT(!FRAG_NO_HDR(pip), ("header-less fragment isn't expected here"));
735#endif
736 dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2);
737 if (dlen < sizeof(struct udphdr))
738 return (NULL);
739 ud = (struct udphdr *)ip_next(pip);
740 if (!MF_ISSET(pip) && dlen < ntohs(ud->uh_ulen))
741 return (NULL);
742 return (ud);
743}
744
745static int
746UdpAliasIn(struct libalias *la, struct ip *pip)
747{
748 struct udphdr *ud;
749 struct alias_link *lnk;
750
752
753 ud = ValidateUdpLength(pip);
754 if (ud == NULL)
755 return (PKT_ALIAS_IGNORED);
756
757 lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst,
758 ud->uh_sport, ud->uh_dport,
760 if (lnk != NULL) {
761 struct in_addr alias_address;
762 struct in_addr original_address;
763 struct in_addr proxy_address;
764 u_short alias_port;
765 u_short proxy_port;
766 int accumulate;
767 int error;
768 struct alias_data ad = {
769 .lnk = lnk,
770 .oaddr = &original_address,
771 .aaddr = &alias_address,
772 .aport = &alias_port,
773 .sport = &ud->uh_sport,
774 .dport = &ud->uh_dport,
775 .maxpktsize = 0
776 };
777
778 alias_address = GetAliasAddress(lnk);
779 original_address = GetOriginalAddress(lnk);
780 proxy_address = GetProxyAddress(lnk);
781 alias_port = ud->uh_dport;
783 proxy_port = GetProxyPort(lnk);
784
785 /* Walk out chain. */
786 error = find_handler(IN, UDP, la, pip, &ad);
787 /* If we cannot figure out the packet, ignore it. */
788 if (error < 0)
789 return (PKT_ALIAS_IGNORED);
790
791 /* If UDP checksum is not zero, then adjust since
792 * destination port is being unaliased and
793 * destination address is being altered. */
794 if (ud->uh_sum != 0) {
795 accumulate = alias_port;
796 accumulate -= ud->uh_dport;
797 accumulate += twowords(&alias_address);
798 accumulate -= twowords(&original_address);
799
800 /* If this is a proxy packet, modify checksum
801 * because of source change.*/
802 if (proxy_port != 0) {
803 accumulate += ud->uh_sport;
804 accumulate -= proxy_port;
805 }
806
807 if (proxy_address.s_addr != 0) {
808 accumulate += twowords(&pip->ip_src);
809 accumulate -= twowords(&proxy_address);
810 }
811
812 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
813 }
814
815 /* XXX: Could the two if's below be concatenated to one ? */
816 /* Restore source port and/or address in case of proxying*/
817 if (proxy_port != 0)
818 ud->uh_sport = proxy_port;
819
820 if (proxy_address.s_addr != 0) {
822 &proxy_address, &pip->ip_src, 2);
823 pip->ip_src = proxy_address;
824 }
825
826 /* Restore original IP address */
828 &original_address, &pip->ip_dst, 2);
829 pip->ip_dst = original_address;
830
831 return (PKT_ALIAS_OK);
832 }
833 return (PKT_ALIAS_IGNORED);
834}
835
836static int
837UdpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create)
838{
839 struct udphdr *ud;
840 struct alias_link *lnk;
841 struct in_addr dest_address;
842 struct in_addr proxy_server_address;
843 u_short dest_port;
844 u_short proxy_server_port;
845 int proxy_type;
846 int error;
847
849
850 ud = ValidateUdpLength(pip);
851 if (ud == NULL)
852 return (PKT_ALIAS_IGNORED);
853
854 /* Return if proxy-only mode is enabled and not proxyrule found.*/
855 proxy_type = ProxyCheck(la, &proxy_server_address, &proxy_server_port,
856 pip->ip_src, pip->ip_dst, ud->uh_dport, pip->ip_p);
857 if (proxy_type == 0 && (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY))
858 return (PKT_ALIAS_OK);
859
860 /* If this is a transparent proxy, save original destination,
861 * then alter the destination and adjust checksums */
862 dest_port = ud->uh_dport;
863 dest_address = pip->ip_dst;
864
865 if (proxy_type != 0) {
866 int accumulate;
867
868 accumulate = twowords(&pip->ip_dst);
869 accumulate -= twowords(&proxy_server_address);
870
871 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
872
873 if (ud->uh_sum != 0) {
874 accumulate = twowords(&pip->ip_dst);
875 accumulate -= twowords(&proxy_server_address);
876 accumulate += ud->uh_dport;
877 accumulate -= proxy_server_port;
878 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
879 }
880 pip->ip_dst = proxy_server_address;
881 ud->uh_dport = proxy_server_port;
882 }
883 lnk = FindUdpTcpOut(la, pip->ip_src, pip->ip_dst,
884 ud->uh_sport, ud->uh_dport,
885 IPPROTO_UDP, create);
886 if (lnk != NULL) {
887 u_short alias_port;
888 struct in_addr alias_address;
889 struct alias_data ad = {
890 .lnk = lnk,
891 .oaddr = NULL,
892 .aaddr = &alias_address,
893 .aport = &alias_port,
894 .sport = &ud->uh_sport,
895 .dport = &ud->uh_dport,
896 .maxpktsize = 0
897 };
898
899 /* Save original destination address, if this is a proxy packet.
900 * Also modify packet to include destination encoding. This may
901 * change the size of IP header. */
902 if (proxy_type != 0) {
903 SetProxyPort(lnk, dest_port);
904 SetProxyAddress(lnk, dest_address);
905 ProxyModify(la, lnk, pip, maxpacketsize, proxy_type);
906 ud = (struct udphdr *)ip_next(pip);
907 }
908
909 alias_address = GetAliasAddress(lnk);
910 alias_port = GetAliasPort(lnk);
911
912 /* Walk out chain. */
913 error = find_handler(OUT, UDP, la, pip, &ad);
914
915 /* If UDP checksum is not zero, adjust since source port is */
916 /* being aliased and source address is being altered */
917 if (ud->uh_sum != 0) {
918 int accumulate;
919
920 accumulate = ud->uh_sport;
921 accumulate -= alias_port;
922 accumulate += twowords(&pip->ip_src);
923 accumulate -= twowords(&alias_address);
924 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
925 }
926 /* Put alias port in UDP header */
927 ud->uh_sport = alias_port;
928
929 /* Change source address */
931 &alias_address, &pip->ip_src, 2);
932 pip->ip_src = alias_address;
933
934 return (PKT_ALIAS_OK);
935 }
936 return (PKT_ALIAS_IGNORED);
937}
938
939static int
940TcpAliasIn(struct libalias *la, struct ip *pip)
941{
942 struct tcphdr *tc;
943 struct alias_link *lnk;
944 size_t dlen;
945
947
948 dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2);
949 if (dlen < sizeof(struct tcphdr))
950 return (PKT_ALIAS_IGNORED);
951 tc = (struct tcphdr *)ip_next(pip);
952
953 lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst,
954 tc->th_sport, tc->th_dport,
957 if (lnk != NULL) {
958 struct in_addr alias_address;
959 struct in_addr original_address;
960 struct in_addr proxy_address;
961 u_short alias_port;
962 u_short proxy_port;
963 int accumulate, error;
964
965 /*
966 * The init of MANY vars is a bit below, but aliashandlepptpin
967 * seems to need the destination port that came within the
968 * packet and not the original one looks below [*].
969 */
970
971 struct alias_data ad = {
972 .lnk = lnk,
973 .oaddr = NULL,
974 .aaddr = NULL,
975 .aport = NULL,
976 .sport = &tc->th_sport,
977 .dport = &tc->th_dport,
978 .maxpktsize = 0
979 };
980
981 /* Walk out chain. */
982 error = find_handler(IN, TCP, la, pip, &ad);
983
984 alias_address = GetAliasAddress(lnk);
985 original_address = GetOriginalAddress(lnk);
986 proxy_address = GetProxyAddress(lnk);
987 alias_port = tc->th_dport;
988 tc->th_dport = GetOriginalPort(lnk);
989 proxy_port = GetProxyPort(lnk);
990
991 /*
992 * Look above, if anyone is going to add find_handler AFTER
993 * this aliashandlepptpin/point, please redo alias_data too.
994 * Uncommenting the piece here below should be enough.
995 */
996#if 0
997 struct alias_data ad = {
998 .lnk = lnk,
999 .oaddr = &original_address,
1000 .aaddr = &alias_address,
1001 .aport = &alias_port,
1002 .sport = &ud->uh_sport,
1003 .dport = &ud->uh_dport,
1004 .maxpktsize = 0
1005 };
1006
1007 /* Walk out chain. */
1008 error = find_handler(la, pip, &ad);
1009 if (error == EHDNOF)
1010 printf("Protocol handler not found\n");
1011#endif
1012
1013 /* Adjust TCP checksum since destination port is being
1014 * unaliased and destination port is being altered. */
1015 accumulate = alias_port;
1016 accumulate -= tc->th_dport;
1017 accumulate += twowords(&alias_address);
1018 accumulate -= twowords(&original_address);
1019
1020 /* If this is a proxy, then modify the TCP source port
1021 * and checksum accumulation */
1022 if (proxy_port != 0) {
1023 accumulate += tc->th_sport;
1024 tc->th_sport = proxy_port;
1025 accumulate -= tc->th_sport;
1026 accumulate += twowords(&pip->ip_src);
1027 accumulate -= twowords(&proxy_address);
1028 }
1029 /* See if ACK number needs to be modified */
1030 if (GetAckModified(lnk) == 1) {
1031 int delta;
1032
1033 tc = (struct tcphdr *)ip_next(pip);
1034 delta = GetDeltaAckIn(tc->th_ack, lnk);
1035 if (delta != 0) {
1036 accumulate += twowords(&tc->th_ack);
1037 tc->th_ack = htonl(ntohl(tc->th_ack) - delta);
1038 accumulate -= twowords(&tc->th_ack);
1039 }
1040 }
1041 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1042
1043 /* Restore original IP address */
1044 accumulate = twowords(&pip->ip_dst);
1045 pip->ip_dst = original_address;
1046 accumulate -= twowords(&pip->ip_dst);
1047
1048 /* If this is a transparent proxy packet,
1049 * then modify the source address */
1050 if (proxy_address.s_addr != 0) {
1051 accumulate += twowords(&pip->ip_src);
1052 pip->ip_src = proxy_address;
1053 accumulate -= twowords(&pip->ip_src);
1054 }
1055 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1056
1057 /* Monitor TCP connection state */
1058 tc = (struct tcphdr *)ip_next(pip);
1059 TcpMonitorIn(tc->th_flags, lnk);
1060
1061 return (PKT_ALIAS_OK);
1062 }
1063 return (PKT_ALIAS_IGNORED);
1064}
1065
1066static int
1067TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create)
1068{
1069 int proxy_type, error;
1070 u_short dest_port;
1071 u_short proxy_server_port;
1072 size_t dlen;
1073 struct in_addr dest_address;
1074 struct in_addr proxy_server_address;
1075 struct tcphdr *tc;
1076 struct alias_link *lnk;
1077
1079
1080 dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2);
1081 if (dlen < sizeof(struct tcphdr))
1082 return (PKT_ALIAS_IGNORED);
1083 tc = (struct tcphdr *)ip_next(pip);
1084
1085 if (create)
1086 proxy_type = ProxyCheck(la, &proxy_server_address,
1087 &proxy_server_port, pip->ip_src, pip->ip_dst,
1088 tc->th_dport, pip->ip_p);
1089 else
1090 proxy_type = 0;
1091
1092 if (proxy_type == 0 && (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY))
1093 return (PKT_ALIAS_OK);
1094
1095 /* If this is a transparent proxy, save original destination,
1096 * then alter the destination and adjust checksums */
1097 dest_port = tc->th_dport;
1098 dest_address = pip->ip_dst;
1099 if (proxy_type != 0) {
1100 int accumulate;
1101
1102 accumulate = tc->th_dport;
1103 tc->th_dport = proxy_server_port;
1104 accumulate -= tc->th_dport;
1105 accumulate += twowords(&pip->ip_dst);
1106 accumulate -= twowords(&proxy_server_address);
1107 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1108
1109 accumulate = twowords(&pip->ip_dst);
1110 pip->ip_dst = proxy_server_address;
1111 accumulate -= twowords(&pip->ip_dst);
1112 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1113 }
1114 lnk = FindUdpTcpOut(la, pip->ip_src, pip->ip_dst,
1115 tc->th_sport, tc->th_dport,
1116 IPPROTO_TCP, create);
1117 if (lnk == NULL)
1118 return (PKT_ALIAS_IGNORED);
1119 if (lnk != NULL) {
1120 u_short alias_port;
1121 struct in_addr alias_address;
1122 int accumulate;
1123 struct alias_data ad = {
1124 .lnk = lnk,
1125 .oaddr = NULL,
1126 .aaddr = &alias_address,
1127 .aport = &alias_port,
1128 .sport = &tc->th_sport,
1129 .dport = &tc->th_dport,
1130 .maxpktsize = maxpacketsize
1131 };
1132
1133 /* Save original destination address, if this is a proxy packet.
1134 * Also modify packet to include destination
1135 * encoding. This may change the size of IP header. */
1136 if (proxy_type != 0) {
1137 SetProxyPort(lnk, dest_port);
1138 SetProxyAddress(lnk, dest_address);
1139 ProxyModify(la, lnk, pip, maxpacketsize, proxy_type);
1140 tc = (struct tcphdr *)ip_next(pip);
1141 }
1142 /* Get alias address and port */
1143 alias_port = GetAliasPort(lnk);
1144 alias_address = GetAliasAddress(lnk);
1145
1146 /* Monitor TCP connection state */
1147 tc = (struct tcphdr *)ip_next(pip);
1148 TcpMonitorOut(tc->th_flags, lnk);
1149
1150 /* Walk out chain. */
1151 error = find_handler(OUT, TCP, la, pip, &ad);
1152
1153 /* Adjust TCP checksum since source port is being aliased
1154 * and source address is being altered */
1155 accumulate = tc->th_sport;
1156 tc->th_sport = alias_port;
1157 accumulate -= tc->th_sport;
1158 accumulate += twowords(&pip->ip_src);
1159 accumulate -= twowords(&alias_address);
1160
1161 /* Modify sequence number if necessary */
1162 if (GetAckModified(lnk) == 1) {
1163 int delta;
1164
1165 tc = (struct tcphdr *)ip_next(pip);
1166 delta = GetDeltaSeqOut(tc->th_seq, lnk);
1167 if (delta != 0) {
1168 accumulate += twowords(&tc->th_seq);
1169 tc->th_seq = htonl(ntohl(tc->th_seq) + delta);
1170 accumulate -= twowords(&tc->th_seq);
1171 }
1172 }
1173 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1174
1175 /* Change source address */
1176 accumulate = twowords(&pip->ip_src);
1177 pip->ip_src = alias_address;
1178 accumulate -= twowords(&pip->ip_src);
1179 ADJUST_CHECKSUM(accumulate, pip->ip_sum);
1180
1181 return (PKT_ALIAS_OK);
1182 }
1183 return (PKT_ALIAS_IGNORED);
1184}
1185
1186/* Fragment Handling
1187
1188 FragmentIn()
1189 FragmentOut()
1190
1191The packet aliasing module has a limited ability for handling IP
1192fragments. If the ICMP, TCP or UDP header is in the first fragment
1193received, then the ID number of the IP packet is saved, and other
1194fragments are identified according to their ID number and IP address
1195they were sent from. Pointers to unresolved fragments can also be
1196saved and recalled when a header fragment is seen.
1197*/
1198
1199/* Local prototypes */
1200static int FragmentIn(struct libalias *la, struct in_addr ip_src,
1201 struct ip *pip, u_short ip_id, u_short *ip_sum);
1202static int FragmentOut(struct libalias *, struct ip *pip,
1203 u_short *ip_sum);
1204
1205static int
1206FragmentIn(struct libalias *la, struct in_addr ip_src, struct ip *pip,
1207 u_short ip_id, u_short *ip_sum)
1208{
1209 struct alias_link *lnk;
1210
1212 lnk = FindFragmentIn2(la, ip_src, pip->ip_dst, ip_id);
1213 if (lnk != NULL) {
1214 struct in_addr original_address;
1215
1216 GetFragmentAddr(lnk, &original_address);
1218 &original_address, &pip->ip_dst, 2);
1219 pip->ip_dst = original_address;
1220
1221 return (PKT_ALIAS_OK);
1222 }
1224}
1225
1226static int
1227FragmentOut(struct libalias *la, struct ip *pip, u_short *ip_sum)
1228{
1229 struct in_addr alias_address;
1230
1232 alias_address = FindAliasAddress(la, pip->ip_src);
1234 &alias_address, &pip->ip_src, 2);
1235 pip->ip_src = alias_address;
1236
1237 return (PKT_ALIAS_OK);
1238}
1239
1240/* Outside World Access
1241
1242 PacketAliasSaveFragment()
1243 PacketAliasGetFragment()
1244 PacketAliasFragmentIn()
1245 PacketAliasIn()
1246 PacketAliasOut()
1247 PacketUnaliasOut()
1248
1249(prototypes in alias.h)
1250*/
1251
1252int
1253LibAliasSaveFragment(struct libalias *la, void *ptr)
1254{
1255 int iresult;
1256 struct alias_link *lnk;
1257 struct ip *pip;
1258
1259 LIBALIAS_LOCK(la);
1260 pip = (struct ip *)ptr;
1261 lnk = AddFragmentPtrLink(la, pip->ip_src, pip->ip_id);
1262 iresult = PKT_ALIAS_ERROR;
1263 if (lnk != NULL) {
1264 SetFragmentPtr(lnk, ptr);
1265 iresult = PKT_ALIAS_OK;
1266 }
1267 LIBALIAS_UNLOCK(la);
1268 return (iresult);
1269}
1270
1271void *
1272LibAliasGetFragment(struct libalias *la, void *ptr)
1273{
1274 struct alias_link *lnk;
1275 void *fptr;
1276 struct ip *pip;
1277
1278 LIBALIAS_LOCK(la);
1279 pip = (struct ip *)ptr;
1280 lnk = FindFragmentPtr(la, pip->ip_src, pip->ip_id);
1281 if (lnk != NULL) {
1282 GetFragmentPtr(lnk, &fptr);
1283 SetFragmentPtr(lnk, NULL);
1284 SetExpire(lnk, 0); /* Deletes link */
1285 } else
1286 fptr = NULL;
1287
1288 LIBALIAS_UNLOCK(la);
1289 return (fptr);
1290}
1291
1292void
1294 void *ptr, /* Points to correctly de-aliased header fragment */
1295 void *ptr_fragment /* fragment which must be de-aliased */
1296)
1297{
1298 struct ip *pip;
1299 struct ip *fpip;
1300
1301 LIBALIAS_LOCK(la);
1302 (void)la;
1303 pip = (struct ip *)ptr;
1304 fpip = (struct ip *)ptr_fragment;
1305
1307 &pip->ip_dst, &fpip->ip_dst, 2);
1308 fpip->ip_dst = pip->ip_dst;
1309 LIBALIAS_UNLOCK(la);
1310}
1311
1312/* Local prototypes */
1313static int
1314LibAliasOutLocked(struct libalias *la, struct ip *pip,
1315 int maxpacketsize, int create);
1316static int
1317LibAliasInLocked(struct libalias *la, struct ip *pip,
1318 int maxpacketsize);
1319
1320int
1321LibAliasIn(struct libalias *la, void *ptr, int maxpacketsize)
1322{
1323 int res;
1324
1325 LIBALIAS_LOCK(la);
1326 res = LibAliasInLocked(la, (struct ip *)ptr, maxpacketsize);
1327 LIBALIAS_UNLOCK(la);
1328 return (res);
1329}
1330
1331static int
1332LibAliasInLocked(struct libalias *la, struct ip *pip, int maxpacketsize)
1333{
1334 struct in_addr alias_addr;
1335 int iresult;
1336
1338 la->packetAliasMode &= ~PKT_ALIAS_REVERSE;
1339 iresult = LibAliasOutLocked(la, pip, maxpacketsize, 1);
1341 goto getout;
1342 }
1343 HouseKeeping(la);
1344 alias_addr = pip->ip_dst;
1345
1346 /* Defense against mangled packets */
1347 if (ntohs(pip->ip_len) > maxpacketsize
1348 || (pip->ip_hl << 2) > maxpacketsize) {
1349 iresult = PKT_ALIAS_IGNORED;
1350 goto getout;
1351 }
1352
1353 if (FRAG_NO_HDR(pip)) {
1354 iresult = FragmentIn(la, pip->ip_src, pip, pip->ip_id,
1355 &pip->ip_sum);
1356 goto getout;
1357 }
1358
1359 iresult = PKT_ALIAS_IGNORED;
1360 switch (pip->ip_p) {
1361 case IPPROTO_ICMP:
1362 iresult = IcmpAliasIn(la, pip);
1363 break;
1364 case IPPROTO_UDP:
1365 iresult = UdpAliasIn(la, pip);
1366 break;
1367 case IPPROTO_TCP:
1368 iresult = TcpAliasIn(la, pip);
1369 break;
1370#ifdef _KERNEL
1371 case IPPROTO_SCTP:
1372 iresult = SctpAlias(la, pip, SN_TO_LOCAL);
1373 break;
1374#endif
1375 case IPPROTO_GRE: {
1376 int error;
1377 struct alias_data ad = {
1378 .lnk = NULL,
1379 .oaddr = NULL,
1380 .aaddr = NULL,
1381 .aport = NULL,
1382 .sport = NULL,
1383 .dport = NULL,
1384 .maxpktsize = 0
1385 };
1386
1387 /* Walk out chain. */
1388 error = find_handler(IN, IP, la, pip, &ad);
1389 if (error == 0)
1390 iresult = PKT_ALIAS_OK;
1391 else
1392 iresult = ProtoAliasIn(la, pip->ip_src,
1393 pip, pip->ip_p, &pip->ip_sum);
1394 break;
1395 }
1396 default:
1397 iresult = ProtoAliasIn(la, pip->ip_src, pip,
1398 pip->ip_p, &pip->ip_sum);
1399 break;
1400 }
1401
1402 if (MF_ISSET(pip)) {
1403 struct alias_link *lnk;
1404
1405 lnk = FindFragmentIn1(la, pip->ip_src, alias_addr, pip->ip_id);
1406 if (lnk != NULL) {
1408 SetFragmentAddr(lnk, pip->ip_dst);
1409 } else {
1410 iresult = PKT_ALIAS_ERROR;
1411 }
1412 }
1413
1414getout:
1415 return (iresult);
1416}
1417
1418/* Unregistered address ranges */
1419
1420/* 10.0.0.0 -> 10.255.255.255 */
1421#define UNREG_ADDR_A_LOWER 0x0a000000
1422#define UNREG_ADDR_A_UPPER 0x0affffff
1423
1424/* 172.16.0.0 -> 172.31.255.255 */
1425#define UNREG_ADDR_B_LOWER 0xac100000
1426#define UNREG_ADDR_B_UPPER 0xac1fffff
1427
1428/* 192.168.0.0 -> 192.168.255.255 */
1429#define UNREG_ADDR_C_LOWER 0xc0a80000
1430#define UNREG_ADDR_C_UPPER 0xc0a8ffff
1431
1432/* 100.64.0.0 -> 100.127.255.255 (RFC 6598 - Carrier Grade NAT) */
1433#define UNREG_ADDR_CGN_LOWER 0x64400000
1434#define UNREG_ADDR_CGN_UPPER 0x647fffff
1435
1436int
1437LibAliasOut(struct libalias *la, void *ptr, int maxpacketsize)
1438{
1439 int res;
1440
1442 res = LibAliasOutLocked(la, (struct ip *)ptr, maxpacketsize, 1);
1444 return (res);
1445}
1446
1447int
1448LibAliasOutTry(struct libalias *la, void *ptr, int maxpacketsize, int create)
1449{
1450 int res;
1451
1453 res = LibAliasOutLocked(la, (struct ip *)ptr, maxpacketsize, create);
1455 return (res);
1456}
1457
1458static int
1460 struct ip *pip, /* valid IP packet */
1461 int maxpacketsize, /* How much the packet data may grow (FTP and IRC inline changes) */
1462 int create /* Create new entries ? */
1463)
1464{
1465 int iresult;
1466 struct in_addr addr_save;
1467
1469 la->packetAliasMode &= ~PKT_ALIAS_REVERSE;
1470 iresult = LibAliasInLocked(la, pip, maxpacketsize);
1472 goto getout;
1473 }
1474 HouseKeeping(la);
1475
1476 /* Defense against mangled packets */
1477 if (ntohs(pip->ip_len) > maxpacketsize
1478 || (pip->ip_hl << 2) > maxpacketsize) {
1479 iresult = PKT_ALIAS_IGNORED;
1480 goto getout;
1481 }
1482
1483 addr_save = GetDefaultAliasAddress(la);
1486 u_long addr;
1487 int iclass;
1488
1489 iclass = 0;
1490 addr = ntohl(pip->ip_src.s_addr);
1491 if (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER)
1492 iclass = 3;
1493 else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER)
1494 iclass = 2;
1495 else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER)
1496 iclass = 1;
1497 else if (addr >= UNREG_ADDR_CGN_LOWER && addr <= UNREG_ADDR_CGN_UPPER &&
1499 iclass = 4;
1500
1501 if (iclass == 0) {
1502 SetDefaultAliasAddress(la, pip->ip_src);
1503 }
1504 } else if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) {
1505 SetDefaultAliasAddress(la, pip->ip_src);
1506 }
1507
1508 if (FRAG_NO_HDR(pip)) {
1509 iresult = FragmentOut(la, pip, &pip->ip_sum);
1510 goto getout_restore;
1511 }
1512
1513 iresult = PKT_ALIAS_IGNORED;
1514 switch (pip->ip_p) {
1515 case IPPROTO_ICMP:
1516 iresult = IcmpAliasOut(la, pip, create);
1517 break;
1518 case IPPROTO_UDP:
1519 iresult = UdpAliasOut(la, pip, maxpacketsize, create);
1520 break;
1521 case IPPROTO_TCP:
1522 iresult = TcpAliasOut(la, pip, maxpacketsize, create);
1523 break;
1524#ifdef _KERNEL
1525 case IPPROTO_SCTP:
1526 iresult = SctpAlias(la, pip, SN_TO_GLOBAL);
1527 break;
1528#endif
1529 case IPPROTO_GRE: {
1530 int error;
1531 struct alias_data ad = {
1532 .lnk = NULL,
1533 .oaddr = NULL,
1534 .aaddr = NULL,
1535 .aport = NULL,
1536 .sport = NULL,
1537 .dport = NULL,
1538 .maxpktsize = 0
1539 };
1540 /* Walk out chain. */
1541 error = find_handler(OUT, IP, la, pip, &ad);
1542 if (error == 0)
1543 iresult = PKT_ALIAS_OK;
1544 else
1545 iresult = ProtoAliasOut(la, pip,
1546 pip->ip_dst, pip->ip_p, &pip->ip_sum, create);
1547 break;
1548 }
1549 default:
1550 iresult = ProtoAliasOut(la, pip,
1551 pip->ip_dst, pip->ip_p, &pip->ip_sum, create);
1552 break;
1553 }
1554
1555getout_restore:
1556 SetDefaultAliasAddress(la, addr_save);
1557getout:
1558 return (iresult);
1559}
1560
1561int
1563 void *ptr, /* valid IP packet */
1564 int maxpacketsize /* for error checking */
1565)
1566{
1567 struct ip *pip;
1568 struct icmp *ic;
1569 struct udphdr *ud;
1570 struct tcphdr *tc;
1571 struct alias_link *lnk;
1572 int iresult = PKT_ALIAS_IGNORED;
1573
1575 pip = (struct ip *)ptr;
1576
1577 /* Defense against mangled packets */
1578 if (ntohs(pip->ip_len) > maxpacketsize
1579 || (pip->ip_hl << 2) > maxpacketsize)
1580 goto getout;
1581
1582 ud = (struct udphdr *)ip_next(pip);
1583 tc = (struct tcphdr *)ip_next(pip);
1584 ic = (struct icmp *)ip_next(pip);
1585
1586 /* Find a link */
1587 if (pip->ip_p == IPPROTO_UDP)
1588 lnk = FindUdpTcpIn(la, pip->ip_dst, pip->ip_src,
1589 ud->uh_dport, ud->uh_sport,
1590 IPPROTO_UDP, 0);
1591 else if (pip->ip_p == IPPROTO_TCP)
1592 lnk = FindUdpTcpIn(la, pip->ip_dst, pip->ip_src,
1593 tc->th_dport, tc->th_sport,
1594 IPPROTO_TCP, 0);
1595 else if (pip->ip_p == IPPROTO_ICMP)
1596 lnk = FindIcmpIn(la, pip->ip_dst, pip->ip_src, ic->icmp_id, 0);
1597 else
1598 lnk = NULL;
1599
1600 /* Change it from an aliased packet to an unaliased packet */
1601 if (lnk != NULL) {
1602 if (pip->ip_p == IPPROTO_UDP || pip->ip_p == IPPROTO_TCP) {
1603 int accumulate;
1604 struct in_addr original_address;
1605 u_short original_port;
1606
1607 original_address = GetOriginalAddress(lnk);
1608 original_port = GetOriginalPort(lnk);
1609
1610 /* Adjust TCP/UDP checksum */
1611 accumulate = twowords(&pip->ip_src);
1612 accumulate -= twowords(&original_address);
1613
1614 if (pip->ip_p == IPPROTO_UDP) {
1615 accumulate += ud->uh_sport;
1616 accumulate -= original_port;
1617 ADJUST_CHECKSUM(accumulate, ud->uh_sum);
1618 } else {
1619 accumulate += tc->th_sport;
1620 accumulate -= original_port;
1621 ADJUST_CHECKSUM(accumulate, tc->th_sum);
1622 }
1623
1624 /* Adjust IP checksum */
1626 &original_address, &pip->ip_src, 2);
1627
1628 /* Un-alias source address and port number */
1629 pip->ip_src = original_address;
1630 if (pip->ip_p == IPPROTO_UDP)
1631 ud->uh_sport = original_port;
1632 else
1633 tc->th_sport = original_port;
1634
1635 iresult = PKT_ALIAS_OK;
1636 } else if (pip->ip_p == IPPROTO_ICMP) {
1637 int accumulate;
1638 struct in_addr original_address;
1639 u_short original_id;
1640
1641 original_address = GetOriginalAddress(lnk);
1642 original_id = GetOriginalPort(lnk);
1643
1644 /* Adjust ICMP checksum */
1645 accumulate = twowords(&pip->ip_src);
1646 accumulate -= twowords(&original_address);
1647 accumulate += ic->icmp_id;
1648 accumulate -= original_id;
1649 ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);
1650
1651 /* Adjust IP checksum */
1653 &original_address, &pip->ip_src, 2);
1654
1655 /* Un-alias source address and port number */
1656 pip->ip_src = original_address;
1657 ic->icmp_id = original_id;
1658
1659 iresult = PKT_ALIAS_OK;
1660 }
1661 }
1662getout:
1663 LIBALIAS_UNLOCK(la);
1664 return (iresult);
1665}
1666
1667#ifndef _KERNEL
1668
1669int
1671{
1672 char buf[256], conf[] = "/etc/libalias.conf";
1673 FILE *fd;
1674 int i, len;
1675
1676 fd = fopen(conf, "r");
1677 if (fd == NULL)
1678 err(1, "fopen(%s)", conf);
1679
1681
1682 for (;;) {
1683 fgets(buf, 256, fd);
1684 if (feof(fd))
1685 break;
1686 len = strlen(buf);
1687 if (len > 1) {
1688 for (i = 0; i < len; i++)
1689 if (!isspace(buf[i]))
1690 break;
1691 if (buf[i] == '#')
1692 continue;
1693 buf[len - 1] = '\0';
1694 LibAliasLoadModule(buf);
1695 }
1696 }
1697 fclose(fd);
1698 return (0);
1699}
1700
1701int
1702LibAliasLoadModule(char *path)
1703{
1704 struct dll *t;
1705 void *handle;
1706 struct proto_handler *m;
1707 const char *error;
1708 moduledata_t *p;
1709
1710 handle = dlopen (path, RTLD_LAZY);
1711 if (!handle) {
1712 fprintf(stderr, "%s\n", dlerror());
1713 return (EINVAL);
1714 }
1715
1716 p = dlsym(handle, "alias_mod");
1717 if ((error = dlerror()) != NULL) {
1718 fprintf(stderr, "%s\n", dlerror());
1719 return (EINVAL);
1720 }
1721
1722 t = malloc(sizeof(struct dll));
1723 if (t == NULL)
1724 return (ENOMEM);
1725 strncpy(t->name, p->name, DLL_LEN);
1726 t->handle = handle;
1727 if (attach_dll(t) == EEXIST) {
1728 free(t);
1729 fprintf(stderr, "dll conflict\n");
1730 return (EEXIST);
1731 }
1732
1733 m = dlsym(t->handle, "handlers");
1734 if ((error = dlerror()) != NULL) {
1735 fprintf(stderr, "%s\n", error);
1736 return (EINVAL);
1737 }
1738
1740 return (0);
1741}
1742
1743int
1745{
1746 struct dll *t;
1747 struct proto_handler *p;
1748
1749 /* Unload all modules then reload everything. */
1750 while ((p = first_handler()) != NULL) {
1752 }
1753 while ((t = walk_dll_chain()) != NULL) {
1754 dlclose(t->handle);
1755 free(t);
1756 }
1757 return (1);
1758}
1759
1760#endif
1761
1762#ifdef _KERNEL
1763/*
1764 * m_megapullup() - this function is a big hack.
1765 * Thankfully, it's only used in ng_nat and ipfw+nat.
1766 *
1767 * It allocates an mbuf with cluster and copies the specified part of the chain
1768 * into cluster, so that it is all contiguous and can be accessed via a plain
1769 * (char *) pointer. This is required, because libalias doesn't know how to
1770 * handle mbuf chains.
1771 *
1772 * On success, m_megapullup returns an mbuf (possibly with cluster) containing
1773 * the input packet, on failure NULL. The input packet is always consumed.
1774 */
1775struct mbuf *
1776m_megapullup(struct mbuf *m, int len)
1777{
1778 struct mbuf *mcl;
1779
1780 if (len > m->m_pkthdr.len)
1781 goto bad;
1782
1783 if (m->m_next == NULL && M_WRITABLE(m))
1784 return (m);
1785
1786 if (len <= MJUMPAGESIZE)
1787 mcl = m_get2(len, M_NOWAIT, MT_DATA, M_PKTHDR);
1788 else if (len <= MJUM9BYTES)
1789 mcl = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
1790 else if (len <= MJUM16BYTES)
1791 mcl = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM16BYTES);
1792 else
1793 goto bad;
1794 if (mcl == NULL)
1795 goto bad;
1796 m_align(mcl, len);
1797 m_move_pkthdr(mcl, m);
1798 m_copydata(m, 0, len, mtod(mcl, caddr_t));
1799 mcl->m_len = mcl->m_pkthdr.len = len;
1800 m_freem(m);
1801
1802 return (mcl);
1803bad:
1804 m_freem(m);
1805 return (NULL);
1806}
1807#endif
static SYSCTL_NODE(_net_inet_accf, OID_AUTO, http, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "HTTP accept filter")
static int LibAliasOutLocked(struct libalias *la, struct ip *pip, int maxpacketsize, int create)
Definition: alias.c:1459
#define UNREG_ADDR_CGN_LOWER
Definition: alias.c:1433
static int IcmpAliasOut1(struct libalias *, struct ip *, int create)
Definition: alias.c:480
struct mbuf * m_megapullup(struct mbuf *m, int len)
Definition: alias.c:1776
static int ProtoAliasOut(struct libalias *la, struct ip *pip, struct in_addr ip_dst, u_char ip_p, u_short *ip_sum, int create)
Definition: alias.c:694
static int UdpAliasOut(struct libalias *, struct ip *, int, int create)
Definition: alias.c:837
int LibAliasOut(struct libalias *la, void *ptr, int maxpacketsize)
Definition: alias.c:1437
static int TcpAliasIn(struct libalias *, struct ip *)
Definition: alias.c:940
static __inline int twowords(void *p)
Definition: alias.c:162
static void TcpMonitorIn(u_char, struct alias_link *)
Definition: alias.c:193
#define UNREG_ADDR_B_LOWER
Definition: alias.c:1425
#define UNREG_ADDR_A_UPPER
Definition: alias.c:1422
#define MF_ISSET(_pip)
Definition: alias.c:724
static int IcmpAliasOut2(struct libalias *, struct ip *)
Definition: alias.c:524
static int IcmpAliasOut(struct libalias *, struct ip *, int create)
Definition: alias.c:620
void * LibAliasGetFragment(struct libalias *la, void *ptr)
Definition: alias.c:1272
#define UNREG_ADDR_C_LOWER
Definition: alias.c:1429
static struct udphdr * ValidateUdpLength(struct ip *pip)
Definition: alias.c:728
static int FragmentOut(struct libalias *, struct ip *pip, u_short *ip_sum)
Definition: alias.c:1227
int LibAliasSaveFragment(struct libalias *la, void *ptr)
Definition: alias.c:1253
#define UNREG_ADDR_CGN_UPPER
Definition: alias.c:1434
static int ProtoAliasIn(struct libalias *la, struct in_addr ip_src, struct ip *pip, u_char ip_p, u_short *ip_sum)
Definition: alias.c:662
static int LibAliasInLocked(struct libalias *la, struct ip *pip, int maxpacketsize)
Definition: alias.c:1332
int LibAliasIn(struct libalias *la, void *ptr, int maxpacketsize)
Definition: alias.c:1321
__FBSDID("$FreeBSD$")
static int IcmpAliasIn1(struct libalias *, struct ip *)
Definition: alias.c:291
#define FRAG_NO_HDR(_pip)
Definition: alias.c:725
void LibAliasFragmentIn(struct libalias *la, void *ptr, void *ptr_fragment)
Definition: alias.c:1293
#define UNREG_ADDR_B_UPPER
Definition: alias.c:1426
#define UNREG_ADDR_A_LOWER
Definition: alias.c:1421
static int IcmpAliasIn2(struct libalias *, struct ip *)
Definition: alias.c:335
int LibAliasOutTry(struct libalias *la, void *ptr, int maxpacketsize, int create)
Definition: alias.c:1448
static int TcpAliasOut(struct libalias *, struct ip *, int, int create)
Definition: alias.c:1067
static int FragmentIn(struct libalias *la, struct in_addr ip_src, struct ip *pip, u_short ip_id, u_short *ip_sum)
Definition: alias.c:1206
static void TcpMonitorOut(u_char, struct alias_link *)
Definition: alias.c:210
#define UNREG_ADDR_C_UPPER
Definition: alias.c:1430
int LibAliasUnaliasOut(struct libalias *la, void *ptr, int maxpacketsize)
Definition: alias.c:1562
static int IcmpAliasIn(struct libalias *, struct ip *)
Definition: alias.c:432
static int UdpAliasIn(struct libalias *, struct ip *)
Definition: alias.c:746
#define PKT_ALIAS_FOUND_HEADER_FRAGMENT
Definition: alias.h:237
int LibAliasUnLoadAllModule(void)
#define PKT_ALIAS_OK
Definition: alias.h:234
int LibAliasRefreshModules(void)
#define PKT_ALIAS_PROXY_ONLY
Definition: alias.h:199
#define PKT_ALIAS_UNREGISTERED_ONLY
Definition: alias.h:184
#define PKT_ALIAS_REVERSE
Definition: alias.h:205
#define PKT_ALIAS_UNREGISTERED_CGN
Definition: alias.h:230
#define PKT_ALIAS_ERROR
Definition: alias.h:233
int LibAliasLoadModule(char *)
#define PKT_ALIAS_UNRESOLVED_FRAGMENT
Definition: alias.h:236
#define PKT_ALIAS_IGNORED
Definition: alias.h:235
struct alias_link * FindUdpTcpIn(struct libalias *la, struct in_addr dst_addr, struct in_addr alias_addr, u_short dst_port, u_short alias_port, u_char proto, int create)
Definition: alias_db.c:1135
void SetFragmentAddr(struct alias_link *lnk, struct in_addr src_addr)
Definition: alias_db.c:1397
u_short GetAliasPort(struct alias_link *lnk)
Definition: alias_db.c:1529
struct alias_link * FindProtoIn(struct libalias *la, struct in_addr dst_addr, struct in_addr alias_addr, u_char proto)
Definition: alias_db.c:1089
void SetProxyAddress(struct alias_link *lnk, struct in_addr addr)
Definition: alias_db.c:1557
void SetFragmentPtr(struct alias_link *lnk, void *fptr)
Definition: alias_db.c:1409
int GetAckModified(struct alias_link *lnk)
Definition: alias_db.c:1576
void SetStateIn(struct alias_link *lnk, int state)
Definition: alias_db.c:1421
u_short GetProxyPort(struct alias_link *lnk)
Definition: alias_db.c:1563
int GetDeltaAckIn(u_long ack, struct alias_link *lnk)
Definition: alias_db.c:1588
void SetStateOut(struct alias_link *lnk, int state)
Definition: alias_db.c:1446
struct in_addr GetAliasAddress(struct alias_link *lnk)
Definition: alias_db.c:1500
void SetDefaultAliasAddress(struct libalias *la, struct in_addr alias_addr)
Definition: alias_db.c:1516
struct alias_link * FindIcmpIn(struct libalias *la, struct in_addr dst_addr, struct in_addr alias_addr, u_short id_alias, int create)
Definition: alias_db.c:992
void GetFragmentAddr(struct alias_link *lnk, struct in_addr *src_addr)
Definition: alias_db.c:1403
struct in_addr FindAliasAddress(struct libalias *la, struct in_addr original_addr)
Definition: alias_db.c:1363
struct alias_link * FindFragmentIn2(struct libalias *la, struct in_addr dst_addr, struct in_addr alias_addr, u_short ip_id)
Definition: alias_db.c:1059
struct alias_link * FindFragmentIn1(struct libalias *la, struct in_addr dst_addr, struct in_addr alias_addr, u_short ip_id)
Definition: alias_db.c:1038
void SetExpire(struct alias_link *lnk, int expire)
Definition: alias_db.c:1699
struct in_addr GetProxyAddress(struct alias_link *lnk)
Definition: alias_db.c:1551
struct alias_link * FindIcmpOut(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, u_short id, int create)
Definition: alias_db.c:1015
struct alias_link * FindProtoOut(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, u_char proto)
Definition: alias_db.c:1112
int GetStateOut(struct alias_link *lnk)
Definition: alias_db.c:1478
void GetFragmentPtr(struct alias_link *lnk, void **fptr)
Definition: alias_db.c:1415
struct alias_link * AddFragmentPtrLink(struct libalias *la, struct in_addr dst_addr, u_short ip_id)
Definition: alias_db.c:1069
void HouseKeeping(struct libalias *la)
Definition: alias_db.c:1753
int GetStateIn(struct alias_link *lnk)
Definition: alias_db.c:1471
struct in_addr GetOriginalAddress(struct alias_link *lnk)
Definition: alias_db.c:1485
void SetProxyPort(struct alias_link *lnk, u_short port)
Definition: alias_db.c:1569
u_short GetOriginalPort(struct alias_link *lnk)
Definition: alias_db.c:1523
struct alias_link * FindFragmentPtr(struct libalias *la, struct in_addr dst_addr, u_short ip_id)
Definition: alias_db.c:1079
struct in_addr GetDefaultAliasAddress(struct libalias *la)
Definition: alias_db.c:1509
int GetDeltaSeqOut(u_long seq, struct alias_link *lnk)
Definition: alias_db.c:1630
struct alias_link * FindUdpTcpOut(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, u_short src_port, u_short dst_port, u_char proto, int create)
Definition: alias_db.c:1174
#define LIBALIAS_LOCK_ASSERT(l)
Definition: alias_local.h:174
int SctpAlias(struct libalias *la, struct ip *ip, int direction)
Handles SCTP packets passed from libalias.
Definition: alias_sctp.c:741
int ProxyCheck(struct libalias *la, struct in_addr *proxy_server_addr, u_short *proxy_server_port, struct in_addr src_addr, struct in_addr dst_addr, u_short dst_port, u_char ip_p)
Definition: alias_proxy.c:457
#define LIBALIAS_LOCK(l)
Definition: alias_local.h:175
#define ADJUST_CHECKSUM(acc, cksum)
Definition: alias_local.h:194
#define LIBALIAS_UNLOCK(l)
Definition: alias_local.h:176
void ProxyModify(struct libalias *la, struct alias_link *_lnk, struct ip *_pip, int _maxpacketsize, int _proxy_type)
Definition: alias_proxy.c:494
@ ALIAS_TCP_STATE_NOT_CONNECTED
Definition: alias_local.h:351
@ ALIAS_TCP_STATE_CONNECTED
Definition: alias_local.h:352
@ ALIAS_TCP_STATE_DISCONNECTED
Definition: alias_local.h:353
void DifferentialChecksum(u_short *_cksum, void *_new, void *_old, int _n)
Definition: alias_util.c:154
int LibAliasAttachHandlers(struct proto_handler *p)
Definition: alias_mod.c:82
int find_handler(int8_t dir, int8_t proto, struct libalias *la, struct ip *ip, struct alias_data *ad)
Definition: alias_mod.c:109
int LibAliasDetachHandlers(struct proto_handler *p)
Definition: alias_mod.c:98
struct proto_handler * first_handler(void)
Definition: alias_mod.c:123
#define UDP
Definition: alias_mod.h:59
#define TCP
Definition: alias_mod.h:58
#define IN
Definition: alias_mod.h:52
#define OUT
Definition: alias_mod.h:53
#define IP
Definition: alias_mod.h:57
#define SN_TO_LOCAL
Definition: alias_sctp.h:100
#define SN_TO_GLOBAL
Definition: alias_sctp.h:101
SYSCTL_DECL(_net_inet_tcp_cc)
__uint16_t uint16_t
Definition: in.h:57
__uint8_t uint8_t
Definition: in.h:52
#define IPPROTO_TCP
Definition: in.h:45
#define IPPROTO_ICMP
Definition: in.h:44
#define IPPROTO_UDP
Definition: in.h:46
u_char ip_p
Definition: ip.h:17
struct in_addr ip_src ip_dst
Definition: ip.h:19
u_short ip_sum
Definition: ip.h:18
u_short ip_id
Definition: ip.h:10
#define ICMP_ADVLEN(p)
Definition: ip_icmp.h:139
#define ICMP_MINLEN
Definition: ip_icmp.h:135
#define ICMP_TSTAMP
Definition: ip_icmp.h:190
#define ICMP_ECHOREPLY
Definition: ip_icmp.h:153
#define ICMP_SOURCEQUENCH
Definition: ip_icmp.h:171
#define ICMP_TIMXCEED
Definition: ip_icmp.h:183
#define ICMP_PARAMPROB
Definition: ip_icmp.h:186
#define ICMP_ADVLENMIN
Definition: ip_icmp.h:138
#define ICMP_UNREACH
Definition: ip_icmp.h:154
#define ICMP_ECHO
Definition: ip_icmp.h:178
#define ICMP_TSTAMPREPLY
Definition: ip_icmp.h:191
#define IPPROTO_SCTP
struct alias_link * lnk
Definition: alias_mod.h:67
Definition: ip_icmp.h:65
u_char icmp_code
Definition: ip_icmp.h:67
u_char icmp_type
Definition: ip_icmp.h:66
u_short icmp_cksum
Definition: ip_icmp.h:68
Definition: in.h:83
in_addr_t s_addr
Definition: in.h:84
Definition: ip.h:51
u_char ip_p
Definition: ip.h:69
u_short ip_id
Definition: ip.h:62
struct in_addr ip_src ip_dst
Definition: ip.h:71
u_char ip_hl
Definition: ip.h:53
u_short ip_sum
Definition: ip.h:70
u_short ip_len
Definition: ip.h:61
int packetAliasMode
Definition: alias_local.h:92
Definition: udp.h:45
u_short uh_ulen
Definition: udp.h:48
u_short uh_sport
Definition: udp.h:46
u_short uh_sum
Definition: udp.h:49
u_short uh_dport
Definition: udp.h:47