1 1.2 darrenr /* $NetBSD: iplang_y.y,v 1.2 2012/07/22 14:27:35 darrenr Exp $ */ 2 1.1 christos 3 1.1 christos %{ 4 1.1 christos /* 5 1.2 darrenr * Copyright (C) 2012 by Darren Reed. 6 1.1 christos * 7 1.1 christos * See the IPFILTER.LICENCE file for details on licencing. 8 1.1 christos * 9 1.2 darrenr * Id: iplang_y.y,v 1.1.1.2 2012/07/22 13:44:34 darrenr Exp $ 10 1.1 christos */ 11 1.1 christos 12 1.1 christos #include <stdio.h> 13 1.1 christos #include <string.h> 14 1.1 christos #include <fcntl.h> 15 1.1 christos #if !defined(__SVR4) && !defined(__svr4__) 16 1.1 christos # include <strings.h> 17 1.1 christos #else 18 1.1 christos # include <sys/byteorder.h> 19 1.1 christos #endif 20 1.1 christos #include <sys/types.h> 21 1.1 christos #include <sys/stat.h> 22 1.1 christos #include <sys/param.h> 23 1.1 christos #include <sys/time.h> 24 1.1 christos #include <stdlib.h> 25 1.1 christos #include <unistd.h> 26 1.1 christos #include <stddef.h> 27 1.1 christos #include <sys/socket.h> 28 1.1 christos #include <net/if.h> 29 1.1 christos #include <netinet/in.h> 30 1.1 christos #include <netinet/in_systm.h> 31 1.1 christos #include <netinet/ip.h> 32 1.1 christos #ifndef linux 33 1.1 christos # include <netinet/ip_var.h> 34 1.1 christos # include <net/route.h> 35 1.1 christos # include <netinet/if_ether.h> 36 1.1 christos #endif 37 1.1 christos #include <netdb.h> 38 1.1 christos #include <arpa/nameser.h> 39 1.1 christos #include <arpa/inet.h> 40 1.1 christos #include <resolv.h> 41 1.1 christos #include <ctype.h> 42 1.1 christos #include "ipsend.h" 43 1.1 christos #include "ip_compat.h" 44 1.1 christos #include "ipf.h" 45 1.1 christos #include "iplang.h" 46 1.1 christos 47 1.1 christos #if !defined(__NetBSD__) && (!defined(__FreeBSD_version) && \ 48 1.1 christos __FreeBSD_version < 400020) && (!SOLARIS || SOLARIS2 < 10) 49 1.1 christos extern struct ether_addr *ether_aton __P((char *)); 50 1.1 christos #endif 51 1.1 christos 52 1.1 christos extern int opts; 53 1.1 christos extern struct ipopt_names ionames[]; 54 1.1 christos extern int state, state, lineNum, token; 55 1.1 christos extern int yylineno; 56 1.1 christos extern char yytext[]; 57 1.1 christos extern FILE *yyin; 58 1.1 christos int yylex __P((void)); 59 1.1 christos #define YYDEBUG 1 60 1.1 christos #if !defined(ultrix) && !defined(hpux) 61 1.1 christos int yydebug = 1; 62 1.1 christos #else 63 1.1 christos extern int yydebug; 64 1.1 christos #endif 65 1.1 christos 66 1.1 christos iface_t *iflist = NULL, **iftail = &iflist; 67 1.1 christos iface_t *cifp = NULL; 68 1.1 christos arp_t *arplist = NULL, **arptail = &arplist, *carp = NULL; 69 1.1 christos struct in_addr defrouter; 70 1.1 christos send_t sending; 71 1.1 christos char *sclass = NULL; 72 1.1 christos u_short c_chksum __P((u_short *, u_int, u_long)); 73 1.1 christos u_long p_chksum __P((u_short *, u_int)); 74 1.1 christos 75 1.1 christos u_long ipbuffer[67584/sizeof(u_long)]; /* 66K */ 76 1.1 christos aniphdr_t *aniphead = NULL, *canip = NULL, **aniptail = &aniphead; 77 1.1 christos ip_t *ip = NULL; 78 1.1 christos udphdr_t *udp = NULL; 79 1.1 christos tcphdr_t *tcp = NULL; 80 1.1 christos icmphdr_t *icmp = NULL; 81 1.1 christos 82 1.1 christos struct statetoopt { 83 1.1 christos int sto_st; 84 1.1 christos int sto_op; 85 1.1 christos }; 86 1.1 christos 87 1.1 christos struct in_addr getipv4addr __P((char *arg)); 88 1.1 christos u_short getportnum __P((char *, char *)); 89 1.1 christos struct ether_addr *geteaddr __P((char *, struct ether_addr *)); 90 1.1 christos void *new_header __P((int)); 91 1.1 christos void free_aniplist __P((void)); 92 1.1 christos void inc_anipheaders __P((int)); 93 1.1 christos void new_data __P((void)); 94 1.1 christos void set_datalen __P((char **)); 95 1.1 christos void set_datafile __P((char **)); 96 1.1 christos void set_data __P((char **)); 97 1.1 christos void new_packet __P((void)); 98 1.1 christos void set_ipv4proto __P((char **)); 99 1.1 christos void set_ipv4src __P((char **)); 100 1.1 christos void set_ipv4dst __P((char **)); 101 1.1 christos void set_ipv4off __P((char **)); 102 1.1 christos void set_ipv4v __P((char **)); 103 1.1 christos void set_ipv4hl __P((char **)); 104 1.1 christos void set_ipv4ttl __P((char **)); 105 1.1 christos void set_ipv4tos __P((char **)); 106 1.1 christos void set_ipv4id __P((char **)); 107 1.1 christos void set_ipv4sum __P((char **)); 108 1.1 christos void set_ipv4len __P((char **)); 109 1.1 christos void new_tcpheader __P((void)); 110 1.1 christos void set_tcpsport __P((char **)); 111 1.1 christos void set_tcpdport __P((char **)); 112 1.1 christos void set_tcpseq __P((char **)); 113 1.1 christos void set_tcpack __P((char **)); 114 1.1 christos void set_tcpoff __P((char **)); 115 1.1 christos void set_tcpurp __P((char **)); 116 1.1 christos void set_tcpwin __P((char **)); 117 1.1 christos void set_tcpsum __P((char **)); 118 1.1 christos void set_tcpflags __P((char **)); 119 1.1 christos void set_tcpopt __P((int, char **)); 120 1.1 christos void end_tcpopt __P((void)); 121 1.1 christos void new_udpheader __P((void)); 122 1.1 christos void set_udplen __P((char **)); 123 1.1 christos void set_udpsum __P((char **)); 124 1.1 christos void prep_packet __P((void)); 125 1.1 christos void packet_done __P((void)); 126 1.1 christos void new_interface __P((void)); 127 1.1 christos void check_interface __P((void)); 128 1.1 christos void set_ifname __P((char **)); 129 1.1 christos void set_ifmtu __P((int)); 130 1.1 christos void set_ifv4addr __P((char **)); 131 1.1 christos void set_ifeaddr __P((char **)); 132 1.1 christos void new_arp __P((void)); 133 1.1 christos void set_arpeaddr __P((char **)); 134 1.1 christos void set_arpv4addr __P((char **)); 135 1.1 christos void reset_send __P((void)); 136 1.1 christos void set_sendif __P((char **)); 137 1.1 christos void set_sendvia __P((char **)); 138 1.1 christos void set_defaultrouter __P((char **)); 139 1.1 christos void new_icmpheader __P((void)); 140 1.1 christos void set_icmpcode __P((int)); 141 1.1 christos void set_icmptype __P((int)); 142 1.1 christos void set_icmpcodetok __P((char **)); 143 1.1 christos void set_icmptypetok __P((char **)); 144 1.1 christos void set_icmpid __P((int)); 145 1.1 christos void set_icmpseq __P((int)); 146 1.1 christos void set_icmpotime __P((int)); 147 1.1 christos void set_icmprtime __P((int)); 148 1.1 christos void set_icmpttime __P((int)); 149 1.1 christos void set_icmpmtu __P((int)); 150 1.1 christos void set_redir __P((int, char **)); 151 1.1 christos void new_ipv4opt __P((void)); 152 1.1 christos void set_icmppprob __P((int)); 153 1.1 christos void add_ipopt __P((int, void *)); 154 1.1 christos void end_ipopt __P((void)); 155 1.1 christos void set_secclass __P((char **)); 156 1.1 christos void free_anipheader __P((void)); 157 1.1 christos void end_ipv4 __P((void)); 158 1.1 christos void end_icmp __P((void)); 159 1.1 christos void end_udp __P((void)); 160 1.1 christos void end_tcp __P((void)); 161 1.1 christos void end_data __P((void)); 162 1.1 christos void yyerror __P((char *)); 163 1.1 christos void iplang __P((FILE *)); 164 1.1 christos int arp_getipv4 __P((char *, char *)); 165 1.1 christos int yyparse __P((void)); 166 1.1 christos %} 167 1.1 christos %union { 168 1.1 christos char *str; 169 1.1 christos int num; 170 1.1 christos } 171 1.1 christos %token <num> IL_NUMBER 172 1.1 christos %type <num> number digits optnumber 173 1.1 christos %token <str> IL_TOKEN 174 1.1 christos %type <str> token optoken 175 1.1 christos %token IL_HEXDIGIT IL_COLON IL_DOT IL_EOF IL_COMMENT 176 1.1 christos %token IL_INTERFACE IL_IFNAME IL_MTU IL_EADDR 177 1.1 christos %token IL_IPV4 IL_V4PROTO IL_V4SRC IL_V4DST IL_V4OFF IL_V4V IL_V4HL IL_V4TTL 178 1.1 christos %token IL_V4TOS IL_V4SUM IL_V4LEN IL_V4OPT IL_V4ID 179 1.1 christos %token IL_TCP IL_SPORT IL_DPORT IL_TCPFL IL_TCPSEQ IL_TCPACK IL_TCPOFF 180 1.1 christos %token IL_TCPWIN IL_TCPSUM IL_TCPURP IL_TCPOPT IL_TCPO_NOP IL_TCPO_EOL 181 1.1 christos %token IL_TCPO_MSS IL_TCPO_WSCALE IL_TCPO_TS 182 1.1 christos %token IL_UDP IL_UDPLEN IL_UDPSUM 183 1.1 christos %token IL_ICMP IL_ICMPTYPE IL_ICMPCODE 184 1.1 christos %token IL_SEND IL_VIA 185 1.1 christos %token IL_ARP 186 1.1 christos %token IL_DEFROUTER 187 1.1 christos %token IL_SUM IL_OFF IL_LEN IL_V4ADDR IL_OPT 188 1.1 christos %token IL_DATA IL_DLEN IL_DVALUE IL_DFILE 189 1.1 christos %token IL_IPO_NOP IL_IPO_RR IL_IPO_ZSU IL_IPO_MTUP IL_IPO_MTUR IL_IPO_EOL 190 1.1 christos %token IL_IPO_TS IL_IPO_TR IL_IPO_SEC IL_IPO_LSRR IL_IPO_ESEC 191 1.1 christos %token IL_IPO_SATID IL_IPO_SSRR IL_IPO_ADDEXT IL_IPO_VISA IL_IPO_IMITD 192 1.1 christos %token IL_IPO_EIP IL_IPO_FINN IL_IPO_SECCLASS IL_IPO_CIPSO IL_IPO_ENCODE 193 1.1 christos %token <str> IL_IPS_RESERV4 IL_IPS_TOPSECRET IL_IPS_SECRET IL_IPS_RESERV3 194 1.1 christos %token <str> IL_IPS_CONFID IL_IPS_UNCLASS IL_IPS_RESERV2 IL_IPS_RESERV1 195 1.1 christos %token IL_ICMP_ECHOREPLY IL_ICMP_UNREACH IL_ICMP_UNREACH_NET 196 1.1 christos %token IL_ICMP_UNREACH_HOST IL_ICMP_UNREACH_PROTOCOL IL_ICMP_UNREACH_PORT 197 1.1 christos %token IL_ICMP_UNREACH_NEEDFRAG IL_ICMP_UNREACH_SRCFAIL 198 1.1 christos %token IL_ICMP_UNREACH_NET_UNKNOWN IL_ICMP_UNREACH_HOST_UNKNOWN 199 1.1 christos %token IL_ICMP_UNREACH_ISOLATED IL_ICMP_UNREACH_NET_PROHIB 200 1.1 christos %token IL_ICMP_UNREACH_HOST_PROHIB IL_ICMP_UNREACH_TOSNET 201 1.1 christos %token IL_ICMP_UNREACH_TOSHOST IL_ICMP_UNREACH_FILTER_PROHIB 202 1.1 christos %token IL_ICMP_UNREACH_HOST_PRECEDENCE IL_ICMP_UNREACH_PRECEDENCE_CUTOFF 203 1.1 christos %token IL_ICMP_SOURCEQUENCH IL_ICMP_REDIRECT IL_ICMP_REDIRECT_NET 204 1.1 christos %token IL_ICMP_REDIRECT_HOST IL_ICMP_REDIRECT_TOSNET 205 1.1 christos %token IL_ICMP_REDIRECT_TOSHOST IL_ICMP_ECHO IL_ICMP_ROUTERADVERT 206 1.1 christos %token IL_ICMP_ROUTERSOLICIT IL_ICMP_TIMXCEED IL_ICMP_TIMXCEED_INTRANS 207 1.1 christos %token IL_ICMP_TIMXCEED_REASS IL_ICMP_PARAMPROB IL_ICMP_PARAMPROB_OPTABSENT 208 1.1 christos %token IL_ICMP_TSTAMP IL_ICMP_TSTAMPREPLY IL_ICMP_IREQ IL_ICMP_IREQREPLY 209 1.1 christos %token IL_ICMP_MASKREQ IL_ICMP_MASKREPLY IL_ICMP_SEQ IL_ICMP_ID 210 1.1 christos %token IL_ICMP_OTIME IL_ICMP_RTIME IL_ICMP_TTIME 211 1.1 christos 212 1.1 christos %% 213 1.1 christos file: line 214 1.1 christos | line file 215 1.1 christos | IL_COMMENT 216 1.1 christos | IL_COMMENT file 217 1.1 christos ; 218 1.1 christos 219 1.1 christos line: iface 220 1.1 christos | arp 221 1.1 christos | send 222 1.1 christos | defrouter 223 1.1 christos | ipline 224 1.1 christos ; 225 1.1 christos 226 1.1 christos iface: ifhdr '{' ifaceopts '}' ';' { check_interface(); } 227 1.1 christos ; 228 1.1 christos 229 1.1 christos ifhdr: IL_INTERFACE { new_interface(); } 230 1.1 christos ; 231 1.1 christos 232 1.1 christos ifaceopts: 233 1.1 christos ifaceopt 234 1.1 christos | ifaceopt ifaceopts 235 1.1 christos ; 236 1.1 christos 237 1.1 christos ifaceopt: 238 1.1 christos IL_IFNAME token { set_ifname(&$2); } 239 1.1 christos | IL_MTU number { set_ifmtu($2); } 240 1.1 christos | IL_V4ADDR token { set_ifv4addr(&$2); } 241 1.1 christos | IL_EADDR token { set_ifeaddr(&$2); } 242 1.1 christos ; 243 1.1 christos 244 1.1 christos send: sendhdr '{' sendbody '}' ';' { packet_done(); } 245 1.1 christos | sendhdr ';' { packet_done(); } 246 1.1 christos ; 247 1.1 christos 248 1.1 christos sendhdr: 249 1.1 christos IL_SEND { reset_send(); } 250 1.1 christos ; 251 1.1 christos 252 1.1 christos sendbody: 253 1.1 christos sendopt 254 1.1 christos | sendbody sendopt 255 1.1 christos ; 256 1.1 christos 257 1.1 christos sendopt: 258 1.1 christos IL_IFNAME token { set_sendif(&$2); } 259 1.1 christos | IL_VIA token { set_sendvia(&$2); } 260 1.1 christos ; 261 1.1 christos 262 1.1 christos arp: arphdr '{' arpbody '}' ';' 263 1.1 christos ; 264 1.1 christos 265 1.1 christos arphdr: IL_ARP { new_arp(); } 266 1.1 christos ; 267 1.1 christos 268 1.1 christos arpbody: 269 1.1 christos arpopt 270 1.1 christos | arpbody arpopt 271 1.1 christos ; 272 1.1 christos 273 1.1 christos arpopt: IL_V4ADDR token { set_arpv4addr(&$2); } 274 1.1 christos | IL_EADDR token { set_arpeaddr(&$2); } 275 1.1 christos ; 276 1.1 christos 277 1.1 christos defrouter: 278 1.1 christos IL_DEFROUTER token { set_defaultrouter(&$2); } 279 1.1 christos ; 280 1.1 christos 281 1.1 christos bodyline: 282 1.1 christos ipline 283 1.1 christos | tcp tcpline 284 1.1 christos | udp udpline 285 1.1 christos | icmp icmpline 286 1.1 christos | data dataline 287 1.1 christos ; 288 1.1 christos 289 1.1 christos ipline: ipv4 '{' ipv4body '}' ';' { end_ipv4(); } 290 1.1 christos ; 291 1.1 christos 292 1.1 christos ipv4: IL_IPV4 { new_packet(); } 293 1.1 christos 294 1.1 christos ipv4body: 295 1.1 christos ipv4type 296 1.1 christos | ipv4type ipv4body 297 1.1 christos | bodyline 298 1.1 christos ; 299 1.1 christos 300 1.1 christos ipv4type: 301 1.1 christos IL_V4PROTO token { set_ipv4proto(&$2); } 302 1.1 christos | IL_V4SRC token { set_ipv4src(&$2); } 303 1.1 christos | IL_V4DST token { set_ipv4dst(&$2); } 304 1.1 christos | IL_V4OFF token { set_ipv4off(&$2); } 305 1.1 christos | IL_V4V token { set_ipv4v(&$2); } 306 1.1 christos | IL_V4HL token { set_ipv4hl(&$2); } 307 1.1 christos | IL_V4ID token { set_ipv4id(&$2); } 308 1.1 christos | IL_V4TTL token { set_ipv4ttl(&$2); } 309 1.1 christos | IL_V4TOS token { set_ipv4tos(&$2); } 310 1.1 christos | IL_V4SUM token { set_ipv4sum(&$2); } 311 1.1 christos | IL_V4LEN token { set_ipv4len(&$2); } 312 1.1 christos | ipv4opt '{' ipv4optlist '}' ';' { end_ipopt(); } 313 1.1 christos ; 314 1.1 christos 315 1.1 christos tcp: IL_TCP { new_tcpheader(); } 316 1.1 christos ; 317 1.1 christos 318 1.1 christos tcpline: 319 1.1 christos '{' tcpheader '}' ';' { end_tcp(); } 320 1.1 christos ; 321 1.1 christos 322 1.1 christos tcpheader: 323 1.1 christos tcpbody 324 1.1 christos | tcpbody tcpheader 325 1.1 christos | bodyline 326 1.1 christos ; 327 1.1 christos 328 1.1 christos tcpbody: 329 1.1 christos IL_SPORT token { set_tcpsport(&$2); } 330 1.1 christos | IL_DPORT token { set_tcpdport(&$2); } 331 1.1 christos | IL_TCPSEQ token { set_tcpseq(&$2); } 332 1.1 christos | IL_TCPACK token { set_tcpack(&$2); } 333 1.1 christos | IL_TCPOFF token { set_tcpoff(&$2); } 334 1.1 christos | IL_TCPURP token { set_tcpurp(&$2); } 335 1.1 christos | IL_TCPWIN token { set_tcpwin(&$2); } 336 1.1 christos | IL_TCPSUM token { set_tcpsum(&$2); } 337 1.1 christos | IL_TCPFL token { set_tcpflags(&$2); } 338 1.1 christos | IL_TCPOPT '{' tcpopts '}' ';' { end_tcpopt(); } 339 1.1 christos ; 340 1.1 christos 341 1.1 christos tcpopts: 342 1.1 christos | tcpopt tcpopts 343 1.1 christos ; 344 1.1 christos 345 1.1 christos tcpopt: IL_TCPO_NOP ';' { set_tcpopt(IL_TCPO_NOP, NULL); } 346 1.1 christos | IL_TCPO_EOL ';' { set_tcpopt(IL_TCPO_EOL, NULL); } 347 1.1 christos | IL_TCPO_MSS optoken { set_tcpopt(IL_TCPO_MSS,&$2);} 348 1.1 christos | IL_TCPO_WSCALE optoken { set_tcpopt(IL_TCPO_WSCALE,&$2);} 349 1.1 christos | IL_TCPO_TS optoken { set_tcpopt(IL_TCPO_TS, &$2);} 350 1.1 christos ; 351 1.1 christos 352 1.1 christos udp: IL_UDP { new_udpheader(); } 353 1.1 christos ; 354 1.1 christos 355 1.1 christos udpline: 356 1.1 christos '{' udpheader '}' ';' { end_udp(); } 357 1.1 christos ; 358 1.1 christos 359 1.1 christos 360 1.1 christos udpheader: 361 1.1 christos udpbody 362 1.1 christos | udpbody udpheader 363 1.1 christos | bodyline 364 1.1 christos ; 365 1.1 christos 366 1.1 christos udpbody: 367 1.1 christos IL_SPORT token { set_tcpsport(&$2); } 368 1.1 christos | IL_DPORT token { set_tcpdport(&$2); } 369 1.1 christos | IL_UDPLEN token { set_udplen(&$2); } 370 1.1 christos | IL_UDPSUM token { set_udpsum(&$2); } 371 1.1 christos ; 372 1.1 christos 373 1.1 christos icmp: IL_ICMP { new_icmpheader(); } 374 1.1 christos ; 375 1.1 christos 376 1.1 christos icmpline: 377 1.1 christos '{' icmpbody '}' ';' { end_icmp(); } 378 1.1 christos ; 379 1.1 christos 380 1.1 christos icmpbody: 381 1.1 christos icmpheader 382 1.1 christos | icmpheader bodyline 383 1.1 christos ; 384 1.1 christos 385 1.1 christos icmpheader: 386 1.1 christos IL_ICMPTYPE icmptype 387 1.1 christos | IL_ICMPTYPE icmptype icmpcode 388 1.1 christos ; 389 1.1 christos 390 1.1 christos icmpcode: 391 1.1 christos IL_ICMPCODE token { set_icmpcodetok(&$2); } 392 1.1 christos ; 393 1.1 christos 394 1.1 christos icmptype: 395 1.1 christos IL_ICMP_ECHOREPLY ';' { set_icmptype(ICMP_ECHOREPLY); } 396 1.1 christos | IL_ICMP_ECHOREPLY '{' icmpechoopts '}' ';' 397 1.1 christos | unreach 398 1.1 christos | IL_ICMP_SOURCEQUENCH ';' { set_icmptype(ICMP_SOURCEQUENCH); } 399 1.1 christos | redirect 400 1.1 christos | IL_ICMP_ROUTERADVERT ';' { set_icmptype(ICMP_ROUTERADVERT); } 401 1.1 christos | IL_ICMP_ROUTERSOLICIT ';' { set_icmptype(ICMP_ROUTERSOLICIT); } 402 1.1 christos | IL_ICMP_ECHO ';' { set_icmptype(ICMP_ECHO); } 403 1.1 christos | IL_ICMP_ECHO '{' icmpechoopts '}' ';' 404 1.1 christos | IL_ICMP_TIMXCEED ';' { set_icmptype(ICMP_TIMXCEED); } 405 1.1 christos | IL_ICMP_TIMXCEED '{' exceed '}' ';' 406 1.1 christos | IL_ICMP_TSTAMP ';' { set_icmptype(ICMP_TSTAMP); } 407 1.1 christos | IL_ICMP_TSTAMPREPLY ';' { set_icmptype(ICMP_TSTAMPREPLY); } 408 1.1 christos | IL_ICMP_TSTAMPREPLY '{' icmptsopts '}' ';' 409 1.1 christos | IL_ICMP_IREQ ';' { set_icmptype(ICMP_IREQ); } 410 1.1 christos | IL_ICMP_IREQREPLY ';' { set_icmptype(ICMP_IREQREPLY); } 411 1.1 christos | IL_ICMP_IREQREPLY '{' data dataline '}' ';' 412 1.1 christos | IL_ICMP_MASKREQ ';' { set_icmptype(ICMP_MASKREQ); } 413 1.1 christos | IL_ICMP_MASKREPLY ';' { set_icmptype(ICMP_MASKREPLY); } 414 1.1 christos | IL_ICMP_MASKREPLY '{' token '}' ';' 415 1.1 christos | IL_ICMP_PARAMPROB ';' { set_icmptype(ICMP_PARAMPROB); } 416 1.1 christos | IL_ICMP_PARAMPROB '{' paramprob '}' ';' 417 1.1 christos | IL_TOKEN ';' { set_icmptypetok(&$1); } 418 1.1 christos ; 419 1.1 christos 420 1.1 christos icmpechoopts: 421 1.1 christos | icmpechoopts icmpecho 422 1.1 christos ; 423 1.1 christos 424 1.1 christos icmpecho: 425 1.1 christos IL_ICMP_SEQ number { set_icmpseq($2); } 426 1.1 christos | IL_ICMP_ID number { set_icmpid($2); } 427 1.1 christos ; 428 1.1 christos 429 1.1 christos icmptsopts: 430 1.1 christos | icmptsopts icmpts ';' 431 1.1 christos ; 432 1.1 christos 433 1.1 christos icmpts: IL_ICMP_OTIME number { set_icmpotime($2); } 434 1.1 christos | IL_ICMP_RTIME number { set_icmprtime($2); } 435 1.1 christos | IL_ICMP_TTIME number { set_icmpttime($2); } 436 1.1 christos ; 437 1.1 christos 438 1.1 christos unreach: 439 1.1 christos IL_ICMP_UNREACH 440 1.1 christos | IL_ICMP_UNREACH '{' unreachopts '}' ';' 441 1.1 christos ; 442 1.1 christos 443 1.1 christos unreachopts: 444 1.1 christos IL_ICMP_UNREACH_NET line 445 1.1 christos | IL_ICMP_UNREACH_HOST line 446 1.1 christos | IL_ICMP_UNREACH_PROTOCOL line 447 1.1 christos | IL_ICMP_UNREACH_PORT line 448 1.1 christos | IL_ICMP_UNREACH_NEEDFRAG number ';' { set_icmpmtu($2); } 449 1.1 christos | IL_ICMP_UNREACH_SRCFAIL line 450 1.1 christos | IL_ICMP_UNREACH_NET_UNKNOWN line 451 1.1 christos | IL_ICMP_UNREACH_HOST_UNKNOWN line 452 1.1 christos | IL_ICMP_UNREACH_ISOLATED line 453 1.1 christos | IL_ICMP_UNREACH_NET_PROHIB line 454 1.1 christos | IL_ICMP_UNREACH_HOST_PROHIB line 455 1.1 christos | IL_ICMP_UNREACH_TOSNET line 456 1.1 christos | IL_ICMP_UNREACH_TOSHOST line 457 1.1 christos | IL_ICMP_UNREACH_FILTER_PROHIB line 458 1.1 christos | IL_ICMP_UNREACH_HOST_PRECEDENCE line 459 1.1 christos | IL_ICMP_UNREACH_PRECEDENCE_CUTOFF line 460 1.1 christos ; 461 1.1 christos 462 1.1 christos redirect: 463 1.1 christos IL_ICMP_REDIRECT 464 1.1 christos | IL_ICMP_REDIRECT '{' redirectopts '}' ';' 465 1.1 christos ; 466 1.1 christos 467 1.1 christos redirectopts: 468 1.1 christos | IL_ICMP_REDIRECT_NET token { set_redir(0, &$2); } 469 1.1 christos | IL_ICMP_REDIRECT_HOST token { set_redir(1, &$2); } 470 1.1 christos | IL_ICMP_REDIRECT_TOSNET token { set_redir(2, &$2); } 471 1.1 christos | IL_ICMP_REDIRECT_TOSHOST token { set_redir(3, &$2); } 472 1.1 christos ; 473 1.1 christos 474 1.1 christos exceed: 475 1.1 christos IL_ICMP_TIMXCEED_INTRANS line 476 1.1 christos | IL_ICMP_TIMXCEED_REASS line 477 1.1 christos ; 478 1.1 christos 479 1.1 christos paramprob: 480 1.1 christos IL_ICMP_PARAMPROB_OPTABSENT 481 1.1 christos | IL_ICMP_PARAMPROB_OPTABSENT paraprobarg 482 1.1 christos 483 1.1 christos paraprobarg: 484 1.1 christos '{' number '}' ';' { set_icmppprob($2); } 485 1.1 christos ; 486 1.1 christos 487 1.1 christos ipv4opt: IL_V4OPT { new_ipv4opt(); } 488 1.1 christos ; 489 1.1 christos 490 1.1 christos ipv4optlist: 491 1.1 christos | ipv4opts ipv4optlist 492 1.1 christos ; 493 1.1 christos 494 1.1 christos ipv4opts: 495 1.1 christos IL_IPO_NOP ';' { add_ipopt(IL_IPO_NOP, NULL); } 496 1.1 christos | IL_IPO_RR optnumber { add_ipopt(IL_IPO_RR, &$2); } 497 1.1 christos | IL_IPO_ZSU ';' { add_ipopt(IL_IPO_ZSU, NULL); } 498 1.1 christos | IL_IPO_MTUP ';' { add_ipopt(IL_IPO_MTUP, NULL); } 499 1.1 christos | IL_IPO_MTUR ';' { add_ipopt(IL_IPO_MTUR, NULL); } 500 1.1 christos | IL_IPO_ENCODE ';' { add_ipopt(IL_IPO_ENCODE, NULL); } 501 1.1 christos | IL_IPO_TS ';' { add_ipopt(IL_IPO_TS, NULL); } 502 1.1 christos | IL_IPO_TR ';' { add_ipopt(IL_IPO_TR, NULL); } 503 1.1 christos | IL_IPO_SEC ';' { add_ipopt(IL_IPO_SEC, NULL); } 504 1.1 christos | IL_IPO_SECCLASS secclass { add_ipopt(IL_IPO_SECCLASS, sclass); } 505 1.1 christos | IL_IPO_LSRR token { add_ipopt(IL_IPO_LSRR,&$2); } 506 1.1 christos | IL_IPO_ESEC ';' { add_ipopt(IL_IPO_ESEC, NULL); } 507 1.1 christos | IL_IPO_CIPSO ';' { add_ipopt(IL_IPO_CIPSO, NULL); } 508 1.1 christos | IL_IPO_SATID optnumber { add_ipopt(IL_IPO_SATID,&$2);} 509 1.1 christos | IL_IPO_SSRR token { add_ipopt(IL_IPO_SSRR,&$2); } 510 1.1 christos | IL_IPO_ADDEXT ';' { add_ipopt(IL_IPO_ADDEXT, NULL); } 511 1.1 christos | IL_IPO_VISA ';' { add_ipopt(IL_IPO_VISA, NULL); } 512 1.1 christos | IL_IPO_IMITD ';' { add_ipopt(IL_IPO_IMITD, NULL); } 513 1.1 christos | IL_IPO_EIP ';' { add_ipopt(IL_IPO_EIP, NULL); } 514 1.1 christos | IL_IPO_FINN ';' { add_ipopt(IL_IPO_FINN, NULL); } 515 1.1 christos ; 516 1.1 christos 517 1.1 christos secclass: 518 1.1 christos IL_IPS_RESERV4 ';' { set_secclass(&$1); } 519 1.1 christos | IL_IPS_TOPSECRET ';' { set_secclass(&$1); } 520 1.1 christos | IL_IPS_SECRET ';' { set_secclass(&$1); } 521 1.1 christos | IL_IPS_RESERV3 ';' { set_secclass(&$1); } 522 1.1 christos | IL_IPS_CONFID ';' { set_secclass(&$1); } 523 1.1 christos | IL_IPS_UNCLASS ';' { set_secclass(&$1); } 524 1.1 christos | IL_IPS_RESERV2 ';' { set_secclass(&$1); } 525 1.1 christos | IL_IPS_RESERV1 ';' { set_secclass(&$1); } 526 1.1 christos ; 527 1.1 christos 528 1.1 christos data: IL_DATA { new_data(); } 529 1.1 christos ; 530 1.1 christos 531 1.1 christos dataline: 532 1.1 christos '{' databody '}' ';' { end_data(); } 533 1.1 christos ; 534 1.1 christos 535 1.1 christos databody: dataopts 536 1.1 christos | dataopts databody 537 1.1 christos ; 538 1.1 christos 539 1.1 christos dataopts: 540 1.1 christos IL_DLEN token { set_datalen(&$2); } 541 1.1 christos | IL_DVALUE token { set_data(&$2); } 542 1.1 christos | IL_DFILE token { set_datafile(&$2); } 543 1.1 christos ; 544 1.1 christos 545 1.1 christos token: IL_TOKEN ';' 546 1.1 christos ; 547 1.1 christos 548 1.1 christos optoken: ';' { $$ = ""; } 549 1.1 christos | token 550 1.1 christos ; 551 1.1 christos 552 1.1 christos number: digits ';' 553 1.1 christos ; 554 1.1 christos 555 1.1 christos optnumber: ';' { $$ = 0; } 556 1.1 christos | number 557 1.1 christos ; 558 1.1 christos 559 1.1 christos digits: IL_NUMBER 560 1.1 christos | digits IL_NUMBER 561 1.1 christos ; 562 1.1 christos %% 563 1.1 christos 564 1.1 christos struct statetoopt toipopts[] = { 565 1.1 christos { IL_IPO_NOP, IPOPT_NOP }, 566 1.1 christos { IL_IPO_RR, IPOPT_RR }, 567 1.1 christos { IL_IPO_ZSU, IPOPT_ZSU }, 568 1.1 christos { IL_IPO_MTUP, IPOPT_MTUP }, 569 1.1 christos { IL_IPO_MTUR, IPOPT_MTUR }, 570 1.1 christos { IL_IPO_ENCODE, IPOPT_ENCODE }, 571 1.1 christos { IL_IPO_TS, IPOPT_TS }, 572 1.1 christos { IL_IPO_TR, IPOPT_TR }, 573 1.1 christos { IL_IPO_SEC, IPOPT_SECURITY }, 574 1.1 christos { IL_IPO_SECCLASS, IPOPT_SECURITY }, 575 1.1 christos { IL_IPO_LSRR, IPOPT_LSRR }, 576 1.1 christos { IL_IPO_ESEC, IPOPT_E_SEC }, 577 1.1 christos { IL_IPO_CIPSO, IPOPT_CIPSO }, 578 1.1 christos { IL_IPO_SATID, IPOPT_SATID }, 579 1.1 christos { IL_IPO_SSRR, IPOPT_SSRR }, 580 1.1 christos { IL_IPO_ADDEXT, IPOPT_ADDEXT }, 581 1.1 christos { IL_IPO_VISA, IPOPT_VISA }, 582 1.1 christos { IL_IPO_IMITD, IPOPT_IMITD }, 583 1.1 christos { IL_IPO_EIP, IPOPT_EIP }, 584 1.1 christos { IL_IPO_FINN, IPOPT_FINN }, 585 1.1 christos { 0, 0 } 586 1.1 christos }; 587 1.1 christos 588 1.1 christos struct statetoopt tosecopts[] = { 589 1.1 christos { IL_IPS_RESERV4, IPSO_CLASS_RES4 }, 590 1.1 christos { IL_IPS_TOPSECRET, IPSO_CLASS_TOPS }, 591 1.1 christos { IL_IPS_SECRET, IPSO_CLASS_SECR }, 592 1.1 christos { IL_IPS_RESERV3, IPSO_CLASS_RES3 }, 593 1.1 christos { IL_IPS_CONFID, IPSO_CLASS_CONF }, 594 1.1 christos { IL_IPS_UNCLASS, IPSO_CLASS_UNCL }, 595 1.1 christos { IL_IPS_RESERV2, IPSO_CLASS_RES2 }, 596 1.1 christos { IL_IPS_RESERV1, IPSO_CLASS_RES1 }, 597 1.1 christos { 0, 0 } 598 1.1 christos }; 599 1.1 christos 600 1.1 christos #ifdef bsdi 601 1.1 christos struct ether_addr * 602 1.1 christos ether_aton(s) 603 1.1 christos char *s; 604 1.1 christos { 605 1.1 christos static struct ether_addr n; 606 1.1 christos u_int i[6]; 607 1.1 christos 608 1.1 christos if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1], 609 1.1 christos &i[2], &i[3], &i[4], &i[5]) == 6) { 610 1.1 christos n.ether_addr_octet[0] = (u_char)i[0]; 611 1.1 christos n.ether_addr_octet[1] = (u_char)i[1]; 612 1.1 christos n.ether_addr_octet[2] = (u_char)i[2]; 613 1.1 christos n.ether_addr_octet[3] = (u_char)i[3]; 614 1.1 christos n.ether_addr_octet[4] = (u_char)i[4]; 615 1.1 christos n.ether_addr_octet[5] = (u_char)i[5]; 616 1.1 christos return &n; 617 1.1 christos } 618 1.1 christos return NULL; 619 1.1 christos } 620 1.1 christos #endif 621 1.1 christos 622 1.1 christos 623 1.1 christos struct in_addr getipv4addr(arg) 624 1.1 christos char *arg; 625 1.1 christos { 626 1.1 christos struct hostent *hp; 627 1.1 christos struct in_addr in; 628 1.1 christos 629 1.1 christos in.s_addr = 0xffffffff; 630 1.1 christos 631 1.1 christos if ((hp = gethostbyname(arg))) 632 1.1 christos bcopy(hp->h_addr, &in.s_addr, sizeof(struct in_addr)); 633 1.1 christos else 634 1.1 christos in.s_addr = inet_addr(arg); 635 1.1 christos return in; 636 1.1 christos } 637 1.1 christos 638 1.1 christos 639 1.1 christos u_short getportnum(pr, name) 640 1.1 christos char *pr, *name; 641 1.1 christos { 642 1.1 christos struct servent *sp; 643 1.1 christos 644 1.1 christos if (!(sp = getservbyname(name, pr))) 645 1.1 christos return htons(atoi(name)); 646 1.1 christos return sp->s_port; 647 1.1 christos } 648 1.1 christos 649 1.1 christos 650 1.1 christos struct ether_addr *geteaddr(arg, buf) 651 1.1 christos char *arg; 652 1.1 christos struct ether_addr *buf; 653 1.1 christos { 654 1.1 christos struct ether_addr *e; 655 1.1 christos 656 1.1 christos #if !defined(hpux) && !defined(linux) 657 1.1 christos e = ether_aton(arg); 658 1.1 christos if (!e) 659 1.1 christos fprintf(stderr, "Invalid ethernet address: %s\n", arg); 660 1.1 christos else 661 1.1 christos # ifdef __FreeBSD__ 662 1.1 christos bcopy(e->octet, buf->octet, sizeof(e->octet)); 663 1.1 christos # else 664 1.1 christos bcopy(e->ether_addr_octet, buf->ether_addr_octet, 665 1.1 christos sizeof(e->ether_addr_octet)); 666 1.1 christos # endif 667 1.1 christos return e; 668 1.1 christos #else 669 1.1 christos return NULL; 670 1.1 christos #endif 671 1.1 christos } 672 1.1 christos 673 1.1 christos 674 1.1 christos void *new_header(type) 675 1.1 christos int type; 676 1.1 christos { 677 1.1 christos aniphdr_t *aip, *oip = canip; 678 1.1 christos int sz = 0; 679 1.1 christos 680 1.1 christos aip = (aniphdr_t *)calloc(1, sizeof(*aip)); 681 1.1 christos *aniptail = aip; 682 1.1 christos aniptail = &aip->ah_next; 683 1.1 christos aip->ah_p = type; 684 1.1 christos aip->ah_prev = oip; 685 1.1 christos canip = aip; 686 1.1 christos 687 1.1 christos if (type == IPPROTO_UDP) 688 1.1 christos sz = sizeof(udphdr_t); 689 1.1 christos else if (type == IPPROTO_TCP) 690 1.1 christos sz = sizeof(tcphdr_t); 691 1.1 christos else if (type == IPPROTO_ICMP) 692 1.1 christos sz = sizeof(icmphdr_t); 693 1.1 christos else if (type == IPPROTO_IP) 694 1.1 christos sz = sizeof(ip_t); 695 1.1 christos 696 1.1 christos if (oip) 697 1.1 christos canip->ah_data = oip->ah_data + oip->ah_len; 698 1.1 christos else 699 1.1 christos canip->ah_data = (char *)ipbuffer; 700 1.1 christos 701 1.1 christos /* 702 1.1 christos * Increase the size fields in all wrapping headers. 703 1.1 christos */ 704 1.1 christos for (aip = aniphead; aip; aip = aip->ah_next) { 705 1.1 christos aip->ah_len += sz; 706 1.1 christos if (aip->ah_p == IPPROTO_IP) 707 1.1 christos aip->ah_ip->ip_len += sz; 708 1.1 christos else if (aip->ah_p == IPPROTO_UDP) 709 1.1 christos aip->ah_udp->uh_ulen += sz; 710 1.1 christos } 711 1.1 christos return (void *)canip->ah_data; 712 1.1 christos } 713 1.1 christos 714 1.1 christos 715 1.1 christos void free_aniplist() 716 1.1 christos { 717 1.1 christos aniphdr_t *aip, **aipp = &aniphead; 718 1.1 christos 719 1.1 christos while ((aip = *aipp)) { 720 1.1 christos *aipp = aip->ah_next; 721 1.1 christos free(aip); 722 1.1 christos } 723 1.1 christos aniptail = &aniphead; 724 1.1 christos } 725 1.1 christos 726 1.1 christos 727 1.1 christos void inc_anipheaders(inc) 728 1.1 christos int inc; 729 1.1 christos { 730 1.1 christos aniphdr_t *aip; 731 1.1 christos 732 1.1 christos for (aip = aniphead; aip; aip = aip->ah_next) { 733 1.1 christos aip->ah_len += inc; 734 1.1 christos if (aip->ah_p == IPPROTO_IP) 735 1.1 christos aip->ah_ip->ip_len += inc; 736 1.1 christos else if (aip->ah_p == IPPROTO_UDP) 737 1.1 christos aip->ah_udp->uh_ulen += inc; 738 1.1 christos } 739 1.1 christos } 740 1.1 christos 741 1.1 christos 742 1.1 christos void new_data() 743 1.1 christos { 744 1.1 christos (void) new_header(-1); 745 1.1 christos canip->ah_len = 0; 746 1.1 christos } 747 1.1 christos 748 1.1 christos 749 1.1 christos void set_datalen(arg) 750 1.1 christos char **arg; 751 1.1 christos { 752 1.1 christos int len; 753 1.1 christos 754 1.1 christos len = strtol(*arg, NULL, 0); 755 1.1 christos inc_anipheaders(len); 756 1.1 christos free(*arg); 757 1.1 christos *arg = NULL; 758 1.1 christos } 759 1.1 christos 760 1.1 christos 761 1.1 christos void set_data(arg) 762 1.1 christos char **arg; 763 1.1 christos { 764 1.1 christos u_char *s = (u_char *)*arg, *t = (u_char *)canip->ah_data, c; 765 1.1 christos int len = 0, todo = 0, quote = 0, val = 0; 766 1.1 christos 767 1.1 christos while ((c = *s++)) { 768 1.1 christos if (todo) { 769 1.1 christos if (ISDIGIT(c)) { 770 1.1 christos todo--; 771 1.1 christos if (c > '7') { 772 1.1 christos fprintf(stderr, "octal with %c!\n", c); 773 1.1 christos break; 774 1.1 christos } 775 1.1 christos val <<= 3; 776 1.1 christos val |= (c - '0'); 777 1.1 christos } 778 1.1 christos if (!ISDIGIT(c) || !todo) { 779 1.1 christos *t++ = (u_char)(val & 0xff); 780 1.1 christos todo = 0; 781 1.1 christos } 782 1.1 christos if (todo) 783 1.1 christos continue; 784 1.1 christos } 785 1.1 christos if (quote) { 786 1.1 christos if (ISDIGIT(c)) { 787 1.1 christos todo = 2; 788 1.1 christos if (c > '7') { 789 1.1 christos fprintf(stderr, "octal with %c!\n", c); 790 1.1 christos break; 791 1.1 christos } 792 1.1 christos val = (c - '0'); 793 1.1 christos } else { 794 1.1 christos switch (c) 795 1.1 christos { 796 1.1 christos case '\"' : 797 1.1 christos *t++ = '\"'; 798 1.1 christos break; 799 1.1 christos case '\\' : 800 1.1 christos *t++ = '\\'; 801 1.1 christos break; 802 1.1 christos case 'n' : 803 1.1 christos *t++ = '\n'; 804 1.1 christos break; 805 1.1 christos case 'r' : 806 1.1 christos *t++ = '\r'; 807 1.1 christos break; 808 1.1 christos case 't' : 809 1.1 christos *t++ = '\t'; 810 1.1 christos break; 811 1.1 christos } 812 1.1 christos } 813 1.1 christos quote = 0; 814 1.1 christos continue; 815 1.1 christos } 816 1.1 christos 817 1.1 christos if (c == '\\') 818 1.1 christos quote = 1; 819 1.1 christos else 820 1.1 christos *t++ = c; 821 1.1 christos } 822 1.1 christos if (todo) 823 1.1 christos *t++ = (u_char)(val & 0xff); 824 1.1 christos if (quote) 825 1.1 christos *t++ = '\\'; 826 1.1 christos len = t - (u_char *)canip->ah_data; 827 1.1 christos inc_anipheaders(len - canip->ah_len); 828 1.1 christos canip->ah_len = len; 829 1.1 christos } 830 1.1 christos 831 1.1 christos 832 1.1 christos void set_datafile(arg) 833 1.1 christos char **arg; 834 1.1 christos { 835 1.1 christos struct stat sb; 836 1.1 christos char *file = *arg; 837 1.1 christos int fd, len; 838 1.1 christos 839 1.1 christos if ((fd = open(file, O_RDONLY)) == -1) { 840 1.1 christos perror("open"); 841 1.1 christos exit(-1); 842 1.1 christos } 843 1.1 christos 844 1.1 christos if (fstat(fd, &sb) == -1) { 845 1.1 christos perror("fstat"); 846 1.1 christos exit(-1); 847 1.1 christos } 848 1.1 christos 849 1.1 christos if ((sb.st_size + aniphead->ah_len ) > 65535) { 850 1.1 christos fprintf(stderr, "data file %s too big to include.\n", file); 851 1.1 christos close(fd); 852 1.1 christos return; 853 1.1 christos } 854 1.1 christos if ((len = read(fd, canip->ah_data, sb.st_size)) == -1) { 855 1.1 christos perror("read"); 856 1.1 christos close(fd); 857 1.1 christos return; 858 1.1 christos } 859 1.1 christos inc_anipheaders(len); 860 1.1 christos canip->ah_len += len; 861 1.1 christos close(fd); 862 1.1 christos } 863 1.1 christos 864 1.1 christos 865 1.1 christos void new_packet() 866 1.1 christos { 867 1.1 christos static u_short id = 0; 868 1.1 christos 869 1.1 christos if (!aniphead) 870 1.1 christos bzero((char *)ipbuffer, sizeof(ipbuffer)); 871 1.1 christos 872 1.1 christos ip = (ip_t *)new_header(IPPROTO_IP); 873 1.1 christos ip->ip_v = IPVERSION; 874 1.1 christos ip->ip_hl = sizeof(ip_t) >> 2; 875 1.1 christos ip->ip_len = sizeof(ip_t); 876 1.1 christos ip->ip_ttl = 63; 877 1.1 christos ip->ip_id = htons(id++); 878 1.1 christos } 879 1.1 christos 880 1.1 christos 881 1.1 christos void set_ipv4proto(arg) 882 1.1 christos char **arg; 883 1.1 christos { 884 1.1 christos struct protoent *pr; 885 1.1 christos 886 1.1 christos if ((pr = getprotobyname(*arg))) 887 1.1 christos ip->ip_p = pr->p_proto; 888 1.1 christos else 889 1.1 christos if (!(ip->ip_p = atoi(*arg))) 890 1.1 christos fprintf(stderr, "unknown protocol %s\n", *arg); 891 1.1 christos free(*arg); 892 1.1 christos *arg = NULL; 893 1.1 christos } 894 1.1 christos 895 1.1 christos 896 1.1 christos void set_ipv4src(arg) 897 1.1 christos char **arg; 898 1.1 christos { 899 1.1 christos ip->ip_src = getipv4addr(*arg); 900 1.1 christos free(*arg); 901 1.1 christos *arg = NULL; 902 1.1 christos } 903 1.1 christos 904 1.1 christos 905 1.1 christos void set_ipv4dst(arg) 906 1.1 christos char **arg; 907 1.1 christos { 908 1.1 christos ip->ip_dst = getipv4addr(*arg); 909 1.1 christos free(*arg); 910 1.1 christos *arg = NULL; 911 1.1 christos } 912 1.1 christos 913 1.1 christos 914 1.1 christos void set_ipv4off(arg) 915 1.1 christos char **arg; 916 1.1 christos { 917 1.1 christos ip->ip_off = htons(strtol(*arg, NULL, 0)); 918 1.1 christos free(*arg); 919 1.1 christos *arg = NULL; 920 1.1 christos } 921 1.1 christos 922 1.1 christos 923 1.1 christos void set_ipv4v(arg) 924 1.1 christos char **arg; 925 1.1 christos { 926 1.1 christos ip->ip_v = strtol(*arg, NULL, 0); 927 1.1 christos free(*arg); 928 1.1 christos *arg = NULL; 929 1.1 christos } 930 1.1 christos 931 1.1 christos 932 1.1 christos void set_ipv4hl(arg) 933 1.1 christos char **arg; 934 1.1 christos { 935 1.1 christos int newhl, inc; 936 1.1 christos 937 1.1 christos newhl = strtol(*arg, NULL, 0); 938 1.1 christos inc = (newhl - ip->ip_hl) << 2; 939 1.1 christos ip->ip_len += inc; 940 1.1 christos ip->ip_hl = newhl; 941 1.1 christos canip->ah_len += inc; 942 1.1 christos free(*arg); 943 1.1 christos *arg = NULL; 944 1.1 christos } 945 1.1 christos 946 1.1 christos 947 1.1 christos void set_ipv4ttl(arg) 948 1.1 christos char **arg; 949 1.1 christos { 950 1.1 christos ip->ip_ttl = strtol(*arg, NULL, 0); 951 1.1 christos free(*arg); 952 1.1 christos *arg = NULL; 953 1.1 christos } 954 1.1 christos 955 1.1 christos 956 1.1 christos void set_ipv4tos(arg) 957 1.1 christos char **arg; 958 1.1 christos { 959 1.1 christos ip->ip_tos = strtol(*arg, NULL, 0); 960 1.1 christos free(*arg); 961 1.1 christos *arg = NULL; 962 1.1 christos } 963 1.1 christos 964 1.1 christos 965 1.1 christos void set_ipv4id(arg) 966 1.1 christos char **arg; 967 1.1 christos { 968 1.1 christos ip->ip_id = htons(strtol(*arg, NULL, 0)); 969 1.1 christos free(*arg); 970 1.1 christos *arg = NULL; 971 1.1 christos } 972 1.1 christos 973 1.1 christos 974 1.1 christos void set_ipv4sum(arg) 975 1.1 christos char **arg; 976 1.1 christos { 977 1.1 christos ip->ip_sum = strtol(*arg, NULL, 0); 978 1.1 christos free(*arg); 979 1.1 christos *arg = NULL; 980 1.1 christos } 981 1.1 christos 982 1.1 christos 983 1.1 christos void set_ipv4len(arg) 984 1.1 christos char **arg; 985 1.1 christos { 986 1.1 christos int len; 987 1.1 christos 988 1.1 christos len = strtol(*arg, NULL, 0); 989 1.1 christos inc_anipheaders(len - ip->ip_len); 990 1.1 christos ip->ip_len = len; 991 1.1 christos free(*arg); 992 1.1 christos *arg = NULL; 993 1.1 christos } 994 1.1 christos 995 1.1 christos 996 1.1 christos void new_tcpheader() 997 1.1 christos { 998 1.1 christos 999 1.1 christos if ((ip->ip_p) && (ip->ip_p != IPPROTO_TCP)) { 1000 1.1 christos fprintf(stderr, "protocol %d specified with TCP!\n", ip->ip_p); 1001 1.1 christos return; 1002 1.1 christos } 1003 1.1 christos ip->ip_p = IPPROTO_TCP; 1004 1.1 christos 1005 1.1 christos tcp = (tcphdr_t *)new_header(IPPROTO_TCP); 1006 1.1 christos tcp->th_win = htons(4096); 1007 1.1 christos tcp->th_off = sizeof(*tcp) >> 2; 1008 1.1 christos } 1009 1.1 christos 1010 1.1 christos 1011 1.1 christos void set_tcpsport(arg) 1012 1.1 christos char **arg; 1013 1.1 christos { 1014 1.1 christos u_short *port; 1015 1.1 christos char *pr; 1016 1.1 christos 1017 1.1 christos if (ip->ip_p == IPPROTO_UDP) { 1018 1.1 christos port = &udp->uh_sport; 1019 1.1 christos pr = "udp"; 1020 1.1 christos } else { 1021 1.1 christos port = &tcp->th_sport; 1022 1.1 christos pr = "udp"; 1023 1.1 christos } 1024 1.1 christos 1025 1.1 christos *port = getportnum(pr, *arg); 1026 1.1 christos free(*arg); 1027 1.1 christos *arg = NULL; 1028 1.1 christos } 1029 1.1 christos 1030 1.1 christos 1031 1.1 christos void set_tcpdport(arg) 1032 1.1 christos char **arg; 1033 1.1 christos { 1034 1.1 christos u_short *port; 1035 1.1 christos char *pr; 1036 1.1 christos 1037 1.1 christos if (ip->ip_p == IPPROTO_UDP) { 1038 1.1 christos port = &udp->uh_dport; 1039 1.1 christos pr = "udp"; 1040 1.1 christos } else { 1041 1.1 christos port = &tcp->th_dport; 1042 1.1 christos pr = "udp"; 1043 1.1 christos } 1044 1.1 christos 1045 1.1 christos *port = getportnum(pr, *arg); 1046 1.1 christos free(*arg); 1047 1.1 christos *arg = NULL; 1048 1.1 christos } 1049 1.1 christos 1050 1.1 christos 1051 1.1 christos void set_tcpseq(arg) 1052 1.1 christos char **arg; 1053 1.1 christos { 1054 1.1 christos tcp->th_seq = htonl(strtol(*arg, NULL, 0)); 1055 1.1 christos free(*arg); 1056 1.1 christos *arg = NULL; 1057 1.1 christos } 1058 1.1 christos 1059 1.1 christos 1060 1.1 christos void set_tcpack(arg) 1061 1.1 christos char **arg; 1062 1.1 christos { 1063 1.1 christos tcp->th_ack = htonl(strtol(*arg, NULL, 0)); 1064 1.1 christos free(*arg); 1065 1.1 christos *arg = NULL; 1066 1.1 christos } 1067 1.1 christos 1068 1.1 christos 1069 1.1 christos void set_tcpoff(arg) 1070 1.1 christos char **arg; 1071 1.1 christos { 1072 1.1 christos int off; 1073 1.1 christos 1074 1.1 christos off = strtol(*arg, NULL, 0); 1075 1.1 christos inc_anipheaders((off - tcp->th_off) << 2); 1076 1.1 christos tcp->th_off = off; 1077 1.1 christos free(*arg); 1078 1.1 christos *arg = NULL; 1079 1.1 christos } 1080 1.1 christos 1081 1.1 christos 1082 1.1 christos void set_tcpurp(arg) 1083 1.1 christos char **arg; 1084 1.1 christos { 1085 1.1 christos tcp->th_urp = htons(strtol(*arg, NULL, 0)); 1086 1.1 christos free(*arg); 1087 1.1 christos *arg = NULL; 1088 1.1 christos } 1089 1.1 christos 1090 1.1 christos 1091 1.1 christos void set_tcpwin(arg) 1092 1.1 christos char **arg; 1093 1.1 christos { 1094 1.1 christos tcp->th_win = htons(strtol(*arg, NULL, 0)); 1095 1.1 christos free(*arg); 1096 1.1 christos *arg = NULL; 1097 1.1 christos } 1098 1.1 christos 1099 1.1 christos 1100 1.1 christos void set_tcpsum(arg) 1101 1.1 christos char **arg; 1102 1.1 christos { 1103 1.1 christos tcp->th_sum = strtol(*arg, NULL, 0); 1104 1.1 christos free(*arg); 1105 1.1 christos *arg = NULL; 1106 1.1 christos } 1107 1.1 christos 1108 1.1 christos 1109 1.1 christos void set_tcpflags(arg) 1110 1.1 christos char **arg; 1111 1.1 christos { 1112 1.1 christos static char flags[] = "ASURPF"; 1113 1.1 christos static int flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH, 1114 1.1 christos TH_FIN } ; 1115 1.1 christos char *s, *t; 1116 1.1 christos 1117 1.1 christos for (s = *arg; *s; s++) 1118 1.1 christos if (!(t = strchr(flags, *s))) { 1119 1.1 christos if (s - *arg) { 1120 1.1 christos fprintf(stderr, "unknown TCP flag %c\n", *s); 1121 1.1 christos break; 1122 1.1 christos } 1123 1.1 christos tcp->th_flags = strtol(*arg, NULL, 0); 1124 1.1 christos break; 1125 1.1 christos } else 1126 1.1 christos tcp->th_flags |= flagv[t - flags]; 1127 1.1 christos free(*arg); 1128 1.1 christos *arg = NULL; 1129 1.1 christos } 1130 1.1 christos 1131 1.1 christos 1132 1.1 christos void set_tcpopt(state, arg) 1133 1.1 christos int state; 1134 1.1 christos char **arg; 1135 1.1 christos { 1136 1.1 christos u_char *s; 1137 1.1 christos int val, len, val2, pad, optval; 1138 1.1 christos 1139 1.1 christos if (arg && *arg) 1140 1.1 christos val = atoi(*arg); 1141 1.1 christos else 1142 1.1 christos val = 0; 1143 1.1 christos 1144 1.1 christos s = (u_char *)tcp + sizeof(*tcp) + canip->ah_optlen; 1145 1.1 christos switch (state) 1146 1.1 christos { 1147 1.1 christos case IL_TCPO_EOL : 1148 1.1 christos optval = 0; 1149 1.1 christos len = 1; 1150 1.1 christos break; 1151 1.1 christos case IL_TCPO_NOP : 1152 1.1 christos optval = 1; 1153 1.1 christos len = 1; 1154 1.1 christos break; 1155 1.1 christos case IL_TCPO_MSS : 1156 1.1 christos optval = 2; 1157 1.1 christos len = 4; 1158 1.1 christos break; 1159 1.1 christos case IL_TCPO_WSCALE : 1160 1.1 christos optval = 3; 1161 1.1 christos len = 3; 1162 1.1 christos break; 1163 1.1 christos case IL_TCPO_TS : 1164 1.1 christos optval = 8; 1165 1.1 christos len = 10; 1166 1.1 christos break; 1167 1.1 christos default : 1168 1.1 christos optval = 0; 1169 1.1 christos len = 0; 1170 1.1 christos break; 1171 1.1 christos } 1172 1.1 christos 1173 1.1 christos if (len > 1) { 1174 1.1 christos /* 1175 1.1 christos * prepend padding - if required. 1176 1.1 christos */ 1177 1.1 christos if (len & 3) 1178 1.1 christos for (pad = 4 - (len & 3); pad; pad--) { 1179 1.1 christos *s++ = 1; 1180 1.1 christos canip->ah_optlen++; 1181 1.1 christos } 1182 1.1 christos /* 1183 1.1 christos * build tcp option 1184 1.1 christos */ 1185 1.1 christos *s++ = (u_char)optval; 1186 1.1 christos *s++ = (u_char)len; 1187 1.1 christos if (len > 2) { 1188 1.1 christos if (len == 3) { /* 1 byte - char */ 1189 1.1 christos *s++ = (u_char)val; 1190 1.1 christos } else if (len == 4) { /* 2 bytes - short */ 1191 1.1 christos *s++ = (u_char)((val >> 8) & 0xff); 1192 1.1 christos *s++ = (u_char)(val & 0xff); 1193 1.1 christos } else if (len >= 6) { /* 4 bytes - long */ 1194 1.1 christos val2 = htonl(val); 1195 1.1 christos bcopy((char *)&val2, s, 4); 1196 1.1 christos } 1197 1.1 christos s += (len - 2); 1198 1.1 christos } 1199 1.1 christos } else 1200 1.1 christos *s++ = (u_char)optval; 1201 1.1 christos 1202 1.1 christos canip->ah_lastopt = optval; 1203 1.1 christos canip->ah_optlen += len; 1204 1.1 christos 1205 1.1 christos if (arg && *arg) { 1206 1.1 christos free(*arg); 1207 1.1 christos *arg = NULL; 1208 1.1 christos } 1209 1.1 christos } 1210 1.1 christos 1211 1.1 christos 1212 1.1 christos void end_tcpopt() 1213 1.1 christos { 1214 1.1 christos int pad; 1215 1.1 christos char *s = (char *)tcp; 1216 1.1 christos 1217 1.1 christos s += sizeof(*tcp) + canip->ah_optlen; 1218 1.1 christos /* 1219 1.1 christos * pad out so that we have a multiple of 4 bytes in size fo the 1220 1.1 christos * options. make sure last byte is EOL. 1221 1.1 christos */ 1222 1.1 christos if (canip->ah_optlen & 3) { 1223 1.1 christos if (canip->ah_lastopt != 1) { 1224 1.1 christos for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { 1225 1.1 christos *s++ = 1; 1226 1.1 christos canip->ah_optlen++; 1227 1.1 christos } 1228 1.1 christos canip->ah_optlen++; 1229 1.1 christos } else { 1230 1.1 christos s -= 1; 1231 1.1 christos 1232 1.1 christos for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { 1233 1.1 christos *s++ = 1; 1234 1.1 christos canip->ah_optlen++; 1235 1.1 christos } 1236 1.1 christos } 1237 1.1 christos *s++ = 0; 1238 1.1 christos } 1239 1.1 christos tcp->th_off = (sizeof(*tcp) + canip->ah_optlen) >> 2; 1240 1.1 christos inc_anipheaders(canip->ah_optlen); 1241 1.1 christos } 1242 1.1 christos 1243 1.1 christos 1244 1.1 christos void new_udpheader() 1245 1.1 christos { 1246 1.1 christos if ((ip->ip_p) && (ip->ip_p != IPPROTO_UDP)) { 1247 1.1 christos fprintf(stderr, "protocol %d specified with UDP!\n", ip->ip_p); 1248 1.1 christos return; 1249 1.1 christos } 1250 1.1 christos ip->ip_p = IPPROTO_UDP; 1251 1.1 christos 1252 1.1 christos udp = (udphdr_t *)new_header(IPPROTO_UDP); 1253 1.1 christos udp->uh_ulen = sizeof(*udp); 1254 1.1 christos } 1255 1.1 christos 1256 1.1 christos 1257 1.1 christos void set_udplen(arg) 1258 1.1 christos char **arg; 1259 1.1 christos { 1260 1.1 christos int len; 1261 1.1 christos 1262 1.1 christos len = strtol(*arg, NULL, 0); 1263 1.1 christos inc_anipheaders(len - udp->uh_ulen); 1264 1.1 christos udp->uh_ulen = len; 1265 1.1 christos free(*arg); 1266 1.1 christos *arg = NULL; 1267 1.1 christos } 1268 1.1 christos 1269 1.1 christos 1270 1.1 christos void set_udpsum(arg) 1271 1.1 christos char **arg; 1272 1.1 christos { 1273 1.1 christos udp->uh_sum = strtol(*arg, NULL, 0); 1274 1.1 christos free(*arg); 1275 1.1 christos *arg = NULL; 1276 1.1 christos } 1277 1.1 christos 1278 1.1 christos 1279 1.1 christos void prep_packet() 1280 1.1 christos { 1281 1.1 christos iface_t *ifp; 1282 1.1 christos struct in_addr gwip; 1283 1.1 christos 1284 1.1 christos ifp = sending.snd_if; 1285 1.1 christos if (!ifp) { 1286 1.1 christos fprintf(stderr, "no interface defined for sending!\n"); 1287 1.1 christos return; 1288 1.1 christos } 1289 1.1 christos if (ifp->if_fd == -1) 1290 1.1 christos ifp->if_fd = initdevice(ifp->if_name, 5); 1291 1.1 christos gwip = sending.snd_gw; 1292 1.1 christos if (!gwip.s_addr) { 1293 1.1 christos if (aniphead == NULL) { 1294 1.1 christos fprintf(stderr, 1295 1.1 christos "no destination address defined for sending\n"); 1296 1.1 christos return; 1297 1.1 christos } 1298 1.1 christos gwip = aniphead->ah_ip->ip_dst; 1299 1.1 christos } 1300 1.1 christos (void) send_ip(ifp->if_fd, ifp->if_MTU, (ip_t *)ipbuffer, gwip, 2); 1301 1.1 christos } 1302 1.1 christos 1303 1.1 christos 1304 1.1 christos void packet_done() 1305 1.1 christos { 1306 1.1 christos char outline[80]; 1307 1.1 christos int i, j, k; 1308 1.1 christos u_char *s = (u_char *)ipbuffer, *t = (u_char *)outline; 1309 1.1 christos 1310 1.1 christos if (opts & OPT_VERBOSE) { 1311 1.1 christos ip->ip_len = htons(ip->ip_len); 1312 1.1 christos for (i = ntohs(ip->ip_len), j = 0; i; i--, j++, s++) { 1313 1.1 christos if (j && !(j & 0xf)) { 1314 1.1 christos *t++ = '\n'; 1315 1.1 christos *t = '\0'; 1316 1.1 christos fputs(outline, stdout); 1317 1.1 christos fflush(stdout); 1318 1.1 christos t = (u_char *)outline; 1319 1.1 christos *t = '\0'; 1320 1.1 christos } 1321 1.1 christos sprintf((char *)t, "%02x", *s & 0xff); 1322 1.1 christos t += 2; 1323 1.1 christos if (!((j + 1) & 0xf)) { 1324 1.1 christos s -= 15; 1325 1.1 christos sprintf((char *)t, " "); 1326 1.1 christos t += 8; 1327 1.1 christos for (k = 16; k; k--, s++) 1328 1.2 darrenr *t++ = (isprint(*s) ? *s : '.'); 1329 1.1 christos s--; 1330 1.1 christos } 1331 1.1 christos 1332 1.1 christos if ((j + 1) & 0xf) 1333 1.1 christos *t++ = ' ';; 1334 1.1 christos } 1335 1.1 christos 1336 1.1 christos if (j & 0xf) { 1337 1.1 christos for (k = 16 - (j & 0xf); k; k--) { 1338 1.1 christos *t++ = ' '; 1339 1.1 christos *t++ = ' '; 1340 1.1 christos *t++ = ' '; 1341 1.1 christos } 1342 1.1 christos sprintf((char *)t, " "); 1343 1.1 christos t += 7; 1344 1.1 christos s -= j & 0xf; 1345 1.1 christos for (k = j & 0xf; k; k--, s++) 1346 1.2 darrenr *t++ = (isprint(*s) ? *s : '.'); 1347 1.1 christos *t++ = '\n'; 1348 1.1 christos *t = '\0'; 1349 1.1 christos } 1350 1.1 christos fputs(outline, stdout); 1351 1.1 christos fflush(stdout); 1352 1.1 christos ip->ip_len = ntohs(ip->ip_len); 1353 1.1 christos } 1354 1.1 christos 1355 1.1 christos prep_packet(); 1356 1.1 christos free_aniplist(); 1357 1.1 christos } 1358 1.1 christos 1359 1.1 christos 1360 1.1 christos void new_interface() 1361 1.1 christos { 1362 1.1 christos cifp = (iface_t *)calloc(1, sizeof(iface_t)); 1363 1.1 christos *iftail = cifp; 1364 1.1 christos iftail = &cifp->if_next; 1365 1.1 christos cifp->if_fd = -1; 1366 1.1 christos } 1367 1.1 christos 1368 1.1 christos 1369 1.1 christos void check_interface() 1370 1.1 christos { 1371 1.1 christos if (!cifp->if_name || !*cifp->if_name) 1372 1.1 christos fprintf(stderr, "No interface name given!\n"); 1373 1.1 christos if (!cifp->if_MTU || !*cifp->if_name) 1374 1.1 christos fprintf(stderr, "Interface %s has an MTU of 0!\n", 1375 1.1 christos cifp->if_name); 1376 1.1 christos } 1377 1.1 christos 1378 1.1 christos 1379 1.1 christos void set_ifname(arg) 1380 1.1 christos char **arg; 1381 1.1 christos { 1382 1.1 christos cifp->if_name = *arg; 1383 1.1 christos *arg = NULL; 1384 1.1 christos } 1385 1.1 christos 1386 1.1 christos 1387 1.1 christos void set_ifmtu(arg) 1388 1.1 christos int arg; 1389 1.1 christos { 1390 1.1 christos cifp->if_MTU = arg; 1391 1.1 christos } 1392 1.1 christos 1393 1.1 christos 1394 1.1 christos void set_ifv4addr(arg) 1395 1.1 christos char **arg; 1396 1.1 christos { 1397 1.1 christos cifp->if_addr = getipv4addr(*arg); 1398 1.1 christos free(*arg); 1399 1.1 christos *arg = NULL; 1400 1.1 christos } 1401 1.1 christos 1402 1.1 christos 1403 1.1 christos void set_ifeaddr(arg) 1404 1.1 christos char **arg; 1405 1.1 christos { 1406 1.1 christos (void) geteaddr(*arg, &cifp->if_eaddr); 1407 1.1 christos free(*arg); 1408 1.1 christos *arg = NULL; 1409 1.1 christos } 1410 1.1 christos 1411 1.1 christos 1412 1.1 christos void new_arp() 1413 1.1 christos { 1414 1.1 christos carp = (arp_t *)calloc(1, sizeof(arp_t)); 1415 1.1 christos *arptail = carp; 1416 1.1 christos arptail = &carp->arp_next; 1417 1.1 christos } 1418 1.1 christos 1419 1.1 christos 1420 1.1 christos void set_arpeaddr(arg) 1421 1.1 christos char **arg; 1422 1.1 christos { 1423 1.1 christos (void) geteaddr(*arg, &carp->arp_eaddr); 1424 1.1 christos free(*arg); 1425 1.1 christos *arg = NULL; 1426 1.1 christos } 1427 1.1 christos 1428 1.1 christos 1429 1.1 christos void set_arpv4addr(arg) 1430 1.1 christos char **arg; 1431 1.1 christos { 1432 1.1 christos carp->arp_addr = getipv4addr(*arg); 1433 1.1 christos free(*arg); 1434 1.1 christos *arg = NULL; 1435 1.1 christos } 1436 1.1 christos 1437 1.1 christos 1438 1.1 christos int arp_getipv4(ip, addr) 1439 1.1 christos char *ip; 1440 1.1 christos char *addr; 1441 1.1 christos { 1442 1.1 christos arp_t *a; 1443 1.1 christos 1444 1.1 christos for (a = arplist; a; a = a->arp_next) 1445 1.1 christos if (!bcmp(ip, (char *)&a->arp_addr, 4)) { 1446 1.1 christos bcopy((char *)&a->arp_eaddr, addr, 6); 1447 1.1 christos return 0; 1448 1.1 christos } 1449 1.1 christos return -1; 1450 1.1 christos } 1451 1.1 christos 1452 1.1 christos 1453 1.1 christos void reset_send() 1454 1.1 christos { 1455 1.1 christos sending.snd_if = iflist; 1456 1.1 christos sending.snd_gw = defrouter; 1457 1.1 christos } 1458 1.1 christos 1459 1.1 christos 1460 1.1 christos void set_sendif(arg) 1461 1.1 christos char **arg; 1462 1.1 christos { 1463 1.1 christos iface_t *ifp; 1464 1.1 christos 1465 1.1 christos for (ifp = iflist; ifp; ifp = ifp->if_next) 1466 1.1 christos if (ifp->if_name && !strcmp(ifp->if_name, *arg)) 1467 1.1 christos break; 1468 1.1 christos sending.snd_if = ifp; 1469 1.1 christos if (!ifp) 1470 1.1 christos fprintf(stderr, "couldn't find interface %s\n", *arg); 1471 1.1 christos free(*arg); 1472 1.1 christos *arg = NULL; 1473 1.1 christos } 1474 1.1 christos 1475 1.1 christos 1476 1.1 christos void set_sendvia(arg) 1477 1.1 christos char **arg; 1478 1.1 christos { 1479 1.1 christos sending.snd_gw = getipv4addr(*arg); 1480 1.1 christos free(*arg); 1481 1.1 christos *arg = NULL; 1482 1.1 christos } 1483 1.1 christos 1484 1.1 christos 1485 1.1 christos void set_defaultrouter(arg) 1486 1.1 christos char **arg; 1487 1.1 christos { 1488 1.1 christos defrouter = getipv4addr(*arg); 1489 1.1 christos free(*arg); 1490 1.1 christos *arg = NULL; 1491 1.1 christos } 1492 1.1 christos 1493 1.1 christos 1494 1.1 christos void new_icmpheader() 1495 1.1 christos { 1496 1.1 christos if ((ip->ip_p) && (ip->ip_p != IPPROTO_ICMP)) { 1497 1.1 christos fprintf(stderr, "protocol %d specified with ICMP!\n", 1498 1.1 christos ip->ip_p); 1499 1.1 christos return; 1500 1.1 christos } 1501 1.1 christos ip->ip_p = IPPROTO_ICMP; 1502 1.1 christos icmp = (icmphdr_t *)new_header(IPPROTO_ICMP); 1503 1.1 christos } 1504 1.1 christos 1505 1.1 christos 1506 1.1 christos void set_icmpcode(code) 1507 1.1 christos int code; 1508 1.1 christos { 1509 1.1 christos icmp->icmp_code = code; 1510 1.1 christos } 1511 1.1 christos 1512 1.1 christos 1513 1.1 christos void set_icmptype(type) 1514 1.1 christos int type; 1515 1.1 christos { 1516 1.1 christos icmp->icmp_type = type; 1517 1.1 christos } 1518 1.1 christos 1519 1.1 christos 1520 1.1 christos void set_icmpcodetok(code) 1521 1.1 christos char **code; 1522 1.1 christos { 1523 1.1 christos char *s; 1524 1.1 christos int i; 1525 1.1 christos 1526 1.1 christos for (i = 0; (s = icmpcodes[i]); i++) 1527 1.1 christos if (!strcmp(s, *code)) { 1528 1.1 christos icmp->icmp_code = i; 1529 1.1 christos break; 1530 1.1 christos } 1531 1.1 christos if (!s) 1532 1.1 christos fprintf(stderr, "unknown ICMP code %s\n", *code); 1533 1.1 christos free(*code); 1534 1.1 christos *code = NULL; 1535 1.1 christos } 1536 1.1 christos 1537 1.1 christos 1538 1.1 christos void set_icmptypetok(type) 1539 1.1 christos char **type; 1540 1.1 christos { 1541 1.1 christos char *s; 1542 1.1 christos int i, done = 0; 1543 1.1 christos 1544 1.1 christos for (i = 0; !(s = icmptypes[i]) || strcmp(s, "END"); i++) 1545 1.1 christos if (s && !strcmp(s, *type)) { 1546 1.1 christos icmp->icmp_type = i; 1547 1.1 christos done = 1; 1548 1.1 christos break; 1549 1.1 christos } 1550 1.1 christos if (!done) 1551 1.1 christos fprintf(stderr, "unknown ICMP type %s\n", *type); 1552 1.1 christos free(*type); 1553 1.1 christos *type = NULL; 1554 1.1 christos } 1555 1.1 christos 1556 1.1 christos 1557 1.1 christos void set_icmpid(arg) 1558 1.1 christos int arg; 1559 1.1 christos { 1560 1.1 christos icmp->icmp_id = htons(arg); 1561 1.1 christos } 1562 1.1 christos 1563 1.1 christos 1564 1.1 christos void set_icmpseq(arg) 1565 1.1 christos int arg; 1566 1.1 christos { 1567 1.1 christos icmp->icmp_seq = htons(arg); 1568 1.1 christos } 1569 1.1 christos 1570 1.1 christos 1571 1.1 christos void set_icmpotime(arg) 1572 1.1 christos int arg; 1573 1.1 christos { 1574 1.1 christos icmp->icmp_otime = htonl(arg); 1575 1.1 christos } 1576 1.1 christos 1577 1.1 christos 1578 1.1 christos void set_icmprtime(arg) 1579 1.1 christos int arg; 1580 1.1 christos { 1581 1.1 christos icmp->icmp_rtime = htonl(arg); 1582 1.1 christos } 1583 1.1 christos 1584 1.1 christos 1585 1.1 christos void set_icmpttime(arg) 1586 1.1 christos int arg; 1587 1.1 christos { 1588 1.1 christos icmp->icmp_ttime = htonl(arg); 1589 1.1 christos } 1590 1.1 christos 1591 1.1 christos 1592 1.1 christos void set_icmpmtu(arg) 1593 1.1 christos int arg; 1594 1.1 christos { 1595 1.1 christos #if BSD >= 199306 1596 1.1 christos icmp->icmp_nextmtu = htons(arg); 1597 1.1 christos #endif 1598 1.1 christos } 1599 1.1 christos 1600 1.1 christos 1601 1.1 christos void set_redir(redir, arg) 1602 1.1 christos int redir; 1603 1.1 christos char **arg; 1604 1.1 christos { 1605 1.1 christos icmp->icmp_code = redir; 1606 1.1 christos icmp->icmp_gwaddr = getipv4addr(*arg); 1607 1.1 christos free(*arg); 1608 1.1 christos *arg = NULL; 1609 1.1 christos } 1610 1.1 christos 1611 1.1 christos 1612 1.1 christos void set_icmppprob(num) 1613 1.1 christos int num; 1614 1.1 christos { 1615 1.1 christos icmp->icmp_pptr = num; 1616 1.1 christos } 1617 1.1 christos 1618 1.1 christos 1619 1.1 christos void new_ipv4opt() 1620 1.1 christos { 1621 1.1 christos new_header(-2); 1622 1.1 christos } 1623 1.1 christos 1624 1.1 christos 1625 1.1 christos void add_ipopt(state, ptr) 1626 1.1 christos int state; 1627 1.1 christos void *ptr; 1628 1.1 christos { 1629 1.1 christos struct ipopt_names *io; 1630 1.1 christos struct statetoopt *sto; 1631 1.1 christos char numbuf[16], *arg, **param = ptr; 1632 1.1 christos int inc, hlen; 1633 1.1 christos 1634 1.1 christos if (state == IL_IPO_RR || state == IL_IPO_SATID) { 1635 1.1 christos if (param) 1636 1.1 christos sprintf(numbuf, "%d", *(int *)param); 1637 1.1 christos else 1638 1.1 christos strcpy(numbuf, "0"); 1639 1.1 christos arg = numbuf; 1640 1.1 christos } else 1641 1.1 christos arg = param ? *param : NULL; 1642 1.1 christos 1643 1.1 christos if (canip->ah_next) { 1644 1.1 christos fprintf(stderr, "cannot specify options after data body\n"); 1645 1.1 christos return; 1646 1.1 christos } 1647 1.1 christos for (sto = toipopts; sto->sto_st; sto++) 1648 1.1 christos if (sto->sto_st == state) 1649 1.1 christos break; 1650 1.1 christos if (!sto->sto_st) { 1651 1.1 christos fprintf(stderr, "No mapping for state %d to IP option\n", 1652 1.1 christos state); 1653 1.1 christos return; 1654 1.1 christos } 1655 1.1 christos 1656 1.1 christos hlen = sizeof(ip_t) + canip->ah_optlen; 1657 1.1 christos for (io = ionames; io->on_name; io++) 1658 1.1 christos if (io->on_value == sto->sto_op) 1659 1.1 christos break; 1660 1.1 christos canip->ah_lastopt = io->on_value; 1661 1.1 christos 1662 1.1 christos if (io->on_name) { 1663 1.1 christos inc = addipopt((char *)ip + hlen, io, hlen - sizeof(ip_t),arg); 1664 1.1 christos if (inc > 0) { 1665 1.1 christos while (inc & 3) { 1666 1.1 christos ((char *)ip)[sizeof(*ip) + inc] = IPOPT_NOP; 1667 1.1 christos canip->ah_lastopt = IPOPT_NOP; 1668 1.1 christos inc++; 1669 1.1 christos } 1670 1.1 christos hlen += inc; 1671 1.1 christos } 1672 1.1 christos } 1673 1.1 christos 1674 1.1 christos canip->ah_optlen = hlen - sizeof(ip_t); 1675 1.1 christos 1676 1.1 christos if (state != IL_IPO_RR && state != IL_IPO_SATID) 1677 1.1 christos if (param && *param) { 1678 1.1 christos free(*param); 1679 1.1 christos *param = NULL; 1680 1.1 christos } 1681 1.1 christos sclass = NULL; 1682 1.1 christos } 1683 1.1 christos 1684 1.1 christos 1685 1.1 christos void end_ipopt() 1686 1.1 christos { 1687 1.1 christos int pad; 1688 1.1 christos char *s, *buf = (char *)ip; 1689 1.1 christos 1690 1.1 christos /* 1691 1.1 christos * pad out so that we have a multiple of 4 bytes in size fo the 1692 1.1 christos * options. make sure last byte is EOL. 1693 1.1 christos */ 1694 1.1 christos if (canip->ah_lastopt == IPOPT_NOP) { 1695 1.1 christos buf[sizeof(*ip) + canip->ah_optlen - 1] = IPOPT_EOL; 1696 1.1 christos } else if (canip->ah_lastopt != IPOPT_EOL) { 1697 1.1 christos s = buf + sizeof(*ip) + canip->ah_optlen; 1698 1.1 christos 1699 1.1 christos for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { 1700 1.1 christos *s++ = IPOPT_NOP; 1701 1.1 christos *s = IPOPT_EOL; 1702 1.1 christos canip->ah_optlen++; 1703 1.1 christos } 1704 1.1 christos canip->ah_optlen++; 1705 1.1 christos } else { 1706 1.1 christos s = buf + sizeof(*ip) + canip->ah_optlen - 1; 1707 1.1 christos 1708 1.1 christos for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { 1709 1.1 christos *s++ = IPOPT_NOP; 1710 1.1 christos *s = IPOPT_EOL; 1711 1.1 christos canip->ah_optlen++; 1712 1.1 christos } 1713 1.1 christos } 1714 1.1 christos ip->ip_hl = (sizeof(*ip) + canip->ah_optlen) >> 2; 1715 1.1 christos inc_anipheaders(canip->ah_optlen); 1716 1.1 christos free_anipheader(); 1717 1.1 christos } 1718 1.1 christos 1719 1.1 christos 1720 1.1 christos void set_secclass(arg) 1721 1.1 christos char **arg; 1722 1.1 christos { 1723 1.1 christos sclass = *arg; 1724 1.1 christos *arg = NULL; 1725 1.1 christos } 1726 1.1 christos 1727 1.1 christos 1728 1.1 christos void free_anipheader() 1729 1.1 christos { 1730 1.1 christos aniphdr_t *aip; 1731 1.1 christos 1732 1.1 christos aip = canip; 1733 1.1 christos if ((canip = aip->ah_prev)) { 1734 1.1 christos canip->ah_next = NULL; 1735 1.1 christos aniptail = &canip->ah_next; 1736 1.1 christos } 1737 1.1 christos 1738 1.1 christos if (canip) 1739 1.1 christos free(aip); 1740 1.1 christos } 1741 1.1 christos 1742 1.1 christos 1743 1.1 christos void end_ipv4() 1744 1.1 christos { 1745 1.1 christos aniphdr_t *aip; 1746 1.1 christos 1747 1.1 christos ip->ip_sum = 0; 1748 1.1 christos ip->ip_len = htons(ip->ip_len); 1749 1.1 christos ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2); 1750 1.1 christos ip->ip_len = ntohs(ip->ip_len); 1751 1.1 christos free_anipheader(); 1752 1.1 christos for (aip = aniphead, ip = NULL; aip; aip = aip->ah_next) 1753 1.1 christos if (aip->ah_p == IPPROTO_IP) 1754 1.1 christos ip = aip->ah_ip; 1755 1.1 christos } 1756 1.1 christos 1757 1.1 christos 1758 1.1 christos void end_icmp() 1759 1.1 christos { 1760 1.1 christos aniphdr_t *aip; 1761 1.1 christos 1762 1.1 christos icmp->icmp_cksum = 0; 1763 1.1 christos icmp->icmp_cksum = chksum((u_short *)icmp, canip->ah_len); 1764 1.1 christos free_anipheader(); 1765 1.1 christos for (aip = aniphead, icmp = NULL; aip; aip = aip->ah_next) 1766 1.1 christos if (aip->ah_p == IPPROTO_ICMP) 1767 1.1 christos icmp = aip->ah_icmp; 1768 1.1 christos } 1769 1.1 christos 1770 1.1 christos 1771 1.1 christos void end_udp() 1772 1.1 christos { 1773 1.1 christos u_long sum; 1774 1.1 christos aniphdr_t *aip; 1775 1.1 christos ip_t iptmp; 1776 1.1 christos 1777 1.1 christos bzero((char *)&iptmp, sizeof(iptmp)); 1778 1.1 christos iptmp.ip_p = ip->ip_p; 1779 1.1 christos iptmp.ip_src = ip->ip_src; 1780 1.1 christos iptmp.ip_dst = ip->ip_dst; 1781 1.1 christos iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2)); 1782 1.1 christos sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp)); 1783 1.1 christos udp->uh_ulen = htons(udp->uh_ulen); 1784 1.1 christos udp->uh_sum = c_chksum((u_short *)udp, (u_int)ntohs(iptmp.ip_len), sum); 1785 1.1 christos free_anipheader(); 1786 1.1 christos for (aip = aniphead, udp = NULL; aip; aip = aip->ah_next) 1787 1.1 christos if (aip->ah_p == IPPROTO_UDP) 1788 1.1 christos udp = aip->ah_udp; 1789 1.1 christos } 1790 1.1 christos 1791 1.1 christos 1792 1.1 christos void end_tcp() 1793 1.1 christos { 1794 1.1 christos u_long sum; 1795 1.1 christos aniphdr_t *aip; 1796 1.1 christos ip_t iptmp; 1797 1.1 christos 1798 1.1 christos bzero((char *)&iptmp, sizeof(iptmp)); 1799 1.1 christos iptmp.ip_p = ip->ip_p; 1800 1.1 christos iptmp.ip_src = ip->ip_src; 1801 1.1 christos iptmp.ip_dst = ip->ip_dst; 1802 1.1 christos iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2)); 1803 1.1 christos sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp)); 1804 1.1 christos tcp->th_sum = 0; 1805 1.1 christos tcp->th_sum = c_chksum((u_short *)tcp, (u_int)ntohs(iptmp.ip_len), sum); 1806 1.1 christos free_anipheader(); 1807 1.1 christos for (aip = aniphead, tcp = NULL; aip; aip = aip->ah_next) 1808 1.1 christos if (aip->ah_p == IPPROTO_TCP) 1809 1.1 christos tcp = aip->ah_tcp; 1810 1.1 christos } 1811 1.1 christos 1812 1.1 christos 1813 1.1 christos void end_data() 1814 1.1 christos { 1815 1.1 christos free_anipheader(); 1816 1.1 christos } 1817 1.1 christos 1818 1.1 christos 1819 1.1 christos void iplang(fp) 1820 1.1 christos FILE *fp; 1821 1.1 christos { 1822 1.1 christos yyin = fp; 1823 1.1 christos 1824 1.1 christos yydebug = (opts & OPT_DEBUG) ? 1 : 0; 1825 1.1 christos 1826 1.1 christos while (!feof(fp)) 1827 1.1 christos yyparse(); 1828 1.1 christos } 1829 1.1 christos 1830 1.1 christos 1831 1.1 christos u_short c_chksum(buf, len, init) 1832 1.1 christos u_short *buf; 1833 1.1 christos u_int len; 1834 1.1 christos u_long init; 1835 1.1 christos { 1836 1.1 christos u_long sum = init; 1837 1.1 christos int nwords = len >> 1; 1838 1.1 christos 1839 1.1 christos for(; nwords > 0; nwords--) 1840 1.1 christos sum += *buf++; 1841 1.1 christos sum = (sum>>16) + (sum & 0xffff); 1842 1.1 christos sum += (sum >>16); 1843 1.1 christos return (~sum); 1844 1.1 christos } 1845 1.1 christos 1846 1.1 christos 1847 1.1 christos u_long p_chksum(buf,len) 1848 1.1 christos u_short *buf; 1849 1.1 christos u_int len; 1850 1.1 christos { 1851 1.1 christos u_long sum = 0; 1852 1.1 christos int nwords = len >> 1; 1853 1.1 christos 1854 1.1 christos for(; nwords > 0; nwords--) 1855 1.1 christos sum += *buf++; 1856 1.1 christos return sum; 1857 1.1 christos } 1858