Deleted Added
full compact
fil.c (153084) fil.c (153876)
1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/fil.c 153084 2005-12-04 10:06:06Z ru $ */
1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/fil.c 153876 2005-12-30 11:32:23Z guido $ */
2
3/*
4 * Copyright (C) 1993-2003 by Darren Reed.
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8#if defined(KERNEL) || defined(_KERNEL)
9# undef KERNEL

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

29# if (__FreeBSD_version == 400019)
30# define CSUM_DELAY_DATA
31# endif
32# endif
33# include <sys/filio.h>
34#else
35# include <sys/ioctl.h>
36#endif
2
3/*
4 * Copyright (C) 1993-2003 by Darren Reed.
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8#if defined(KERNEL) || defined(_KERNEL)
9# undef KERNEL

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

29# if (__FreeBSD_version == 400019)
30# define CSUM_DELAY_DATA
31# endif
32# endif
33# include <sys/filio.h>
34#else
35# include <sys/ioctl.h>
36#endif
37#include <sys/fcntl.h>
37#if !defined(_AIX51)
38# include <sys/fcntl.h>
39#endif
38#if defined(_KERNEL)
39# include <sys/systm.h>
40# include <sys/file.h>
41#else
42# include <stdio.h>
43# include <string.h>
44# include <stdlib.h>
45# include <stddef.h>

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

69# include <sys/protosw.h>
70#endif
71#include <sys/socket.h>
72#include <net/if.h>
73#ifdef sun
74# include <net/af.h>
75#endif
76#if !defined(_KERNEL) && defined(__FreeBSD__)
40#if defined(_KERNEL)
41# include <sys/systm.h>
42# include <sys/file.h>
43#else
44# include <stdio.h>
45# include <string.h>
46# include <stdlib.h>
47# include <stddef.h>

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

71# include <sys/protosw.h>
72#endif
73#include <sys/socket.h>
74#include <net/if.h>
75#ifdef sun
76# include <net/af.h>
77#endif
78#if !defined(_KERNEL) && defined(__FreeBSD__)
79# if (__FreeBSD_version >= 504000)
80# undef _RADIX_H_
81# endif
77# include "radix_ipf.h"
78#endif
79#include <net/route.h>
80#include <netinet/in.h>
81#include <netinet/in_systm.h>
82#include <netinet/ip.h>
83#if !defined(linux)
84# include <netinet/ip_var.h>
85#endif
86#if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
87# include <sys/hashing.h>
88# include <netinet/in_var.h>
89#endif
90#include <netinet/tcp.h>
82# include "radix_ipf.h"
83#endif
84#include <net/route.h>
85#include <netinet/in.h>
86#include <netinet/in_systm.h>
87#include <netinet/ip.h>
88#if !defined(linux)
89# include <netinet/ip_var.h>
90#endif
91#if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
92# include <sys/hashing.h>
93# include <netinet/in_var.h>
94#endif
95#include <netinet/tcp.h>
91#if !defined(__sgi) || defined(_KERNEL)
96#if (!defined(__sgi) && !defined(AIX)) || defined(_KERNEL)
92# include <netinet/udp.h>
93# include <netinet/ip_icmp.h>
94#endif
95#ifdef __hpux
96# undef _NET_ROUTE_INCLUDED
97#endif
98#include "netinet/ip_compat.h"
99#ifdef USE_INET6

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

131#endif
132#include "netinet/ipl.h"
133/* END OF INCLUDES */
134
135#include <machine/in_cksum.h>
136
137#if !defined(lint)
138static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
97# include <netinet/udp.h>
98# include <netinet/ip_icmp.h>
99#endif
100#ifdef __hpux
101# undef _NET_ROUTE_INCLUDED
102#endif
103#include "netinet/ip_compat.h"
104#ifdef USE_INET6

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

136#endif
137#include "netinet/ipl.h"
138/* END OF INCLUDES */
139
140#include <machine/in_cksum.h>
141
142#if !defined(lint)
143static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
139static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/fil.c 153084 2005-12-04 10:06:06Z ru $";
144static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/fil.c 153876 2005-12-30 11:32:23Z guido $";
140/* static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp"; */
141#endif
142
143#ifndef _KERNEL
144# include "ipf.h"
145# include "ipt.h"
146# include "bpf-ipf.h"
147extern int opts;

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

171int fr_running = 0;
172int fr_flags = IPF_LOGGING;
173int fr_active = 0;
174int fr_control_forwarding = 0;
175int fr_update_ipid = 0;
176u_short fr_ip_id = 0;
177int fr_chksrc = 0; /* causes a system crash if enabled */
178int fr_minttl = 4;
145/* static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp"; */
146#endif
147
148#ifndef _KERNEL
149# include "ipf.h"
150# include "ipt.h"
151# include "bpf-ipf.h"
152extern int opts;

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

176int fr_running = 0;
177int fr_flags = IPF_LOGGING;
178int fr_active = 0;
179int fr_control_forwarding = 0;
180int fr_update_ipid = 0;
181u_short fr_ip_id = 0;
182int fr_chksrc = 0; /* causes a system crash if enabled */
183int fr_minttl = 4;
184int fr_icmpminfragmtu = 68;
179u_long fr_frouteok[2] = {0, 0};
180u_long fr_userifqs = 0;
181u_long fr_badcoalesces[2] = {0, 0};
182u_char ipf_iss_secret[32];
183#if defined(IPFILTER_DEFAULT_BLOCK)
184int fr_pass = FR_BLOCK|FR_NOMATCH;
185#else
186int fr_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH;

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

216 ;
217
218static INLINE int fr_ipfcheck __P((fr_info_t *, frentry_t *, int));
219static int fr_portcheck __P((frpcmp_t *, u_short *));
220static int frflushlist __P((int, minor_t, int *, frentry_t **));
221static ipfunc_t fr_findfunc __P((ipfunc_t));
222static frentry_t *fr_firewall __P((fr_info_t *, u_32_t *));
223static int fr_funcinit __P((frentry_t *fr));
185u_long fr_frouteok[2] = {0, 0};
186u_long fr_userifqs = 0;
187u_long fr_badcoalesces[2] = {0, 0};
188u_char ipf_iss_secret[32];
189#if defined(IPFILTER_DEFAULT_BLOCK)
190int fr_pass = FR_BLOCK|FR_NOMATCH;
191#else
192int fr_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH;

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

