5 * Copyright (C) 1997-1998 by Darren Reed.
7 * See the IPFILTER.LICENCE file for details on licencing.
9 * Id: iplang_y.y,v 2.9.2.5 2007/02/17 12:41:48 darrenr Exp
15 #if !defined(__SVR4) && !defined(__svr4__)
18 # include <sys/byteorder.h>
20 #include <sys/types.h>
22 #include <sys/param.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <netinet/in_systm.h>
30 #include <netinet/ip.h>
32 # include <netinet/ip_var.h>
35 # include "radix_ipf_local.h"
39 # include <netinet/if_ether.h>
42 #include <arpa/nameser.h>
43 #include <arpa/inet.h>
47 #include "ip_compat.h"
51 #if !defined(__NetBSD__) && (!defined(__FreeBSD_version) && \
52 __FreeBSD_version
< 400020) && (!SOLARIS || SOLARIS2
< 10)
53 extern
struct ether_addr
*ether_aton __P
((char *));
57 extern
struct ipopt_names ionames
[];
58 extern
int state
, state
, lineNum
, token
;
62 int yylex __P
((void));
64 #if !defined(ultrix) && !defined(hpux)
70 iface_t
*iflist
= NULL
, **iftail
= &iflist
;
72 arp_t
*arplist
= NULL
, **arptail
= &arplist
, *carp
= NULL
;
73 struct in_addr defrouter
;
76 u_short c_chksum __P
((u_short
*, u_int
, u_long
));
77 u_long p_chksum __P
((u_short
*, u_int
));
79 u_long ipbuffer
[67584/sizeof
(u_long
)]; /* 66K */
80 aniphdr_t
*aniphead
= NULL
, *canip
= NULL
, **aniptail
= &aniphead
;
84 icmphdr_t
*icmp
= NULL
;
91 struct in_addr getipv4addr __P
((char *arg
));
92 u_short getportnum __P
((char *, char *));
93 struct ether_addr
*geteaddr __P
((char *, struct ether_addr
*));
94 void *new_header __P
((int));
95 void free_aniplist __P
((void));
96 void inc_anipheaders __P
((int));
97 void new_data __P
((void));
98 void set_datalen __P
((char **));
99 void set_datafile __P
((char **));
100 void set_data __P
((char **));
101 void new_packet __P
((void));
102 void set_ipv4proto __P
((char **));
103 void set_ipv4src __P
((char **));
104 void set_ipv4dst __P
((char **));
105 void set_ipv4off __P
((char **));
106 void set_ipv4v __P
((char **));
107 void set_ipv4hl __P
((char **));
108 void set_ipv4ttl __P
((char **));
109 void set_ipv4tos __P
((char **));
110 void set_ipv4id __P
((char **));
111 void set_ipv4sum __P
((char **));
112 void set_ipv4len __P
((char **));
113 void new_tcpheader __P
((void));
114 void set_tcpsport __P
((char **));
115 void set_tcpdport __P
((char **));
116 void set_tcpseq __P
((char **));
117 void set_tcpack __P
((char **));
118 void set_tcpoff __P
((char **));
119 void set_tcpurp __P
((char **));
120 void set_tcpwin __P
((char **));
121 void set_tcpsum __P
((char **));
122 void set_tcpflags __P
((char **));
123 void set_tcpopt __P
((int, char **));
124 void end_tcpopt __P
((void));
125 void new_udpheader __P
((void));
126 void set_udplen __P
((char **));
127 void set_udpsum __P
((char **));
128 void prep_packet __P
((void));
129 void packet_done __P
((void));
130 void new_interface __P
((void));
131 void check_interface __P
((void));
132 void set_ifname __P
((char **));
133 void set_ifmtu __P
((int));
134 void set_ifv4addr __P
((char **));
135 void set_ifeaddr __P
((char **));
136 void new_arp __P
((void));
137 void set_arpeaddr __P
((char **));
138 void set_arpv4addr __P
((char **));
139 void reset_send __P
((void));
140 void set_sendif __P
((char **));
141 void set_sendvia __P
((char **));
142 void set_defaultrouter __P
((char **));
143 void new_icmpheader __P
((void));
144 void set_icmpcode __P
((int));
145 void set_icmptype __P
((int));
146 void set_icmpcodetok __P
((char **));
147 void set_icmptypetok __P
((char **));
148 void set_icmpid __P
((int));
149 void set_icmpseq __P
((int));
150 void set_icmpotime __P
((int));
151 void set_icmprtime __P
((int));
152 void set_icmpttime __P
((int));
153 void set_icmpmtu __P
((int));
154 void set_redir __P
((int, char **));
155 void new_ipv4opt __P
((void));
156 void set_icmppprob __P
((int));
157 void add_ipopt __P
((int, void *));
158 void end_ipopt __P
((void));
159 void set_secclass __P
((char **));
160 void free_anipheader __P
((void));
161 void end_ipv4 __P
((void));
162 void end_icmp __P
((void));
163 void end_udp __P
((void));
164 void end_tcp __P
((void));
165 void end_data __P
((void));
166 void yyerror __P
((char *));
167 void iplang __P
((FILE *));
168 int arp_getipv4 __P
((char *, char *));
169 int yyparse __P
((void));
175 %token
<num
> IL_NUMBER
176 %type
<num
> number digits optnumber
177 %token
<str
> IL_TOKEN
178 %type
<str
> token optoken
179 %token IL_HEXDIGIT IL_COLON IL_DOT IL_EOF IL_COMMENT
180 %token IL_INTERFACE IL_IFNAME IL_MTU IL_EADDR
181 %token IL_IPV4 IL_V4PROTO IL_V4SRC IL_V4DST IL_V4OFF IL_V4V IL_V4HL IL_V4TTL
182 %token IL_V4TOS IL_V4SUM IL_V4LEN IL_V4OPT IL_V4ID
183 %token IL_TCP IL_SPORT IL_DPORT IL_TCPFL IL_TCPSEQ IL_TCPACK IL_TCPOFF
184 %token IL_TCPWIN IL_TCPSUM IL_TCPURP IL_TCPOPT IL_TCPO_NOP IL_TCPO_EOL
185 %token IL_TCPO_MSS IL_TCPO_WSCALE IL_TCPO_TS
186 %token IL_UDP IL_UDPLEN IL_UDPSUM
187 %token IL_ICMP IL_ICMPTYPE IL_ICMPCODE
188 %token IL_SEND IL_VIA
191 %token IL_SUM IL_OFF IL_LEN IL_V4ADDR IL_OPT
192 %token IL_DATA IL_DLEN IL_DVALUE IL_DFILE
193 %token IL_IPO_NOP IL_IPO_RR IL_IPO_ZSU IL_IPO_MTUP IL_IPO_MTUR IL_IPO_EOL
194 %token IL_IPO_TS IL_IPO_TR IL_IPO_SEC IL_IPO_LSRR IL_IPO_ESEC
195 %token IL_IPO_SATID IL_IPO_SSRR IL_IPO_ADDEXT IL_IPO_VISA IL_IPO_IMITD
196 %token IL_IPO_EIP IL_IPO_FINN IL_IPO_SECCLASS IL_IPO_CIPSO IL_IPO_ENCODE
197 %token
<str
> IL_IPS_RESERV4 IL_IPS_TOPSECRET IL_IPS_SECRET IL_IPS_RESERV3
198 %token
<str
> IL_IPS_CONFID IL_IPS_UNCLASS IL_IPS_RESERV2 IL_IPS_RESERV1
199 %token IL_ICMP_ECHOREPLY IL_ICMP_UNREACH IL_ICMP_UNREACH_NET
200 %token IL_ICMP_UNREACH_HOST IL_ICMP_UNREACH_PROTOCOL IL_ICMP_UNREACH_PORT
201 %token IL_ICMP_UNREACH_NEEDFRAG IL_ICMP_UNREACH_SRCFAIL
202 %token IL_ICMP_UNREACH_NET_UNKNOWN IL_ICMP_UNREACH_HOST_UNKNOWN
203 %token IL_ICMP_UNREACH_ISOLATED IL_ICMP_UNREACH_NET_PROHIB
204 %token IL_ICMP_UNREACH_HOST_PROHIB IL_ICMP_UNREACH_TOSNET
205 %token IL_ICMP_UNREACH_TOSHOST IL_ICMP_UNREACH_FILTER_PROHIB
206 %token IL_ICMP_UNREACH_HOST_PRECEDENCE IL_ICMP_UNREACH_PRECEDENCE_CUTOFF
207 %token IL_ICMP_SOURCEQUENCH IL_ICMP_REDIRECT IL_ICMP_REDIRECT_NET
208 %token IL_ICMP_REDIRECT_HOST IL_ICMP_REDIRECT_TOSNET
209 %token IL_ICMP_REDIRECT_TOSHOST IL_ICMP_ECHO IL_ICMP_ROUTERADVERT
210 %token IL_ICMP_ROUTERSOLICIT IL_ICMP_TIMXCEED IL_ICMP_TIMXCEED_INTRANS
211 %token IL_ICMP_TIMXCEED_REASS IL_ICMP_PARAMPROB IL_ICMP_PARAMPROB_OPTABSENT
212 %token IL_ICMP_TSTAMP IL_ICMP_TSTAMPREPLY IL_ICMP_IREQ IL_ICMP_IREQREPLY
213 %token IL_ICMP_MASKREQ IL_ICMP_MASKREPLY IL_ICMP_SEQ IL_ICMP_ID
214 %token IL_ICMP_OTIME IL_ICMP_RTIME IL_ICMP_TTIME
230 iface: ifhdr
'{' ifaceopts
'}' ';' { check_interface
(); }
233 ifhdr: IL_INTERFACE
{ new_interface
(); }
242 IL_IFNAME token
{ set_ifname
(&$2); }
243 | IL_MTU number
{ set_ifmtu
($2); }
244 | IL_V4ADDR token
{ set_ifv4addr
(&$2); }
245 | IL_EADDR token
{ set_ifeaddr
(&$2); }
248 send: sendhdr
'{' sendbody
'}' ';' { packet_done
(); }
249 | sendhdr
';' { packet_done
(); }
253 IL_SEND
{ reset_send
(); }
262 IL_IFNAME token
{ set_sendif
(&$2); }
263 | IL_VIA token
{ set_sendvia
(&$2); }
266 arp: arphdr
'{' arpbody
'}' ';'
269 arphdr: IL_ARP
{ new_arp
(); }
277 arpopt: IL_V4ADDR token
{ set_arpv4addr
(&$2); }
278 | IL_EADDR token
{ set_arpeaddr
(&$2); }
282 IL_DEFROUTER token
{ set_defaultrouter
(&$2); }
293 ipline: ipv4
'{' ipv4body
'}' ';' { end_ipv4
(); }
296 ipv4: IL_IPV4
{ new_packet
(); }
305 IL_V4PROTO token
{ set_ipv4proto
(&$2); }
306 | IL_V4SRC token
{ set_ipv4src
(&$2); }
307 | IL_V4DST token
{ set_ipv4dst
(&$2); }
308 | IL_V4OFF token
{ set_ipv4off
(&$2); }
309 | IL_V4V token
{ set_ipv4v
(&$2); }
310 | IL_V4HL token
{ set_ipv4hl
(&$2); }
311 | IL_V4ID token
{ set_ipv4id
(&$2); }
312 | IL_V4TTL token
{ set_ipv4ttl
(&$2); }
313 | IL_V4TOS token
{ set_ipv4tos
(&$2); }
314 | IL_V4SUM token
{ set_ipv4sum
(&$2); }
315 | IL_V4LEN token
{ set_ipv4len
(&$2); }
316 | ipv4opt
'{' ipv4optlist
'}' ';' { end_ipopt
(); }
319 tcp: IL_TCP
{ new_tcpheader
(); }
323 '{' tcpheader
'}' ';' { end_tcp
(); }
333 IL_SPORT token
{ set_tcpsport
(&$2); }
334 | IL_DPORT token
{ set_tcpdport
(&$2); }
335 | IL_TCPSEQ token
{ set_tcpseq
(&$2); }
336 | IL_TCPACK token
{ set_tcpack
(&$2); }
337 | IL_TCPOFF token
{ set_tcpoff
(&$2); }
338 | IL_TCPURP token
{ set_tcpurp
(&$2); }
339 | IL_TCPWIN token
{ set_tcpwin
(&$2); }
340 | IL_TCPSUM token
{ set_tcpsum
(&$2); }
341 | IL_TCPFL token
{ set_tcpflags
(&$2); }
342 | IL_TCPOPT
'{' tcpopts
'}' ';' { end_tcpopt
(); }
349 tcpopt: IL_TCPO_NOP
';' { set_tcpopt
(IL_TCPO_NOP
, NULL
); }
350 | IL_TCPO_EOL
';' { set_tcpopt
(IL_TCPO_EOL
, NULL
); }
351 | IL_TCPO_MSS optoken
{ set_tcpopt
(IL_TCPO_MSS
,&$2);}
352 | IL_TCPO_WSCALE optoken
{ set_tcpopt
(IL_TCPO_WSCALE
,&$2);}
353 | IL_TCPO_TS optoken
{ set_tcpopt
(IL_TCPO_TS
, &$2);}
356 udp: IL_UDP
{ new_udpheader
(); }
360 '{' udpheader
'}' ';' { end_udp
(); }
371 IL_SPORT token
{ set_tcpsport
(&$2); }
372 | IL_DPORT token
{ set_tcpdport
(&$2); }
373 | IL_UDPLEN token
{ set_udplen
(&$2); }
374 | IL_UDPSUM token
{ set_udpsum
(&$2); }
377 icmp: IL_ICMP
{ new_icmpheader
(); }
381 '{' icmpbody
'}' ';' { end_icmp
(); }
386 | icmpheader bodyline
391 | IL_ICMPTYPE icmptype icmpcode
395 IL_ICMPCODE token
{ set_icmpcodetok
(&$2); }
399 IL_ICMP_ECHOREPLY
';' { set_icmptype
(ICMP_ECHOREPLY
); }
400 | IL_ICMP_ECHOREPLY
'{' icmpechoopts
'}' ';'
402 | IL_ICMP_SOURCEQUENCH
';' { set_icmptype
(ICMP_SOURCEQUENCH
); }
404 | IL_ICMP_ROUTERADVERT
';' { set_icmptype
(ICMP_ROUTERADVERT
); }
405 | IL_ICMP_ROUTERSOLICIT
';' { set_icmptype
(ICMP_ROUTERSOLICIT
); }
406 | IL_ICMP_ECHO
';' { set_icmptype
(ICMP_ECHO
); }
407 | IL_ICMP_ECHO
'{' icmpechoopts
'}' ';'
408 | IL_ICMP_TIMXCEED
';' { set_icmptype
(ICMP_TIMXCEED
); }
409 | IL_ICMP_TIMXCEED
'{' exceed
'}' ';'
410 | IL_ICMP_TSTAMP
';' { set_icmptype
(ICMP_TSTAMP
); }
411 | IL_ICMP_TSTAMPREPLY
';' { set_icmptype
(ICMP_TSTAMPREPLY
); }
412 | IL_ICMP_TSTAMPREPLY
'{' icmptsopts
'}' ';'
413 | IL_ICMP_IREQ
';' { set_icmptype
(ICMP_IREQ
); }
414 | IL_ICMP_IREQREPLY
';' { set_icmptype
(ICMP_IREQREPLY
); }
415 | IL_ICMP_IREQREPLY
'{' data dataline
'}' ';'
416 | IL_ICMP_MASKREQ
';' { set_icmptype
(ICMP_MASKREQ
); }
417 | IL_ICMP_MASKREPLY
';' { set_icmptype
(ICMP_MASKREPLY
); }
418 | IL_ICMP_MASKREPLY
'{' token
'}' ';'
419 | IL_ICMP_PARAMPROB
';' { set_icmptype
(ICMP_PARAMPROB
); }
420 | IL_ICMP_PARAMPROB
'{' paramprob
'}' ';'
421 | IL_TOKEN
';' { set_icmptypetok
(&$1); }
425 | icmpechoopts icmpecho
429 IL_ICMP_SEQ number
{ set_icmpseq
($2); }
430 | IL_ICMP_ID number
{ set_icmpid
($2); }
434 | icmptsopts icmpts
';'
437 icmpts: IL_ICMP_OTIME number
{ set_icmpotime
($2); }
438 | IL_ICMP_RTIME number
{ set_icmprtime
($2); }
439 | IL_ICMP_TTIME number
{ set_icmpttime
($2); }
444 | IL_ICMP_UNREACH
'{' unreachopts
'}' ';'
448 IL_ICMP_UNREACH_NET line
449 | IL_ICMP_UNREACH_HOST line
450 | IL_ICMP_UNREACH_PROTOCOL line
451 | IL_ICMP_UNREACH_PORT line
452 | IL_ICMP_UNREACH_NEEDFRAG number
';' { set_icmpmtu
($2); }
453 | IL_ICMP_UNREACH_SRCFAIL line
454 | IL_ICMP_UNREACH_NET_UNKNOWN line
455 | IL_ICMP_UNREACH_HOST_UNKNOWN line
456 | IL_ICMP_UNREACH_ISOLATED line
457 | IL_ICMP_UNREACH_NET_PROHIB line
458 | IL_ICMP_UNREACH_HOST_PROHIB line
459 | IL_ICMP_UNREACH_TOSNET line
460 | IL_ICMP_UNREACH_TOSHOST line
461 | IL_ICMP_UNREACH_FILTER_PROHIB line
462 | IL_ICMP_UNREACH_HOST_PRECEDENCE line
463 | IL_ICMP_UNREACH_PRECEDENCE_CUTOFF line
468 | IL_ICMP_REDIRECT
'{' redirectopts
'}' ';'
472 | IL_ICMP_REDIRECT_NET token
{ set_redir
(0, &$2); }
473 | IL_ICMP_REDIRECT_HOST token
{ set_redir
(1, &$2); }
474 | IL_ICMP_REDIRECT_TOSNET token
{ set_redir
(2, &$2); }
475 | IL_ICMP_REDIRECT_TOSHOST token
{ set_redir
(3, &$2); }
479 IL_ICMP_TIMXCEED_INTRANS line
480 | IL_ICMP_TIMXCEED_REASS line
484 IL_ICMP_PARAMPROB_OPTABSENT
485 | IL_ICMP_PARAMPROB_OPTABSENT paraprobarg
488 '{' number
'}' ';' { set_icmppprob
($2); }
491 ipv4opt: IL_V4OPT
{ new_ipv4opt
(); }
495 | ipv4opts ipv4optlist
499 IL_IPO_NOP
';' { add_ipopt
(IL_IPO_NOP
, NULL
); }
500 | IL_IPO_RR optnumber
{ add_ipopt
(IL_IPO_RR
, &$2); }
501 | IL_IPO_ZSU
';' { add_ipopt
(IL_IPO_ZSU
, NULL
); }
502 | IL_IPO_MTUP
';' { add_ipopt
(IL_IPO_MTUP
, NULL
); }
503 | IL_IPO_MTUR
';' { add_ipopt
(IL_IPO_MTUR
, NULL
); }
504 | IL_IPO_ENCODE
';' { add_ipopt
(IL_IPO_ENCODE
, NULL
); }
505 | IL_IPO_TS
';' { add_ipopt
(IL_IPO_TS
, NULL
); }
506 | IL_IPO_TR
';' { add_ipopt
(IL_IPO_TR
, NULL
); }
507 | IL_IPO_SEC
';' { add_ipopt
(IL_IPO_SEC
, NULL
); }
508 | IL_IPO_SECCLASS secclass
{ add_ipopt
(IL_IPO_SECCLASS
, sclass
); }
509 | IL_IPO_LSRR token
{ add_ipopt
(IL_IPO_LSRR
,&$2); }
510 | IL_IPO_ESEC
';' { add_ipopt
(IL_IPO_ESEC
, NULL
); }
511 | IL_IPO_CIPSO
';' { add_ipopt
(IL_IPO_CIPSO
, NULL
); }
512 | IL_IPO_SATID optnumber
{ add_ipopt
(IL_IPO_SATID
,&$2);}
513 | IL_IPO_SSRR token
{ add_ipopt
(IL_IPO_SSRR
,&$2); }
514 | IL_IPO_ADDEXT
';' { add_ipopt
(IL_IPO_ADDEXT
, NULL
); }
515 | IL_IPO_VISA
';' { add_ipopt
(IL_IPO_VISA
, NULL
); }
516 | IL_IPO_IMITD
';' { add_ipopt
(IL_IPO_IMITD
, NULL
); }
517 | IL_IPO_EIP
';' { add_ipopt
(IL_IPO_EIP
, NULL
); }
518 | IL_IPO_FINN
';' { add_ipopt
(IL_IPO_FINN
, NULL
); }
522 IL_IPS_RESERV4
';' { set_secclass
(&$1); }
523 | IL_IPS_TOPSECRET
';' { set_secclass
(&$1); }
524 | IL_IPS_SECRET
';' { set_secclass
(&$1); }
525 | IL_IPS_RESERV3
';' { set_secclass
(&$1); }
526 | IL_IPS_CONFID
';' { set_secclass
(&$1); }
527 | IL_IPS_UNCLASS
';' { set_secclass
(&$1); }
528 | IL_IPS_RESERV2
';' { set_secclass
(&$1); }
529 | IL_IPS_RESERV1
';' { set_secclass
(&$1); }
532 data: IL_DATA
{ new_data
(); }
536 '{' databody
'}' ';' { end_data
(); }
544 IL_DLEN token
{ set_datalen
(&$2); }
545 | IL_DVALUE token
{ set_data
(&$2); }
546 | IL_DFILE token
{ set_datafile
(&$2); }
552 optoken: ';' { $$
= ""; }
559 optnumber: ';' { $$
= 0; }
568 struct statetoopt toipopts
[] = {
569 { IL_IPO_NOP
, IPOPT_NOP
},
570 { IL_IPO_RR
, IPOPT_RR
},
571 { IL_IPO_ZSU
, IPOPT_ZSU
},
572 { IL_IPO_MTUP
, IPOPT_MTUP
},
573 { IL_IPO_MTUR
, IPOPT_MTUR
},
574 { IL_IPO_ENCODE
, IPOPT_ENCODE
},
575 { IL_IPO_TS
, IPOPT_TS
},
576 { IL_IPO_TR
, IPOPT_TR
},
577 { IL_IPO_SEC
, IPOPT_SECURITY
},
578 { IL_IPO_SECCLASS
, IPOPT_SECURITY
},
579 { IL_IPO_LSRR
, IPOPT_LSRR
},
580 { IL_IPO_ESEC
, IPOPT_E_SEC
},
581 { IL_IPO_CIPSO
, IPOPT_CIPSO
},
582 { IL_IPO_SATID
, IPOPT_SATID
},
583 { IL_IPO_SSRR
, IPOPT_SSRR
},
584 { IL_IPO_ADDEXT
, IPOPT_ADDEXT
},
585 { IL_IPO_VISA
, IPOPT_VISA
},
586 { IL_IPO_IMITD
, IPOPT_IMITD
},
587 { IL_IPO_EIP
, IPOPT_EIP
},
588 { IL_IPO_FINN
, IPOPT_FINN
},
592 struct statetoopt tosecopts
[] = {
593 { IL_IPS_RESERV4
, IPSO_CLASS_RES4
},
594 { IL_IPS_TOPSECRET
, IPSO_CLASS_TOPS
},
595 { IL_IPS_SECRET
, IPSO_CLASS_SECR
},
596 { IL_IPS_RESERV3
, IPSO_CLASS_RES3
},
597 { IL_IPS_CONFID
, IPSO_CLASS_CONF
},
598 { IL_IPS_UNCLASS
, IPSO_CLASS_UNCL
},
599 { IL_IPS_RESERV2
, IPSO_CLASS_RES2
},
600 { IL_IPS_RESERV1
, IPSO_CLASS_RES1
},
609 static struct ether_addr n
;
612 if
(sscanf
(s
, " %x:%x:%x:%x:%x:%x ", &i
[0], &i
[1],
613 &i
[2], &i
[3], &i
[4], &i
[5]) == 6) {
614 n.ether_addr_octet
[0] = (u_char
)i
[0];
615 n.ether_addr_octet
[1] = (u_char
)i
[1];
616 n.ether_addr_octet
[2] = (u_char
)i
[2];
617 n.ether_addr_octet
[3] = (u_char
)i
[3];
618 n.ether_addr_octet
[4] = (u_char
)i
[4];
619 n.ether_addr_octet
[5] = (u_char
)i
[5];
627 struct in_addr getipv4addr
(arg
)
633 in.s_addr
= 0xffffffff;
635 if
((hp
= gethostbyname
(arg
)))
636 bcopy
(hp
->h_addr
, &in.s_addr
, sizeof
(struct in_addr
));
638 in.s_addr
= inet_addr
(arg
);
643 u_short getportnum
(pr
, name
)
648 if
(!(sp
= getservbyname
(name
, pr
)))
649 return htons
(atoi
(name
));
654 struct ether_addr
*geteaddr
(arg
, buf
)
656 struct ether_addr
*buf
;
658 struct ether_addr
*e
;
660 #if !defined(hpux) && !defined(linux)
663 fprintf
(stderr
, "Invalid ethernet address: %s\n", arg
);
666 bcopy
(e
->octet
, buf
->octet
, sizeof
(e
->octet
));
668 bcopy
(e
->ether_addr_octet
, buf
->ether_addr_octet
,
669 sizeof
(e
->ether_addr_octet
));
678 void *new_header
(type
)
681 aniphdr_t
*aip
, *oip
= canip
;
684 aip
= (aniphdr_t
*)calloc
(1, sizeof
(*aip
));
686 aniptail
= &aip
->ah_next
;
691 if
(type
== IPPROTO_UDP
)
692 sz
= sizeof
(udphdr_t
);
693 else if
(type
== IPPROTO_TCP
)
694 sz
= sizeof
(tcphdr_t
);
695 else if
(type
== IPPROTO_ICMP
)
696 sz
= sizeof
(icmphdr_t
);
697 else if
(type
== IPPROTO_IP
)
701 canip
->ah_data
= oip
->ah_data
+ oip
->ah_len
;
703 canip
->ah_data
= (char *)ipbuffer
;
706 * Increase the size fields in all wrapping headers.
708 for
(aip
= aniphead
; aip
; aip
= aip
->ah_next
) {
710 if
(aip
->ah_p
== IPPROTO_IP
)
711 aip
->ah_ip
->ip_len
+= sz
;
712 else if
(aip
->ah_p
== IPPROTO_UDP
)
713 aip
->ah_udp
->uh_ulen
+= sz
;
715 return
(void *)canip
->ah_data
;
721 aniphdr_t
*aip
, **aipp
= &aniphead
;
723 while
((aip
= *aipp
)) {
724 *aipp
= aip
->ah_next
;
727 aniptail
= &aniphead
;
731 void inc_anipheaders
(inc
)
736 for
(aip
= aniphead
; aip
; aip
= aip
->ah_next
) {
738 if
(aip
->ah_p
== IPPROTO_IP
)
739 aip
->ah_ip
->ip_len
+= inc
;
740 else if
(aip
->ah_p
== IPPROTO_UDP
)
741 aip
->ah_udp
->uh_ulen
+= inc
;
748 (void) new_header
(-1);
753 void set_datalen
(arg
)
758 len
= strtol
(*arg
, NULL
, 0);
759 inc_anipheaders
(len
);
768 u_char
*s
= (u_char
*)*arg
, *t
= (u_char
*)canip
->ah_data
, c
;
769 int len
= 0, todo
= 0, quote
= 0, val
= 0;
776 fprintf
(stderr
, "octal with %c!\n", c
);
782 if
(!ISDIGIT
(c
) ||
!todo
) {
783 *t
++ = (u_char
)(val
& 0xff);
793 fprintf
(stderr
, "octal with %c!\n", c
);
827 *t
++ = (u_char
)(val
& 0xff);
830 len
= t
- (u_char
*)canip
->ah_data
;
831 inc_anipheaders
(len
- canip
->ah_len
);
836 void set_datafile
(arg
)
843 if
((fd
= open
(file
, O_RDONLY
)) == -1) {
848 if
(fstat
(fd
, &sb
) == -1) {
853 if
((sb.st_size
+ aniphead
->ah_len
) > 65535) {
854 fprintf
(stderr
, "data file %s too big to include.\n", file
);
858 if
((len
= read
(fd
, canip
->ah_data
, sb.st_size
)) == -1) {
863 inc_anipheaders
(len
);
864 canip
->ah_len
+= len
;
871 static u_short id
= 0;
874 bzero
((char *)ipbuffer
, sizeof
(ipbuffer
));
876 ip
= (ip_t
*)new_header
(IPPROTO_IP
);
877 ip
->ip_v
= IPVERSION
;
878 ip
->ip_hl
= sizeof
(ip_t
) >> 2;
879 ip
->ip_len
= sizeof
(ip_t
);
881 ip
->ip_id
= htons
(id
++);
885 void set_ipv4proto
(arg
)
890 if
((pr
= getprotobyname
(*arg
)))
891 ip
->ip_p
= pr
->p_proto
;
893 if
(!(ip
->ip_p
= atoi
(*arg
)))
894 fprintf
(stderr
, "unknown protocol %s\n", *arg
);
900 void set_ipv4src
(arg
)
903 ip
->ip_src
= getipv4addr
(*arg
);
909 void set_ipv4dst
(arg
)
912 ip
->ip_dst
= getipv4addr
(*arg
);
918 void set_ipv4off
(arg
)
921 ip
->ip_off
= htons
(strtol
(*arg
, NULL
, 0));
930 ip
->ip_v
= strtol
(*arg
, NULL
, 0);
941 newhl
= strtol
(*arg
, NULL
, 0);
942 inc
= (newhl
- ip
->ip_hl
) << 2;
945 canip
->ah_len
+= inc
;
951 void set_ipv4ttl
(arg
)
954 ip
->ip_ttl
= strtol
(*arg
, NULL
, 0);
960 void set_ipv4tos
(arg
)
963 ip
->ip_tos
= strtol
(*arg
, NULL
, 0);
972 ip
->ip_id
= htons
(strtol
(*arg
, NULL
, 0));
978 void set_ipv4sum
(arg
)
981 ip
->ip_sum
= strtol
(*arg
, NULL
, 0);
987 void set_ipv4len
(arg
)
992 len
= strtol
(*arg
, NULL
, 0);
993 inc_anipheaders
(len
- ip
->ip_len
);
1000 void new_tcpheader
()
1003 if
((ip
->ip_p
) && (ip
->ip_p
!= IPPROTO_TCP
)) {
1004 fprintf
(stderr
, "protocol %d specified with TCP!\n", ip
->ip_p
);
1007 ip
->ip_p
= IPPROTO_TCP
;
1009 tcp
= (tcphdr_t
*)new_header
(IPPROTO_TCP
);
1010 tcp
->th_win
= htons
(4096);
1011 tcp
->th_off
= sizeof
(*tcp
) >> 2;
1015 void set_tcpsport
(arg
)
1021 if
(ip
->ip_p
== IPPROTO_UDP
) {
1022 port
= &udp
->uh_sport
;
1025 port
= &tcp
->th_sport
;
1029 *port
= getportnum
(pr
, *arg
);
1035 void set_tcpdport
(arg
)
1041 if
(ip
->ip_p
== IPPROTO_UDP
) {
1042 port
= &udp
->uh_dport
;
1045 port
= &tcp
->th_dport
;
1049 *port
= getportnum
(pr
, *arg
);
1055 void set_tcpseq
(arg
)
1058 tcp
->th_seq
= htonl
(strtol
(*arg
, NULL
, 0));
1064 void set_tcpack
(arg
)
1067 tcp
->th_ack
= htonl
(strtol
(*arg
, NULL
, 0));
1073 void set_tcpoff
(arg
)
1078 off
= strtol
(*arg
, NULL
, 0);
1079 inc_anipheaders
((off
- tcp
->th_off
) << 2);
1086 void set_tcpurp
(arg
)
1089 tcp
->th_urp
= htons
(strtol
(*arg
, NULL
, 0));
1095 void set_tcpwin
(arg
)
1098 tcp
->th_win
= htons
(strtol
(*arg
, NULL
, 0));
1104 void set_tcpsum
(arg
)
1107 tcp
->th_sum
= strtol
(*arg
, NULL
, 0);
1113 void set_tcpflags
(arg
)
1116 static char flags
[] = "ASURPF";
1117 static int flagv
[] = { TH_ACK
, TH_SYN
, TH_URG
, TH_RST
, TH_PUSH
,
1121 for
(s
= *arg
; *s
; s
++)
1122 if
(!(t
= strchr
(flags
, *s
))) {
1124 fprintf
(stderr
, "unknown TCP flag %c\n", *s
);
1127 tcp
->th_flags
= strtol
(*arg
, NULL
, 0);
1130 tcp
->th_flags |
= flagv
[t
- flags
];
1136 void set_tcpopt
(state
, arg
)
1141 int val
, len
, val2
, pad
, optval
;
1148 s
= (u_char
*)tcp
+ sizeof
(*tcp
) + canip
->ah_optlen
;
1163 case IL_TCPO_WSCALE
:
1179 * prepend padding - if required.
1182 for
(pad
= 4 - (len
& 3); pad
; pad
--) {
1189 *s
++ = (u_char
)optval
;
1192 if
(len
== 3) { /* 1 byte - char */
1194 } else if
(len
== 4) { /* 2 bytes - short */
1195 *s
++ = (u_char
)((val
>> 8) & 0xff);
1196 *s
++ = (u_char
)(val
& 0xff);
1197 } else if
(len
>= 6) { /* 4 bytes - long */
1199 bcopy
((char *)&val2
, s
, 4);
1204 *s
++ = (u_char
)optval
;
1206 canip
->ah_lastopt
= optval
;
1207 canip
->ah_optlen
+= len
;
1219 char *s
= (char *)tcp
;
1221 s
+= sizeof
(*tcp
) + canip
->ah_optlen
;
1223 * pad out so that we have a multiple of 4 bytes in size fo the
1224 * options. make sure last byte is EOL.
1226 if
(canip
->ah_optlen
& 3) {
1227 if
(canip
->ah_lastopt
!= 1) {
1228 for
(pad
= 3 - (canip
->ah_optlen
& 3); pad
; pad
--) {
1236 for
(pad
= 3 - (canip
->ah_optlen
& 3); pad
; pad
--) {
1243 tcp
->th_off
= (sizeof
(*tcp
) + canip
->ah_optlen
) >> 2;
1244 inc_anipheaders
(canip
->ah_optlen
);
1248 void new_udpheader
()
1250 if
((ip
->ip_p
) && (ip
->ip_p
!= IPPROTO_UDP
)) {
1251 fprintf
(stderr
, "protocol %d specified with UDP!\n", ip
->ip_p
);
1254 ip
->ip_p
= IPPROTO_UDP
;
1256 udp
= (udphdr_t
*)new_header
(IPPROTO_UDP
);
1257 udp
->uh_ulen
= sizeof
(*udp
);
1261 void set_udplen
(arg
)
1266 len
= strtol
(*arg
, NULL
, 0);
1267 inc_anipheaders
(len
- udp
->uh_ulen
);
1274 void set_udpsum
(arg
)
1277 udp
->uh_sum
= strtol
(*arg
, NULL
, 0);
1286 struct in_addr gwip
;
1288 ifp
= sending.snd_if
;
1290 fprintf
(stderr
, "no interface defined for sending!\n");
1293 if
(ifp
->if_fd
== -1)
1294 ifp
->if_fd
= initdevice
(ifp
->if_name
, 5);
1295 gwip
= sending.snd_gw
;
1297 if
(aniphead
== NULL
) {
1299 "no destination address defined for sending\n");
1302 gwip
= aniphead
->ah_ip
->ip_dst
;
1304 (void) send_ip
(ifp
->if_fd
, ifp
->if_MTU
, (ip_t
*)ipbuffer
, gwip
, 2);
1312 u_char
*s
= (u_char
*)ipbuffer
, *t
= (u_char
*)outline
;
1314 if
(opts
& OPT_VERBOSE
) {
1315 ip
->ip_len
= htons
(ip
->ip_len
);
1316 for
(i
= ntohs
(ip
->ip_len
), j
= 0; i
; i
--, j
++, s
++) {
1317 if
(j
&& !(j
& 0xf)) {
1320 fputs
(outline
, stdout
);
1322 t
= (u_char
*)outline
;
1325 sprintf
((char *)t
, "%02x", *s
& 0xff);
1327 if
(!((j
+ 1) & 0xf)) {
1329 sprintf
((char *)t
, " ");
1331 for
(k
= 16; k
; k
--, s
++)
1332 *t
++ = (ISPRINT
(*s
) ?
*s
: '.');
1341 for
(k
= 16 - (j
& 0xf); k
; k
--) {
1346 sprintf
((char *)t
, " ");
1349 for
(k
= j
& 0xf; k
; k
--, s
++)
1350 *t
++ = (ISPRINT
(*s
) ?
*s
: '.');
1354 fputs
(outline
, stdout
);
1356 ip
->ip_len
= ntohs
(ip
->ip_len
);
1364 void new_interface
()
1366 cifp
= (iface_t
*)calloc
(1, sizeof
(iface_t
));
1368 iftail
= &cifp
->if_next
;
1373 void check_interface
()
1375 if
(!cifp
->if_name ||
!*cifp
->if_name
)
1376 fprintf
(stderr
, "No interface name given!\n");
1377 if
(!cifp
->if_MTU ||
!*cifp
->if_name
)
1378 fprintf
(stderr
, "Interface %s has an MTU of 0!\n",
1383 void set_ifname
(arg
)
1386 cifp
->if_name
= *arg
;
1398 void set_ifv4addr
(arg
)
1401 cifp
->if_addr
= getipv4addr
(*arg
);
1407 void set_ifeaddr
(arg
)
1410 (void) geteaddr
(*arg
, &cifp
->if_eaddr
);
1418 carp
= (arp_t
*)calloc
(1, sizeof
(arp_t
));
1420 arptail
= &carp
->arp_next
;
1424 void set_arpeaddr
(arg
)
1427 (void) geteaddr
(*arg
, &carp
->arp_eaddr
);
1433 void set_arpv4addr
(arg
)
1436 carp
->arp_addr
= getipv4addr
(*arg
);
1442 int arp_getipv4
(ip
, addr
)
1448 for
(a
= arplist
; a
; a
= a
->arp_next
)
1449 if
(!bcmp
(ip
, (char *)&a
->arp_addr
, 4)) {
1450 bcopy
((char *)&a
->arp_eaddr
, addr
, 6);
1459 sending.snd_if
= iflist
;
1460 sending.snd_gw
= defrouter
;
1464 void set_sendif
(arg
)
1469 for
(ifp
= iflist
; ifp
; ifp
= ifp
->if_next
)
1470 if
(ifp
->if_name
&& !strcmp
(ifp
->if_name
, *arg
))
1472 sending.snd_if
= ifp
;
1474 fprintf
(stderr
, "couldn't find interface %s\n", *arg
);
1480 void set_sendvia
(arg
)
1483 sending.snd_gw
= getipv4addr
(*arg
);
1489 void set_defaultrouter
(arg
)
1492 defrouter
= getipv4addr
(*arg
);
1498 void new_icmpheader
()
1500 if
((ip
->ip_p
) && (ip
->ip_p
!= IPPROTO_ICMP
)) {
1501 fprintf
(stderr
, "protocol %d specified with ICMP!\n",
1505 ip
->ip_p
= IPPROTO_ICMP
;
1506 icmp
= (icmphdr_t
*)new_header
(IPPROTO_ICMP
);
1510 void set_icmpcode
(code
)
1513 icmp
->icmp_code
= code
;
1517 void set_icmptype
(type
)
1520 icmp
->icmp_type
= type
;
1524 void set_icmpcodetok
(code
)
1530 for
(i
= 0; (s
= icmpcodes
[i
]); i
++)
1531 if
(!strcmp
(s
, *code
)) {
1532 icmp
->icmp_code
= i
;
1536 fprintf
(stderr
, "unknown ICMP code %s\n", *code
);
1542 void set_icmptypetok
(type
)
1548 for
(i
= 0; !(s
= icmptypes
[i
]) || strcmp
(s
, "END"); i
++)
1549 if
(s
&& !strcmp
(s
, *type
)) {
1550 icmp
->icmp_type
= i
;
1555 fprintf
(stderr
, "unknown ICMP type %s\n", *type
);
1561 void set_icmpid
(arg
)
1564 icmp
->icmp_id
= htons
(arg
);
1568 void set_icmpseq
(arg
)
1571 icmp
->icmp_seq
= htons
(arg
);
1575 void set_icmpotime
(arg
)
1578 icmp
->icmp_otime
= htonl
(arg
);
1582 void set_icmprtime
(arg
)
1585 icmp
->icmp_rtime
= htonl
(arg
);
1589 void set_icmpttime
(arg
)
1592 icmp
->icmp_ttime
= htonl
(arg
);
1596 void set_icmpmtu
(arg
)
1600 icmp
->icmp_nextmtu
= htons
(arg
);
1605 void set_redir
(redir
, arg
)
1609 icmp
->icmp_code
= redir
;
1610 icmp
->icmp_gwaddr
= getipv4addr
(*arg
);
1616 void set_icmppprob
(num
)
1619 icmp
->icmp_pptr
= num
;
1629 void add_ipopt
(state
, ptr
)
1633 struct ipopt_names
*io
;
1634 struct statetoopt
*sto
;
1635 char numbuf
[16], *arg
, **param
= ptr
;
1638 if
(state
== IL_IPO_RR || state
== IL_IPO_SATID
) {
1640 sprintf
(numbuf
, "%d", *(int *)param
);
1642 strcpy
(numbuf
, "0");
1645 arg
= param ?
*param
: NULL
;
1647 if
(canip
->ah_next
) {
1648 fprintf
(stderr
, "cannot specify options after data body\n");
1651 for
(sto
= toipopts
; sto
->sto_st
; sto
++)
1652 if
(sto
->sto_st
== state
)
1655 fprintf
(stderr
, "No mapping for state %d to IP option\n",
1660 hlen
= sizeof
(ip_t
) + canip
->ah_optlen
;
1661 for
(io
= ionames
; io
->on_name
; io
++)
1662 if
(io
->on_value
== sto
->sto_op
)
1664 canip
->ah_lastopt
= io
->on_value
;
1667 inc
= addipopt
((char *)ip
+ hlen
, io
, hlen
- sizeof
(ip_t
),arg
);
1670 ((char *)ip
)[sizeof
(*ip
) + inc
] = IPOPT_NOP
;
1671 canip
->ah_lastopt
= IPOPT_NOP
;
1678 canip
->ah_optlen
= hlen
- sizeof
(ip_t
);
1680 if
(state
!= IL_IPO_RR
&& state
!= IL_IPO_SATID
)
1681 if
(param
&& *param
) {
1692 char *s
, *buf
= (char *)ip
;
1695 * pad out so that we have a multiple of 4 bytes in size fo the
1696 * options. make sure last byte is EOL.
1698 if
(canip
->ah_lastopt
== IPOPT_NOP
) {
1699 buf
[sizeof
(*ip
) + canip
->ah_optlen
- 1] = IPOPT_EOL
;
1700 } else if
(canip
->ah_lastopt
!= IPOPT_EOL
) {
1701 s
= buf
+ sizeof
(*ip
) + canip
->ah_optlen
;
1703 for
(pad
= 3 - (canip
->ah_optlen
& 3); pad
; pad
--) {
1710 s
= buf
+ sizeof
(*ip
) + canip
->ah_optlen
- 1;
1712 for
(pad
= 3 - (canip
->ah_optlen
& 3); pad
; pad
--) {
1718 ip
->ip_hl
= (sizeof
(*ip
) + canip
->ah_optlen
) >> 2;
1719 inc_anipheaders
(canip
->ah_optlen
);
1724 void set_secclass
(arg
)
1732 void free_anipheader
()
1737 if
((canip
= aip
->ah_prev
)) {
1738 canip
->ah_next
= NULL
;
1739 aniptail
= &canip
->ah_next
;
1752 ip
->ip_len
= htons
(ip
->ip_len
);
1753 ip
->ip_sum
= chksum
((u_short
*)ip
, ip
->ip_hl
<< 2);
1754 ip
->ip_len
= ntohs
(ip
->ip_len
);
1756 for
(aip
= aniphead
, ip
= NULL
; aip
; aip
= aip
->ah_next
)
1757 if
(aip
->ah_p
== IPPROTO_IP
)
1766 icmp
->icmp_cksum
= 0;
1767 icmp
->icmp_cksum
= chksum
((u_short
*)icmp
, canip
->ah_len
);
1769 for
(aip
= aniphead
, icmp
= NULL
; aip
; aip
= aip
->ah_next
)
1770 if
(aip
->ah_p
== IPPROTO_ICMP
)
1771 icmp
= aip
->ah_icmp
;
1781 bzero
((char *)&iptmp
, sizeof
(iptmp
));
1782 iptmp.ip_p
= ip
->ip_p
;
1783 iptmp.ip_src
= ip
->ip_src
;
1784 iptmp.ip_dst
= ip
->ip_dst
;
1785 iptmp.ip_len
= htons
(ip
->ip_len
- (ip
->ip_hl
<< 2));
1786 sum
= p_chksum
((u_short
*)&iptmp
, (u_int
)sizeof
(iptmp
));
1787 udp
->uh_ulen
= htons
(udp
->uh_ulen
);
1788 udp
->uh_sum
= c_chksum
((u_short
*)udp
, (u_int
)ntohs
(iptmp.ip_len
), sum
);
1790 for
(aip
= aniphead
, udp
= NULL
; aip
; aip
= aip
->ah_next
)
1791 if
(aip
->ah_p
== IPPROTO_UDP
)
1802 bzero
((char *)&iptmp
, sizeof
(iptmp
));
1803 iptmp.ip_p
= ip
->ip_p
;
1804 iptmp.ip_src
= ip
->ip_src
;
1805 iptmp.ip_dst
= ip
->ip_dst
;
1806 iptmp.ip_len
= htons
(ip
->ip_len
- (ip
->ip_hl
<< 2));
1807 sum
= p_chksum
((u_short
*)&iptmp
, (u_int
)sizeof
(iptmp
));
1809 tcp
->th_sum
= c_chksum
((u_short
*)tcp
, (u_int
)ntohs
(iptmp.ip_len
), sum
);
1811 for
(aip
= aniphead
, tcp
= NULL
; aip
; aip
= aip
->ah_next
)
1812 if
(aip
->ah_p
== IPPROTO_TCP
)
1828 yydebug = (opts
& OPT_DEBUG
) ?
1 : 0;
1835 u_short c_chksum
(buf
, len
, init
)
1841 int nwords
= len
>> 1;
1843 for
(; nwords
> 0; nwords
--)
1845 sum
= (sum
>>16) + (sum
& 0xffff);
1851 u_long p_chksum
(buf
,len
)
1856 int nwords
= len
>> 1;
1858 for
(; nwords
> 0; nwords
--)