3 * Copyright (C) 2003 by Darren Reed.
5 * See the IPFILTER.LICENCE file for details on licencing.
7 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
8 * Use is subject to license terms.
12 #include <sys/ioctl.h>
15 # include "pcap-bpf.h"
19 #include "netinet/ip_pool.h"
20 #include "netinet/ip_htable.h"
21 #include "netinet/ipl.h"
25 #define DOALL(x) for (fr = frc; fr != NULL; fr = fr->fr_next) { x }
26 #define DOREM(x) for (; fr != NULL; fr = fr->fr_next) { x }
28 #define OPTION_LOG 0x1
29 #define OPTION_QUICK 0x2
30 #define OPTION_DUP 0x4
31 #define OPTION_PROUTE 0x8
32 #define OPTION_ON 0x10
33 #define OPTION_REPLYTO 0x20
34 #define OPTION_FROUTE 0x40
36 extern
void yyerror __P
((char *));
37 extern
int yyparse __P
((void));
38 extern
int yylex __P
((void));
43 static void newrule __P
((void));
44 static void setipftype __P
((void));
45 static u_32_t lookuphost __P
((char *, i6addr_t
*));
46 static void dobpf __P
((int, char *));
47 static void resetaddr __P
((void));
48 static struct alist_s
*newalist __P
((struct alist_s
*));
49 static u_int makehash __P
((struct alist_s
*));
50 static int makepool __P
((struct alist_s
*));
51 static frentry_t
*addrule __P
((void));
52 static void setsyslog __P
((void));
53 static void unsetsyslog __P
((void));
54 static void fillgroup __P
((frentry_t
*));
56 frentry_t
*fr
= NULL
, *frc
= NULL
, *frtop
= NULL
, *frold
= NULL
;
58 static int ifpflag
= 0;
59 static int nowith
= 0;
60 static int dynamic
= -1;
61 static int pooled
= 0;
62 static int hashed
= 0;
63 static int nrules
= 0;
64 static int newlist
= 0;
66 static int ipffd
= -1;
67 static int ruleopts
= 0;
68 static int *yycont
= 0;
69 static ioctlfunc_t ipfioctl
[IPL_LOGSIZE
];
70 static addfunc_t ipfaddfunc
= NULL
;
71 static struct wordtab ipfwords
[96];
72 static struct wordtab addrwords
[4];
73 static struct wordtab maskwords
[5];
74 static struct wordtab icmpcodewords
[17];
75 static struct wordtab icmptypewords
[16];
76 static struct wordtab ipv4optwords
[25];
77 static struct wordtab ipv4secwords
[9];
78 static struct wordtab ipv6optwords
[8];
79 static struct wordtab logwords
[33];
80 static int set_ipv6_addr
= 0;
89 struct alist_s
*alist
;
104 %type
<num
> facility priority icmpcode seclevel secname icmptype
105 %type
<num
> opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr
106 %type
<num
> portc porteq
107 %type
<ipa
> ipv4 ipv4_16 ipv4_24
108 %type
<ip6
> hostname mask
109 %type
<ipp
> addr ipaddr
110 %type
<str
> servicename name interfacename
111 %type
<pc
> portrange portcomp
112 %type
<alist
> addrlist poollist
114 %token
<num
> YY_NUMBER YY_HEX
117 %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
118 %token YY_RANGE_OUT YY_RANGE_IN
121 %token IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL
122 %token IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST
123 %token IPFY_IN IPFY_OUT
124 %token IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA
125 %token IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO
126 %token IPFY_TOS IPFY_TTL IPFY_PROTO
127 %token IPFY_HEAD IPFY_GROUP
128 %token IPFY_AUTH IPFY_PREAUTH
129 %token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK
130 %token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP
131 %token IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH
133 %token IPFY_ESP IPFY_AH
134 %token IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT
135 %token IPFY_TCPUDP IPFY_TCP IPFY_UDP
136 %token IPFY_FLAGS IPFY_MULTICAST
137 %token IPFY_MASK IPFY_BROADCAST IPFY_NETWORK IPFY_NETMASKED IPFY_PEER
140 %token IPFY_ICMP IPFY_ICMPTYPE IPFY_ICMPCODE
141 %token IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG
142 %token IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR
143 %token IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE
144 %token IPFY_SYNC IPFY_FRAGBODY
145 %token IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP
146 %token IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR
147 %token IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO
148 %token IPFY_IPOPT_SATID IPFY_IPOPT_SSRR IPFY_IPOPT_ADDEXT IPFY_IPOPT_VISA
149 %token IPFY_IPOPT_IMITD IPFY_IPOPT_EIP IPFY_IPOPT_FINN IPFY_IPOPT_DPS
150 %token IPFY_IPOPT_SDB IPFY_IPOPT_NSAPA IPFY_IPOPT_RTRALRT IPFY_IPOPT_UMP
151 %token IPFY_SECCLASS IPFY_SEC_UNC IPFY_SEC_CONF IPFY_SEC_RSV1 IPFY_SEC_RSV2
152 %token IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3
154 %token IPF6_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS
155 %token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING
157 %token IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH
158 %token IPFY_ICMPT_REDIR IPFY_ICMPT_TIMEX IPFY_ICMPT_PARAMP IPFY_ICMPT_TIMEST
159 %token IPFY_ICMPT_TIMESTREP IPFY_ICMPT_INFOREQ IPFY_ICMPT_INFOREP
160 %token IPFY_ICMPT_MASKREQ IPFY_ICMPT_MASKREP IPFY_ICMPT_ROUTERAD
161 %token IPFY_ICMPT_ROUTERSOL
163 %token IPFY_ICMPC_NETUNR IPFY_ICMPC_HSTUNR IPFY_ICMPC_PROUNR IPFY_ICMPC_PORUNR
164 %token IPFY_ICMPC_NEEDF IPFY_ICMPC_SRCFAIL IPFY_ICMPC_NETUNK IPFY_ICMPC_HSTUNK
165 %token IPFY_ICMPC_ISOLATE IPFY_ICMPC_NETPRO IPFY_ICMPC_HSTPRO
166 %token IPFY_ICMPC_NETTOS IPFY_ICMPC_HSTTOS IPFY_ICMPC_FLTPRO IPFY_ICMPC_HSTPRE
167 %token IPFY_ICMPC_CUTPRE
169 %token IPFY_FAC_KERN IPFY_FAC_USER IPFY_FAC_MAIL IPFY_FAC_DAEMON IPFY_FAC_AUTH
170 %token IPFY_FAC_SYSLOG IPFY_FAC_LPR IPFY_FAC_NEWS IPFY_FAC_UUCP IPFY_FAC_CRON
171 %token IPFY_FAC_LOCAL0 IPFY_FAC_LOCAL1 IPFY_FAC_LOCAL2 IPFY_FAC_LOCAL3
172 %token IPFY_FAC_LOCAL4 IPFY_FAC_LOCAL5 IPFY_FAC_LOCAL6 IPFY_FAC_LOCAL7
173 %token IPFY_FAC_SECURITY IPFY_FAC_FTP IPFY_FAC_AUTHPRIV IPFY_FAC_AUDIT
174 %token IPFY_FAC_LFMT IPFY_FAC_CONSOLE
176 %token IPFY_PRI_EMERG IPFY_PRI_ALERT IPFY_PRI_CRIT IPFY_PRI_ERR IPFY_PRI_WARN
177 %token IPFY_PRI_NOTICE IPFY_PRI_INFO IPFY_PRI_DEBUG
178 %token IPFY_SET_LOOPBACK IPFY_SET
186 line: xx rule
{ while
((fr
= frtop
) != NULL
) {
189 (*ipfaddfunc
)(ipffd
, ipfioctl
[IPL_LOGIPF
], fr
);
202 assign: YY_STR assigning YY_STR
';' { set_variable
($1, $3);
211 '=' { yyvarnext
= 1; }
215 IPFY_SET IPFY_SET_LOOPBACK YY_STR
';'
219 yyerror("ipf rules before \"set\"");
222 if
(!strcmp
($3, "true"))
224 else if
(!strcmp
($3, "false"))
227 yyerror("invalid argument for ipf_loopback");
230 if
(((opts
& OPT_DONOTHING
) == 0) &&
231 (ioctl
(ipffd
, SIOCIPFLP
, &data
) == -1))
232 perror
("ioctl(SIOCIPFLP)");
244 rulehead markin
{ ruleopts
= 0; } inopts rulemain ruletail intag ruletail2
248 rulehead markout
{ ruleopts
= 0; } outopts rulemain ruletail outtag ruletail2
253 | insert collection action
256 markin: IPFY_IN
{ fr
->fr_flags |
= FR_INQUE
; }
260 IPFY_OUT
{ fr
->fr_flags |
= FR_OUTQUE
; }
273 IPFY_BPFV4
'{' YY_STR
'}' { dobpf
(4, $3); free
($3); }
274 | IPFY_BPFV6
'{' YY_STR
'}' { dobpf
(6, $3); free
($3); }
285 intag: settagin matchtagin
288 outtag: settagout matchtagout
292 '@' YY_NUMBER
{ fr
->fr_hits
= (U_QUAD_T
)$2 + 1; }
296 | YY_NUMBER
{ fr
->fr_collect
= $1; }
300 | IPFY_PASS
{ fr
->fr_flags |
= FR_PASS
; }
302 | IPFY_COUNT
{ fr
->fr_flags |
= FR_ACCOUNT
; }
304 | IPFY_SKIP YY_NUMBER
{ fr
->fr_flags |
= FR_SKIP
;
307 | IPFY_CALL IPFY_NOW func
{ fr
->fr_flags |
= FR_CALLNOW
; }
311 | blocked blockreturn
315 IPFY_BLOCK
{ fr
->fr_flags
= FR_BLOCK
; }
318 IPFY_RETICMP
{ fr
->fr_flags |
= FR_RETICMP
; }
319 | IPFY_RETICMP returncode
{ fr
->fr_flags |
= FR_RETICMP
; }
320 | IPFY_RETICMPASDST
{ fr
->fr_flags |
= FR_FAKEICMP
; }
321 | IPFY_RETICMPASDST returncode
{ fr
->fr_flags |
= FR_FAKEICMP
; }
322 | IPFY_RETRST
{ fr
->fr_flags |
= FR_RETRST
; }
325 log: IPFY_LOG
{ fr
->fr_flags |
= FR_LOG
; }
326 | IPFY_LOG logoptions
{ fr
->fr_flags |
= FR_LOG
; }
329 auth: IPFY_AUTH
{ fr
->fr_flags |
= FR_AUTH
; }
330 | IPFY_AUTH IPFY_RETRST
{ fr
->fr_flags |
= (FR_AUTH|FR_RETRST
);}
331 | IPFY_PREAUTH
{ fr
->fr_flags |
= FR_PREAUTH
; }
334 func: YY_STR
'/' YY_NUMBER
{ fr
->fr_func
= nametokva
($1,
335 ipfioctl
[IPL_LOGIPF
]);
347 if
( ruleopts
& OPTION_LOG
)
348 yyerror("Duplicate log option");
349 ruleopts |
= OPTION_LOG
;
353 if
( ruleopts
& OPTION_QUICK
)
354 yyerror("Duplicate quick option");
355 ruleopts |
= OPTION_QUICK
;
359 if
( ruleopts
& OPTION_ON
)
360 yyerror("Duplicate on option");
361 ruleopts |
= OPTION_ON
;
365 if
( ruleopts
& OPTION_DUP
)
366 yyerror("Duplicate dup option");
367 ruleopts |
= OPTION_DUP
;
371 if
( ruleopts
& OPTION_FROUTE
)
372 yyerror("Duplicate froute option");
373 ruleopts |
= OPTION_FROUTE
;
377 if
( ruleopts
& OPTION_PROUTE
)
378 yyerror("Duplicate proute option");
379 ruleopts |
= OPTION_PROUTE
;
383 if
( ruleopts
& OPTION_REPLYTO
)
384 yyerror("Duplicate replyto option");
385 ruleopts |
= OPTION_REPLYTO
;
396 if
( ruleopts
& OPTION_LOG
)
397 yyerror("Duplicate log option");
398 ruleopts |
= OPTION_LOG
;
402 if
( ruleopts
& OPTION_QUICK
)
403 yyerror("Duplicate quick option");
404 ruleopts |
= OPTION_QUICK
;
408 if
( ruleopts
& OPTION_ON
)
409 yyerror("Duplicate on option");
410 ruleopts |
= OPTION_ON
;
414 if
( ruleopts
& OPTION_DUP
)
415 yyerror("Duplicate dup option");
416 ruleopts |
= OPTION_DUP
;
420 if
( ruleopts
& OPTION_PROUTE
)
421 yyerror("Duplicate proute option");
422 ruleopts |
= OPTION_PROUTE
;
426 if
( ruleopts
& OPTION_REPLYTO
)
427 yyerror("Duplicate replyto option");
428 ruleopts |
= OPTION_REPLYTO
;
432 tos: | settos YY_NUMBER
{ DOALL
(fr
->fr_tos
= $2; fr
->fr_mtos
= 0xff;) }
433 | settos YY_HEX
{ DOALL
(fr
->fr_tos
= $2; fr
->fr_mtos
= 0xff;) }
434 | settos lstart toslist lend
437 settos: IPFY_TOS
{ setipftype
(); }
441 YY_NUMBER
{ DOALL
(fr
->fr_tos
= $1; fr
->fr_mtos
= 0xff;) }
442 | YY_HEX
{ DOREM
(fr
->fr_tos
= $1; fr
->fr_mtos
= 0xff;) }
443 | toslist lmore YY_NUMBER
444 { DOREM
(fr
->fr_tos
= $3; fr
->fr_mtos
= 0xff;) }
445 | toslist lmore YY_HEX
446 { DOREM
(fr
->fr_tos
= $3; fr
->fr_mtos
= 0xff;) }
449 ttl: | setttl YY_NUMBER
450 { DOALL
(fr
->fr_ttl
= $2; fr
->fr_mttl
= 0xff;) }
451 | setttl lstart ttllist lend
454 lstart: '(' { newlist
= 1; fr
= frc
; added
= 0; }
457 lend: ')' { nrules
+= added
; }
460 lmore: lanother
{ if
(newlist
== 1) {
473 setttl: IPFY_TTL
{ setipftype
(); }
477 YY_NUMBER
{ DOREM
(fr
->fr_ttl
= $1; fr
->fr_mttl
= 0xff;) }
478 | ttllist lmore YY_NUMBER
479 { DOREM
(fr
->fr_ttl
= $3; fr
->fr_mttl
= 0xff;) }
482 proto: | protox protocol
{ yyresetdict
(); }
485 protox: IPFY_PROTO
{ setipftype
();
490 ip: srcdst flags icmp
493 group: | IPFY_GROUP YY_STR
{ DOALL
(strncpy
(fr
->fr_group
, $2, \
497 | IPFY_GROUP YY_NUMBER
{ DOALL
(sprintf
(fr
->fr_group
, "%d", \
502 head: | IPFY_HEAD YY_STR
{ DOALL
(strncpy
(fr
->fr_grhead
, $2, \
505 | IPFY_HEAD YY_NUMBER
{ DOALL
(sprintf
(fr
->fr_grhead
, "%d", \
510 | IPFY_SETTAG
'(' taginlist
')'
515 | taginlist
',' taginspec
523 nattag: IPFY_NAT
'=' YY_STR
{ DOALL
(strncpy
(fr
->fr_nattag.ipt_tag
,\
526 | IPFY_NAT
'=' YY_NUMBER
{ DOALL
(sprintf
(fr
->fr_nattag.ipt_tag
,\
527 "%d", $3 & 0xffffffff);) }
530 logtag: IPFY_LOG
'=' YY_NUMBER
{ DOALL
(fr
->fr_logtag
= $3;) }
534 | IPFY_SETTAG
'(' tagoutlist
')'
539 | tagoutlist
',' tagoutspec
548 | IPFY_MATCHTAG
'(' tagoutlist
')'
552 | IPFY_MATCHTAG
'(' taginlist
')'
555 pps: | IPFY_PPS YY_NUMBER
{ DOALL
(fr
->fr_pps
= $2;) }
558 new: | savegroup file restoregroup
573 IPFY_QUICK
{ fr
->fr_flags |
= FR_QUICK
; }
577 | IPFY_ON onname IPFY_INVIA vianame
578 | IPFY_ON onname IPFY_OUTVIA vianame
581 onname: interfacename
582 { strncpy
(fr
->fr_ifnames
[0], $1, sizeof
(fr
->fr_ifnames
[0]));
585 | interfacename
',' interfacename
586 { strncpy
(fr
->fr_ifnames
[0], $1, sizeof
(fr
->fr_ifnames
[0]));
588 strncpy
(fr
->fr_ifnames
[1], $3, sizeof
(fr
->fr_ifnames
[1]));
595 { strncpy
(fr
->fr_ifnames
[2], $1, sizeof
(fr
->fr_ifnames
[2]));
599 { strncpy
(fr
->fr_ifnames
[2], $1, sizeof
(fr
->fr_ifnames
[2]));
601 strncpy
(fr
->fr_ifnames
[3], $3, sizeof
(fr
->fr_ifnames
[3]));
607 { strncpy
(fr
->fr_dif.fd_ifname
, $2, sizeof
(fr
->fr_dif.fd_ifname
));
609 fr
->fr_flags |
= FR_DUP
;
611 | IPFY_DUPTO name duptoseparator hostname
612 { strncpy
(fr
->fr_dif.fd_ifname
, $2, sizeof
(fr
->fr_dif.fd_ifname
));
614 fr
->fr_dif.fd_ip
= $4.in4
;
616 bcopy
(&$4, &fr
->fr_dif.fd_ip6
, sizeof
(fr
->fr_dif.fd_ip6
));
618 fr
->fr_flags |
= FR_DUP
;
621 | IPFY_DUPTO name duptoseparator YY_IPV6
622 { strncpy
(fr
->fr_dif.fd_ifname
, $2, sizeof
(fr
->fr_dif.fd_ifname
));
623 bcopy
(&$4, &fr
->fr_dif.fd_ip6
, sizeof
(fr
->fr_dif.fd_ip6
));
625 fr
->fr_flags |
= FR_DUP
;
631 ':' { yyexpectaddr
= 1; yycont
= &yyexpectaddr
; resetaddr
(); }
634 froute: IPFY_FROUTE
{ fr
->fr_flags |
= FR_FASTROUTE
; }
638 { strncpy
(fr
->fr_tif.fd_ifname
, $2, sizeof
(fr
->fr_tif.fd_ifname
));
641 | routeto name duptoseparator hostname
642 { strncpy
(fr
->fr_tif.fd_ifname
, $2, sizeof
(fr
->fr_tif.fd_ifname
));
644 fr
->fr_tif.fd_ip
= $4.in4
;
646 bcopy
(&$4, &fr
->fr_tif.fd_ip6
, sizeof
(fr
->fr_tif.fd_ip6
));
650 | routeto name duptoseparator YY_IPV6
651 { strncpy
(fr
->fr_tif.fd_ifname
, $2, sizeof
(fr
->fr_tif.fd_ifname
));
652 bcopy
(&$4, &fr
->fr_tif.fd_ip6
, sizeof
(fr
->fr_tif.fd_ip6
));
665 { strncpy
(fr
->fr_rif.fd_ifname
, $2, sizeof
(fr
->fr_rif.fd_ifname
));
668 | IPFY_REPLY_TO name duptoseparator hostname
669 { strncpy
(fr
->fr_rif.fd_ifname
, $2, sizeof
(fr
->fr_rif.fd_ifname
));
671 fr
->fr_rif.fd_ip
= $4.in4
;
673 bcopy
(&$4, &fr
->fr_rif.fd_ip6
, sizeof
(fr
->fr_rif.fd_ip6
));
677 | IPFY_REPLY_TO name duptoseparator YY_IPV6
678 { strncpy
(fr
->fr_rif.fd_ifname
, $2, sizeof
(fr
->fr_rif.fd_ifname
));
679 bcopy
(&$4, &fr
->fr_rif.fd_ip6
, sizeof
(fr
->fr_rif.fd_ip6
));
687 | logoptions logoption
691 IPFY_BODY
{ fr
->fr_flags |
= FR_LOGBODY
; }
692 | IPFY_FIRST
{ fr
->fr_flags |
= FR_LOGFIRST
; }
693 | IPFY_ORBLOCK
{ fr
->fr_flags |
= FR_LOGORBLOCK
; }
694 | level loglevel
{ unsetsyslog
(); }
698 starticmpcode icmpcode
')' { fr
->fr_icode
= $2; yyresetdict
(); }
702 '(' { yysetdict
(icmpcodewords
); }
710 YY_NUMBER
{ DOREM
(fr
->fr_proto
= $1; \
711 fr
->fr_mproto
= 0xff;) }
712 | YY_STR
{ if
(!strcmp
($1, "tcp-udp")) {
713 DOREM
(fr
->fr_flx |
= FI_TCPUDP
; \
714 fr
->fr_mflx |
= FI_TCPUDP
;)
716 int p
= getproto
($1);
718 yyerror("protocol unknown");
719 DOREM
(fr
->fr_proto
= p
; \
720 fr
->fr_mproto
= 0xff;)
724 | YY_STR nextstring YY_STR
725 { if
(!strcmp
($1, "tcp") &&
726 !strcmp
($3, "udp")) {
727 DOREM
(fr
->fr_flx |
= FI_TCPUDP
; \
728 fr
->fr_mflx |
= FI_TCPUDP
;)
737 '/' { yysetdict
(NULL
); }
740 fromto: from srcobject to dstobject
{ yyexpectaddr
= 0; yycont
= NULL
; }
741 | to dstobject
{ yyexpectaddr
= 0; yycont
= NULL
; }
742 | from srcobject
{ yyexpectaddr
= 0; yycont
= NULL
; }
745 from: IPFY_FROM
{ setipftype
();
750 printf
("set yyexpectaddr\n");
751 yycont
= &yyexpectaddr
;
752 yysetdict
(addrwords
);
756 to: IPFY_TO
{ if
(fr
== NULL
)
760 printf
("set yyexpectaddr\n");
761 yycont
= &yyexpectaddr
;
762 yysetdict
(addrwords
);
766 with: | andwith withlist
770 IPFY_WITH
{ nowith
= 0; setipftype
(); }
771 | IPFY_AND
{ nowith
= 0; setipftype
(); }
774 flags: | startflags flagset
775 { DOALL
(fr
->fr_tcpf
= $2; fr
->fr_tcpfm
= FR_TCPFMAX
;) }
776 | startflags flagset
'/' flagset
777 { DOALL
(fr
->fr_tcpf
= $2; fr
->fr_tcpfm
= $4;) }
778 | startflags
'/' flagset
779 { DOALL
(fr
->fr_tcpf
= 0; fr
->fr_tcpfm
= $3;) }
780 | startflags YY_NUMBER
781 { DOALL
(fr
->fr_tcpf
= $2; fr
->fr_tcpfm
= FR_TCPFMAX
;) }
782 | startflags
'/' YY_NUMBER
783 { DOALL
(fr
->fr_tcpf
= 0; fr
->fr_tcpfm
= $3;) }
784 | startflags YY_NUMBER
'/' YY_NUMBER
785 { DOALL
(fr
->fr_tcpf
= $2; fr
->fr_tcpfm
= $4;) }
786 | startflags flagset
'/' YY_NUMBER
787 { DOALL
(fr
->fr_tcpf
= $2; fr
->fr_tcpfm
= $4;) }
788 | startflags YY_NUMBER
'/' flagset
789 { DOALL
(fr
->fr_tcpf
= $2; fr
->fr_tcpfm
= $4;) }
793 IPFY_FLAGS
{ if
(frc
->fr_type
!= FR_T_IPF
)
794 yyerror("flags with non-ipf type rule");
795 if
(frc
->fr_proto
!= IPPROTO_TCP
)
796 yyerror("flags with non-TCP rule");
801 YY_STR
{ $$
= tcpflags
($1); free
($1); }
802 | YY_HEX
{ $$
= $1; }
806 { yyresetdict
(); } fromport
808 |
'!' srcaddr srcport
809 { DOALL
(fr
->fr_flags |
= FR_NOTSRCIP
;) }
813 addr
{ DOREM
(bcopy
(&($1.a
), &fr
->fr_ip.fi_src
, sizeof
($1.a
)); \
814 bcopy
(&($1.m
), &fr
->fr_mip.fi_src
, sizeof
($1.m
)); \
815 if
(dynamic
!= -1) { \
816 fr
->fr_satype
= ifpflag
; \
817 fr
->fr_ipf
->fri_sifpidx
= dynamic
; \
818 } else if
(pooled || hashed
) \
819 fr
->fr_satype
= FRI_LOOKUP
;)
821 | lstart srcaddrlist lend
825 addr
{ DOREM
(bcopy
(&($1.a
), &fr
->fr_ip.fi_src
, sizeof
($1.a
)); \
826 bcopy
(&($1.m
), &fr
->fr_mip.fi_src
, sizeof
($1.m
)); \
827 if
(dynamic
!= -1) { \
828 fr
->fr_satype
= ifpflag
; \
829 fr
->fr_ipf
->fri_sifpidx
= dynamic
; \
830 } else if
(pooled || hashed
) \
831 fr
->fr_satype
= FRI_LOOKUP
;)
833 | srcaddrlist lmore addr
834 { DOREM
(bcopy
(&($3.a
), &fr
->fr_ip.fi_src
, sizeof
($3.a
)); \
835 bcopy
(&($3.m
), &fr
->fr_mip.fi_src
, sizeof
($3.m
)); \
836 if
(dynamic
!= -1) { \
837 fr
->fr_satype
= ifpflag
; \
838 fr
->fr_ipf
->fri_sifpidx
= dynamic
; \
839 } else if
(pooled || hashed
) \
840 fr
->fr_satype
= FRI_LOOKUP
;)
846 { DOALL
(fr
->fr_scmp
= $1.pc
; fr
->fr_sport
= $1.p1
;) }
848 { DOALL
(fr
->fr_scmp
= $1.pc
; fr
->fr_sport
= $1.p1
; \
849 fr
->fr_stop
= $1.p2
;) }
850 | porteq lstart srcportlist lend
856 { DOALL
(fr
->fr_scmp
= $1.pc
; fr
->fr_sport
= $1.p1
;) }
858 { DOALL
(fr
->fr_scmp
= $1.pc
; fr
->fr_sport
= $1.p1
; \
859 fr
->fr_stop
= $1.p2
;) }
860 | porteq lstart srcportlist lend
865 portnum
{ DOREM
(fr
->fr_scmp
= FR_EQUAL
; fr
->fr_sport
= $1;) }
866 | srcportlist lmore portnum
867 { DOREM
(fr
->fr_scmp
= FR_EQUAL
; fr
->fr_sport
= $3;) }
871 { yyresetdict
(); } toport
873 |
'!' dstaddr dstport
874 { DOALL
(fr
->fr_flags |
= FR_NOTDSTIP
;) }
878 addr
{ DOREM
(bcopy
(&($1.a
), &fr
->fr_ip.fi_dst
, sizeof
($1.a
)); \
879 bcopy
(&($1.m
), &fr
->fr_mip.fi_dst
, sizeof
($1.m
)); \
880 if
(dynamic
!= -1) { \
881 fr
->fr_datype
= ifpflag
; \
882 fr
->fr_ipf
->fri_difpidx
= dynamic
; \
883 } else if
(pooled || hashed
) \
884 fr
->fr_datype
= FRI_LOOKUP
;)
886 | lstart dstaddrlist lend
890 addr
{ DOREM
(bcopy
(&($1.a
), &fr
->fr_ip.fi_dst
, sizeof
($1.a
)); \
891 bcopy
(&($1.m
), &fr
->fr_mip.fi_dst
, sizeof
($1.m
)); \
892 if
(dynamic
!= -1) { \
893 fr
->fr_datype
= ifpflag
; \
894 fr
->fr_ipf
->fri_difpidx
= dynamic
; \
895 } else if
(pooled || hashed
) \
896 fr
->fr_datype
= FRI_LOOKUP
;)
898 | dstaddrlist lmore addr
899 { DOREM
(bcopy
(&($3.a
), &fr
->fr_ip.fi_dst
, sizeof
($3.a
)); \
900 bcopy
(&($3.m
), &fr
->fr_mip.fi_dst
, sizeof
($3.m
)); \
901 if
(dynamic
!= -1) { \
902 fr
->fr_datype
= ifpflag
; \
903 fr
->fr_ipf
->fri_difpidx
= dynamic
; \
904 } else if
(pooled || hashed
) \
905 fr
->fr_datype
= FRI_LOOKUP
;)
912 { DOALL
(fr
->fr_dcmp
= $1.pc
; fr
->fr_dport
= $1.p1
;) }
914 { DOALL
(fr
->fr_dcmp
= $1.pc
; fr
->fr_dport
= $1.p1
; \
915 fr
->fr_dtop
= $1.p2
;) }
916 | porteq lstart dstportlist lend
922 { DOALL
(fr
->fr_dcmp
= $1.pc
; fr
->fr_dport
= $1.p1
;) }
924 { DOALL
(fr
->fr_dcmp
= $1.pc
; fr
->fr_dport
= $1.p1
; \
925 fr
->fr_dtop
= $1.p2
;) }
926 | porteq lstart dstportlist lend
931 portnum
{ DOREM
(fr
->fr_dcmp
= FR_EQUAL
; fr
->fr_dport
= $1;) }
932 | dstportlist lmore portnum
933 { DOREM
(fr
->fr_dcmp
= FR_EQUAL
; fr
->fr_dport
= $3;) }
936 addr: pool
'/' YY_NUMBER
{ pooled
= 1;
938 $$.a.iplookuptype
= IPLT_POOL
;
939 $$.a.iplookupnum
= $3; }
940 | pool
'=' '(' poollist
')' { pooled
= 1;
942 $$.a.iplookuptype
= IPLT_POOL
;
943 $$.a.iplookupnum
= makepool
($4); }
944 | hash
'/' YY_NUMBER
{ hashed
= 1;
946 $$.a.iplookuptype
= IPLT_HASH
;
947 $$.a.iplookupnum
= $3; }
948 | hash
'=' '(' addrlist
')' { hashed
= 1;
950 $$.a.iplookuptype
= IPLT_HASH
;
951 $$.a.iplookupnum
= makehash
($4); }
952 | ipaddr
{ bcopy
(&$1, &$$
, sizeof
($$
));
956 ipaddr: IPFY_ANY
{ bzero
(&($$
), sizeof
($$
));
959 | hostname
{ if
(use_inet6
== 0) {
961 $$.m.in4_addr
= 0xffffffff;
964 bcopy
(&$1, &$$.a
, sizeof
($$.a
));
965 fill6bits
(128, (u_32_t
*)&$$.m
);
968 | hostname
{ yyresetdict
();
973 bcopy
(&$1, &$$.a
, sizeof
($$.a
));
976 maskspace
{ yysetdict
(maskwords
); }
977 mask
{ if
(use_inet6
== 0) {
978 $$.m.in4_addr
= $5.in4.s_addr
;
979 $$.a.in4_addr
&= $5.in4.s_addr
;
981 bcopy
(&$5, &$$.m
, sizeof
($$.m
));
984 | YY_IPV6
{ set_ipv6_addr
= 1;
985 bcopy
(&$1, &$$.a
, sizeof
($$.a
));
986 fill6bits
(128, (u_32_t
*)&$$.m
);
989 | YY_IPV6
{ set_ipv6_addr
= 1;
991 bcopy
(&$1, &$$.a
, sizeof
($$.a
)); }
992 maskspace
{ yysetdict
(maskwords
); }
993 mask
{ bcopy
(&$5, &$$.m
, sizeof
($$.m
));
1004 ipv4
{ $$.in4
= $1; }
1005 | YY_HEX
{ $$.in4.s_addr
= htonl
($1); }
1006 | YY_NUMBER
{ if
((use_inet6
== 0) && ($1 <= 32))
1007 ntomask
(4, $1, (u_32_t
*)&$$.in4
);
1008 else if
((use_inet6
!= 0) && ($1 <= 128))
1009 ntomask
(6, $1, $$.i6
);
1011 yyerror("Bad value specified for netmask");
1015 | IPFY_BROADCAST
{ if
(ifpflag
== FRI_DYNAMIC
) {
1016 bzero
(&$$
, sizeof
($$
));
1017 ifpflag
= FRI_BROADCAST
;
1021 | IPFY_NETWORK
{ if
(ifpflag
== FRI_DYNAMIC
) {
1022 bzero
(&$$
, sizeof
($$
));
1023 ifpflag
= FRI_NETWORK
;
1027 | IPFY_NETMASKED
{ if
(ifpflag
== FRI_DYNAMIC
) {
1028 bzero
(&$$
, sizeof
($$
));
1029 ifpflag
= FRI_NETMASKED
;
1033 | IPFY_PEER
{ if
(ifpflag
== FRI_DYNAMIC
) {
1034 bzero
(&$$
, sizeof
($$
));
1035 ifpflag
= FRI_PEERADDR
;
1042 ipv4
{ $$.in4
= $1; }
1043 | YY_NUMBER
{ $$.in4.s_addr
= $1; }
1044 | YY_HEX
{ $$.in4.s_addr
= $1; }
1045 | YY_STR
{ if
(lookuphost
($1, &$$
) == 1)
1049 if
(ifpflag
!= FRI_DYNAMIC
)
1050 yyerror("Unknown hostname");
1056 ipaddr
{ $$
= newalist
(NULL
);
1058 $$
->al_family
= AF_INET6
;
1060 $$
->al_family
= AF_INET
;
1062 bcopy
(&($1.a
), &($$
->al_i6addr
), sizeof
($1.a
));
1063 bcopy
(&($1.m
), &($$
->al_i6mask
), sizeof
($1.m
)); }
1064 | addrlist
',' ipaddr
1065 { $$
= newalist
($1);
1067 $$
->al_family
= AF_INET6
;
1069 $$
->al_family
= AF_INET
;
1071 bcopy
(&($3.a
), &($$
->al_i6addr
), sizeof
($3.a
));
1072 bcopy
(&($3.m
), &($$
->al_i6mask
), sizeof
($3.m
)); }
1075 pool: IPFY_POOL
{ yyexpectaddr
= 0; yycont
= NULL
; yyresetdict
(); }
1078 hash: IPFY_HASH
{ yyexpectaddr
= 0; yycont
= NULL
; yyresetdict
(); }
1082 ipaddr
{ $$
= newalist
(NULL
);
1084 $$
->al_family
= AF_INET6
;
1086 $$
->al_family
= AF_INET
;
1088 bcopy
(&($1.a
), &($$
->al_i6addr
), sizeof
($1.a
));
1089 bcopy
(&($1.m
), &($$
->al_i6mask
), sizeof
($1.m
)); }
1090 |
'!' ipaddr
{ $$
= newalist
(NULL
);
1093 $$
->al_family
= AF_INET6
;
1095 $$
->al_family
= AF_INET
;
1097 bcopy
(&($2.a
), &($$
->al_i6addr
), sizeof
($2.a
));
1098 bcopy
(&($2.m
), &($$
->al_i6mask
), sizeof
($2.m
)); }
1099 | poollist
',' ipaddr
1100 { $$
= newalist
($1);
1102 $$
->al_family
= AF_INET6
;
1104 $$
->al_family
= AF_INET
;
1106 bcopy
(&($3.a
), &($$
->al_i6addr
), sizeof
($3.a
));
1107 bcopy
(&($3.m
), &($$
->al_i6mask
), sizeof
($3.m
)); }
1108 | poollist
',' '!' ipaddr
1109 { $$
= newalist
($1);
1112 $$
->al_family
= AF_INET6
;
1114 $$
->al_family
= AF_INET
;
1116 bcopy
(&($4.a
), &($$
->al_i6addr
), sizeof
($4.a
));
1117 bcopy
(&($4.m
), &($$
->al_i6mask
), sizeof
($4.m
)); }
1120 port: IPFY_PORT
{ yyexpectaddr
= 0;
1125 portc: port compare
{ $$
= $2;
1127 | porteq
{ $$
= $1; }
1130 porteq: port
'=' { $$
= FR_EQUAL
;
1134 portr: IPFY_PORT
{ yyexpectaddr
= 0;
1140 portc portnum
{ $$.pc
= $1;
1146 portr portnum range portnum
{ $$.p1
= $2;
1155 itype: seticmptype icmptype
1156 { DOALL
(fr
->fr_icmp
= htons
($2 << 8); fr
->fr_icmpm
= htons
(0xff00););
1159 | seticmptype lstart typelist lend
{ yyresetdict
(); }
1163 IPFY_ICMPTYPE
{ setipftype
();
1164 yysetdict
(icmptypewords
); }
1167 icode: | seticmpcode icmpcode
1168 { DOALL
(fr
->fr_icmp |
= htons
($2); fr
->fr_icmpm |
= htons
(0xff););
1171 | seticmpcode lstart codelist lend
{ yyresetdict
(); }
1175 IPFY_ICMPCODE
{ yysetdict
(icmpcodewords
); }
1180 { DOREM
(fr
->fr_icmp
= htons
($1 << 8); fr
->fr_icmpm
= htons
(0xff00);) }
1181 | typelist lmore icmptype
1182 { DOREM
(fr
->fr_icmp
= htons
($3 << 8); fr
->fr_icmpm
= htons
(0xff00);) }
1187 { DOREM
(fr
->fr_icmp |
= htons
($1); fr
->fr_icmpm |
= htons
(0xff);) }
1188 | codelist lmore icmpcode
1189 { DOREM
(fr
->fr_icmp |
= htons
($3); fr
->fr_icmpm |
= htons
(0xff);) }
1192 age: | IPFY_AGE YY_NUMBER
{ DOALL
(fr
->fr_age
[0] = $2; \
1193 fr
->fr_age
[1] = $2;) }
1194 | IPFY_AGE YY_NUMBER
'/' YY_NUMBER
1195 { DOALL
(fr
->fr_age
[0] = $2; \
1196 fr
->fr_age
[1] = $4;) }
1199 keep: | IPFY_KEEP keepstate
1200 | IPFY_KEEP keepfrag
1201 | IPFY_KEEP keepstate IPFY_KEEP keepfrag
1202 | IPFY_KEEP keepfrag IPFY_KEEP keepstate
1206 IPFY_STATE stateoptlist
{ DOALL
(fr
->fr_flags |
= FR_KEEPSTATE
;)}
1210 IPFY_FRAGS fragoptlist
{ DOALL
(fr
->fr_flags |
= FR_KEEPFRAG
;) }
1211 | IPFY_FRAG fragoptlist
{ DOALL
(fr
->fr_flags |
= FR_KEEPFRAG
;) }
1219 fragopt lanother fragopts
1224 IPFY_STRICT
{ DOALL
(fr
->fr_flags |
= FR_FRSTRICT
;) }
1232 stateopt lanother stateopts
1237 IPFY_LIMIT YY_NUMBER
{ DOALL
(fr
->fr_statemax
= $2;) }
1238 | IPFY_STRICT
{ DOALL
(if
(fr
->fr_proto
!= IPPROTO_TCP
) { \
1241 fr
->fr_flags |
= FR_STSTRICT
;)
1243 | IPFY_NEWISN
{ DOALL
(if
(fr
->fr_proto
!= IPPROTO_TCP
) { \
1246 fr
->fr_flags |
= FR_NEWISN
;)
1248 | IPFY_NOICMPERR
{ DOALL
(fr
->fr_flags |
= FR_NOICMPERR
;) }
1250 | IPFY_SYNC
{ DOALL
(fr
->fr_flags |
= FR_STATESYNC
;) }
1254 servicename
{ if
(getport
(frc
, $1, &($$
)) == -1)
1255 yyerror("service unknown");
1260 | YY_NUMBER
{ if
($1 > 65535) /* Unsigned */
1261 yyerror("invalid port number");
1270 | withlist
',' withopt
1274 opttype
{ DOALL
(fr
->fr_flx |
= $1; fr
->fr_mflx |
= $1;) }
1276 { DOALL
(fr
->fr_mflx |
= $2;) }
1277 | ipopt ipopts
{ yyresetdict
(); }
1278 | notwith ipopt ipopts
{ yyresetdict
(); }
1279 | startv6hdrs ipv6hdrs
{ yyresetdict
(); }
1282 ipopt: IPFY_OPT
{ yysetdict
(ipv4optwords
); }
1286 IPF6_V6HDRS
{ if
(use_inet6
== 0)
1287 yyerror("only available with IPv6");
1288 yysetdict
(ipv6optwords
);
1293 IPFY_NOT
{ nowith
= 1; }
1294 | IPFY_NO
{ nowith
= 1; }
1298 IPFY_IPOPTS
{ $$
= FI_OPTIONS
; }
1299 | IPFY_SHORT
{ $$
= FI_SHORT
; }
1300 | IPFY_NAT
{ $$
= FI_NATED
; }
1301 | IPFY_BAD
{ $$
= FI_BAD
; }
1302 | IPFY_BADNAT
{ $$
= FI_BADNAT
; }
1303 | IPFY_BADSRC
{ $$
= FI_BADSRC
; }
1304 | IPFY_LOWTTL
{ $$
= FI_LOWTTL
; }
1305 | IPFY_FRAG
{ $$
= FI_FRAG
; }
1306 | IPFY_FRAGBODY
{ $$
= FI_FRAGBODY
; }
1307 | IPFY_FRAGS
{ $$
= FI_FRAG
; }
1308 | IPFY_MBCAST
{ $$
= FI_MBCAST
; }
1309 | IPFY_MULTICAST
{ $$
= FI_MULTICAST
; }
1310 | IPFY_BROADCAST
{ $$
= FI_BROADCAST
; }
1311 | IPFY_STATE
{ $$
= FI_STATE
; }
1312 | IPFY_OOW
{ $$
= FI_OOW
; }
1315 ipopts: optlist
{ DOALL
(fr
->fr_mip.fi_optmsk |
= $1;
1317 fr
->fr_ip.fi_optmsk |
= $1;)
1323 | optlist
',' opt
{ $$ |
= $1 |
$3; }
1327 ipv6hdrlist
{ DOALL
(fr
->fr_mip.fi_optmsk |
= $1;
1329 fr
->fr_ip.fi_optmsk |
= $1;)
1334 ipv6hdr
{ $$ |
= $1; }
1335 | ipv6hdrlist
',' ipv6hdr
{ $$ |
= $1 |
$3; }
1339 seclevel
{ $$ |
= $1; }
1340 | secname
',' seclevel
{ $$ |
= $1 |
$3; }
1344 IPFY_SEC_UNC
{ $$
= secbit
(IPSO_CLASS_UNCL
); }
1345 | IPFY_SEC_CONF
{ $$
= secbit
(IPSO_CLASS_CONF
); }
1346 | IPFY_SEC_RSV1
{ $$
= secbit
(IPSO_CLASS_RES1
); }
1347 | IPFY_SEC_RSV2
{ $$
= secbit
(IPSO_CLASS_RES2
); }
1348 | IPFY_SEC_RSV3
{ $$
= secbit
(IPSO_CLASS_RES3
); }
1349 | IPFY_SEC_RSV4
{ $$
= secbit
(IPSO_CLASS_RES4
); }
1350 | IPFY_SEC_SEC
{ $$
= secbit
(IPSO_CLASS_SECR
); }
1351 | IPFY_SEC_TS
{ $$
= secbit
(IPSO_CLASS_TOPS
); }
1355 YY_NUMBER
{ $$
= $1; }
1356 | IPFY_ICMPT_UNR
{ $$
= ICMP_UNREACH
; }
1357 | IPFY_ICMPT_ECHO
{ $$
= ICMP_ECHO
; }
1358 | IPFY_ICMPT_ECHOR
{ $$
= ICMP_ECHOREPLY
; }
1359 | IPFY_ICMPT_SQUENCH
{ $$
= ICMP_SOURCEQUENCH
; }
1360 | IPFY_ICMPT_REDIR
{ $$
= ICMP_REDIRECT
; }
1361 | IPFY_ICMPT_TIMEX
{ $$
= ICMP_TIMXCEED
; }
1362 | IPFY_ICMPT_PARAMP
{ $$
= ICMP_PARAMPROB
; }
1363 | IPFY_ICMPT_TIMEST
{ $$
= ICMP_TSTAMP
; }
1364 | IPFY_ICMPT_TIMESTREP
{ $$
= ICMP_TSTAMPREPLY
; }
1365 | IPFY_ICMPT_INFOREQ
{ $$
= ICMP_IREQ
; }
1366 | IPFY_ICMPT_INFOREP
{ $$
= ICMP_IREQREPLY
; }
1367 | IPFY_ICMPT_MASKREQ
{ $$
= ICMP_MASKREQ
; }
1368 | IPFY_ICMPT_MASKREP
{ $$
= ICMP_MASKREPLY
; }
1369 | IPFY_ICMPT_ROUTERAD
{ $$
= ICMP_ROUTERADVERT
; }
1370 | IPFY_ICMPT_ROUTERSOL
{ $$
= ICMP_ROUTERSOLICIT
; }
1374 YY_NUMBER
{ $$
= $1; }
1375 | IPFY_ICMPC_NETUNR
{ $$
= ICMP_UNREACH_NET
; }
1376 | IPFY_ICMPC_HSTUNR
{ $$
= ICMP_UNREACH_HOST
; }
1377 | IPFY_ICMPC_PROUNR
{ $$
= ICMP_UNREACH_PROTOCOL
; }
1378 | IPFY_ICMPC_PORUNR
{ $$
= ICMP_UNREACH_PORT
; }
1379 | IPFY_ICMPC_NEEDF
{ $$
= ICMP_UNREACH_NEEDFRAG
; }
1380 | IPFY_ICMPC_SRCFAIL
{ $$
= ICMP_UNREACH_SRCFAIL
; }
1381 | IPFY_ICMPC_NETUNK
{ $$
= ICMP_UNREACH_NET_UNKNOWN
; }
1382 | IPFY_ICMPC_HSTUNK
{ $$
= ICMP_UNREACH_HOST_UNKNOWN
; }
1383 | IPFY_ICMPC_ISOLATE
{ $$
= ICMP_UNREACH_ISOLATED
; }
1384 | IPFY_ICMPC_NETPRO
{ $$
= ICMP_UNREACH_NET_PROHIB
; }
1385 | IPFY_ICMPC_HSTPRO
{ $$
= ICMP_UNREACH_HOST_PROHIB
; }
1386 | IPFY_ICMPC_NETTOS
{ $$
= ICMP_UNREACH_TOSNET
; }
1387 | IPFY_ICMPC_HSTTOS
{ $$
= ICMP_UNREACH_TOSHOST
; }
1388 | IPFY_ICMPC_FLTPRO
{ $$
= ICMP_UNREACH_ADMIN_PROHIBIT
; }
1389 | IPFY_ICMPC_HSTPRE
{ $$
= 14; }
1390 | IPFY_ICMPC_CUTPRE
{ $$
= 15; }
1394 IPFY_IPOPT_NOP
{ $$
= getoptbyvalue
(IPOPT_NOP
); }
1395 | IPFY_IPOPT_RR
{ $$
= getoptbyvalue
(IPOPT_RR
); }
1396 | IPFY_IPOPT_ZSU
{ $$
= getoptbyvalue
(IPOPT_ZSU
); }
1397 | IPFY_IPOPT_MTUP
{ $$
= getoptbyvalue
(IPOPT_MTUP
); }
1398 | IPFY_IPOPT_MTUR
{ $$
= getoptbyvalue
(IPOPT_MTUR
); }
1399 | IPFY_IPOPT_ENCODE
{ $$
= getoptbyvalue
(IPOPT_ENCODE
); }
1400 | IPFY_IPOPT_TS
{ $$
= getoptbyvalue
(IPOPT_TS
); }
1401 | IPFY_IPOPT_TR
{ $$
= getoptbyvalue
(IPOPT_TR
); }
1402 | IPFY_IPOPT_SEC
{ $$
= getoptbyvalue
(IPOPT_SECURITY
); }
1403 | IPFY_IPOPT_LSRR
{ $$
= getoptbyvalue
(IPOPT_LSRR
); }
1404 | IPFY_IPOPT_ESEC
{ $$
= getoptbyvalue
(IPOPT_E_SEC
); }
1405 | IPFY_IPOPT_CIPSO
{ $$
= getoptbyvalue
(IPOPT_CIPSO
); }
1406 | IPFY_IPOPT_SATID
{ $$
= getoptbyvalue
(IPOPT_SATID
); }
1407 | IPFY_IPOPT_SSRR
{ $$
= getoptbyvalue
(IPOPT_SSRR
); }
1408 | IPFY_IPOPT_ADDEXT
{ $$
= getoptbyvalue
(IPOPT_ADDEXT
); }
1409 | IPFY_IPOPT_VISA
{ $$
= getoptbyvalue
(IPOPT_VISA
); }
1410 | IPFY_IPOPT_IMITD
{ $$
= getoptbyvalue
(IPOPT_IMITD
); }
1411 | IPFY_IPOPT_EIP
{ $$
= getoptbyvalue
(IPOPT_EIP
); }
1412 | IPFY_IPOPT_FINN
{ $$
= getoptbyvalue
(IPOPT_FINN
); }
1413 | IPFY_IPOPT_DPS
{ $$
= getoptbyvalue
(IPOPT_DPS
); }
1414 | IPFY_IPOPT_SDB
{ $$
= getoptbyvalue
(IPOPT_SDB
); }
1415 | IPFY_IPOPT_NSAPA
{ $$
= getoptbyvalue
(IPOPT_NSAPA
); }
1416 | IPFY_IPOPT_RTRALRT
{ $$
= getoptbyvalue
(IPOPT_RTRALRT
); }
1417 | IPFY_IPOPT_UMP
{ $$
= getoptbyvalue
(IPOPT_UMP
); }
1418 | setsecclass secname
1419 { DOALL
(fr
->fr_mip.fi_secmsk |
= $2;
1421 fr
->fr_ip.fi_secmsk |
= $2;)
1428 IPFY_SECCLASS
{ yysetdict
(ipv4secwords
); }
1432 IPFY_AH
{ $$
= getv6optbyvalue
(IPPROTO_AH
); }
1433 | IPFY_IPV6OPT_DSTOPTS
{ $$
= getv6optbyvalue
(IPPROTO_DSTOPTS
); }
1434 | IPFY_ESP
{ $$
= getv6optbyvalue
(IPPROTO_ESP
); }
1435 | IPFY_IPV6OPT_HOPOPTS
{ $$
= getv6optbyvalue
(IPPROTO_HOPOPTS
); }
1436 | IPFY_IPV6OPT_IPV6
{ $$
= getv6optbyvalue
(IPPROTO_IPV6
); }
1437 | IPFY_IPV6OPT_NONE
{ $$
= getv6optbyvalue
(IPPROTO_NONE
); }
1438 | IPFY_IPV6OPT_ROUTING
{ $$
= getv6optbyvalue
(IPPROTO_ROUTING
); }
1439 | IPFY_FRAG
{ $$
= getv6optbyvalue
(IPPROTO_FRAGMENT
); }
1442 level: IPFY_LEVEL
{ setsyslog
(); }
1446 priority
{ fr
->fr_loglevel
= LOG_LOCAL0|
$1; }
1447 | facility
'.' priority
{ fr
->fr_loglevel
= $1 |
$3; }
1451 IPFY_FAC_KERN
{ $$
= LOG_KERN
; }
1452 | IPFY_FAC_USER
{ $$
= LOG_USER
; }
1453 | IPFY_FAC_MAIL
{ $$
= LOG_MAIL
; }
1454 | IPFY_FAC_DAEMON
{ $$
= LOG_DAEMON
; }
1455 | IPFY_FAC_AUTH
{ $$
= LOG_AUTH
; }
1456 | IPFY_FAC_SYSLOG
{ $$
= LOG_SYSLOG
; }
1457 | IPFY_FAC_LPR
{ $$
= LOG_LPR
; }
1458 | IPFY_FAC_NEWS
{ $$
= LOG_NEWS
; }
1459 | IPFY_FAC_UUCP
{ $$
= LOG_UUCP
; }
1460 | IPFY_FAC_CRON
{ $$
= LOG_CRON
; }
1461 | IPFY_FAC_FTP
{ $$
= LOG_FTP
; }
1462 | IPFY_FAC_AUTHPRIV
{ $$
= LOG_AUTHPRIV
; }
1463 | IPFY_FAC_AUDIT
{ $$
= LOG_AUDIT
; }
1464 | IPFY_FAC_LFMT
{ $$
= LOG_LFMT
; }
1465 | IPFY_FAC_LOCAL0
{ $$
= LOG_LOCAL0
; }
1466 | IPFY_FAC_LOCAL1
{ $$
= LOG_LOCAL1
; }
1467 | IPFY_FAC_LOCAL2
{ $$
= LOG_LOCAL2
; }
1468 | IPFY_FAC_LOCAL3
{ $$
= LOG_LOCAL3
; }
1469 | IPFY_FAC_LOCAL4
{ $$
= LOG_LOCAL4
; }
1470 | IPFY_FAC_LOCAL5
{ $$
= LOG_LOCAL5
; }
1471 | IPFY_FAC_LOCAL6
{ $$
= LOG_LOCAL6
; }
1472 | IPFY_FAC_LOCAL7
{ $$
= LOG_LOCAL7
; }
1473 | IPFY_FAC_SECURITY
{ $$
= LOG_SECURITY
; }
1477 IPFY_PRI_EMERG
{ $$
= LOG_EMERG
; }
1478 | IPFY_PRI_ALERT
{ $$
= LOG_ALERT
; }
1479 | IPFY_PRI_CRIT
{ $$
= LOG_CRIT
; }
1480 | IPFY_PRI_ERR
{ $$
= LOG_ERR
; }
1481 | IPFY_PRI_WARN
{ $$
= LOG_WARNING
; }
1482 | IPFY_PRI_NOTICE
{ $$
= LOG_NOTICE
; }
1483 | IPFY_PRI_INFO
{ $$
= LOG_INFO
; }
1484 | IPFY_PRI_DEBUG
{ $$
= LOG_DEBUG
; }
1488 YY_CMP_EQ
{ $$
= FR_EQUAL
; }
1489 | YY_CMP_NE
{ $$
= FR_NEQUAL
; }
1490 | YY_CMP_LT
{ $$
= FR_LESST
; }
1491 | YY_CMP_LE
{ $$
= FR_LESSTE
; }
1492 | YY_CMP_GT
{ $$
= FR_GREATERT
; }
1493 | YY_CMP_GE
{ $$
= FR_GREATERTE
; }
1496 range: YY_RANGE_IN
{ $$
= FR_INRANGE
; }
1497 | YY_RANGE_OUT
{ $$
= FR_OUTRANGE
; }
1498 |
':' { $$
= FR_INCRANGE
; }
1505 interfacename: YY_STR
{ $$
= $1; }
1506 | YY_STR
':' YY_NUMBER
1508 fprintf
(stderr
, "%d: Logical interface %s:%d unsupported, "
1509 "use the physical interface %s instead.\n",
1510 yylineNum
, $1, $3, $1);
1514 name: YY_STR
{ $$
= $1; }
1518 YY_NUMBER
'.' YY_NUMBER
1519 { if
($1 > 255 ||
$3 > 255) {
1520 yyerror("Invalid octet string for IP address");
1523 $$.s_addr
= ($1 << 24) |
($3 << 16);
1524 $$.s_addr
= htonl
($$.s_addr
);
1529 ipv4_16
'.' YY_NUMBER
1531 yyerror("Invalid octet string for IP address");
1534 $$.s_addr |
= htonl
($3 << 8);
1538 ipv4: ipv4_24
'.' YY_NUMBER
1540 yyerror("Invalid octet string for IP address");
1543 $$.s_addr |
= htonl
($3);
1552 static struct wordtab ipfwords
[96] = {
1553 { "age", IPFY_AGE
},
1555 { "all", IPFY_ALL
},
1556 { "and", IPFY_AND
},
1557 { "auth", IPFY_AUTH
},
1558 { "bad", IPFY_BAD
},
1559 { "bad-nat", IPFY_BADNAT
},
1560 { "bad-src", IPFY_BADSRC
},
1561 { "bcast", IPFY_BROADCAST
},
1562 { "block", IPFY_BLOCK
},
1563 { "body", IPFY_BODY
},
1564 { "bpf-v4", IPFY_BPFV4
},
1566 { "bpf-v6", IPFY_BPFV6
},
1568 { "call", IPFY_CALL
},
1569 { "code", IPFY_ICMPCODE
},
1570 { "count", IPFY_COUNT
},
1571 { "dup-to", IPFY_DUPTO
},
1572 { "eq", YY_CMP_EQ
},
1573 { "esp", IPFY_ESP
},
1574 { "fastroute", IPFY_FROUTE
},
1575 { "first", IPFY_FIRST
},
1576 { "flags", IPFY_FLAGS
},
1577 { "frag", IPFY_FRAG
},
1578 { "frag-body", IPFY_FRAGBODY
},
1579 { "frags", IPFY_FRAGS
},
1580 { "from", IPFY_FROM
},
1581 { "ge", YY_CMP_GE
},
1582 { "group", IPFY_GROUP
},
1583 { "gt", YY_CMP_GT
},
1584 { "head", IPFY_HEAD
},
1585 { "icmp", IPFY_ICMP
},
1586 { "icmp-type", IPFY_ICMPTYPE
},
1588 { "in-via", IPFY_INVIA
},
1589 { "intercept_loopback", IPFY_SET_LOOPBACK
},
1590 { "ipopt", IPFY_IPOPTS
},
1591 { "ipopts", IPFY_IPOPTS
},
1592 { "keep", IPFY_KEEP
},
1593 { "le", YY_CMP_LE
},
1594 { "level", IPFY_LEVEL
},
1595 { "limit", IPFY_LIMIT
},
1596 { "log", IPFY_LOG
},
1597 { "lowttl", IPFY_LOWTTL
},
1598 { "lt", YY_CMP_LT
},
1599 { "mask", IPFY_MASK
},
1600 { "match-tag", IPFY_MATCHTAG
},
1601 { "mbcast", IPFY_MBCAST
},
1602 { "mcast", IPFY_MULTICAST
},
1603 { "multicast", IPFY_MULTICAST
},
1604 { "nat", IPFY_NAT
},
1605 { "ne", YY_CMP_NE
},
1606 { "net", IPFY_NETWORK
},
1607 { "newisn", IPFY_NEWISN
},
1609 { "no-icmp-err", IPFY_NOICMPERR
},
1610 { "now", IPFY_NOW
},
1611 { "not", IPFY_NOT
},
1612 { "oow", IPFY_OOW
},
1614 { "opt", IPFY_OPT
},
1615 { "or-block", IPFY_ORBLOCK
},
1616 { "out", IPFY_OUT
},
1617 { "out-via", IPFY_OUTVIA
},
1618 { "pass", IPFY_PASS
},
1619 { "port", IPFY_PORT
},
1620 { "pps", IPFY_PPS
},
1621 { "preauth", IPFY_PREAUTH
},
1622 { "proto", IPFY_PROTO
},
1623 { "quick", IPFY_QUICK
},
1624 { "reply-to", IPFY_REPLY_TO
},
1625 { "return-icmp", IPFY_RETICMP
},
1626 { "return-icmp-as-dest", IPFY_RETICMPASDST
},
1627 { "return-rst", IPFY_RETRST
},
1628 { "route-to", IPFY_ROUTETO
},
1629 { "sec-class", IPFY_SECCLASS
},
1630 { "set-tag", IPFY_SETTAG
},
1631 { "set", IPFY_SET
},
1632 { "skip", IPFY_SKIP
},
1633 { "short", IPFY_SHORT
},
1634 { "state", IPFY_STATE
},
1635 { "state-age", IPFY_AGE
},
1636 { "strict", IPFY_STRICT
},
1637 { "sync", IPFY_SYNC
},
1638 { "tcp", IPFY_TCP
},
1639 { "tcp-udp", IPFY_TCPUDP
},
1640 { "tos", IPFY_TOS
},
1642 { "ttl", IPFY_TTL
},
1643 { "udp", IPFY_UDP
},
1644 { "v6hdrs", IPF6_V6HDRS
},
1645 { "with", IPFY_WITH
},
1649 static struct wordtab addrwords
[4] = {
1650 { "any", IPFY_ANY
},
1651 { "hash", IPFY_HASH
},
1652 { "pool", IPFY_POOL
},
1656 static struct wordtab maskwords
[5] = {
1657 { "broadcast", IPFY_BROADCAST
},
1658 { "netmasked", IPFY_NETMASKED
},
1659 { "network", IPFY_NETWORK
},
1660 { "peer", IPFY_PEER
},
1664 static struct wordtab icmptypewords
[16] = {
1665 { "echo", IPFY_ICMPT_ECHO
},
1666 { "echorep", IPFY_ICMPT_ECHOR
},
1667 { "inforeq", IPFY_ICMPT_INFOREQ
},
1668 { "inforep", IPFY_ICMPT_INFOREP
},
1669 { "maskrep", IPFY_ICMPT_MASKREP
},
1670 { "maskreq", IPFY_ICMPT_MASKREQ
},
1671 { "paramprob", IPFY_ICMPT_PARAMP
},
1672 { "redir", IPFY_ICMPT_REDIR
},
1673 { "unreach", IPFY_ICMPT_UNR
},
1674 { "routerad", IPFY_ICMPT_ROUTERAD
},
1675 { "routersol", IPFY_ICMPT_ROUTERSOL
},
1676 { "squench", IPFY_ICMPT_SQUENCH
},
1677 { "timest", IPFY_ICMPT_TIMEST
},
1678 { "timestrep", IPFY_ICMPT_TIMESTREP
},
1679 { "timex", IPFY_ICMPT_TIMEX
},
1683 static struct wordtab icmpcodewords
[17] = {
1684 { "cutoff-preced", IPFY_ICMPC_CUTPRE
},
1685 { "filter-prohib", IPFY_ICMPC_FLTPRO
},
1686 { "isolate", IPFY_ICMPC_ISOLATE
},
1687 { "needfrag", IPFY_ICMPC_NEEDF
},
1688 { "net-prohib", IPFY_ICMPC_NETPRO
},
1689 { "net-tos", IPFY_ICMPC_NETTOS
},
1690 { "host-preced", IPFY_ICMPC_HSTPRE
},
1691 { "host-prohib", IPFY_ICMPC_HSTPRO
},
1692 { "host-tos", IPFY_ICMPC_HSTTOS
},
1693 { "host-unk", IPFY_ICMPC_HSTUNK
},
1694 { "host-unr", IPFY_ICMPC_HSTUNR
},
1695 { "net-unk", IPFY_ICMPC_NETUNK
},
1696 { "net-unr", IPFY_ICMPC_NETUNR
},
1697 { "port-unr", IPFY_ICMPC_PORUNR
},
1698 { "proto-unr", IPFY_ICMPC_PROUNR
},
1699 { "srcfail", IPFY_ICMPC_SRCFAIL
},
1703 static struct wordtab ipv4optwords
[25] = {
1704 { "addext", IPFY_IPOPT_ADDEXT
},
1705 { "cipso", IPFY_IPOPT_CIPSO
},
1706 { "dps", IPFY_IPOPT_DPS
},
1707 { "e-sec", IPFY_IPOPT_ESEC
},
1708 { "eip", IPFY_IPOPT_EIP
},
1709 { "encode", IPFY_IPOPT_ENCODE
},
1710 { "finn", IPFY_IPOPT_FINN
},
1711 { "imitd", IPFY_IPOPT_IMITD
},
1712 { "lsrr", IPFY_IPOPT_LSRR
},
1713 { "mtup", IPFY_IPOPT_MTUP
},
1714 { "mtur", IPFY_IPOPT_MTUR
},
1715 { "nop", IPFY_IPOPT_NOP
},
1716 { "nsapa", IPFY_IPOPT_NSAPA
},
1717 { "rr", IPFY_IPOPT_RR
},
1718 { "rtralrt", IPFY_IPOPT_RTRALRT
},
1719 { "satid", IPFY_IPOPT_SATID
},
1720 { "sdb", IPFY_IPOPT_SDB
},
1721 { "sec", IPFY_IPOPT_SEC
},
1722 { "ssrr", IPFY_IPOPT_SSRR
},
1723 { "tr", IPFY_IPOPT_TR
},
1724 { "ts", IPFY_IPOPT_TS
},
1725 { "ump", IPFY_IPOPT_UMP
},
1726 { "visa", IPFY_IPOPT_VISA
},
1727 { "zsu", IPFY_IPOPT_ZSU
},
1731 static struct wordtab ipv4secwords
[9] = {
1732 { "confid", IPFY_SEC_CONF
},
1733 { "reserv-1", IPFY_SEC_RSV1
},
1734 { "reserv-2", IPFY_SEC_RSV2
},
1735 { "reserv-3", IPFY_SEC_RSV3
},
1736 { "reserv-4", IPFY_SEC_RSV4
},
1737 { "secret", IPFY_SEC_SEC
},
1738 { "topsecret", IPFY_SEC_TS
},
1739 { "unclass", IPFY_SEC_UNC
},
1743 static struct wordtab ipv6optwords
[8] = {
1744 { "dstopts", IPFY_IPV6OPT_DSTOPTS
},
1745 { "esp", IPFY_ESP
},
1746 { "frag", IPFY_FRAG
},
1747 { "hopopts", IPFY_IPV6OPT_HOPOPTS
},
1748 { "ipv6", IPFY_IPV6OPT_IPV6
},
1749 { "none", IPFY_IPV6OPT_NONE
},
1750 { "routing", IPFY_IPV6OPT_ROUTING
},
1754 static struct wordtab logwords
[33] = {
1755 { "kern", IPFY_FAC_KERN
},
1756 { "user", IPFY_FAC_USER
},
1757 { "mail", IPFY_FAC_MAIL
},
1758 { "daemon", IPFY_FAC_DAEMON
},
1759 { "auth", IPFY_FAC_AUTH
},
1760 { "syslog", IPFY_FAC_SYSLOG
},
1761 { "lpr", IPFY_FAC_LPR
},
1762 { "news", IPFY_FAC_NEWS
},
1763 { "uucp", IPFY_FAC_UUCP
},
1764 { "cron", IPFY_FAC_CRON
},
1765 { "ftp", IPFY_FAC_FTP
},
1766 { "authpriv", IPFY_FAC_AUTHPRIV
},
1767 { "audit", IPFY_FAC_AUDIT
},
1768 { "logalert", IPFY_FAC_LFMT
},
1769 { "console", IPFY_FAC_CONSOLE
},
1770 { "security", IPFY_FAC_SECURITY
},
1771 { "local0", IPFY_FAC_LOCAL0
},
1772 { "local1", IPFY_FAC_LOCAL1
},
1773 { "local2", IPFY_FAC_LOCAL2
},
1774 { "local3", IPFY_FAC_LOCAL3
},
1775 { "local4", IPFY_FAC_LOCAL4
},
1776 { "local5", IPFY_FAC_LOCAL5
},
1777 { "local6", IPFY_FAC_LOCAL6
},
1778 { "local7", IPFY_FAC_LOCAL7
},
1779 { "emerg", IPFY_PRI_EMERG
},
1780 { "alert", IPFY_PRI_ALERT
},
1781 { "crit", IPFY_PRI_CRIT
},
1782 { "err", IPFY_PRI_ERR
},
1783 { "warn", IPFY_PRI_WARN
},
1784 { "notice", IPFY_PRI_NOTICE
},
1785 { "info", IPFY_PRI_INFO
},
1786 { "debug", IPFY_PRI_DEBUG
},
1793 int ipf_parsefile
(fd
, addfunc
, iocfuncs
, filename
)
1796 ioctlfunc_t
*iocfuncs
;
1805 s
= getenv
("YYDEBUG");
1811 if
(strcmp
(filename
, "-")) {
1812 fp
= fopen
(filename
, "r");
1814 fprintf
(stderr
, "fopen(%s) failed: %s\n", filename
,
1821 while
(ipf_parsesome
(fd
, addfunc
, iocfuncs
, fp
) == 1)
1829 int ipf_parsesome
(fd
, addfunc
, iocfuncs
, fp
)
1832 ioctlfunc_t
*iocfuncs
;
1839 for
(i
= 0; i
<= IPL_LOGMAX
; i
++)
1840 ipfioctl
[i
] = iocfuncs
[i
];
1841 ipfaddfunc
= addfunc
;
1848 if
(ungetc
(i
, fp
) == 0)
1852 s
= getenv
("YYDEBUG");
1864 static void newrule
()
1868 frn
= (frentry_t
*)calloc
(1, sizeof
(frentry_t
));
1870 yyerror("sorry, out of memory");
1871 for
(fr
= frtop
; fr
!= NULL
&& fr
->fr_next
!= NULL
; fr
= fr
->fr_next
)
1879 fr
->fr_loglevel
= 0xffff;
1880 fr
->fr_isc
= (void *)-1;
1881 fr
->fr_logtag
= FR_NOLOGTAG
;
1882 fr
->fr_type
= FR_T_NONE
;
1892 static void setipftype
()
1894 for
(fr
= frc
; fr
!= NULL
; fr
= fr
->fr_next
) {
1895 if
(fr
->fr_type
== FR_T_NONE
) {
1896 fr
->fr_type
= FR_T_IPF
;
1897 fr
->fr_data
= (void *)calloc
(sizeof
(fripf_t
), 1);
1898 if
(fr
->fr_data
== NULL
)
1899 yyerror("sorry, out of memory");
1900 fr
->fr_dsize
= sizeof
(fripf_t
);
1901 fr
->fr_ip.fi_v
= frc
->fr_v
;
1902 fr
->fr_mip.fi_v
= 0xf;
1903 fr
->fr_ipf
->fri_sifpidx
= -1;
1904 fr
->fr_ipf
->fri_difpidx
= -1;
1906 if
(fr
->fr_type
!= FR_T_IPF
) {
1907 fprintf
(stderr
, "IPF Type not set\n");
1913 static frentry_t
*addrule
()
1915 frentry_t
*f
, *f1
, *f2
;
1918 for
(f2
= frc
; f2
->fr_next
!= NULL
; f2
= f2
->fr_next
)
1923 f
= (frentry_t
*)calloc
(sizeof
(*f
), 1);
1925 yyerror("sorry, out of memory");
1928 bcopy
(f2
, f
, sizeof
(*f
));
1929 if
(f2
->fr_caddr
!= NULL
) {
1930 f
->fr_caddr
= malloc
(f
->fr_dsize
);
1931 if
(f
->fr_caddr
== NULL
)
1932 yyerror("sorry, out of memory");
1933 bcopy
(f2
->fr_caddr
, f
->fr_caddr
, f
->fr_dsize
);
1939 for
(f1
= frc
; count
> 0; count
--, f1
= f1
->fr_next
) {
1940 f
->fr_next
= (frentry_t
*)calloc
(sizeof
(*f
), 1);
1941 if
(f
->fr_next
== NULL
)
1942 yyerror("sorry, out of memory");
1945 bcopy
(f1
, f
, sizeof
(*f
));
1947 if
(f
->fr_caddr
!= NULL
) {
1948 f
->fr_caddr
= malloc
(f
->fr_dsize
);
1949 if
(f
->fr_caddr
== NULL
)
1950 yyerror("sorry, out of memory");
1951 bcopy
(f1
->fr_caddr
, f
->fr_caddr
, f
->fr_dsize
);
1959 static u_32_t lookuphost
(name
, addr
)
1969 for
(i
= 0; i
< 4; i
++) {
1970 if
(strncmp
(name
, frc
->fr_ifnames
[i
],
1971 sizeof
(frc
->fr_ifnames
[i
])) == 0) {
1972 ifpflag
= FRI_DYNAMIC
;
1978 if
(gethost
(name
, addr
, use_inet6
) == -1) {
1979 fprintf
(stderr
, "unknown name \"%s\"\n", name
);
1986 static void dobpf
(v
, phrase
)
1991 struct bpf_program bpf
;
1999 for
(fr
= frc
; fr
!= NULL
; fr
= fr
->fr_next
) {
2000 if
(fr
->fr_type
!= FR_T_NONE
) {
2001 fprintf
(stderr
, "cannot mix IPF and BPF matching\n");
2005 fr
->fr_type
= FR_T_BPFOPC
;
2007 if
(!strncmp
(phrase
, "\"0x", 2)) {
2009 fb
= malloc
(sizeof
(fakebpf_t
));
2011 yyerror("sorry, out of memory");
2013 for
(i
= 0, s
= strtok
(phrase
, " \r\n\t"); s
!= NULL
;
2014 s
= strtok
(NULL
, " \r\n\t"), i
++) {
2015 fb
= realloc
(fb
, (i
/ 4 + 1) * sizeof
(*fb
));
2017 yyerror("sorry, out of memory");
2018 l
= (u_32_t
)strtol
(s
, NULL
, 0);
2022 fb
[i
/ 4].fb_c
= l
& 0xffff;
2025 fb
[i
/ 4].fb_t
= l
& 0xff;
2028 fb
[i
/ 4].fb_f
= l
& 0xff;
2037 "Odd number of bytes in BPF code\n");
2041 fr
->fr_dsize
= (i
/ 4 + 1) * sizeof
(*fb
);
2047 bzero
((char *)&bpf
, sizeof
(bpf
));
2048 p
= pcap_open_dead
(DLT_RAW
, 1);
2050 fprintf
(stderr
, "pcap_open_dead failed\n");
2054 if
(pcap_compile
(p
, &bpf
, phrase
, 1, 0xffffffff)) {
2055 pcap_perror
(p
, "ipf");
2057 fprintf
(stderr
, "pcap parsing failed (%s)\n", phrase
);
2062 fr
->fr_dsize
= bpf.bf_len
* sizeof
(struct bpf_insn
);
2063 fr
->fr_data
= malloc
(fr
->fr_dsize
);
2064 if
(fr
->fr_data
== NULL
)
2065 yyerror("sorry, out of memory");
2066 bcopy
((char *)bpf.bf_insns
, fr
->fr_data
, fr
->fr_dsize
);
2067 if
(!bpf_validate
(fr
->fr_data
, bpf.bf_len
)) {
2068 fprintf
(stderr
, "BPF validation failed\n");
2075 if
(opts
& OPT_DEBUG
)
2078 fprintf
(stderr
, "BPF filter expressions not supported\n");
2084 static void resetaddr
()
2092 static alist_t
*newalist
(ptr
)
2097 al
= malloc
(sizeof
(*al
));
2106 static int makepool
(list
)
2109 ip_pool_node_t
*n
, *top
;
2116 top
= calloc
(1, sizeof
(*top
));
2120 for
(n
= top
, a
= list
; (n
!= NULL
) && (a
!= NULL
); a
= a
->al_next
) {
2121 n
->ipn_addr.adf_family
= a
->al_family
;
2122 n
->ipn_mask.adf_family
= a
->al_family
;
2123 (void *)bcopy
((void *)&a
->al_i6addr
,
2124 (void *)&n
->ipn_addr.adf_addr
,
2125 sizeof
(n
->ipn_addr.adf_addr
));
2126 (void *)bcopy
((void *)&a
->al_i6mask
,
2127 (void *)&n
->ipn_mask.adf_addr
,
2128 sizeof
(n
->ipn_mask.adf_addr
));
2129 n
->ipn_info
= a
->al_not
;
2130 if
(a
->al_next
!= NULL
) {
2131 n
->ipn_next
= calloc
(1, sizeof
(*n
));
2132 if
(n
->ipn_next
== NULL
)
2133 yyerror("sorry, out of memory");
2138 bzero
((char *)&pool
, sizeof
(pool
));
2139 pool.ipo_unit
= IPL_LOGIPF
;
2140 pool.ipo_list
= top
;
2141 num
= load_pool
(&pool
, ipfioctl
[IPL_LOGLOOKUP
]);
2143 while
((n
= top
) != NULL
) {
2151 static u_int makehash
(list
)
2161 top
= calloc
(1, sizeof
(*top
));
2165 for
(n
= top
, a
= list
; (n
!= NULL
) && (a
!= NULL
); a
= a
->al_next
) {
2166 n
->ipe_family
= a
->al_family
;
2167 (void *)bcopy
((void *)&a
->al_i6addr
,
2168 (void *)&n
->ipe_addr
,
2169 sizeof
(n
->ipe_addr
));
2170 (void *)bcopy
((void *)&a
->al_i6mask
,
2171 (void *)&n
->ipe_mask
,
2172 sizeof
(n
->ipe_mask
));
2174 if
(a
->al_next
!= NULL
) {
2175 n
->ipe_next
= calloc
(1, sizeof
(*n
));
2176 if
(n
->ipe_next
== NULL
)
2177 yyerror("sorry, out of memory");
2182 bzero
((char *)&iph
, sizeof
(iph
));
2183 iph.iph_unit
= IPL_LOGIPF
;
2184 iph.iph_type
= IPHASH_LOOKUP
;
2185 *iph.iph_name
= '\0';
2187 if
(load_hash
(&iph
, top
, ipfioctl
[IPL_LOGLOOKUP
]) == 0)
2188 sscanf
(iph.iph_name
, "%u", &num
);
2192 while
((n
= top
) != NULL
) {
2200 void ipf_addrule
(fd
, ioctlfunc
, ptr
)
2202 ioctlfunc_t ioctlfunc
;
2205 ioctlcmd_t add
, del
;
2213 bzero
((char *)&obj
, sizeof
(obj
));
2214 obj.ipfo_rev
= IPFILTER_VERSION
;
2215 obj.ipfo_size
= sizeof
(*fr
);
2216 obj.ipfo_type
= IPFOBJ_FRENTRY
;
2219 if
((opts
& OPT_DONOTHING
) != 0)
2222 if
(opts
& OPT_ZERORULEST
) {
2224 } else if
(opts
& OPT_INACTIVE
) {
2225 add
= (u_int
)fr
->fr_hits ? SIOCINIFR
:
2229 add
= (u_int
)fr
->fr_hits ? SIOCINAFR
:
2234 if
(fr
&& (opts
& OPT_OUTQUE
))
2235 fr
->fr_flags |
= FR_OUTQUE
;
2238 if
(fr
&& (opts
& OPT_VERBOSE
))
2239 printfr
(fr
, ioctlfunc
);
2241 if
(opts
& OPT_DEBUG
) {
2242 binprint
(fr
, sizeof
(*fr
));
2243 if
(fr
->fr_data
!= NULL
)
2244 binprint
(fr
->fr_data
, fr
->fr_dsize
);
2247 if
((opts
& OPT_ZERORULEST
) != 0) {
2248 if
((*ioctlfunc
)(fd
, add
, (void *)&obj
) == -1) {
2249 if
((opts
& OPT_DONOTHING
) == 0) {
2250 fprintf
(stderr
, "%d:", yylineNum
);
2251 perror
("ioctl(SIOCZRLST)");
2255 printf
("hits %qd bytes %qd ",
2256 (long long)fr
->fr_hits
,
2257 (long long)fr
->fr_bytes
);
2259 printf
("hits %ld bytes %ld ",
2260 fr
->fr_hits
, fr
->fr_bytes
);
2262 printfr
(fr
, ioctlfunc
);
2264 } else if
((opts
& OPT_REMOVE
) != 0) {
2265 if
((*ioctlfunc
)(fd
, del
, (void *)&obj
) == -1) {
2266 if
((opts
& OPT_DONOTHING
) != 0) {
2267 fprintf
(stderr
, "%d:", yylineNum
);
2268 perror
("ioctl(delete rule)");
2272 if
((*ioctlfunc
)(fd
, add
, (void *)&obj
) == -1) {
2273 if
(!(opts
& OPT_DONOTHING
)) {
2274 fprintf
(stderr
, "%d:", yylineNum
);
2275 perror
("ioctl(add/insert rule)");
2281 static void setsyslog
()
2283 yysetdict
(logwords
);
2288 static void unsetsyslog
()
2295 static void fillgroup
(fr
)
2300 for
(f
= frold
; f
!= NULL
; f
= f
->fr_next
)
2301 if
(strncmp
(f
->fr_grhead
, fr
->fr_group
, FR_GROUPLEN
) == 0)
2307 * Only copy down matching fields if the rules are of the same type
2308 * and are of ipf type. The only fields that are copied are those
2309 * that impact the rule parsing itself, eg. need for knowing what the
2310 * protocol should be for rules with port comparisons in them.
2312 if
(f
->fr_type
!= fr
->fr_type || f
->fr_type
!= FR_T_IPF
)
2315 if
(fr
->fr_v
== 0 && f
->fr_v
!= 0)
2318 if
(fr
->fr_mproto
== 0 && f
->fr_mproto
!= 0)
2319 fr
->fr_mproto
= f
->fr_mproto
;
2320 if
(fr
->fr_proto
== 0 && f
->fr_proto
!= 0)
2321 fr
->fr_proto
= f
->fr_proto
;
2323 if
((fr
->fr_mproto
== 0) && ((fr
->fr_flx
& FI_TCPUDP
) == 0) &&
2324 ((f
->fr_flx
& FI_TCPUDP
) != 0))
2325 fr
->fr_flx |
= FI_TCPUDP
;