222 ;
223
224static INLINE int fr_ipfcheck __P((fr_info_t *, frentry_t *, int));
225static int fr_portcheck __P((frpcmp_t *, u_short *));
226static int frflushlist __P((int, minor_t, int *, frentry_t **));
227static ipfunc_t fr_findfunc __P((ipfunc_t));
228static frentry_t *fr_firewall __P((fr_info_t *, u_32_t *));
229static int fr_funcinit __P((frentry_t *fr));
230static INLINE void frpr_ah __P((fr_info_t *));
224static INLINE void frpr_esp __P((fr_info_t *));
225static INLINE void frpr_gre __P((fr_info_t *));
226static INLINE void frpr_udp __P((fr_info_t *));
227static INLINE void frpr_tcp __P((fr_info_t *));
228static INLINE void frpr_icmp __P((fr_info_t *));
229static INLINE void frpr_ipv4hdr __P((fr_info_t *));
230static INLINE int frpr_pullup __P((fr_info_t *, int));
231static INLINE void frpr_short __P((fr_info_t *, int));
231static INLINE void frpr_esp __P((fr_info_t *));
232static INLINE void frpr_gre __P((fr_info_t *));
233static INLINE void frpr_udp __P((fr_info_t *));
234static INLINE void frpr_tcp __P((fr_info_t *));
235static INLINE void frpr_icmp __P((fr_info_t *));
236static INLINE void frpr_ipv4hdr __P((fr_info_t *));
237static INLINE int frpr_pullup __P((fr_info_t *, int));
238static INLINE void frpr_short __P((fr_info_t *, int));
232static INLINE void frpr_tcpcommon __P((fr_info_t *));
233static INLINE void frpr_udpcommon __P((fr_info_t *));
234static INLINE int fr_updateipid __P((fr_info_t *));
239static INLINE int frpr_tcpcommon __P((fr_info_t *));
240static INLINE int frpr_udpcommon __P((fr_info_t *));
241static int fr_updateipid __P((fr_info_t *));
235#ifdef IPFILTER_LOOKUP
236static int fr_grpmapinit __P((frentry_t *fr));
237static INLINE void *fr_resolvelookup __P((u_int, u_int, lookupfunc_t *));
238#endif
239static void frsynclist __P((frentry_t *, void *));
242#ifdef IPFILTER_LOOKUP
243static int fr_grpmapinit __P((frentry_t *fr));
244static INLINE void *fr_resolvelookup __P((u_int, u_int, lookupfunc_t *));
245#endif
246static void frsynclist __P((frentry_t *, void *));
240static ipftuneable_t *fr_findtunebyname __P((char *));
247static ipftuneable_t *fr_findtunebyname __P((const char *));
241static ipftuneable_t *fr_findtunebycookie __P((void *, void **));
242
243
244/*
245 * bit values for identifying presence of individual IP options
246 * All of these tables should be ordered by increasing key value on the left
247 * hand side to allow for binary searching of the array and include a trailer
248 * with a 0 for the bitmask for linear searches to easily find the end with.

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

275 { IPPROTO_HOPOPTS, 0x000001 },
276 { IPPROTO_IPV6, 0x000002 },
277 { IPPROTO_ROUTING, 0x000004 },
278 { IPPROTO_FRAGMENT, 0x000008 },
279 { IPPROTO_ESP, 0x000010 },
280 { IPPROTO_AH, 0x000020 },
281 { IPPROTO_NONE, 0x000040 },
282 { IPPROTO_DSTOPTS, 0x000080 },
248static ipftuneable_t *fr_findtunebycookie __P((void *, void **));
249
250
251/*
252 * bit values for identifying presence of individual IP options
253 * All of these tables should be ordered by increasing key value on the left
254 * hand side to allow for binary searching of the array and include a trailer
255 * with a 0 for the bitmask for linear searches to easily find the end with.

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

282 { IPPROTO_HOPOPTS, 0x000001 },
283 { IPPROTO_IPV6, 0x000002 },
284 { IPPROTO_ROUTING, 0x000004 },
285 { IPPROTO_FRAGMENT, 0x000008 },
286 { IPPROTO_ESP, 0x000010 },
287 { IPPROTO_AH, 0x000020 },
288 { IPPROTO_NONE, 0x000040 },
289 { IPPROTO_DSTOPTS, 0x000080 },
290 { IPPROTO_MOBILITY, 0x000100 },
283 { 0, 0 }
284};
285#endif
286
287struct optlist tcpopts[] = {
288 { TCPOPT_NOP, 0x000001 },
289 { TCPOPT_MAXSEG, 0x000002 },
290 { TCPOPT_WINDOW, 0x000004 },

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

326 * fields in the fr_info_t structure passed based on properties of the
327 * current packet. There are different routines for the same protocol
328 * for each of IPv4 and IPv6. Adding a new protocol, for which there
329 * will "special" inspection for setup, is now more easily done by adding
330 * a new routine and expanding the frpr_ipinit*() function rather than by
331 * adding more code to a growing switch statement.
332 */
333#ifdef USE_INET6
291 { 0, 0 }
292};
293#endif
294
295struct optlist tcpopts[] = {
296 { TCPOPT_NOP, 0x000001 },
297 { TCPOPT_MAXSEG, 0x000002 },
298 { TCPOPT_WINDOW, 0x000004 },

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

334 * fields in the fr_info_t structure passed based on properties of the
335 * current packet. There are different routines for the same protocol
336 * for each of IPv4 and IPv6. Adding a new protocol, for which there
337 * will "special" inspection for setup, is now more easily done by adding
338 * a new routine and expanding the frpr_ipinit*() function rather than by
339 * adding more code to a growing switch statement.
340 */
341#ifdef USE_INET6
342static INLINE int frpr_ah6 __P((fr_info_t *));
343static INLINE void frpr_esp6 __P((fr_info_t *));
344static INLINE void frpr_gre6 __P((fr_info_t *));
334static INLINE void frpr_udp6 __P((fr_info_t *));
335static INLINE void frpr_tcp6 __P((fr_info_t *));
336static INLINE void frpr_icmp6 __P((fr_info_t *));
345static INLINE void frpr_udp6 __P((fr_info_t *));
346static INLINE void frpr_tcp6 __P((fr_info_t *));
347static INLINE void frpr_icmp6 __P((fr_info_t *));
337static INLINE void frpr_ipv6hdr __P((fr_info_t *));
348static INLINE int frpr_ipv6hdr __P((fr_info_t *));
338static INLINE void frpr_short6 __P((fr_info_t *, int));
339static INLINE int frpr_hopopts6 __P((fr_info_t *));
349static INLINE void frpr_short6 __P((fr_info_t *, int));
350static INLINE int frpr_hopopts6 __P((fr_info_t *));
351static INLINE int frpr_mobility6 __P((fr_info_t *));
340static INLINE int frpr_routing6 __P((fr_info_t *));
341static INLINE int frpr_dstopts6 __P((fr_info_t *));
352static INLINE int frpr_routing6 __P((fr_info_t *));
353static INLINE int frpr_dstopts6 __P((fr_info_t *));
342static INLINE int frpr_fragment6 __P((fr_info_t *));
354static INLINE void frpr_fragment6 __P((fr_info_t *));
355static INLINE int frpr_ipv6exthdr __P((fr_info_t *, int, int));
343
344
345/* ------------------------------------------------------------------------ */
346/* Function: frpr_short6 */
347/* Returns: void */
348/* Parameters: fin(I) - pointer to packet information */
349/* */
350/* IPv6 Only */
351/* This is function enforces the 'is a packet too short to be legit' rule */
352/* for IPv6 and marks the packet with FI_SHORT if so. See function comment */
353/* for frpr_short() for more details. */
354/* ------------------------------------------------------------------------ */
356
357
358/* ------------------------------------------------------------------------ */
359/* Function: frpr_short6 */
360/* Returns: void */
361/* Parameters: fin(I) - pointer to packet information */
362/* */
363/* IPv6 Only */
364/* This is function enforces the 'is a packet too short to be legit' rule */
365/* for IPv6 and marks the packet with FI_SHORT if so. See function comment */
366/* for frpr_short() for more details. */
367/* ------------------------------------------------------------------------ */
355static INLINE void frpr_short6(fin, min)
368static INLINE void frpr_short6(fin, xmin)
356fr_info_t *fin;
369fr_info_t *fin;
357int min;
370int xmin;
358{
371{
359 fr_ip_t *fi = &fin->fin_fi;
360 int off;
361
372
362 off = fin->fin_off;
363 if (off == 0) {
364 if (fin->fin_plen < fin->fin_hlen + min)
365 fi->fi_flx |= FI_SHORT;
366 } else if (off < min) {
367 fi->fi_flx |= FI_SHORT;
368 }
373 if (fin->fin_dlen < xmin)
374 fin->fin_flx |= FI_SHORT;
369}
370
371
372/* ------------------------------------------------------------------------ */
373/* Function: frpr_ipv6hdr */
375}
376
377
378/* ------------------------------------------------------------------------ */
379/* Function: frpr_ipv6hdr */
374/* Returns: void */
380/* Returns: int - 0 = IPv6 packet intact, -1 = packet lost */
375/* Parameters: fin(I) - pointer to packet information */
376/* */
377/* IPv6 Only */
378/* Copy values from the IPv6 header into the fr_info_t struct and call the */
381/* Parameters: fin(I) - pointer to packet information */
382/* */
383/* IPv6 Only */
384/* Copy values from the IPv6 header into the fr_info_t struct and call the */
379/* per-protocol analyzer if it exists. */
385/* per-protocol analyzer if it exists. In validating the packet, a protocol*/
386/* analyzer may pullup or free the packet itself so we need to be vigiliant */
387/* of that possibility arising. */
380/* ------------------------------------------------------------------------ */
388/* ------------------------------------------------------------------------ */
381static INLINE void frpr_ipv6hdr(fin)
389static INLINE int frpr_ipv6hdr(fin)
382fr_info_t *fin;
383{
390fr_info_t *fin;
391{
384 int p, go = 1, i, hdrcount, coalesced;
385 ip6_t *ip6 = (ip6_t *)fin->fin_ip;
392 ip6_t *ip6 = (ip6_t *)fin->fin_ip;
393 int p, go = 1, i, hdrcount;
386 fr_ip_t *fi = &fin->fin_fi;
387
388 fin->fin_off = 0;
389
390 fi->fi_tos = 0;
391 fi->fi_optmsk = 0;
392 fi->fi_secmsk = 0;
393 fi->fi_auth = 0;
394
394 fr_ip_t *fi = &fin->fin_fi;
395
396 fin->fin_off = 0;
397
398 fi->fi_tos = 0;
399 fi->fi_optmsk = 0;
400 fi->fi_secmsk = 0;
401 fi->fi_auth = 0;
402
395 coalesced = (fin->fin_flx & FI_COALESCE) ? 1 : 0;
396 p = ip6->ip6_nxt;
397 fi->fi_ttl = ip6->ip6_hlim;
398 fi->fi_src.in6 = ip6->ip6_src;
399 fi->fi_dst.in6 = ip6->ip6_dst;
400 fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff);
401
402 hdrcount = 0;
403 while (go && !(fin->fin_flx & (FI_BAD|FI_SHORT))) {

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

414 break;
415
416 case IPPROTO_ICMPV6 :
417 frpr_icmp6(fin);
418 go = 0;
419 break;
420
421 case IPPROTO_GRE :
403 p = ip6->ip6_nxt;
404 fi->fi_ttl = ip6->ip6_hlim;
405 fi->fi_src.in6 = ip6->ip6_src;
406 fi->fi_dst.in6 = ip6->ip6_dst;
407 fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff);
408
409 hdrcount = 0;
410 while (go && !(fin->fin_flx & (FI_BAD|FI_SHORT))) {

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

421 break;
422
423 case IPPROTO_ICMPV6 :
424 frpr_icmp6(fin);
425 go = 0;
426 break;
427
428 case IPPROTO_GRE :
422 frpr_gre(fin);
429 frpr_gre6(fin);
423 go = 0;
424 break;
425
426 case IPPROTO_HOPOPTS :
430 go = 0;
431 break;
432
433 case IPPROTO_HOPOPTS :
427 /*
428 * Actually, hop by hop header is only allowed right
429 * after IPv6 header!
430 */
431 if (hdrcount != 0)
432 fin->fin_flx |= FI_BAD;
433
434 if (coalesced == 0) {
435 coalesced = fr_coalesce(fin);
436 if (coalesced != 1)
437 return;
438 }
439 p = frpr_hopopts6(fin);
440 break;
441
434 p = frpr_hopopts6(fin);
435 break;
436
437 case IPPROTO_MOBILITY :
438 p = frpr_mobility6(fin);
439 break;
440
442 case IPPROTO_DSTOPTS :
441 case IPPROTO_DSTOPTS :
443 if (coalesced == 0) {
444 coalesced = fr_coalesce(fin);
445 if (coalesced != 1)
446 return;
447 }
448 p = frpr_dstopts6(fin);
449 break;
450
451 case IPPROTO_ROUTING :
442 p = frpr_dstopts6(fin);
443 break;
444
445 case IPPROTO_ROUTING :
452 if (coalesced == 0) {
453 coalesced = fr_coalesce(fin);
454 if (coalesced != 1)
455 return;
456 }
457 p = frpr_routing6(fin);
458 break;
459
446 p = frpr_routing6(fin);
447 break;
448
460 case IPPROTO_ESP :
461 frpr_esp(fin);
462 /*FALLTHROUGH*/
463 case IPPROTO_AH :
449 case IPPROTO_AH :
450 p = frpr_ah6(fin);
451 break;
452
453 case IPPROTO_ESP :
454 frpr_esp6(fin);
455 go = 0;
456 break;
457
464 case IPPROTO_IPV6 :
465 for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
466 if (ip6exthdr[i].ol_val == p) {
467 fin->fin_flx |= ip6exthdr[i].ol_bit;
468 break;
469 }
470 go = 0;
471 break;
472
473 case IPPROTO_NONE :
474 go = 0;
475 break;
476
477 case IPPROTO_FRAGMENT :
458 case IPPROTO_IPV6 :
459 for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
460 if (ip6exthdr[i].ol_val == p) {
461 fin->fin_flx |= ip6exthdr[i].ol_bit;
462 break;
463 }
464 go = 0;
465 break;
466
467 case IPPROTO_NONE :
468 go = 0;
469 break;
470
471 case IPPROTO_FRAGMENT :
478 if (coalesced == 0) {
479 coalesced = fr_coalesce(fin);
480 if (coalesced != 1)
481 return;
482 }
483 p = frpr_fragment6(fin);
472 frpr_fragment6(fin);
473 go = 0;
484 break;
485
486 default :
487 go = 0;
488 break;
489 }
490 hdrcount++;
491
492 /*
493 * It is important to note that at this point, for the
494 * extension headers (go != 0), the entire header may not have
495 * been pulled up when the code gets to this point. This is
496 * only done for "go != 0" because the other header handlers
474 break;
475
476 default :
477 go = 0;
478 break;
479 }
480 hdrcount++;
481
482 /*
483 * It is important to note that at this point, for the
484 * extension headers (go != 0), the entire header may not have
485 * been pulled up when the code gets to this point. This is
486 * only done for "go != 0" because the other header handlers
497 * will all pullup their complete header and the other
498 * indicator of an incomplete header is that this eas just an
499 * extension header.
487 * will all pullup their complete header. The other indicator
488 * of an incomplete packet is that this was just an extension
489 * header.
500 */
501 if ((go != 0) && (p != IPPROTO_NONE) &&
502 (frpr_pullup(fin, 0) == -1)) {
503 p = IPPROTO_NONE;
504 go = 0;
505 }
506 }
507 fi->fi_p = p;
490 */
491 if ((go != 0) && (p != IPPROTO_NONE) &&
492 (frpr_pullup(fin, 0) == -1)) {
493 p = IPPROTO_NONE;
494 go = 0;
495 }
496 }
497 fi->fi_p = p;
498
499 /*
500 * Some of the above functions, like frpr_esp6(), can call fr_pullup
501 * and destroy whatever packet was here. The caller of this function
502 * expects us to return -1 if there is a problem with fr_pullup.
503 */
504 if (fin->fin_m == NULL)
505 return -1;
506
507 return 0;
508}
509
510
511/* ------------------------------------------------------------------------ */
508}
509
510
511/* ------------------------------------------------------------------------ */
512/* Function: frpr_hopopts6 */
512/* Function: frpr_ipv6exthdr */
513/* Returns: int - value of the next header or IPPROTO_NONE if error */
513/* Returns: int - value of the next header or IPPROTO_NONE if error */
514/* Parameters: fin(I) - pointer to packet information */
514/* Parameters: fin(I) - pointer to packet information */
515/* multiple(I) - flag indicating yes/no if multiple occurances */
516/* of this extension header are allowed. */
517/* proto(I) - protocol number for this extension header */
515/* */
516/* IPv6 Only */
518/* */
519/* IPv6 Only */
517/* This is function checks pending hop by hop options extension header */
518/* ------------------------------------------------------------------------ */
520/* ------------------------------------------------------------------------ */
519static INLINE int frpr_hopopts6(fin)
521static INLINE int frpr_ipv6exthdr(fin, multiple, proto)
520fr_info_t *fin;
522fr_info_t *fin;
523int multiple, proto;
521{
522 struct ip6_ext *hdr;
523 u_short shift;
524 int i;
525
526 fin->fin_flx |= FI_V6EXTHDR;
527
528 /* 8 is default length of extension hdr */

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

537 hdr = fin->fin_dp;
538 shift = 8 + (hdr->ip6e_len << 3);
539 if (shift > fin->fin_dlen) { /* Nasty extension header length? */
540 fin->fin_flx |= FI_BAD;
541 return IPPROTO_NONE;
542 }
543
544 for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
524{
525 struct ip6_ext *hdr;
526 u_short shift;
527 int i;
528
529 fin->fin_flx |= FI_V6EXTHDR;
530
531 /* 8 is default length of extension hdr */

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

540 hdr = fin->fin_dp;
541 shift = 8 + (hdr->ip6e_len << 3);
542 if (shift > fin->fin_dlen) { /* Nasty extension header length? */
543 fin->fin_flx |= FI_BAD;
544 return IPPROTO_NONE;
545 }
546
547 for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
545 if (ip6exthdr[i].ol_val == IPPROTO_HOPOPTS) {
546 fin->fin_optmsk |= ip6exthdr[i].ol_bit;
548 if (ip6exthdr[i].ol_val == proto) {
549 /*
550 * Most IPv6 extension headers are only allowed once.
551 */
552 if ((multiple == 0) &&
553 ((fin->fin_optmsk & ip6exthdr[i].ol_bit) != 0))
554 fin->fin_flx |= FI_BAD;
555 else
556 fin->fin_optmsk |= ip6exthdr[i].ol_bit;
547 break;
548 }
549
550 fin->fin_dp = (char *)fin->fin_dp + shift;
551 fin->fin_dlen -= shift;
552
553 return hdr->ip6e_nxt;
554}
555
556
557/* ------------------------------------------------------------------------ */
557 break;
558 }
559
560 fin->fin_dp = (char *)fin->fin_dp + shift;
561 fin->fin_dlen -= shift;
562
563 return hdr->ip6e_nxt;
564}
565
566
567/* ------------------------------------------------------------------------ */
568/* Function: frpr_hopopts6 */
569/* Returns: int - value of the next header or IPPROTO_NONE if error */
570/* Parameters: fin(I) - pointer to packet information */
571/* */
572/* IPv6 Only */
573/* This is function checks pending hop by hop options extension header */
574/* ------------------------------------------------------------------------ */
575static INLINE int frpr_hopopts6(fin)
576fr_info_t *fin;
577{
578 return frpr_ipv6exthdr(fin, 0, IPPROTO_HOPOPTS);
579}
580
581
582/* ------------------------------------------------------------------------ */
583/* Function: frpr_mobility6 */
584/* Returns: int - value of the next header or IPPROTO_NONE if error */
585/* Parameters: fin(I) - pointer to packet information */
586/* */
587/* IPv6 Only */
588/* This is function checks the IPv6 mobility extension header */
589/* ------------------------------------------------------------------------ */
590static INLINE int frpr_mobility6(fin)
591fr_info_t *fin;
592{
593 return frpr_ipv6exthdr(fin, 0, IPPROTO_MOBILITY);
594}
595
596
597/* ------------------------------------------------------------------------ */
558/* Function: frpr_routing6 */
559/* Returns: int - value of the next header or IPPROTO_NONE if error */
560/* Parameters: fin(I) - pointer to packet information */
561/* */
562/* IPv6 Only */
563/* This is function checks pending routing extension header */
564/* ------------------------------------------------------------------------ */
565static INLINE int frpr_routing6(fin)
566fr_info_t *fin;
567{
568 struct ip6_ext *hdr;
598/* Function: frpr_routing6 */
599/* Returns: int - value of the next header or IPPROTO_NONE if error */
600/* Parameters: fin(I) - pointer to packet information */
601/* */
602/* IPv6 Only */
603/* This is function checks pending routing extension header */
604/* ------------------------------------------------------------------------ */
605static INLINE int frpr_routing6(fin)
606fr_info_t *fin;
607{
608 struct ip6_ext *hdr;
569 u_short shift;
570 int i;
609 int shift;
571
610
572 fin->fin_flx |= FI_V6EXTHDR;
573
574 /* 8 is default length of extension hdr */
575 if ((fin->fin_dlen - 8) < 0) {
576 fin->fin_flx |= FI_SHORT;
611 if (frpr_ipv6exthdr(fin, 0, IPPROTO_ROUTING) == IPPROTO_NONE)
577 return IPPROTO_NONE;
612 return IPPROTO_NONE;
578 }
579
613
580 if (frpr_pullup(fin, 8) == -1)
581 return IPPROTO_NONE;
582 hdr = fin->fin_dp;
614 hdr = fin->fin_dp;
583
584 shift = 8 + (hdr->ip6e_len << 3);
585 /*
586 * Nasty extension header length?
587 */
615 shift = 8 + (hdr->ip6e_len << 3);
616 /*
617 * Nasty extension header length?
618 */
588 if ((shift > fin->fin_dlen) || (shift < sizeof(struct ip6_hdr)) ||
619 if ((shift < sizeof(struct ip6_hdr)) ||
589 ((shift - sizeof(struct ip6_hdr)) & 15)) {
590 fin->fin_flx |= FI_BAD;
620 ((shift - sizeof(struct ip6_hdr)) & 15)) {
621 fin->fin_flx |= FI_BAD;
622 /*
623 * Compensate for the changes made in frpr_ipv6exthdr()
624 */
625 fin->fin_dlen += shift;
626 fin->fin_dp = (char *)fin->fin_dp - shift;
591 return IPPROTO_NONE;
592 }
593
627 return IPPROTO_NONE;
628 }
629
594 for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
595 if (ip6exthdr[i].ol_val == IPPROTO_ROUTING) {
596 fin->fin_optmsk |= ip6exthdr[i].ol_bit;
597 break;
598 }
599
600 fin->fin_dp = (char *)fin->fin_dp + shift;
601 fin->fin_dlen -= shift;
602
603 return hdr->ip6e_nxt;
604}
605
606
607/* ------------------------------------------------------------------------ */
608/* Function: frpr_fragment6 */
630 return hdr->ip6e_nxt;
631}
632
633
634/* ------------------------------------------------------------------------ */
635/* Function: frpr_fragment6 */
609/* Returns: int - value of the next header or IPPROTO_NONE if error */
636/* Returns: void */
610/* Parameters: fin(I) - pointer to packet information */
611/* */
612/* IPv6 Only */
613/* Examine the IPv6 fragment header and extract fragment offset information.*/
637/* Parameters: fin(I) - pointer to packet information */
638/* */
639/* IPv6 Only */
640/* Examine the IPv6 fragment header and extract fragment offset information.*/
641/* */
642/* We don't know where the transport layer header (or whatever is next is), */
643/* as it could be behind destination options (amongst others). Because */
644/* there is no fragment cache, there is no knowledge about whether or not an*/
645/* upper layer header has been seen (or where it ends) and thus we are not */
646/* able to continue processing beyond this header with any confidence. */
614/* ------------------------------------------------------------------------ */
647/* ------------------------------------------------------------------------ */
615static INLINE int frpr_fragment6(fin)
648static INLINE void frpr_fragment6(fin)
616fr_info_t *fin;
617{
618 struct ip6_frag *frag;
649fr_info_t *fin;
650{
651 struct ip6_frag *frag;
619 struct ip6_ext *hdr;
620 int i;
621
652
622 fin->fin_flx |= (FI_FRAG|FI_V6EXTHDR);
653 fin->fin_flx |= FI_FRAG;
623
654
624 /* 8 is default length of extension hdr */
625 if ((fin->fin_dlen - 8) < 0) {
626 fin->fin_flx |= FI_SHORT;
627 return IPPROTO_NONE;
628 }
655 if (frpr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT) == IPPROTO_NONE)
656 return;
629
657
630 /*
631 * Only one frgament header is allowed per IPv6 packet but it need
632 * not be the first nor last (not possible in some cases.)
633 */
634 for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
635 if (ip6exthdr[i].ol_val == IPPROTO_FRAGMENT)
636 break;
637
638 if (fin->fin_optmsk & ip6exthdr[i].ol_bit) {
639 fin->fin_flx |= FI_BAD;
640 return IPPROTO_NONE;
641 }
642
643 fin->fin_optmsk |= ip6exthdr[i].ol_bit;
644
645 if (frpr_pullup(fin, sizeof(*frag)) == -1)
658 if (frpr_pullup(fin, sizeof(*frag)) == -1)
646 return IPPROTO_NONE;
647 hdr = fin->fin_dp;
659 return;
648
660
661 frag = fin->fin_dp;
649 /*
662 /*
650 * Length must be zero, i.e. it has no length.
663 * Fragment but no fragmentation info set? Bad packet...
651 */
664 */
652 if (hdr->ip6e_len != 0) {
665 if (frag->ip6f_offlg == 0) {
653 fin->fin_flx |= FI_BAD;
666 fin->fin_flx |= FI_BAD;
654 return IPPROTO_NONE;
667 return;
655 }
656
668 }
669
657 if ((int)(fin->fin_dlen - sizeof(*frag)) < 0) {
658 fin->fin_flx |= FI_SHORT;
659 return IPPROTO_NONE;
660 }
661
662 frag = fin->fin_dp;
663 fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK;
664 fin->fin_off <<= 3;
665 if (fin->fin_off != 0)
666 fin->fin_flx |= FI_FRAGBODY;
667
668 fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag);
669 fin->fin_dlen -= sizeof(*frag);
670 fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK;
671 fin->fin_off <<= 3;
672 if (fin->fin_off != 0)
673 fin->fin_flx |= FI_FRAGBODY;
674
675 fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag);
676 fin->fin_dlen -= sizeof(*frag);
670
671 return frag->ip6f_nxt;
672}
673
674
675/* ------------------------------------------------------------------------ */
676/* Function: frpr_dstopts6 */
677/* Returns: int - value of the next header or IPPROTO_NONE if error */
678/* Parameters: fin(I) - pointer to packet information */
679/* nextheader(I) - stores next header value */
680/* */
681/* IPv6 Only */
682/* This is function checks pending destination options extension header */
683/* ------------------------------------------------------------------------ */
684static INLINE int frpr_dstopts6(fin)
685fr_info_t *fin;
686{
677}
678
679
680/* ------------------------------------------------------------------------ */
681/* Function: frpr_dstopts6 */
682/* Returns: int - value of the next header or IPPROTO_NONE if error */
683/* Parameters: fin(I) - pointer to packet information */
684/* nextheader(I) - stores next header value */
685/* */
686/* IPv6 Only */
687/* This is function checks pending destination options extension header */
688/* ------------------------------------------------------------------------ */
689static INLINE int frpr_dstopts6(fin)
690fr_info_t *fin;
691{
687 struct ip6_ext *hdr;
688 u_short shift;
689 int i;
690
691 /* 8 is default length of extension hdr */
692 if ((fin->fin_dlen - 8) < 0) {
693 fin->fin_flx |= FI_SHORT;
694 return IPPROTO_NONE;
695 }
696
697 if (frpr_pullup(fin, 8) == -1)
698 return IPPROTO_NONE;
699 hdr = fin->fin_dp;
700
701 shift = 8 + (hdr->ip6e_len << 3);
702 if (shift > fin->fin_dlen) { /* Nasty extension header length? */
703 fin->fin_flx |= FI_BAD;
704 return IPPROTO_NONE;
705 }
706
707 for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
708 if (ip6exthdr[i].ol_val == IPPROTO_DSTOPTS)
709 break;
710 fin->fin_optmsk |= ip6exthdr[i].ol_bit;
711 fin->fin_dp = (char *)fin->fin_dp + shift;
712 fin->fin_dlen -= shift;
713
714 return hdr->ip6e_nxt;
692 return frpr_ipv6exthdr(fin, 1, IPPROTO_DSTOPTS);
715}
716
717
718/* ------------------------------------------------------------------------ */
719/* Function: frpr_icmp6 */
720/* Returns: void */
721/* Parameters: fin(I) - pointer to packet information */
722/* */

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

