4 * Copyright (C) 2001-2004 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
10 #include <sys/ioctl.h>
15 #include "netinet/ip_scan.h"
20 extern
void yyerror __P
((char *));
21 extern
int yyparse __P
((void));
22 extern
int yylex __P
((void));
26 extern
void printbuf __P
((char *, int, int));
29 void printent __P
((ipscan_t
*));
30 void showlist __P
((void));
31 int getportnum __P
((char *));
32 struct in_addr gethostip __P
((char *));
33 struct in_addr combine __P
((int, int, int, int));
34 char **makepair __P
((char *, char *));
35 void addtag __P
((char *, char **, char **, struct action
*));
36 int cram __P
((char *, char *));
37 void usage __P
((char *));
38 int main __P
((int, char **));
56 %type
<act
> action redirect result
59 %type
<astr
> matchup onehalf twohalves
61 %token
<num
> YY_NUMBER YY_HEX
64 %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
65 %token YY_RANGE_OUT YY_RANGE_IN
67 %token IPSL_START IPSL_STARTGROUP IPSL_CONTENT
69 %token IPSL_CLOSE IPSL_TRACK IPSL_EOF IPSL_REDIRECT IPSL_ELSE
79 line: IPSL_START dline
80 | IPSL_STARTGROUP gline
84 dline: cline
{ resetlexer
(); }
85 | sline
{ resetlexer
(); }
86 | csline
{ resetlexer
(); }
89 gline: YY_STR
':' glist
'=' action
97 assign: YY_STR assigning YY_STR
98 { set_variable
($1, $3);
107 '=' { yyvarnext
= 1; }
110 cline: tag
':' matchup
'=' action
{ addtag
($1, $3, NULL
, &$5); }
113 sline: tag
':' '(' ')' ',' matchup
'=' action
{ addtag
($1, NULL
, $6, &$8); }
116 csline: tag
':' matchup
',' matchup
'=' action
{ addtag
($1, $3, $5, &$7); }
123 tag: YY_STR
{ $$
= $1; }
128 | twohalves
{ $$
= $1; }
131 action: result
{ $$.act_val
= $1.act_val
;
132 $$.act_ip
= $1.act_ip
;
133 $$.act_port
= $1.act_port
; }
134 | result IPSL_ELSE result
{ $$.act_val
= $1.act_val
;
135 $$.act_else
= $3.act_val
;
136 if
($1.act_val
== IPSL_REDIRECT
) {
137 $$.act_ip
= $1.act_ip
;
138 $$.act_port
= $1.act_port
;
140 if
($3.act_val
== IPSL_REDIRECT
) {
141 $$.act_eip
= $3.act_eip
;
142 $$.act_eport
= $3.act_eport
;
146 result: IPSL_CLOSE
{ $$.act_val
= IPSL_CLOSE
; }
147 | IPSL_TRACK
{ $$.act_val
= IPSL_TRACK
; }
148 | redirect
{ $$.act_val
= IPSL_REDIRECT
;
149 $$.act_ip
= $1.act_ip
;
150 $$.act_port
= $1.act_port
; }
154 '(' YY_STR
')' { $$
= makepair
($2, NULL
); }
158 '(' YY_STR
',' YY_STR
')' { $$
= makepair
($2, $4); }
162 IPSL_REDIRECT
'(' ipaddr
')' { $$.act_ip
= $3;
164 | IPSL_REDIRECT
'(' ipaddr
',' portnum
')'
170 ipaddr: YY_NUMBER
'.' YY_NUMBER
'.' YY_NUMBER
'.' YY_NUMBER
171 { $$
= combine
($1,$3,$5,$7); }
172 | YY_STR
{ $$
= gethostip
($1);
178 YY_NUMBER
{ $$
= htons
($1); }
179 | YY_STR
{ $$
= getportnum
($1);
187 static struct wordtab yywords
[] = {
188 { "close", IPSL_CLOSE
},
189 { "content", IPSL_CONTENT
},
190 { "else", IPSL_ELSE
},
191 { "start-group", IPSL_STARTGROUP
},
192 { "redirect", IPSL_REDIRECT
},
193 { "start", IPSL_START
},
194 { "track", IPSL_TRACK
},
210 for
(u
= dst
, i
= 0; (i
<= ISC_TLEN
) && (s
< t
); ) {
218 if
(j
&& (!ISDIGIT
(c
) ||
(c
> '7') ||
227 if
(ISALPHA
(c
) ||
(c
> '7')) {
243 } else if
(ISDIGIT
(c
)) {
250 } while
((i
<= ISC_TLEN
) && (s
<= t
) && (j
> 0));
261 char buf
[ISC_TLEN
+1];
265 buf
[ISC_TLEN
] = '\0';
266 bcopy
(isc
->ipsc_ctxt
, buf
, ISC_TLEN
);
267 printf
("%s : (\"", isc
->ipsc_tag
);
268 printbuf
(isc
->ipsc_ctxt
, isc
->ipsc_clen
, 0);
270 bcopy
(isc
->ipsc_cmsk
, buf
, ISC_TLEN
);
271 printf
("\", \"%s\"), (\"", buf
);
273 printbuf
(isc
->ipsc_stxt
, isc
->ipsc_slen
, 0);
275 bcopy
(isc
->ipsc_smsk
, buf
, ISC_TLEN
);
276 printf
("\", \"%s\") = ", buf
);
278 switch
(isc
->ipsc_action
)
283 case ISC_A_REDIRECT
:
285 printf
("(%s", inet_ntoa
(isc
->ipsc_ip
));
287 printf
(",%d", isc
->ipsc_port
);
297 if
(isc
->ipsc_else
!= ISC_A_NONE
) {
299 switch
(isc
->ipsc_else
)
304 case ISC_A_REDIRECT
:
306 printf
("(%s", inet_ntoa
(isc
->ipsc_eip
));
308 printf
(",%d", isc
->ipsc_eport
);
320 if
(opts
& OPT_DEBUG
) {
321 for
(u
= (u_char
*)isc
, i
= sizeof
(*isc
); i
; ) {
323 for
(j
= 32; (j
> 0) && (i
> 0); j
--, i
--)
324 printf
("%s%02x", (j
& 7) ?
"" : " ", *u
++);
328 if
(opts
& OPT_VERBOSE
) {
329 printf
("# hits %d active %d fref %d sref %d\n",
330 isc
->ipsc_hits
, isc
->ipsc_active
, isc
->ipsc_fref
,
336 void addtag
(tstr
, cp
, sp
, act
)
343 bzero
((char *)&isc
, sizeof
(isc
));
345 strncpy
(isc.ipsc_tag
, tstr
, sizeof
(isc.ipsc_tag
));
346 isc.ipsc_tag
[sizeof
(isc.ipsc_tag
) - 1] = '\0';
349 isc.ipsc_clen
= cram
(isc.ipsc_ctxt
, cp
[0]);
351 if
(cram
(isc.ipsc_cmsk
, cp
[1]) != isc.ipsc_clen
) {
353 "client text/mask strings different length\n");
360 isc.ipsc_slen
= cram
(isc.ipsc_stxt
, sp
[0]);
362 if
(cram
(isc.ipsc_smsk
, sp
[1]) != isc.ipsc_slen
) {
364 "server text/mask strings different length\n");
370 if
(act
->act_val
== IPSL_CLOSE
) {
371 isc.ipsc_action
= ISC_A_CLOSE
;
372 } else if
(act
->act_val
== IPSL_TRACK
) {
373 isc.ipsc_action
= ISC_A_TRACK
;
374 } else if
(act
->act_val
== IPSL_REDIRECT
) {
375 isc.ipsc_action
= ISC_A_REDIRECT
;
376 isc.ipsc_ip
= act
->act_ip
;
377 isc.ipsc_port
= act
->act_port
;
378 fprintf
(stderr
, "%d: redirect unsupported\n", yylineNum
+ 1);
381 if
(act
->act_else
== IPSL_CLOSE
) {
382 isc.ipsc_else
= ISC_A_CLOSE
;
383 } else if
(act
->act_else
== IPSL_TRACK
) {
384 isc.ipsc_else
= ISC_A_TRACK
;
385 } else if
(act
->act_else
== IPSL_REDIRECT
) {
386 isc.ipsc_else
= ISC_A_REDIRECT
;
387 isc.ipsc_eip
= act
->act_eip
;
388 isc.ipsc_eport
= act
->act_eport
;
389 fprintf
(stderr
, "%d: redirect unsupported\n", yylineNum
+ 1);
392 if
(!(opts
& OPT_DONOTHING
)) {
394 if
(opts
& OPT_REMOVE
) {
395 if
(ioctl
(fd
, SIOCRMSCA
, &iscp
) == -1)
398 if
(ioctl
(fd
, SIOCADSCA
, &iscp
) == -1)
403 if
(opts
& OPT_VERBOSE
)
408 char **makepair
(s1
, s2
)
413 a
= malloc
(sizeof
(char *) * 2);
420 struct in_addr combine
(a1
, a2
, a3
, a4
)
426 in.s_addr
= a1
<< 24;
428 in.s_addr |
= (a2
<< 16);
430 in.s_addr |
= (a3
<< 8);
433 in.s_addr
= htonl
(in.s_addr
);
438 struct in_addr gethostip
(host
)
446 hp
= gethostbyname
(host
);
449 bcopy
(hp
->h_addr
, (char *)&in
, sizeof
(in
));
459 s
= getservbyname
(port
, "tcp");
468 ipscanstat_t ipsc
, *ipscp
= &ipsc
;
471 if
(ioctl
(fd
, SIOCGSCST
, &ipscp
) == -1)
472 perror
("ioctl(SIOCGSCST)");
473 else if
(opts
& OPT_SHOWLIST
) {
474 while
(ipsc.iscs_list
!= NULL
) {
475 if
(kmemcpy
((char *)&isc
, (u_long
)ipsc.iscs_list
,
476 sizeof
(isc
)) == -1) {
481 ipsc.iscs_list
= isc.ipsc_next
;
485 printf
("scan entries loaded\t%d\n", ipsc.iscs_entries
);
486 printf
("scan entries matches\t%ld\n", ipsc.iscs_acted
);
487 printf
("negative matches\t%ld\n", ipsc.iscs_else
);
495 fprintf
(stderr
, "Usage:\t%s [-dnrv] -f <filename>\n", prog
);
496 fprintf
(stderr
, "\t%s [-dlv]\n", prog
);
508 (void) yysettab
(yywords
);
513 while
((c
= getopt
(argc
, argv
, "df:lnrsv")) != -1)
521 if
(!strcmp
(optarg
, "-"))
524 fp
= fopen
(optarg
, "r");
533 opts |
= OPT_SHOWLIST
;
536 opts |
= OPT_DONOTHING
;
549 if
(!(opts
& OPT_DONOTHING
)) {
550 fd
= open
(IPL_SCAN
, O_RDWR
);
552 perror
("open(IPL_SCAN)");
566 if
(opts
& (OPT_SHOWLIST|OPT_STAT
)) {