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