756 fin->fin_flx |= FI_ICMPERR;
757 minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t);
758 break;
759 default :
760 break;
761 }
762 }
763
693}
694
695
696/* ------------------------------------------------------------------------ */
697/* Function: frpr_icmp6 */
698/* Returns: void */
699/* Parameters: fin(I) - pointer to packet information */
700/* */

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

734 fin->fin_flx |= FI_ICMPERR;
735 minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t);
736 break;
737 default :
738 break;
739 }
740 }
741
764 frpr_short(fin, minicmpsz);
742 frpr_short6(fin, minicmpsz);
765}
766
767
768/* ------------------------------------------------------------------------ */
769/* Function: frpr_udp6 */
770/* Returns: void */
771/* Parameters: fin(I) - pointer to packet information */
772/* */
773/* IPv6 Only */
774/* Analyse the packet for IPv6/UDP properties. */
743}
744
745
746/* ------------------------------------------------------------------------ */
747/* Function: frpr_udp6 */
748/* Returns: void */
749/* Parameters: fin(I) - pointer to packet information */
750/* */
751/* IPv6 Only */
752/* Analyse the packet for IPv6/UDP properties. */
753/* Is not expected to be called for fragmented packets. */
775/* ------------------------------------------------------------------------ */
776static INLINE void frpr_udp6(fin)
777fr_info_t *fin;
778{
779
754/* ------------------------------------------------------------------------ */
755static INLINE void frpr_udp6(fin)
756fr_info_t *fin;
757{
758
780 fr_checkv6sum(fin);
759 frpr_short6(fin, sizeof(struct udphdr));
781
760
782 frpr_short(fin, sizeof(struct udphdr));
783
784 frpr_udpcommon(fin);
761 if (frpr_udpcommon(fin) == 0)
762 fr_checkv6sum(fin);
785}
786
787
788/* ------------------------------------------------------------------------ */
789/* Function: frpr_tcp6 */
790/* Returns: void */
791/* Parameters: fin(I) - pointer to packet information */
792/* */
793/* IPv6 Only */
794/* Analyse the packet for IPv6/TCP properties. */
763}
764
765
766/* ------------------------------------------------------------------------ */
767/* Function: frpr_tcp6 */
768/* Returns: void */
769/* Parameters: fin(I) - pointer to packet information */
770/* */
771/* IPv6 Only */
772/* Analyse the packet for IPv6/TCP properties. */
773/* Is not expected to be called for fragmented packets. */
795/* ------------------------------------------------------------------------ */
796static INLINE void frpr_tcp6(fin)
797fr_info_t *fin;
798{
799
774/* ------------------------------------------------------------------------ */
775static INLINE void frpr_tcp6(fin)
776fr_info_t *fin;
777{
778
800 fr_checkv6sum(fin);
779 frpr_short6(fin, sizeof(struct tcphdr));
801
780
802 frpr_short(fin, sizeof(struct tcphdr));
781 if (frpr_tcpcommon(fin) == 0)
782 fr_checkv6sum(fin);
783}
803
784
804 frpr_tcpcommon(fin);
785
786/* ------------------------------------------------------------------------ */
787/* Function: frpr_esp6 */
788/* Returns: void */
789/* Parameters: fin(I) - pointer to packet information */
790/* */
791/* IPv6 Only */
792/* Analyse the packet for ESP properties. */
793/* The minimum length is taken to be the SPI (32bits) plus a tail (32bits) */
794/* even though the newer ESP packets must also have a sequence number that */
795/* is 32bits as well, it is not possible(?) to determine the version from a */
796/* simple packet header. */
797/* ------------------------------------------------------------------------ */
798static INLINE void frpr_esp6(fin)
799fr_info_t *fin;
800{
801
802 frpr_short6(fin, sizeof(grehdr_t));
803
804 (void) frpr_pullup(fin, 8);
805}
805}
806
807
808/* ------------------------------------------------------------------------ */
809/* Function: frpr_ah6 */
810/* Returns: void */
811/* Parameters: fin(I) - pointer to packet information */
812/* */
813/* IPv6 Only */
814/* Analyse the packet for AH properties. */
815/* The minimum length is taken to be the combination of all fields in the */
816/* header being present and no authentication data (null algorithm used.) */
817/* ------------------------------------------------------------------------ */
818static INLINE int frpr_ah6(fin)
819fr_info_t *fin;
820{
821 authhdr_t *ah;
822
823 frpr_short6(fin, 12);
824
825 if (frpr_pullup(fin, sizeof(*ah)) == -1)
826 return IPPROTO_NONE;
827
828 ah = (authhdr_t *)fin->fin_dp;
829 return ah->ah_next;
830}
831
832
833/* ------------------------------------------------------------------------ */
834/* Function: frpr_gre6 */
835/* Returns: void */
836/* Parameters: fin(I) - pointer to packet information */
837/* */
838/* Analyse the packet for GRE properties. */
839/* ------------------------------------------------------------------------ */
840static INLINE void frpr_gre6(fin)
841fr_info_t *fin;
842{
843 grehdr_t *gre;
844
845 frpr_short6(fin, sizeof(grehdr_t));
846
847 if (frpr_pullup(fin, sizeof(grehdr_t)) == -1)
848 return;
849
850 gre = fin->fin_dp;
851 if (GRE_REV(gre->gr_flags) == 1)
852 fin->fin_data[0] = gre->gr_call;
853}
806#endif /* USE_INET6 */
807
808
809/* ------------------------------------------------------------------------ */
810/* Function: frpr_pullup */
811/* Returns: int - 0 == pullup succeeded, -1 == failure */
812/* Parameters: fin(I) - pointer to packet information */
813/* plen(I) - length (excluding L3 header) to pullup */

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

834#endif
835 return 0;
836}
837
838
839/* ------------------------------------------------------------------------ */
840/* Function: frpr_short */
841/* Returns: void */
854#endif /* USE_INET6 */
855
856
857/* ------------------------------------------------------------------------ */
858/* Function: frpr_pullup */
859/* Returns: int - 0 == pullup succeeded, -1 == failure */
860/* Parameters: fin(I) - pointer to packet information */
861/* plen(I) - length (excluding L3 header) to pullup */

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

882#endif
883 return 0;
884}
885
886
887/* ------------------------------------------------------------------------ */
888/* Function: frpr_short */
889/* Returns: void */
842/* Parameters: fin(I) - pointer to packet information */
843/* min(I) - minimum header size */
890/* Parameters: fin(I) - pointer to packet information */
891/* xmin(I) - minimum header size */
844/* */
892/* */
845/* Check if a packet is "short" as defined by min. The rule we are */
893/* Check if a packet is "short" as defined by xmin. The rule we are */
846/* applying here is that the packet must not be fragmented within the layer */
847/* 4 header. That is, it must not be a fragment that has its offset set to */
848/* start within the layer 4 header (hdrmin) or if it is at offset 0, the */
849/* entire layer 4 header must be present (min). */
850/* ------------------------------------------------------------------------ */
894/* applying here is that the packet must not be fragmented within the layer */
895/* 4 header. That is, it must not be a fragment that has its offset set to */
896/* start within the layer 4 header (hdrmin) or if it is at offset 0, the */
897/* entire layer 4 header must be present (min). */
898/* ------------------------------------------------------------------------ */
851static INLINE void frpr_short(fin, min)
899static INLINE void frpr_short(fin, xmin)
852fr_info_t *fin;
900fr_info_t *fin;
853int min;
901int xmin;
854{
902{
855 fr_ip_t *fi = &fin->fin_fi;
856 int off;
857
903
858 off = fin->fin_off;
859 if (off == 0) {
860 if (fin->fin_plen < fin->fin_hlen + min)
861 fi->fi_flx |= FI_SHORT;
862 } else if (off < min) {
863 fi->fi_flx |= FI_SHORT;
904 if (fin->fin_off == 0) {
905 if (fin->fin_dlen < xmin)
906 fin->fin_flx |= FI_SHORT;
907 } else if (fin->fin_off < xmin) {
908 fin->fin_flx |= FI_SHORT;
864 }
865}
866
867
868/* ------------------------------------------------------------------------ */
869/* Function: frpr_icmp */
870/* Returns: void */
871/* Parameters: fin(I) - pointer to packet information */
872/* */
873/* IPv4 Only */
874/* Do a sanity check on the packet for ICMP (v4). In nearly all cases, */
875/* except extrememly bad packets, both type and code will be present. */
909 }
910}
911
912
913/* ------------------------------------------------------------------------ */
914/* Function: frpr_icmp */
915/* Returns: void */
916/* Parameters: fin(I) - pointer to packet information */
917/* */
918/* IPv4 Only */
919/* Do a sanity check on the packet for ICMP (v4). In nearly all cases, */
920/* except extrememly bad packets, both type and code will be present. */
876/* The expected minimum size of an ICMP packet is very much dependant on */
921/* The expected minimum size of an ICMP packet is very much dependent on */
877/* the type of it. */
878/* */
879/* XXX - other ICMP sanity checks? */
880/* ------------------------------------------------------------------------ */
881static INLINE void frpr_icmp(fin)
882fr_info_t *fin;
883{
884 int minicmpsz = sizeof(struct icmp);
885 icmphdr_t *icmp;
922/* the type of it. */
923/* */
924/* XXX - other ICMP sanity checks? */
925/* ------------------------------------------------------------------------ */
926static INLINE void frpr_icmp(fin)
927fr_info_t *fin;
928{
929 int minicmpsz = sizeof(struct icmp);
930 icmphdr_t *icmp;
931 ip_t *oip;
886
932
933 if (fin->fin_off != 0) {
934 frpr_short(fin, ICMPERR_ICMPHLEN);
935 return;
936 }
937
887 if (frpr_pullup(fin, ICMPERR_ICMPHLEN) == -1)
888 return;
889
938 if (frpr_pullup(fin, ICMPERR_ICMPHLEN) == -1)
939 return;
940
890 fr_checkv4sum(fin);
891
892 if (!fin->fin_off && (fin->fin_dlen > 1)) {
941 if (fin->fin_dlen > 1) {
893 icmp = fin->fin_dp;
894
895 fin->fin_data[0] = *(u_short *)icmp;
896
897 switch (icmp->icmp_type)
898 {
899 case ICMP_ECHOREPLY :
900 case ICMP_ECHO :

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

918 case ICMP_MASKREQ :
919 case ICMP_MASKREPLY :
920 minicmpsz = 12;
921 break;
922 /*
923 * type(1) + code(1) + cksum(2) + id(2) seq(2) + ip(20+)
924 */
925 case ICMP_UNREACH :
942 icmp = fin->fin_dp;
943
944 fin->fin_data[0] = *(u_short *)icmp;
945
946 switch (icmp->icmp_type)
947 {
948 case ICMP_ECHOREPLY :
949 case ICMP_ECHO :

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

967 case ICMP_MASKREQ :
968 case ICMP_MASKREPLY :
969 minicmpsz = 12;
970 break;
971 /*
972 * type(1) + code(1) + cksum(2) + id(2) seq(2) + ip(20+)
973 */
974 case ICMP_UNREACH :
975#ifdef icmp_nextmtu
976 if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG) {
977 if (icmp->icmp_nextmtu < fr_icmpminfragmtu)
978 fin->fin_flx |= FI_BAD;
979 }
980#endif
926 case ICMP_SOURCEQUENCH :
927 case ICMP_REDIRECT :
928 case ICMP_TIMXCEED :
929 case ICMP_PARAMPROB :
981 case ICMP_SOURCEQUENCH :
982 case ICMP_REDIRECT :
983 case ICMP_TIMXCEED :
984 case ICMP_PARAMPROB :
985 fin->fin_flx |= FI_ICMPERR;
930 if (fr_coalesce(fin) != 1)
931 return;
986 if (fr_coalesce(fin) != 1)
987 return;
932 fin->fin_flx |= FI_ICMPERR;
988 /*
989 * ICMP error packets should not be generated for IP
990 * packets that are a fragment that isn't the first
991 * fragment.
992 */
993 oip = (ip_t *)((char *)fin->fin_dp + ICMPERR_ICMPHLEN);
994 if ((ntohs(oip->ip_off) & IP_OFFMASK) != 0)
995 fin->fin_flx |= FI_BAD;
933 break;
934 default :
935 break;
936 }
937
938 if (fin->fin_dlen >= 6) /* ID field */
939 fin->fin_data[1] = icmp->icmp_id;
940 }
941
942 frpr_short(fin, minicmpsz);
996 break;
997 default :
998 break;
999 }
1000
1001 if (fin->fin_dlen >= 6) /* ID field */
1002 fin->fin_data[1] = icmp->icmp_id;
1003 }
1004
1005 frpr_short(fin, minicmpsz);
1006
1007 fr_checkv4sum(fin);
943}
944
945
946/* ------------------------------------------------------------------------ */
947/* Function: frpr_tcpcommon */
1008}
1009
1010
1011/* ------------------------------------------------------------------------ */
1012/* Function: frpr_tcpcommon */
948/* Returns: void */
1013/* Returns: int - 0 = header ok, 1 = bad packet, -1 = buffer error */
949/* Parameters: fin(I) - pointer to packet information */
950/* */
951/* TCP header sanity checking. Look for bad combinations of TCP flags, */
952/* and make some checks with how they interact with other fields. */
953/* If compiled with IPFILTER_CKSUM, check to see if the TCP checksum is */
954/* valid and mark the packet as bad if not. */
955/* ------------------------------------------------------------------------ */
1014/* Parameters: fin(I) - pointer to packet information */
1015/* */
1016/* TCP header sanity checking. Look for bad combinations of TCP flags, */
1017/* and make some checks with how they interact with other fields. */
1018/* If compiled with IPFILTER_CKSUM, check to see if the TCP checksum is */
1019/* valid and mark the packet as bad if not. */
1020/* ------------------------------------------------------------------------ */
956static INLINE void frpr_tcpcommon(fin)
1021static INLINE int frpr_tcpcommon(fin)
957fr_info_t *fin;
958{
959 int flags, tlen;
960 tcphdr_t *tcp;
1022fr_info_t *fin;
1023{
1024 int flags, tlen;
1025 tcphdr_t *tcp;
961 fr_ip_t *fi;
962
1026
963 fi = &fin->fin_fi;
964 fi->fi_flx |= FI_TCPUDP;
1027 fin->fin_flx |= FI_TCPUDP;
965 if (fin->fin_off != 0)
1028 if (fin->fin_off != 0)
966 return;
1029 return 0;
967
968 if (frpr_pullup(fin, sizeof(*tcp)) == -1)
1030
1031 if (frpr_pullup(fin, sizeof(*tcp)) == -1)
969 return;
1032 return -1;
970 tcp = fin->fin_dp;
971
972 if (fin->fin_dlen > 3) {
973 fin->fin_sport = ntohs(tcp->th_sport);
974 fin->fin_dport = ntohs(tcp->th_dport);
975 }
976
1033 tcp = fin->fin_dp;
1034
1035 if (fin->fin_dlen > 3) {
1036 fin->fin_sport = ntohs(tcp->th_sport);
1037 fin->fin_dport = ntohs(tcp->th_dport);
1038 }
1039
977 if ((fi->fi_flx & FI_SHORT) != 0)
978 return;
1040 if ((fin->fin_flx & FI_SHORT) != 0)
1041 return 1;
979
980 /*
981 * Use of the TCP data offset *must* result in a value that is at
982 * least the same size as the TCP header.
983 */
984 tlen = TCP_OFF(tcp) << 2;
985 if (tlen < sizeof(tcphdr_t)) {
986 fin->fin_flx |= FI_BAD;
1042
1043 /*
1044 * Use of the TCP data offset *must* result in a value that is at
1045 * least the same size as the TCP header.
1046 */
1047 tlen = TCP_OFF(tcp) << 2;
1048 if (tlen < sizeof(tcphdr_t)) {
1049 fin->fin_flx |= FI_BAD;
987 return;
1050 return 1;
988 }
989
990 flags = tcp->th_flags;
991 fin->fin_tcpf = tcp->th_flags;
992
993 /*
994 * If the urgent flag is set, then the urgent pointer must
995 * also be set and vice versa. Good TCP packets do not have

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

1033 * At this point, it's not exactly clear what is to be gained by
1034 * marking up which TCP options are and are not present. The one we
1035 * are most interested in is the TCP window scale. This is only in
1036 * a SYN packet [RFC1323] so we don't need this here...?
1037 * Now if we were to analyse the header for passive fingerprinting,
1038 * then that might add some weight to adding this...
1039 */
1040 if (tlen == sizeof(tcphdr_t))
1051 }
1052
1053 flags = tcp->th_flags;
1054 fin->fin_tcpf = tcp->th_flags;
1055
1056 /*
1057 * If the urgent flag is set, then the urgent pointer must
1058 * also be set and vice versa. Good TCP packets do not have

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

1096 * At this point, it's not exactly clear what is to be gained by
1097 * marking up which TCP options are and are not present. The one we
1098 * are most interested in is the TCP window scale. This is only in
1099 * a SYN packet [RFC1323] so we don't need this here...?
1100 * Now if we were to analyse the header for passive fingerprinting,
1101 * then that might add some weight to adding this...
1102 */
1103 if (tlen == sizeof(tcphdr_t))
1041 return;
1104 return 0;
1042
1043 if (frpr_pullup(fin, tlen) == -1)
1105
1106 if (frpr_pullup(fin, tlen) == -1)
1044 return;
1107 return -1;
1045
1046#if 0
1047 ip = fin->fin_ip;
1048 s = (u_char *)(tcp + 1);
1049 off = IP_HL(ip) << 2;
1050# ifdef _KERNEL
1051 if (fin->fin_mp != NULL) {
1052 mb_t *m = *fin->fin_mp;

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

1075 optmsk |= op->ol_bit;
1076 break;
1077 }
1078 }
1079 tlen -= ol;
1080 s += ol;
1081 }
1082#endif /* 0 */
1108
1109#if 0
1110 ip = fin->fin_ip;
1111 s = (u_char *)(tcp + 1);
1112 off = IP_HL(ip) << 2;
1113# ifdef _KERNEL
1114 if (fin->fin_mp != NULL) {
1115 mb_t *m = *fin->fin_mp;

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

1138 optmsk |= op->ol_bit;
1139 break;
1140 }
1141 }
1142 tlen -= ol;
1143 s += ol;
1144 }
1145#endif /* 0 */
1146
1147 return 0;
1083}
1084
1085
1086
1087/* ------------------------------------------------------------------------ */
1088/* Function: frpr_udpcommon */
1148}
1149
1150
1151
1152/* ------------------------------------------------------------------------ */
1153/* Function: frpr_udpcommon */
1089/* Returns: void */
1154/* Returns: int - 0 = header ok, 1 = bad packet */
1090/* Parameters: fin(I) - pointer to packet information */
1091/* */
1092/* Extract the UDP source and destination ports, if present. If compiled */
1093/* with IPFILTER_CKSUM, check to see if the UDP checksum is valid. */
1094/* ------------------------------------------------------------------------ */
1155/* Parameters: fin(I) - pointer to packet information */
1156/* */
1157/* Extract the UDP source and destination ports, if present. If compiled */
1158/* with IPFILTER_CKSUM, check to see if the UDP checksum is valid. */
1159/* ------------------------------------------------------------------------ */
1095static INLINE void frpr_udpcommon(fin)
1160static INLINE int frpr_udpcommon(fin)
1096fr_info_t *fin;
1097{
1098 udphdr_t *udp;
1161fr_info_t *fin;
1162{
1163 udphdr_t *udp;
1099 fr_ip_t *fi;
1100
1164
1101 fi = &fin->fin_fi;
1102 fi->fi_flx |= FI_TCPUDP;
1165 fin->fin_flx |= FI_TCPUDP;
1103
1104 if (!fin->fin_off && (fin->fin_dlen > 3)) {
1105 if (frpr_pullup(fin, sizeof(*udp)) == -1) {
1166
1167 if (!fin->fin_off && (fin->fin_dlen > 3)) {
1168 if (frpr_pullup(fin, sizeof(*udp)) == -1) {
1106 fi->fi_flx |= FI_SHORT;
1107 return;
1169 fin->fin_flx |= FI_SHORT;
1170 return 1;
1108 }
1109
1110 udp = fin->fin_dp;
1111
1112 fin->fin_sport = ntohs(udp->uh_sport);
1113 fin->fin_dport = ntohs(udp->uh_dport);
1114 }
1171 }
1172
1173 udp = fin->fin_dp;
1174
1175 fin->fin_sport = ntohs(udp->uh_sport);
1176 fin->fin_dport = ntohs(udp->uh_dport);
1177 }
1178
1179 return 0;
1115}
1116
1117
1118/* ------------------------------------------------------------------------ */
1119/* Function: frpr_tcp */
1120/* Returns: void */
1121/* Parameters: fin(I) - pointer to packet information */
1122/* */
1123/* IPv4 Only */
1124/* Analyse the packet for IPv4/TCP properties. */
1125/* ------------------------------------------------------------------------ */
1126static INLINE void frpr_tcp(fin)
1127fr_info_t *fin;
1128{
1129
1180}
1181
1182
1183/* ------------------------------------------------------------------------ */
1184/* Function: frpr_tcp */
1185/* Returns: void */
1186/* Parameters: fin(I) - pointer to packet information */
1187/* */
1188/* IPv4 Only */
1189/* Analyse the packet for IPv4/TCP properties. */
1190/* ------------------------------------------------------------------------ */
1191static INLINE void frpr_tcp(fin)
1192fr_info_t *fin;
1193{
1194
1130 fr_checkv4sum(fin);
1131
1132 frpr_short(fin, sizeof(tcphdr_t));
1133
1195 frpr_short(fin, sizeof(tcphdr_t));
1196
1134 frpr_tcpcommon(fin);
1197 if (frpr_tcpcommon(fin) == 0)
1198 fr_checkv4sum(fin);
1135}
1136
1137
1138/* ------------------------------------------------------------------------ */
1139/* Function: frpr_udp */
1140/* Returns: void */
1141/* Parameters: fin(I) - pointer to packet information */
1142/* */
1143/* IPv4 Only */
1144/* Analyse the packet for IPv4/UDP properties. */
1145/* ------------------------------------------------------------------------ */
1146static INLINE void frpr_udp(fin)
1147fr_info_t *fin;
1148{
1149
1199}
1200
1201
1202/* ------------------------------------------------------------------------ */
1203/* Function: frpr_udp */
1204/* Returns: void */
1205/* Parameters: fin(I) - pointer to packet information */
1206/* */
1207/* IPv4 Only */
1208/* Analyse the packet for IPv4/UDP properties. */
1209/* ------------------------------------------------------------------------ */
1210static INLINE void frpr_udp(fin)
1211fr_info_t *fin;
1212{
1213
1150 fr_checkv4sum(fin);
1151
1152 frpr_short(fin, sizeof(udphdr_t));
1153
1214 frpr_short(fin, sizeof(udphdr_t));
1215
1154 frpr_udpcommon(fin);
1216 if (frpr_udpcommon(fin) == 0)
1217 fr_checkv4sum(fin);
1155}
1156
1157
1158/* ------------------------------------------------------------------------ */
1159/* Function: frpr_esp */
1160/* Returns: void */
1161/* Parameters: fin(I) - pointer to packet information */
1162/* */
1163/* Analyse the packet for ESP properties. */
1164/* The minimum length is taken to be the SPI (32bits) plus a tail (32bits) */
1165/* even though the newer ESP packets must also have a sequence number that */
1166/* is 32bits as well, it is not possible(?) to determine the version from a */
1167/* simple packet header. */
1168/* ------------------------------------------------------------------------ */
1169static INLINE void frpr_esp(fin)
1170fr_info_t *fin;
1171{
1218}
1219
1220
1221/* ------------------------------------------------------------------------ */
1222/* Function: frpr_esp */
1223/* Returns: void */
1224/* Parameters: fin(I) - pointer to packet information */
1225/* */
1226/* Analyse the packet for ESP properties. */
1227/* The minimum length is taken to be the SPI (32bits) plus a tail (32bits) */
1228/* even though the newer ESP packets must also have a sequence number that */
1229/* is 32bits as well, it is not possible(?) to determine the version from a */
1230/* simple packet header. */
1231/* ------------------------------------------------------------------------ */
1232static INLINE void frpr_esp(fin)
1233fr_info_t *fin;
1234{
1172 if (frpr_pullup(fin, 8) == -1)
1173 return;
1174
1235
1175 if (fin->fin_v == 4)
1236 if (fin->fin_off == 0) {
1176 frpr_short(fin, 8);
1237 frpr_short(fin, 8);
1177#ifdef USE_INET6
1178 else if (fin->fin_v == 6)
1179 frpr_short6(fin, sizeof(grehdr_t));
1180#endif
1238 (void) frpr_pullup(fin, 8);
1239 }
1240
1181}
1182
1183
1184/* ------------------------------------------------------------------------ */
1241}
1242
1243
1244/* ------------------------------------------------------------------------ */
1245/* Function: frpr_ah */
1246/* Returns: void */
1247/* Parameters: fin(I) - pointer to packet information */
1248/* */
1249/* Analyse the packet for AH properties. */
1250/* The minimum length is taken to be the combination of all fields in the */
1251/* header being present and no authentication data (null algorithm used.) */
1252/* ------------------------------------------------------------------------ */
1253static INLINE void frpr_ah(fin)
1254fr_info_t *fin;
1255{
1256 authhdr_t *ah;
1257 int len;
1258
1259 frpr_short(fin, sizeof(*ah));
1260
1261 if (((fin->fin_flx & FI_SHORT) != 0) || (fin->fin_off != 0))
1262 return;
1263
1264 if (frpr_pullup(fin, sizeof(*ah)) == -1)
1265 return;
1266
1267 ah = (authhdr_t *)fin->fin_dp;
1268
1269 len = (ah->ah_plen + 2) << 2;
1270 frpr_short(fin, len);
1271}
1272
1273
1274/* ------------------------------------------------------------------------ */
1185/* Function: frpr_gre */
1186/* Returns: void */
1187/* Parameters: fin(I) - pointer to packet information */
1188/* */
1189/* Analyse the packet for GRE properties. */
1190/* ------------------------------------------------------------------------ */
1191static INLINE void frpr_gre(fin)
1192fr_info_t *fin;
1193{
1194 grehdr_t *gre;
1195
1275/* Function: frpr_gre */
1276/* Returns: void */
1277/* Parameters: fin(I) - pointer to packet information */
1278/* */
1279/* Analyse the packet for GRE properties. */
1280/* ------------------------------------------------------------------------ */
1281static INLINE void frpr_gre(fin)
1282fr_info_t *fin;
1283{
1284 grehdr_t *gre;
1285
1196 if (frpr_pullup(fin, sizeof(grehdr_t)) == -1)
1286 frpr_short(fin, sizeof(*gre));
1287
1288 if (fin->fin_off != 0)
1197 return;
1198
1289 return;
1290
1199 if (fin->fin_v == 4)
1200 frpr_short(fin, sizeof(grehdr_t));
1201#ifdef USE_INET6
1202 else if (fin->fin_v == 6)
1203 frpr_short6(fin, sizeof(grehdr_t));
1204#endif
1205 gre = fin->fin_dp;
1206 if (GRE_REV(gre->gr_flags) == 1)
1207 fin->fin_data[0] = gre->gr_call;
1291 if (frpr_pullup(fin, sizeof(*gre)) == -1)
1292 return;
1293
1294 if (fin->fin_off == 0) {
1295 gre = fin->fin_dp;
1296 if (GRE_REV(gre->gr_flags) == 1)
1297 fin->fin_data[0] = gre->gr_call;
1298 }
1208}
1209
1210
1211/* ------------------------------------------------------------------------ */
1212/* Function: frpr_ipv4hdr */
1213/* Returns: void */
1214/* Parameters: fin(I) - pointer to packet information */
1215/* */

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

1255
1256 fi->fi_saddr = ip->ip_src.s_addr;
1257 fi->fi_daddr = ip->ip_dst.s_addr;
1258
1259 /*
1260 * set packet attribute flags based on the offset and
1261 * calculate the byte offset that it represents.
1262 */
1299}
1300
1301
1302/* ------------------------------------------------------------------------ */
1303/* Function: frpr_ipv4hdr */
1304/* Returns: void */
1305/* Parameters: fin(I) - pointer to packet information */
1306/* */

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

1346
1347 fi->fi_saddr = ip->ip_src.s_addr;
1348 fi->fi_daddr = ip->ip_dst.s_addr;
1349
1350 /*
1351 * set packet attribute flags based on the offset and
1352 * calculate the byte offset that it represents.
1353 */
1263 if ((off & IP_MF) != 0) {
1264 fi->fi_flx |= FI_FRAG;
1265 if (fin->fin_dlen == 0)
1266 fi->fi_flx |= FI_BAD;
1267 }
1268
1269 off &= IP_MF|IP_OFFMASK;
1270 if (off != 0) {
1271 fi->fi_flx |= FI_FRAG;
1272 off &= IP_OFFMASK;
1273 if (off != 0) {
1274 fin->fin_flx |= FI_FRAGBODY;
1275 off <<= 3;
1354 off &= IP_MF|IP_OFFMASK;
1355 if (off != 0) {
1356 fi->fi_flx |= FI_FRAG;
1357 off &= IP_OFFMASK;
1358 if (off != 0) {
1359 fin->fin_flx |= FI_FRAGBODY;
1360 off <<= 3;
1276 if (off + fin->fin_dlen > 0xffff) {
1361 if ((off + fin->fin_dlen > 65535) ||
1362 (fin->fin_dlen == 0) || (fin->fin_dlen & 7)) {
1363 /*
1364 * The length of the packet, starting at its
1365 * offset cannot exceed 65535 (0xffff) as the
1366 * length of an IP packet is only 16 bits.
1367 *
1368 * Any fragment that isn't the last fragment
1369 * must have a length greater than 0 and it
1370 * must be an even multiple of 8.
1371 */
1277 fi->fi_flx |= FI_BAD;
1278 }
1279 }
1280 }
1281 fin->fin_off = off;
1282
1283 /*
1284 * Call per-protocol setup and checking

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

1289 frpr_udp(fin);
1290 break;
1291 case IPPROTO_TCP :
1292 frpr_tcp(fin);
1293 break;
1294 case IPPROTO_ICMP :
1295 frpr_icmp(fin);
1296 break;
1372 fi->fi_flx |= FI_BAD;
1373 }
1374 }
1375 }
1376 fin->fin_off = off;
1377
1378 /*
1379 * Call per-protocol setup and checking

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

1384 frpr_udp(fin);
1385 break;
1386 case IPPROTO_TCP :
1387 frpr_tcp(fin);
1388 break;
1389 case IPPROTO_ICMP :
1390 frpr_icmp(fin);
1391 break;
1392 case IPPROTO_AH :
1393 frpr_ah(fin);
1394 break;
1297 case IPPROTO_ESP :
1298 frpr_esp(fin);
1299 break;
1300 case IPPROTO_GRE :
1301 frpr_gre(fin);
1302 break;
1303 }
1304

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

1417 fin->fin_group[1] = '\0';
1418 fin->fin_dlen = fin->fin_plen - hlen;
1419 fin->fin_dp = (char *)ip + hlen;
1420
1421 v = fin->fin_v;
1422 if (v == 4)
1423 frpr_ipv4hdr(fin);
1424#ifdef USE_INET6
1395 case IPPROTO_ESP :
1396 frpr_esp(fin);
1397 break;
1398 case IPPROTO_GRE :
1399 frpr_gre(fin);
1400 break;
1401 }
1402

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

1515 fin->fin_group[1] = '\0';
1516 fin->fin_dlen = fin->fin_plen - hlen;
1517 fin->fin_dp = (char *)ip + hlen;
1518
1519 v = fin->fin_v;
1520 if (v == 4)
1521 frpr_ipv4hdr(fin);
1522#ifdef USE_INET6
1425 else if (v == 6)
1426 frpr_ipv6hdr(fin);
1523 else if (v == 6) {
1524 if (frpr_ipv6hdr(fin) == -1)
1525 return -1;
1526 }
1427#endif
1428 if (fin->fin_ip == NULL)
1429 return -1;
1430 return 0;
1431}
1432
1433
1434/* ------------------------------------------------------------------------ */

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

1546 ft->ftu_tcpfm, ft->ftu_tcpf));
1547 err = 0;
1548 }
1549 }
1550 return err;
1551}
1552
1553
1527#endif
1528 if (fin->fin_ip == NULL)
1529 return -1;
1530 return 0;
1531}
1532
1533
1534/* ------------------------------------------------------------------------ */

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

1646 ft->ftu_tcpfm, ft->ftu_tcpf));
1647 err = 0;
1648 }
1649 }
1650 return err;
1651}
1652
1653
1654
1554/* ------------------------------------------------------------------------ */
1555/* Function: fr_ipfcheck */
1556/* Returns: int - 0 == match, 1 == no match */
1557/* Parameters: fin(I) - pointer to packet information */
1558/* fr(I) - pointer to filter rule */
1559/* portcmp(I) - flag indicating whether to attempt matching on */
1560/* TCP/UDP port data. */
1561/* */

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

1751/* or can't easily change, the kernel source code to . */
1752/* ------------------------------------------------------------------------ */
1753int fr_scanlist(fin, pass)
1754fr_info_t *fin;
1755u_32_t pass;
1756{
1757 int rulen, portcmp, off, logged, skip;
1758 struct frentry *fr, *fnext;
1655/* ------------------------------------------------------------------------ */
1656/* Function: fr_ipfcheck */
1657/* Returns: int - 0 == match, 1 == no match */
1658/* Parameters: fin(I) - pointer to packet information */
1659/* fr(I) - pointer to filter rule */
1660/* portcmp(I) - flag indicating whether to attempt matching on */
1661/* TCP/UDP port data. */
1662/* */

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

1852/* or can't easily change, the kernel source code to . */
1853/* ------------------------------------------------------------------------ */
1854int fr_scanlist(fin, pass)
1855fr_info_t *fin;
1856u_32_t pass;
1857{
1858 int rulen, portcmp, off, logged, skip;
1859 struct frentry *fr, *fnext;
1759 u_32_t passt;
1860 u_32_t passt, passo;
1760
1761 /*
1762 * Do not allow nesting deeper than 16 levels.
1763 */
1764 if (fin->fin_depth >= 16)
1765 return pass;
1766
1767 fr = fin->fin_fr;

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

1819 if (fr_ipfcheck(fin, fr, portcmp))
1820 continue;
1821 break;
1822#if defined(IPFILTER_BPF)
1823 case FR_T_BPFOPC :
1824 case FR_T_BPFOPC|FR_T_BUILTIN :
1825 {
1826 u_char *mc;
1861
1862 /*
1863 * Do not allow nesting deeper than 16 levels.
1864 */
1865 if (fin->fin_depth >= 16)
1866 return pass;
1867
1868 fr = fin->fin_fr;

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

1920 if (fr_ipfcheck(fin, fr, portcmp))
1921 continue;
1922 break;
1923#if defined(IPFILTER_BPF)
1924 case FR_T_BPFOPC :
1925 case FR_T_BPFOPC|FR_T_BUILTIN :
1926 {
1927 u_char *mc;
1827 int wlen;
1828
1829 if (*fin->fin_mp == NULL)
1830 continue;
1831 if (fin->fin_v != fr->fr_v)
1832 continue;
1833 mc = (u_char *)fin->fin_m;
1928
1929 if (*fin->fin_mp == NULL)
1930 continue;
1931 if (fin->fin_v != fr->fr_v)
1932 continue;
1933 mc = (u_char *)fin->fin_m;
1834 wlen = fin->fin_dlen + fin->fin_hlen;
1835 if (!bpf_filter(fr->fr_data, mc, wlen, 0))
1934 if (!bpf_filter(fr->fr_data, mc, fin->fin_plen, 0))
1836 continue;
1837 break;
1838 }
1839#endif
1840 case FR_T_CALLFUNC|FR_T_BUILTIN :
1841 {
1842 frentry_t *f;
1843

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

1909 }
1910 ATOMIC_INCL(frstats[fin->fin_out].fr_skip);
1911 }
1912 ATOMIC_INCL(frstats[fin->fin_out].fr_pkl);
1913 logged = 1;
1914 }
1915#endif /* IPFILTER_LOG */
1916 fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
1935 continue;
1936 break;
1937 }
1938#endif
1939 case FR_T_CALLFUNC|FR_T_BUILTIN :
1940 {
1941 frentry_t *f;
1942

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

2008 }
2009 ATOMIC_INCL(frstats[fin->fin_out].fr_skip);
2010 }
2011 ATOMIC_INCL(frstats[fin->fin_out].fr_pkl);
2012 logged = 1;
2013 }
2014#endif /* IPFILTER_LOG */
2015 fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
2016 passo = pass;
1917 if (FR_ISSKIP(passt))
1918 skip = fr->fr_arg;
1919 else if ((passt & FR_LOGMASK) != FR_LOG)
1920 pass = passt;
1921 if (passt & (FR_RETICMP|FR_FAKEICMP))
1922 fin->fin_icode = fr->fr_icode;
1923 FR_DEBUG(("pass %#x\n", pass));
1924 ATOMIC_INC64(fr->fr_hits);

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

1931 fin->fin_rule = rulen;
1932 (void) strncpy(fin->fin_group, fr->fr_group,
1933 FR_GROUPLEN);
1934 fin->fin_fr = fr;
1935 }
1936 if (fin->fin_flx & FI_DONTCACHE)
1937 logged = 1;
1938 }
2017 if (FR_ISSKIP(passt))
2018 skip = fr->fr_arg;
2019 else if ((passt & FR_LOGMASK) != FR_LOG)
2020 pass = passt;
2021 if (passt & (FR_RETICMP|FR_FAKEICMP))
2022 fin->fin_icode = fr->fr_icode;
2023 FR_DEBUG(("pass %#x\n", pass));
2024 ATOMIC_INC64(fr->fr_hits);

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

2031 fin->fin_rule = rulen;
2032 (void) strncpy(fin->fin_group, fr->fr_group,
2033 FR_GROUPLEN);
2034 fin->fin_fr = fr;
2035 }
2036 if (fin->fin_flx & FI_DONTCACHE)
2037 logged = 1;
2038 }
1939 if (pass & FR_QUICK)
2039
2040 if (pass & FR_QUICK) {
2041 /*
2042 * Finally, if we've asked to track state for this
2043 * packet, set it up. Add state for "quick" rules
2044 * here so that if the action fails we can consider
2045 * the rule to "not match" and keep on processing
2046 * filter rules.
2047 */
2048 if ((pass & FR_KEEPSTATE) &&
2049 !(fin->fin_flx & FI_STATE)) {
2050 int out = fin->fin_out;
2051
2052 if (fr_addstate(fin, NULL, 0) != NULL) {
2053 ATOMIC_INCL(frstats[out].fr_ads);
2054 } else {
2055 ATOMIC_INCL(frstats[out].fr_bads);
2056 pass = passo;
2057 continue;
2058 }
2059 }
1940 break;
2060 break;
2061 }
1941 }
1942 if (logged)
1943 fin->fin_flx |= FI_DONTCACHE;
1944 fin->fin_depth--;
1945 return pass;
1946}
1947
1948

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

2017 pass = *passp;
2018
2019 /*
2020 * If a packet is found in the auth table, then skip checking
2021 * the access lists for permission but we do need to consider
2022 * the result as if it were from the ACL's.
2023 */
2024 fc = &frcache[out][CACHE_HASH(fin)];
2062 }
2063 if (logged)
2064 fin->fin_flx |= FI_DONTCACHE;
2065 fin->fin_depth--;
2066 return pass;
2067}
2068
2069

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

2138 pass = *passp;
2139
2140 /*
2141 * If a packet is found in the auth table, then skip checking
2142 * the access lists for permission but we do need to consider
2143 * the result as if it were from the ACL's.
2144 */
2145 fc = &frcache[out][CACHE_HASH(fin)];
2146 READ_ENTER(&ipf_frcache);
2025 if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
2026 /*
2147 if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
2148 /*
2027 * copy cached data so we can unlock the mutex
2028 * earlier.
2149 * copy cached data so we can unlock the mutexes earlier.
2029 */
2030 bcopy((char *)fc, (char *)fin, FI_COPYSIZE);
2150 */
2151 bcopy((char *)fc, (char *)fin, FI_COPYSIZE);
2152 RWLOCK_EXIT(&ipf_frcache);
2031 ATOMIC_INCL(frstats[out].fr_chit);
2153 ATOMIC_INCL(frstats[out].fr_chit);
2154
2032 if ((fr = fin->fin_fr) != NULL) {
2033 ATOMIC_INC64(fr->fr_hits);
2034 pass = fr->fr_flags;
2035 }
2036 } else {
2155 if ((fr = fin->fin_fr) != NULL) {
2156 ATOMIC_INC64(fr->fr_hits);
2157 pass = fr->fr_flags;
2158 }
2159 } else {
2160 RWLOCK_EXIT(&ipf_frcache);
2161
2037#ifdef USE_INET6
2038 if (fin->fin_v == 6)
2039 fin->fin_fr = ipfilter6[out][fr_active];
2040 else
2041#endif
2042 fin->fin_fr = ipfilter[out][fr_active];
2043 if (fin->fin_fr != NULL)
2044 pass = fr_scanlist(fin, fr_pass);
2162#ifdef USE_INET6
2163 if (fin->fin_v == 6)
2164 fin->fin_fr = ipfilter6[out][fr_active];
2165 else
2166#endif
2167 fin->fin_fr = ipfilter[out][fr_active];
2168 if (fin->fin_fr != NULL)
2169 pass = fr_scanlist(fin, fr_pass);
2170
2045 if (((pass & FR_KEEPSTATE) == 0) &&
2171 if (((pass & FR_KEEPSTATE) == 0) &&
2046 ((fin->fin_flx & FI_DONTCACHE) == 0))
2172 ((fin->fin_flx & FI_DONTCACHE) == 0)) {
2173 WRITE_ENTER(&ipf_frcache);
2047 bcopy((char *)fin, (char *)fc, FI_COPYSIZE);
2174 bcopy((char *)fin, (char *)fc, FI_COPYSIZE);
2175 RWLOCK_EXIT(&ipf_frcache);
2176 }
2048 if ((pass & FR_NOMATCH)) {
2049 ATOMIC_INCL(frstats[out].fr_nom);
2050 }
2051 fr = fin->fin_fr;
2052 }
2053
2054 /*
2055 * Apply packets per second rate-limiting to a rule as required.

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

2134
2135
2136/* ------------------------------------------------------------------------ */
2137/* Function: fr_check */
2138/* Returns: int - 0 == packet allowed through, */
2139/* User space: */
2140/* -1 == packet blocked */
2141/* 1 == packet not matched */
2177 if ((pass & FR_NOMATCH)) {
2178 ATOMIC_INCL(frstats[out].fr_nom);
2179 }
2180 fr = fin->fin_fr;
2181 }
2182
2183 /*
2184 * Apply packets per second rate-limiting to a rule as required.

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

2263
2264
2265/* ------------------------------------------------------------------------ */
2266/* Function: fr_check */
2267/* Returns: int - 0 == packet allowed through, */
2268/* User space: */
2269/* -1 == packet blocked */
2270/* 1 == packet not matched */
2142/* -2 == requires authantication */
2271/* -2 == requires authentication */
2143/* Kernel: */
2144/* > 0 == filter error # for packet */
2145/* Parameters: ip(I) - pointer to start of IPv4/6 packet */
2146/* hlen(I) - length of header */
2147/* ifp(I) - pointer to interface this packet is on */
2148/* out(I) - 0 == packet going in, 1 == packet going out */
2149/* mp(IO) - pointer to caller's buffer pointer that holds this */
2150/* IP packet. */

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

2184 u_32_t pass = fr_pass;
2185 frentry_t *fr = NULL;
2186 int v = IP_V(ip);
2187 mb_t *mc = NULL;
2188 mb_t *m;
2189#ifdef USE_INET6
2190 ip6_t *ip6;
2191#endif
2272/* Kernel: */
2273/* > 0 == filter error # for packet */
2274/* Parameters: ip(I) - pointer to start of IPv4/6 packet */
2275/* hlen(I) - length of header */
2276/* ifp(I) - pointer to interface this packet is on */
2277/* out(I) - 0 == packet going in, 1 == packet going out */
2278/* mp(IO) - pointer to caller's buffer pointer that holds this */
2279/* IP packet. */

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

2313 u_32_t pass = fr_pass;
2314 frentry_t *fr = NULL;
2315 int v = IP_V(ip);
2316 mb_t *mc = NULL;
2317 mb_t *m;
2318#ifdef USE_INET6
2319 ip6_t *ip6;
2320#endif
2321 SPL_INT(s);
2192
2193 /*
2194 * The first part of fr_check() deals with making sure that what goes
2195 * into the filtering engine makes some sense. Information about the
2196 * the packet is distilled, collected into a fr_info_t structure and
2197 * the an attempt to ensure the buffer the packet is in is big enough
2198 * to hold all the required packet headers.
2199 */

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

2223# else /* MENTAT */
2224
2225 m = *mp;
2226
2227# if defined(M_MCAST)
2228 if ((m->m_flags & M_MCAST) != 0)
2229 fin->fin_flx |= FI_MBCAST|FI_MULTICAST;
2230# endif
2322
2323 /*
2324 * The first part of fr_check() deals with making sure that what goes
2325 * into the filtering engine makes some sense. Information about the
2326 * the packet is distilled, collected into a fr_info_t structure and
2327 * the an attempt to ensure the buffer the packet is in is big enough
2328 * to hold all the required packet headers.
2329 */

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

2353# else /* MENTAT */
2354
2355 m = *mp;
2356
2357# if defined(M_MCAST)
2358 if ((m->m_flags & M_MCAST) != 0)
2359 fin->fin_flx |= FI_MBCAST|FI_MULTICAST;
2360# endif
2361# if defined(M_MLOOP)
2362 if ((m->m_flags & M_MLOOP) != 0)
2363 fin->fin_flx |= FI_MBCAST|FI_MULTICAST;
2364# endif
2231# if defined(M_BCAST)
2232 if ((m->m_flags & M_BCAST) != 0)
2233 fin->fin_flx |= FI_MBCAST|FI_BROADCAST;
2234# endif
2235# ifdef M_CANFASTFWD
2236 /*
2237 * XXX For now, IP Filter and fast-forwarding of cached flows
2238 * XXX are mutually exclusive. Eventually, IP Filter should

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

2259
2260 fin->fin_v = v;
2261 fin->fin_m = m;
2262 fin->fin_ip = ip;
2263 fin->fin_mp = mp;
2264 fin->fin_out = out;
2265 fin->fin_ifp = ifp;
2266 fin->fin_error = ENETUNREACH;
2365# if defined(M_BCAST)
2366 if ((m->m_flags & M_BCAST) != 0)
2367 fin->fin_flx |= FI_MBCAST|FI_BROADCAST;
2368# endif
2369# ifdef M_CANFASTFWD
2370 /*
2371 * XXX For now, IP Filter and fast-forwarding of cached flows
2372 * XXX are mutually exclusive. Eventually, IP Filter should

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

2393
2394 fin->fin_v = v;
2395 fin->fin_m = m;
2396 fin->fin_ip = ip;
2397 fin->fin_mp = mp;
2398 fin->fin_out = out;
2399 fin->fin_ifp = ifp;
2400 fin->fin_error = ENETUNREACH;
2267 fin->fin_hlen = (u_short )hlen;
2401 fin->fin_hlen = (u_short)hlen;
2268 fin->fin_dp = (char *)ip + hlen;
2269
2270 fin->fin_ipoff = (char *)ip - MTOD(m, char *);
2271
2402 fin->fin_dp = (char *)ip + hlen;
2403
2404 fin->fin_ipoff = (char *)ip - MTOD(m, char *);
2405
2406 SPL_NET(s);
2407
2272#ifdef USE_INET6
2273 if (v == 6) {
2274 ATOMIC_INCL(frstats[out].fr_ipv6);
2275 /*
2276 * Jumbo grams are quite likely too big for internal buffer
2277 * structures to handle comfortably, for now, so just drop
2278 * them.
2279 */
2280 ip6 = (ip6_t *)ip;
2281 fin->fin_plen = ntohs(ip6->ip6_plen);
2282 if (fin->fin_plen == 0) {
2283 pass = FR_BLOCK|FR_NOMATCH;
2408#ifdef USE_INET6
2409 if (v == 6) {
2410 ATOMIC_INCL(frstats[out].fr_ipv6);
2411 /*
2412 * Jumbo grams are quite likely too big for internal buffer
2413 * structures to handle comfortably, for now, so just drop
2414 * them.
2415 */
2416 ip6 = (ip6_t *)ip;
2417 fin->fin_plen = ntohs(ip6->ip6_plen);
2418 if (fin->fin_plen == 0) {
2419 pass = FR_BLOCK|FR_NOMATCH;
2284 goto filtered;
2420 goto finished;
2285 }
2286 fin->fin_plen += sizeof(ip6_t);
2287 } else
2288#endif
2289 {
2290#if (defined(OpenBSD) && OpenBSD >= 200311) && defined(_KERNEL)
2291 ip->ip_len = ntohs(ip->ip_len);
2292 ip->ip_off = ntohs(ip->ip_off);
2293#endif
2294 fin->fin_plen = ip->ip_len;
2295 }
2296
2421 }
2422 fin->fin_plen += sizeof(ip6_t);
2423 } else
2424#endif
2425 {
2426#if (defined(OpenBSD) && OpenBSD >= 200311) && defined(_KERNEL)
2427 ip->ip_len = ntohs(ip->ip_len);
2428 ip->ip_off = ntohs(ip->ip_off);
2429#endif
2430 fin->fin_plen = ip->ip_len;
2431 }
2432
2297 if (fr_makefrip(hlen, ip, fin) == -1)
2433 if (fr_makefrip(hlen, ip, fin) == -1) {
2434 pass = FR_BLOCK|FR_NOMATCH;
2298 goto finished;
2435 goto finished;
2436 }
2299
2300 /*
2301 * For at least IPv6 packets, if a m_pullup() fails then this pointer
2302 * becomes NULL and so we have no packet to free.
2303 */
2304 if (*fin->fin_mp == NULL)
2305 goto finished;
2306

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

2384 }
2385
2386#ifdef IPFILTER_LOG
2387 if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) {
2388 (void) fr_dolog(fin, &pass);
2389 }
2390#endif
2391
2437
2438 /*
2439 * For at least IPv6 packets, if a m_pullup() fails then this pointer
2440 * becomes NULL and so we have no packet to free.
2441 */
2442 if (*fin->fin_mp == NULL)
2443 goto finished;
2444

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

2522 }
2523
2524#ifdef IPFILTER_LOG
2525 if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) {
2526 (void) fr_dolog(fin, &pass);
2527 }
2528#endif
2529
2392 if (fin->fin_state != NULL)
2530 if (fin->fin_state != NULL) {
2393 fr_statederef(fin, (ipstate_t **)&fin->fin_state);
2531 fr_statederef(fin, (ipstate_t **)&fin->fin_state);
2532 fin->fin_state = NULL;
2533 }
2394
2534
2395 if (fin->fin_nat != NULL)
2535 if (fin->fin_nat != NULL) {
2396 fr_natderef((nat_t **)&fin->fin_nat);
2536 fr_natderef((nat_t **)&fin->fin_nat);
2537 fin->fin_nat = NULL;
2538 }
2397
2398 /*
2539
2540 /*
2399 * Only allow FR_DUP to work if a rule matched - it makes no sense to
2400 * set FR_DUP as a "default" as there are no instructions about where
2401 * to send the packet. Use fin_m here because it may have changed
2402 * (without an update of 'm') in prior processing.
2541 * Up the reference on fr_lock and exit ipf_mutex. fr_fastroute
2542 * only frees up the lock on ipf_global and the generation of a
2543 * packet below could cause a recursive call into IPFilter.
2544 * Hang onto the filter rule just in case someone decides to remove
2545 * or flush it in the meantime.
2403 */
2546 */
2404 if ((fr != NULL) && (pass & FR_DUP)) {
2405 mc = M_DUPLICATE(fin->fin_m);
2547 if (fr != NULL) {
2548 MUTEX_ENTER(&fr->fr_lock);
2549 fr->fr_ref++;
2550 MUTEX_EXIT(&fr->fr_lock);
2406 }
2407
2551 }
2552
2553 RWLOCK_EXIT(&ipf_mutex);
2554
2408 if (pass & (FR_RETRST|FR_RETICMP)) {
2409 /*
2410 * Should we return an ICMP packet to indicate error
2411 * status passing through the packet filter ?
2412 * WARNING: ICMP error packets AND TCP RST packets should
2413 * ONLY be sent in repsonse to incoming packets. Sending them
2414 * in response to outbound packets can result in a panic on
2415 * some operating systems.

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

2421 if ((pass & FR_RETMASK) == FR_FAKEICMP)
2422 dst = 1;
2423 else
2424 dst = 0;
2425 (void) fr_send_icmp_err(ICMP_UNREACH, fin, dst);
2426 ATOMIC_INCL(frstats[0].fr_ret);
2427 } else if (((pass & FR_RETMASK) == FR_RETRST) &&
2428 !(fin->fin_flx & FI_SHORT)) {
2555 if (pass & (FR_RETRST|FR_RETICMP)) {
2556 /*
2557 * Should we return an ICMP packet to indicate error
2558 * status passing through the packet filter ?
2559 * WARNING: ICMP error packets AND TCP RST packets should
2560 * ONLY be sent in repsonse to incoming packets. Sending them
2561 * in response to outbound packets can result in a panic on
2562 * some operating systems.

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

2568 if ((pass & FR_RETMASK) == FR_FAKEICMP)
2569 dst = 1;
2570 else
2571 dst = 0;
2572 (void) fr_send_icmp_err(ICMP_UNREACH, fin, dst);
2573 ATOMIC_INCL(frstats[0].fr_ret);
2574 } else if (((pass & FR_RETMASK) == FR_RETRST) &&
2575 !(fin->fin_flx & FI_SHORT)) {
2429 if (fr_send_reset(fin) == 0) {
2576 if (((fin->fin_flx & FI_OOW) != 0) ||
2577 (fr_send_reset(fin) == 0)) {
2430 ATOMIC_INCL(frstats[1].fr_ret);
2431 }
2432 }
2433 } else {
2434 if (pass & FR_RETRST)
2435 fin->fin_error = ECONNRESET;
2436 }
2437 }
2438
2439 /*
2440 * If we didn't drop off the bottom of the list of rules (and thus
2441 * the 'current' rule fr is not NULL), then we may have some extra
2442 * instructions about what to do with a packet.
2443 * Once we're finished return to our caller, freeing the packet if
2444 * we are dropping it (* BSD ONLY *).
2578 ATOMIC_INCL(frstats[1].fr_ret);
2579 }
2580 }
2581 } else {
2582 if (pass & FR_RETRST)
2583 fin->fin_error = ECONNRESET;
2584 }
2585 }
2586
2587 /*
2588 * If we didn't drop off the bottom of the list of rules (and thus
2589 * the 'current' rule fr is not NULL), then we may have some extra
2590 * instructions about what to do with a packet.
2591 * Once we're finished return to our caller, freeing the packet if
2592 * we are dropping it (* BSD ONLY *).
2445 * Reassign m from fin_m as we may have a new buffer, now.
2446 */
2593 */
2447#if defined(USE_INET6) || (defined(__sgi) && defined(_KERNEL))
2448filtered:
2449#endif
2450 m = fin->fin_m;
2451
2452 if (fr != NULL) {
2453 frdest_t *fdp;
2454
2455 fdp = &fr->fr_tifs[fin->fin_rev];
2456
2457 if (!out && (pass & FR_FASTROUTE)) {
2458 /*
2459 * For fastroute rule, no destioation interface defined
2460 * so pass NULL as the frdest_t parameter
2461 */
2594 if (fr != NULL) {
2595 frdest_t *fdp;
2596
2597 fdp = &fr->fr_tifs[fin->fin_rev];
2598
2599 if (!out && (pass & FR_FASTROUTE)) {
2600 /*
2601 * For fastroute rule, no destioation interface defined
2602 * so pass NULL as the frdest_t parameter
2603 */
2462 (void) fr_fastroute(m, mp, fin, NULL);
2604 (void) fr_fastroute(fin->fin_m, mp, fin, NULL);
2463 m = *mp = NULL;
2464 } else if ((fdp->fd_ifp != NULL) &&
2465 (fdp->fd_ifp != (struct ifnet *)-1)) {
2466 /* this is for to rules: */
2605 m = *mp = NULL;
2606 } else if ((fdp->fd_ifp != NULL) &&
2607 (fdp->fd_ifp != (struct ifnet *)-1)) {
2608 /* this is for to rules: */
2467 (void) fr_fastroute(m, mp, fin, fdp);
2609 (void) fr_fastroute(fin->fin_m, mp, fin, fdp);
2468 m = *mp = NULL;
2469 }
2470
2471 /*
2472 * Generate a duplicated packet.
2473 */
2610 m = *mp = NULL;
2611 }
2612
2613 /*
2614 * Generate a duplicated packet.
2615 */
2474 if (mc != NULL)
2475 (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif);
2616 if ((pass & FR_DUP) != 0) {
2617 mc = M_DUPLICATE(fin->fin_m);
2618 if (mc != NULL)
2619 (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif);
2620 }
2621
2622 (void) fr_derefrule(&fr);
2476 }
2477
2623 }
2624
2478 /*
2479 * This late because the likes of fr_fastroute() use fin_fr.
2480 */
2481 RWLOCK_EXIT(&ipf_mutex);
2482
2483finished:
2484 if (!FR_ISPASS(pass)) {
2485 ATOMIC_INCL(frstats[out].fr_block);
2486 if (*mp != NULL) {
2487 FREE_MB_T(*mp);
2488 m = *mp = NULL;
2489 }
2490 } else {
2491 ATOMIC_INCL(frstats[out].fr_pass);
2492#if defined(_KERNEL) && defined(__sgi)
2493 if ((fin->fin_hbuf != NULL) &&
2494 (mtod(fin->fin_m, struct ip *) != fin->fin_ip)) {
2625finished:
2626 if (!FR_ISPASS(pass)) {
2627 ATOMIC_INCL(frstats[out].fr_block);
2628 if (*mp != NULL) {
2629 FREE_MB_T(*mp);
2630 m = *mp = NULL;
2631 }
2632 } else {
2633 ATOMIC_INCL(frstats[out].fr_pass);
2634#if defined(_KERNEL) && defined(__sgi)
2635 if ((fin->fin_hbuf != NULL) &&
2636 (mtod(fin->fin_m, struct ip *) != fin->fin_ip)) {
2495 COPYBACK(m, 0, fin->fin_plen, fin->fin_hbuf);
2637 COPYBACK(fin->fin_m, 0, fin->fin_plen, fin->fin_hbuf);
2496 }
2497#endif
2498 }
2499
2638 }
2639#endif
2640 }
2641
2642 SPL_X(s);
2500 RWLOCK_EXIT(&ipf_global);
2643 RWLOCK_EXIT(&ipf_global);
2644
2501#ifdef _KERNEL
2502# if defined(OpenBSD) && OpenBSD >= 200311
2503 if (FR_ISPASS(pass) && (v == 4)) {
2504 ip = fin->fin_ip;
2505 ip->ip_len = ntohs(ip->ip_len);
2506 ip->ip_off = ntohs(ip->ip_off);
2507 }
2508# endif

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

2885#endif /* _KERNEL */
2886 if (csump != NULL)
2887 *csump = sumsave;
2888 return sum2;
2889}
2890
2891
2892#if defined(_KERNEL) && ( ((BSD < 199103) && !defined(MENTAT)) || \
2645#ifdef _KERNEL
2646# if defined(OpenBSD) && OpenBSD >= 200311
2647 if (FR_ISPASS(pass) && (v == 4)) {
2648 ip = fin->fin_ip;
2649 ip->ip_len = ntohs(ip->ip_len);
2650 ip->ip_off = ntohs(ip->ip_off);
2651 }
2652# endif

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

3029#endif /* _KERNEL */
3030 if (csump != NULL)
3031 *csump = sumsave;
3032 return sum2;
3033}
3034
3035
3036#if defined(_KERNEL) && ( ((BSD < 199103) && !defined(MENTAT)) || \
2893 defined(__sgi) ) && !defined(linux)
3037 defined(__sgi) ) && !defined(linux) && !defined(_AIX51)
2894/*
2895 * Copyright (c) 1982, 1986, 1988, 1991, 1993
2896 * The Regents of the University of California. All rights reserved.
2897 *
2898 * Redistribution and use in source and binary forms, with or without
2899 * modification, are permitted provided that the following conditions
2900 * are met:
2901 * 1. Redistributions of source code must retain the above copyright

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

2915 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2916 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2917 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2918 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2919 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2920 * SUCH DAMAGE.
2921 *
2922 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
3038/*
3039 * Copyright (c) 1982, 1986, 1988, 1991, 1993
3040 * The Regents of the University of California. All rights reserved.
3041 *
3042 * Redistribution and use in source and binary forms, with or without
3043 * modification, are permitted provided that the following conditions
3044 * are met:
3045 * 1. Redistributions of source code must retain the above copyright

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

3059 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3060 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3061 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3062 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3063 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3064 * SUCH DAMAGE.
3065 *
3066 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
2923 * Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp
3067 * $Id: fil.c,v 2.243.2.70 2005/12/07 08:15:16 darrenr Exp $
2924 */
2925/*
2926 * Copy data from an mbuf chain starting "off" bytes from the beginning,
2927 * continuing for "len" bytes, into the indicated buffer.
2928 */
2929void
2930m_copydata(m, off, len, cp)
2931 mb_t *m;

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

2984 if (n == 0)
2985 goto out;
2986 n->m_len = min(MLEN, len + off);
2987 m->m_next = n;
2988 }
2989 m = m->m_next;
2990 }
2991 while (len > 0) {
3068 */
3069/*
3070 * Copy data from an mbuf chain starting "off" bytes from the beginning,
3071 * continuing for "len" bytes, into the indicated buffer.
3072 */
3073void
3074m_copydata(m, off, len, cp)
3075 mb_t *m;

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

3128 if (n == 0)
3129 goto out;
3130 n->m_len = min(MLEN, len + off);
3131 m->m_next = n;
3132 }
3133 m = m->m_next;
3134 }
3135 while (len > 0) {
2992 mlen = min (m->m_len - off, len);
3136 mlen = min(m->m_len - off, len);
2993 bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
2994 cp += mlen;
2995 len -= mlen;
2996 mlen += off;
2997 off = 0;
2998 totlen += mlen;
2999 if (len == 0)
3000 break;

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

3033char *group;
3034minor_t unit;
3035int set;
3036frgroup_t ***fgpp;
3037{
3038 frgroup_t *fg, **fgp;
3039
3040 /*
3137 bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
3138 cp += mlen;
3139 len -= mlen;
3140 mlen += off;
3141 off = 0;
3142 totlen += mlen;
3143 if (len == 0)
3144 break;

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

3177char *group;
3178minor_t unit;
3179int set;
3180frgroup_t ***fgpp;
3181{
3182 frgroup_t *fg, **fgp;
3183
3184 /*
3041 * Which list of groups to search in is dependant on which list of
3185 * Which list of groups to search in is dependent on which list of
3042 * rules are being operated on.
3043 */
3044 fgp = &ipfgroups[unit][set];
3045
3046 while ((fg = *fgp) != NULL) {
3047 if (strncmp(group, fg->fg_name, FR_GROUPLEN) == 0)
3048 break;
3049 else

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

3326/* dst(I) - pointer to byte sequence to search */
3327/* slen(I) - match length */
3328/* dlen(I) - length available to search in */
3329/* */
3330/* Search dst for a sequence of bytes matching those at src and extend for */
3331/* slen bytes. */
3332/* ------------------------------------------------------------------------ */
3333char *memstr(src, dst, slen, dlen)
3186 * rules are being operated on.
3187 */
3188 fgp = &ipfgroups[unit][set];
3189
3190 while ((fg = *fgp) != NULL) {
3191 if (strncmp(group, fg->fg_name, FR_GROUPLEN) == 0)
3192 break;
3193 else

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

3470/* dst(I) - pointer to byte sequence to search */
3471/* slen(I) - match length */
3472/* dlen(I) - length available to search in */
3473/* */
3474/* Search dst for a sequence of bytes matching those at src and extend for */
3475/* slen bytes. */
3476/* ------------------------------------------------------------------------ */
3477char *memstr(src, dst, slen, dlen)
3334char *src, *dst;
3478const char *src;
3479char *dst;
3335int slen, dlen;
3336{
3337 char *s = NULL;
3338
3339 while (dlen >= slen) {
3340 if (bcmp(src, dst, slen) == 0) {
3341 s = dst;
3342 break;

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

4100#ifdef IPFILTER_LOOKUP
4101 case FRI_LOOKUP :
4102 fp->fr_dstptr = fr_resolvelookup(fp->fr_dsttype,
4103 fp->fr_dstnum,
4104 &fp->fr_dstfunc);
4105 break;
4106#endif
4107 default :
3480int slen, dlen;
3481{
3482 char *s = NULL;
3483
3484 while (dlen >= slen) {
3485 if (bcmp(src, dst, slen) == 0) {
3486 s = dst;
3487 break;

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

4245#ifdef IPFILTER_LOOKUP
4246 case FRI_LOOKUP :
4247 fp->fr_dstptr = fr_resolvelookup(fp->fr_dsttype,
4248 fp->fr_dstnum,
4249 &fp->fr_dstfunc);
4250 break;
4251#endif
4252 default :
4108
4109 break;
4110 }
4111 break;
4112 case FR_T_NONE :
4113 break;
4114 case FR_T_CALLFUNC :
4115 break;
4116 case FR_T_COMPIPF :

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

4295 error = fr_preauthcmd(req, fp, ftail);
4296 goto done;
4297 }
4298 if (makecopy) {
4299 KMALLOC(f, frentry_t *);
4300 } else
4301 f = fp;
4302 if (f != NULL) {
4253 break;
4254 }
4255 break;
4256 case FR_T_NONE :
4257 break;
4258 case FR_T_CALLFUNC :
4259 break;
4260 case FR_T_COMPIPF :

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

4439 error = fr_preauthcmd(req, fp, ftail);
4440 goto done;
4441 }
4442 if (makecopy) {
4443 KMALLOC(f, frentry_t *);
4444 } else
4445 f = fp;
4446 if (f != NULL) {
4303 if (fg != NULL && fg->fg_head!= NULL )
4447 if (fg != NULL && fg->fg_head != NULL)
4304 fg->fg_head->fr_ref++;
4305 if (fp != f)
4306 bcopy((char *)fp, (char *)f,
4307 sizeof(*f));
4308 MUTEX_NUKE(&f->fr_lock);
4309 MUTEX_INIT(&f->fr_lock, "filter rule lock");
4310#ifdef IPFILTER_SCAN
4311 if (f->fr_isctag[0] != '\0' &&

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

4962/* */
4963/* When we are doing NAT, change the IP of every packet to represent a */
4964/* single sequence of packets coming from the host, hiding any host */
4965/* specific sequencing that might otherwise be revealed. If the packet is */
4966/* a fragment, then store the 'new' IPid in the fragment cache and look up */
4967/* the fragment cache for non-leading fragments. If a non-leading fragment */
4968/* has no match in the cache, return an error. */
4969/* ------------------------------------------------------------------------ */
4448 fg->fg_head->fr_ref++;
4449 if (fp != f)
4450 bcopy((char *)fp, (char *)f,
4451 sizeof(*f));
4452 MUTEX_NUKE(&f->fr_lock);
4453 MUTEX_INIT(&f->fr_lock, "filter rule lock");
4454#ifdef IPFILTER_SCAN
4455 if (f->fr_isctag[0] != '\0' &&

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

5106/* */
5107/* When we are doing NAT, change the IP of every packet to represent a */
5108/* single sequence of packets coming from the host, hiding any host */
5109/* specific sequencing that might otherwise be revealed. If the packet is */
5110/* a fragment, then store the 'new' IPid in the fragment cache and look up */
5111/* the fragment cache for non-leading fragments. If a non-leading fragment */
5112/* has no match in the cache, return an error. */
5113/* ------------------------------------------------------------------------ */
4970static INLINE int fr_updateipid(fin)
5114static int fr_updateipid(fin)
4971fr_info_t *fin;
4972{
4973 u_short id, ido, sums;
4974 u_32_t sumd, sum;
4975 ip_t *ip;
4976
4977 if (fin->fin_off != 0) {
4978 sum = fr_ipid_knownfrag(fin);

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

5014/* as a NULL pointer then return a pointer to a static array. */
5015/* ------------------------------------------------------------------------ */
5016char *fr_getifname(ifp, buffer)
5017struct ifnet *ifp;
5018char *buffer;
5019{
5020 static char namebuf[LIFNAMSIZ];
5021# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \
5115fr_info_t *fin;
5116{
5117 u_short id, ido, sums;
5118 u_32_t sumd, sum;
5119 ip_t *ip;
5120
5121 if (fin->fin_off != 0) {
5122 sum = fr_ipid_knownfrag(fin);

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

5158/* as a NULL pointer then return a pointer to a static array. */
5159/* ------------------------------------------------------------------------ */
5160char *fr_getifname(ifp, buffer)
5161struct ifnet *ifp;
5162char *buffer;
5163{
5164 static char namebuf[LIFNAMSIZ];
5165# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \
5022 defined(__sgi) || defined(linux) || \
5166 defined(__sgi) || defined(linux) || defined(_AIX51) || \
5023 (defined(sun) && !defined(__SVR4) && !defined(__svr4__))
5024 int unit, space;
5025 char temp[20];
5026 char *s;
5027# endif
5028
5029 if (buffer == NULL)
5030 buffer = namebuf;
5031 (void) strncpy(buffer, ifp->if_name, LIFNAMSIZ);
5032 buffer[LIFNAMSIZ - 1] = '\0';
5033# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \
5167 (defined(sun) && !defined(__SVR4) && !defined(__svr4__))
5168 int unit, space;
5169 char temp[20];
5170 char *s;
5171# endif
5172
5173 if (buffer == NULL)
5174 buffer = namebuf;
5175 (void) strncpy(buffer, ifp->if_name, LIFNAMSIZ);
5176 buffer[LIFNAMSIZ - 1] = '\0';
5177# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \
5034 defined(__sgi) || \
5178 defined(__sgi) || defined(_AIX51) || \
5035 (defined(sun) && !defined(__SVR4) && !defined(__svr4__))
5036 for (s = buffer; *s; s++)
5037 ;
5038 unit = ifp->if_unit;
5039 space = LIFNAMSIZ - (s - buffer);
5040 if (space > 0) {
5041# if defined(SNPRINTF) && defined(_KERNEL)
5042 SNPRINTF(temp, sizeof(temp), "%d", unit);

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

5639 { { &fr_active }, "fr_active", 0, 0,
5640 sizeof(fr_active), IPFT_RDONLY },
5641 { { &fr_control_forwarding }, "fr_control_forwarding", 0, 1,
5642 sizeof(fr_control_forwarding), 0 },
5643 { { &fr_update_ipid }, "fr_update_ipid", 0, 1,
5644 sizeof(fr_update_ipid), 0 },
5645 { { &fr_chksrc }, "fr_chksrc", 0, 1,
5646 sizeof(fr_chksrc), 0 },
5179 (defined(sun) && !defined(__SVR4) && !defined(__svr4__))
5180 for (s = buffer; *s; s++)
5181 ;
5182 unit = ifp->if_unit;
5183 space = LIFNAMSIZ - (s - buffer);
5184 if (space > 0) {
5185# if defined(SNPRINTF) && defined(_KERNEL)
5186 SNPRINTF(temp, sizeof(temp), "%d", unit);

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

5783 { { &fr_active }, "fr_active", 0, 0,
5784 sizeof(fr_active), IPFT_RDONLY },
5785 { { &fr_control_forwarding }, "fr_control_forwarding", 0, 1,
5786 sizeof(fr_control_forwarding), 0 },
5787 { { &fr_update_ipid }, "fr_update_ipid", 0, 1,
5788 sizeof(fr_update_ipid), 0 },
5789 { { &fr_chksrc }, "fr_chksrc", 0, 1,
5790 sizeof(fr_chksrc), 0 },
5791 { { &fr_minttl }, "fr_minttl", 0, 1,
5792 sizeof(fr_minttl), 0 },
5793 { { &fr_icmpminfragmtu }, "fr_icmpminfragmtu", 0, 1,
5794 sizeof(fr_icmpminfragmtu), 0 },
5647 { { &fr_pass }, "fr_pass", 0, 0xffffffff,
5648 sizeof(fr_pass), 0 },
5649 /* state */
5650 { { &fr_tcpidletimeout }, "fr_tcpidletimeout", 1, 0x7fffffff,
5651 sizeof(fr_tcpidletimeout), IPFT_WRDISABLED },
5652 { { &fr_tcpclosewait }, "fr_tcpclosewait", 1, 0x7fffffff,
5653 sizeof(fr_tcpclosewait), IPFT_WRDISABLED },
5654 { { &fr_tcplastack }, "fr_tcplastack", 1, 0x7fffffff,

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

5784/* Returns: NULL = search failed, else pointer to tune struct */
5785/* Parameters: name(I) - name of the tuneable entry to find. */
5786/* */
5787/* Search the static array of tuneables and the list of dynamic tuneables */
5788/* for an entry with a matching name. If we can find one, return a pointer */
5789/* to the matching structure. */
5790/* ------------------------------------------------------------------------ */
5791static ipftuneable_t *fr_findtunebyname(name)
5795 { { &fr_pass }, "fr_pass", 0, 0xffffffff,
5796 sizeof(fr_pass), 0 },
5797 /* state */
5798 { { &fr_tcpidletimeout }, "fr_tcpidletimeout", 1, 0x7fffffff,
5799 sizeof(fr_tcpidletimeout), IPFT_WRDISABLED },
5800 { { &fr_tcpclosewait }, "fr_tcpclosewait", 1, 0x7fffffff,
5801 sizeof(fr_tcpclosewait), IPFT_WRDISABLED },
5802 { { &fr_tcplastack }, "fr_tcplastack", 1, 0x7fffffff,

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

5932/* Returns: NULL = search failed, else pointer to tune struct */
5933/* Parameters: name(I) - name of the tuneable entry to find. */
5934/* */
5935/* Search the static array of tuneables and the list of dynamic tuneables */
5936/* for an entry with a matching name. If we can find one, return a pointer */
5937/* to the matching structure. */
5938/* ------------------------------------------------------------------------ */
5939static ipftuneable_t *fr_findtunebyname(name)
5792char *name;
5940const char *name;
5793{
5794 ipftuneable_t *ta;
5795
5796 for (ta = ipf_tuneables; ta->ipft_name != NULL; ta++)
5797 if (!strcmp(ta->ipft_name, name)) {
5798 return ta;
5799 }
5800

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

6176 if (ifp == NULL)
6177 ifp = (void *)-1;
6178 }
6179 fdp->fd_ifp = ifp;
6180}
6181
6182
6183/* ------------------------------------------------------------------------ */
5941{
5942 ipftuneable_t *ta;
5943
5944 for (ta = ipf_tuneables; ta->ipft_name != NULL; ta++)
5945 if (!strcmp(ta->ipft_name, name)) {
5946 return ta;
5947 }
5948

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

6324 if (ifp == NULL)
6325 ifp = (void *)-1;
6326 }
6327 fdp->fd_ifp = ifp;
6328}
6329
6330
6331/* ------------------------------------------------------------------------ */
6184/* Function: fr_icmp4errortype */
6185/* Returns: int - 1 == success, 0 == failure */
6186/* Parameters: icmptype(I) - ICMP type number */
6187/* */
6188/* Tests to see if the ICMP type number passed is an error type or not. */
6189/* ------------------------------------------------------------------------ */
6190int fr_icmp4errortype(icmptype)
6191int icmptype;
6192{
6193
6194 switch (icmptype)
6195 {
6196 case ICMP_SOURCEQUENCH :
6197 case ICMP_PARAMPROB :
6198 case ICMP_REDIRECT :
6199 case ICMP_TIMXCEED :
6200 case ICMP_UNREACH :
6201 return 1;
6202 default:
6203 return 0;
6204 }
6205}
6206
6207
6208/* ------------------------------------------------------------------------ */
6209/* Function: fr_resolvenic */
6210/* Returns: void* - NULL = wildcard name, -1 = failed to find NIC, else */
6211/* pointer to interface structure for NIC */
6212/* Parameters: name(I) - complete interface name */
6213/* v(I) - IP protocol version */
6214/* */
6215/* Look for a network interface structure that firstly has a matching name */
6216/* to that passed in and that is also being used for that IP protocol */

--- 33 unchanged lines hidden ---
6332/* Function: fr_resolvenic */
6333/* Returns: void* - NULL = wildcard name, -1 = failed to find NIC, else */
6334/* pointer to interface structure for NIC */
6335/* Parameters: name(I) - complete interface name */
6336/* v(I) - IP protocol version */
6337/* */
6338/* Look for a network interface structure that firstly has a matching name */
6339/* to that passed in and that is also being used for that IP protocol */

--- 33 unchanged lines hidden ---