1145519Sdarrenr/* $FreeBSD$ */ 2145519Sdarrenr 331183Speter%{ 431183Speter/* 5255332Scy * Copyright (C) 2012 by Darren Reed. 631183Speter * 7145519Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 831183Speter * 9161357Sguido * Id: iplang_y.y,v 2.9.2.4 2006/03/17 12:11:29 darrenr Exp $ 1063537Sarchie * $FreeBSD$ 1131183Speter */ 1253024Sguido 1331183Speter#include <stdio.h> 1431183Speter#include <string.h> 1531183Speter#include <fcntl.h> 1631183Speter#if !defined(__SVR4) && !defined(__svr4__) 17170268Sdarrenr# include <strings.h> 1831183Speter#else 19170268Sdarrenr# include <sys/byteorder.h> 2031183Speter#endif 2131183Speter#include <sys/types.h> 2231183Speter#include <sys/stat.h> 2331183Speter#include <sys/param.h> 2431183Speter#include <sys/time.h> 2531183Speter#include <stdlib.h> 2631183Speter#include <unistd.h> 2731183Speter#include <stddef.h> 2831183Speter#include <sys/socket.h> 29255332Scy#include <net/if.h> 3031183Speter#include <netinet/in.h> 3131183Speter#include <netinet/in_systm.h> 3231183Speter#include <netinet/ip.h> 3331183Speter#ifndef linux 34170268Sdarrenr# include <netinet/ip_var.h> 35255332Scy# include <net/route.h> 36170268Sdarrenr# include <netinet/if_ether.h> 3731183Speter#endif 3831183Speter#include <netdb.h> 3931183Speter#include <arpa/nameser.h> 4031183Speter#include <arpa/inet.h> 4131183Speter#include <resolv.h> 4231183Speter#include <ctype.h> 4331183Speter#include "ipsend.h" 4431183Speter#include "ip_compat.h" 4531183Speter#include "ipf.h" 4631183Speter#include "iplang.h" 4731183Speter 4864591Sdarrenr#if !defined(__NetBSD__) && (!defined(__FreeBSD_version) && \ 49145519Sdarrenr __FreeBSD_version < 400020) && (!SOLARIS || SOLARIS2 < 10) 5031183Speterextern struct ether_addr *ether_aton __P((char *)); 5137074Speter#endif 5231183Speter 5331183Speterextern int opts; 5431183Speterextern struct ipopt_names ionames[]; 5531183Speterextern int state, state, lineNum, token; 5631183Speterextern int yylineno; 5731183Speterextern char yytext[]; 5831183Speterextern FILE *yyin; 5931183Speterint yylex __P((void)); 6031183Speter#define YYDEBUG 1 6131183Speter#if !defined(ultrix) && !defined(hpux) 6231183Speterint yydebug = 1; 6331183Speter#else 6431183Speterextern int yydebug; 6531183Speter#endif 6631183Speter 6731183Speteriface_t *iflist = NULL, **iftail = &iflist; 6831183Speteriface_t *cifp = NULL; 6931183Speterarp_t *arplist = NULL, **arptail = &arplist, *carp = NULL; 7031183Speterstruct in_addr defrouter; 7131183Spetersend_t sending; 7231183Speterchar *sclass = NULL; 7331183Speteru_short c_chksum __P((u_short *, u_int, u_long)); 7431183Speteru_long p_chksum __P((u_short *, u_int)); 7531183Speter 7631183Speteru_long ipbuffer[67584/sizeof(u_long)]; /* 66K */ 7731183Speteraniphdr_t *aniphead = NULL, *canip = NULL, **aniptail = &aniphead; 7831183Speterip_t *ip = NULL; 7931183Speterudphdr_t *udp = NULL; 8031183Spetertcphdr_t *tcp = NULL; 8131183Spetericmphdr_t *icmp = NULL; 8231183Speter 8331183Speterstruct statetoopt { 8431183Speter int sto_st; 8531183Speter int sto_op; 8631183Speter}; 8731183Speter 8831183Speterstruct in_addr getipv4addr __P((char *arg)); 8931183Speteru_short getportnum __P((char *, char *)); 9031183Speterstruct ether_addr *geteaddr __P((char *, struct ether_addr *)); 9131183Spetervoid *new_header __P((int)); 9231183Spetervoid free_aniplist __P((void)); 9331183Spetervoid inc_anipheaders __P((int)); 9431183Spetervoid new_data __P((void)); 9531183Spetervoid set_datalen __P((char **)); 9631183Spetervoid set_datafile __P((char **)); 9731183Spetervoid set_data __P((char **)); 9831183Spetervoid new_packet __P((void)); 9931183Spetervoid set_ipv4proto __P((char **)); 10031183Spetervoid set_ipv4src __P((char **)); 10131183Spetervoid set_ipv4dst __P((char **)); 10231183Spetervoid set_ipv4off __P((char **)); 10331183Spetervoid set_ipv4v __P((char **)); 10431183Spetervoid set_ipv4hl __P((char **)); 10531183Spetervoid set_ipv4ttl __P((char **)); 10631183Spetervoid set_ipv4tos __P((char **)); 10731183Spetervoid set_ipv4id __P((char **)); 10831183Spetervoid set_ipv4sum __P((char **)); 10931183Spetervoid set_ipv4len __P((char **)); 11031183Spetervoid new_tcpheader __P((void)); 11131183Spetervoid set_tcpsport __P((char **)); 11231183Spetervoid set_tcpdport __P((char **)); 11331183Spetervoid set_tcpseq __P((char **)); 11431183Spetervoid set_tcpack __P((char **)); 11531183Spetervoid set_tcpoff __P((char **)); 11631183Spetervoid set_tcpurp __P((char **)); 11731183Spetervoid set_tcpwin __P((char **)); 11831183Spetervoid set_tcpsum __P((char **)); 11931183Spetervoid set_tcpflags __P((char **)); 12031183Spetervoid set_tcpopt __P((int, char **)); 12131183Spetervoid end_tcpopt __P((void)); 12231183Spetervoid new_udpheader __P((void)); 12331183Spetervoid set_udplen __P((char **)); 12431183Spetervoid set_udpsum __P((char **)); 12531183Spetervoid prep_packet __P((void)); 12631183Spetervoid packet_done __P((void)); 12731183Spetervoid new_interface __P((void)); 12831183Spetervoid check_interface __P((void)); 12931183Spetervoid set_ifname __P((char **)); 13031183Spetervoid set_ifmtu __P((int)); 13131183Spetervoid set_ifv4addr __P((char **)); 13231183Spetervoid set_ifeaddr __P((char **)); 13331183Spetervoid new_arp __P((void)); 13431183Spetervoid set_arpeaddr __P((char **)); 13531183Spetervoid set_arpv4addr __P((char **)); 13631183Spetervoid reset_send __P((void)); 13731183Spetervoid set_sendif __P((char **)); 13831183Spetervoid set_sendvia __P((char **)); 13931183Spetervoid set_defaultrouter __P((char **)); 14031183Spetervoid new_icmpheader __P((void)); 14131183Spetervoid set_icmpcode __P((int)); 14231183Spetervoid set_icmptype __P((int)); 14331183Spetervoid set_icmpcodetok __P((char **)); 14431183Spetervoid set_icmptypetok __P((char **)); 14531183Spetervoid set_icmpid __P((int)); 14631183Spetervoid set_icmpseq __P((int)); 14731183Spetervoid set_icmpotime __P((int)); 14831183Spetervoid set_icmprtime __P((int)); 14931183Spetervoid set_icmpttime __P((int)); 15031183Spetervoid set_icmpmtu __P((int)); 15131183Spetervoid set_redir __P((int, char **)); 15231183Spetervoid new_ipv4opt __P((void)); 15331183Spetervoid set_icmppprob __P((int)); 15431183Spetervoid add_ipopt __P((int, void *)); 15531183Spetervoid end_ipopt __P((void)); 15631183Spetervoid set_secclass __P((char **)); 15731183Spetervoid free_anipheader __P((void)); 15831183Spetervoid end_ipv4 __P((void)); 15931183Spetervoid end_icmp __P((void)); 16031183Spetervoid end_udp __P((void)); 16131183Spetervoid end_tcp __P((void)); 16231183Spetervoid end_data __P((void)); 16331183Spetervoid yyerror __P((char *)); 16431183Spetervoid iplang __P((FILE *)); 16555924Sguidoint arp_getipv4 __P((char *, char *)); 16631183Speterint yyparse __P((void)); 16731183Speter%} 16831183Speter%union { 16931183Speter char *str; 17031183Speter int num; 17131183Speter} 17231183Speter%token <num> IL_NUMBER 17331183Speter%type <num> number digits optnumber 17431183Speter%token <str> IL_TOKEN 17531183Speter%type <str> token optoken 17631183Speter%token IL_HEXDIGIT IL_COLON IL_DOT IL_EOF IL_COMMENT 17731183Speter%token IL_INTERFACE IL_IFNAME IL_MTU IL_EADDR 17831183Speter%token IL_IPV4 IL_V4PROTO IL_V4SRC IL_V4DST IL_V4OFF IL_V4V IL_V4HL IL_V4TTL 17931183Speter%token IL_V4TOS IL_V4SUM IL_V4LEN IL_V4OPT IL_V4ID 18031183Speter%token IL_TCP IL_SPORT IL_DPORT IL_TCPFL IL_TCPSEQ IL_TCPACK IL_TCPOFF 18131183Speter%token IL_TCPWIN IL_TCPSUM IL_TCPURP IL_TCPOPT IL_TCPO_NOP IL_TCPO_EOL 18231183Speter%token IL_TCPO_MSS IL_TCPO_WSCALE IL_TCPO_TS 18331183Speter%token IL_UDP IL_UDPLEN IL_UDPSUM 18431183Speter%token IL_ICMP IL_ICMPTYPE IL_ICMPCODE 18531183Speter%token IL_SEND IL_VIA 18631183Speter%token IL_ARP 18731183Speter%token IL_DEFROUTER 18831183Speter%token IL_SUM IL_OFF IL_LEN IL_V4ADDR IL_OPT 18931183Speter%token IL_DATA IL_DLEN IL_DVALUE IL_DFILE 19031183Speter%token IL_IPO_NOP IL_IPO_RR IL_IPO_ZSU IL_IPO_MTUP IL_IPO_MTUR IL_IPO_EOL 19131183Speter%token IL_IPO_TS IL_IPO_TR IL_IPO_SEC IL_IPO_LSRR IL_IPO_ESEC 19231183Speter%token IL_IPO_SATID IL_IPO_SSRR IL_IPO_ADDEXT IL_IPO_VISA IL_IPO_IMITD 19331183Speter%token IL_IPO_EIP IL_IPO_FINN IL_IPO_SECCLASS IL_IPO_CIPSO IL_IPO_ENCODE 19434739Speter%token <str> IL_IPS_RESERV4 IL_IPS_TOPSECRET IL_IPS_SECRET IL_IPS_RESERV3 19534739Speter%token <str> IL_IPS_CONFID IL_IPS_UNCLASS IL_IPS_RESERV2 IL_IPS_RESERV1 19631183Speter%token IL_ICMP_ECHOREPLY IL_ICMP_UNREACH IL_ICMP_UNREACH_NET 19731183Speter%token IL_ICMP_UNREACH_HOST IL_ICMP_UNREACH_PROTOCOL IL_ICMP_UNREACH_PORT 19831183Speter%token IL_ICMP_UNREACH_NEEDFRAG IL_ICMP_UNREACH_SRCFAIL 19931183Speter%token IL_ICMP_UNREACH_NET_UNKNOWN IL_ICMP_UNREACH_HOST_UNKNOWN 20031183Speter%token IL_ICMP_UNREACH_ISOLATED IL_ICMP_UNREACH_NET_PROHIB 20131183Speter%token IL_ICMP_UNREACH_HOST_PROHIB IL_ICMP_UNREACH_TOSNET 20231183Speter%token IL_ICMP_UNREACH_TOSHOST IL_ICMP_UNREACH_FILTER_PROHIB 20331183Speter%token IL_ICMP_UNREACH_HOST_PRECEDENCE IL_ICMP_UNREACH_PRECEDENCE_CUTOFF 20431183Speter%token IL_ICMP_SOURCEQUENCH IL_ICMP_REDIRECT IL_ICMP_REDIRECT_NET 20531183Speter%token IL_ICMP_REDIRECT_HOST IL_ICMP_REDIRECT_TOSNET 20631183Speter%token IL_ICMP_REDIRECT_TOSHOST IL_ICMP_ECHO IL_ICMP_ROUTERADVERT 20731183Speter%token IL_ICMP_ROUTERSOLICIT IL_ICMP_TIMXCEED IL_ICMP_TIMXCEED_INTRANS 20831183Speter%token IL_ICMP_TIMXCEED_REASS IL_ICMP_PARAMPROB IL_ICMP_PARAMPROB_OPTABSENT 20931183Speter%token IL_ICMP_TSTAMP IL_ICMP_TSTAMPREPLY IL_ICMP_IREQ IL_ICMP_IREQREPLY 21031183Speter%token IL_ICMP_MASKREQ IL_ICMP_MASKREPLY IL_ICMP_SEQ IL_ICMP_ID 21131183Speter%token IL_ICMP_OTIME IL_ICMP_RTIME IL_ICMP_TTIME 21231183Speter 21331183Speter%% 21431183Speterfile: line 21531183Speter | line file 21631183Speter | IL_COMMENT 21731183Speter | IL_COMMENT file 21831183Speter ; 21931183Speter 22031183Speterline: iface 22131183Speter | arp 22231183Speter | send 22331183Speter | defrouter 22431183Speter | ipline 22531183Speter ; 22631183Speter 22731183Speteriface: ifhdr '{' ifaceopts '}' ';' { check_interface(); } 22831183Speter ; 22931183Speter 23031183Speterifhdr: IL_INTERFACE { new_interface(); } 23131183Speter ; 23231183Speter 23331183Speterifaceopts: 23431183Speter ifaceopt 23531183Speter | ifaceopt ifaceopts 23631183Speter ; 23731183Speter 23831183Speterifaceopt: 23934739Speter IL_IFNAME token { set_ifname(&$2); } 24034739Speter | IL_MTU number { set_ifmtu($2); } 24134739Speter | IL_V4ADDR token { set_ifv4addr(&$2); } 24234739Speter | IL_EADDR token { set_ifeaddr(&$2); } 24331183Speter ; 24431183Speter 24531183Spetersend: sendhdr '{' sendbody '}' ';' { packet_done(); } 24631183Speter | sendhdr ';' { packet_done(); } 24731183Speter ; 24831183Speter 24931183Spetersendhdr: 25031183Speter IL_SEND { reset_send(); } 25131183Speter ; 25231183Speter 25331183Spetersendbody: 25431183Speter sendopt 25531183Speter | sendbody sendopt 25631183Speter ; 25731183Speter 25831183Spetersendopt: 25934739Speter IL_IFNAME token { set_sendif(&$2); } 26034739Speter | IL_VIA token { set_sendvia(&$2); } 26131183Speter ; 26231183Speter 26331183Speterarp: arphdr '{' arpbody '}' ';' 26431183Speter ; 26531183Speter 26631183Speterarphdr: IL_ARP { new_arp(); } 26731183Speter ; 26831183Speter 26931183Speterarpbody: 27031183Speter arpopt 27131183Speter | arpbody arpopt 27231183Speter ; 27331183Speter 27434739Speterarpopt: IL_V4ADDR token { set_arpv4addr(&$2); } 27534739Speter | IL_EADDR token { set_arpeaddr(&$2); } 27631183Speter ; 27731183Speter 27831183Speterdefrouter: 27934739Speter IL_DEFROUTER token { set_defaultrouter(&$2); } 28031183Speter ; 28131183Speter 28231183Speterbodyline: 28331183Speter ipline 28431183Speter | tcp tcpline 28531183Speter | udp udpline 28631183Speter | icmp icmpline 28731183Speter | data dataline 28831183Speter ; 28931183Speter 29031183Speteripline: ipv4 '{' ipv4body '}' ';' { end_ipv4(); } 29131183Speter ; 29231183Speter 29331183Speteripv4: IL_IPV4 { new_packet(); } 29431183Speter 29531183Speteripv4body: 29631183Speter ipv4type 29731183Speter | ipv4type ipv4body 29831183Speter | bodyline 29931183Speter ; 30031183Speter 30131183Speteripv4type: 30234739Speter IL_V4PROTO token { set_ipv4proto(&$2); } 30334739Speter | IL_V4SRC token { set_ipv4src(&$2); } 30434739Speter | IL_V4DST token { set_ipv4dst(&$2); } 30534739Speter | IL_V4OFF token { set_ipv4off(&$2); } 30634739Speter | IL_V4V token { set_ipv4v(&$2); } 30734739Speter | IL_V4HL token { set_ipv4hl(&$2); } 30834739Speter | IL_V4ID token { set_ipv4id(&$2); } 30934739Speter | IL_V4TTL token { set_ipv4ttl(&$2); } 31034739Speter | IL_V4TOS token { set_ipv4tos(&$2); } 31134739Speter | IL_V4SUM token { set_ipv4sum(&$2); } 31234739Speter | IL_V4LEN token { set_ipv4len(&$2); } 31331183Speter | ipv4opt '{' ipv4optlist '}' ';' { end_ipopt(); } 31431183Speter ; 31531183Speter 31631183Spetertcp: IL_TCP { new_tcpheader(); } 31731183Speter ; 31831183Speter 31931183Spetertcpline: 32031183Speter '{' tcpheader '}' ';' { end_tcp(); } 32131183Speter ; 32231183Speter 32331183Spetertcpheader: 32434739Speter tcpbody 32534739Speter | tcpbody tcpheader 32631183Speter | bodyline 32731183Speter ; 32831183Speter 32931183Spetertcpbody: 33034739Speter IL_SPORT token { set_tcpsport(&$2); } 33134739Speter | IL_DPORT token { set_tcpdport(&$2); } 33234739Speter | IL_TCPSEQ token { set_tcpseq(&$2); } 33334739Speter | IL_TCPACK token { set_tcpack(&$2); } 33434739Speter | IL_TCPOFF token { set_tcpoff(&$2); } 33534739Speter | IL_TCPURP token { set_tcpurp(&$2); } 33634739Speter | IL_TCPWIN token { set_tcpwin(&$2); } 33734739Speter | IL_TCPSUM token { set_tcpsum(&$2); } 33834739Speter | IL_TCPFL token { set_tcpflags(&$2); } 33931183Speter | IL_TCPOPT '{' tcpopts '}' ';' { end_tcpopt(); } 34031183Speter ; 34131183Speter 34231183Spetertcpopts: 34331183Speter | tcpopt tcpopts 34431183Speter ; 34531183Speter 34631183Spetertcpopt: IL_TCPO_NOP ';' { set_tcpopt(IL_TCPO_NOP, NULL); } 34731183Speter | IL_TCPO_EOL ';' { set_tcpopt(IL_TCPO_EOL, NULL); } 34834739Speter | IL_TCPO_MSS optoken { set_tcpopt(IL_TCPO_MSS,&$2);} 34937074Speter | IL_TCPO_WSCALE optoken { set_tcpopt(IL_TCPO_WSCALE,&$2);} 35034739Speter | IL_TCPO_TS optoken { set_tcpopt(IL_TCPO_TS, &$2);} 35131183Speter ; 35231183Speter 35331183Speterudp: IL_UDP { new_udpheader(); } 35431183Speter ; 35531183Speter 35631183Speterudpline: 35731183Speter '{' udpheader '}' ';' { end_udp(); } 35831183Speter ; 35931183Speter 36031183Speter 36131183Speterudpheader: 36231183Speter udpbody 36331183Speter | udpbody udpheader 36431183Speter | bodyline 36531183Speter ; 36631183Speter 36731183Speterudpbody: 36834739Speter IL_SPORT token { set_tcpsport(&$2); } 36934739Speter | IL_DPORT token { set_tcpdport(&$2); } 37034739Speter | IL_UDPLEN token { set_udplen(&$2); } 37134739Speter | IL_UDPSUM token { set_udpsum(&$2); } 37231183Speter ; 37331183Speter 37431183Spetericmp: IL_ICMP { new_icmpheader(); } 37531183Speter ; 37631183Speter 37731183Spetericmpline: 37831183Speter '{' icmpbody '}' ';' { end_icmp(); } 37931183Speter ; 38031183Speter 38131183Spetericmpbody: 38231183Speter icmpheader 38331183Speter | icmpheader bodyline 38431183Speter ; 38531183Speter 38631183Spetericmpheader: 38731183Speter IL_ICMPTYPE icmptype 38831183Speter | IL_ICMPTYPE icmptype icmpcode 38931183Speter ; 39031183Speter 39131183Spetericmpcode: 39234739Speter IL_ICMPCODE token { set_icmpcodetok(&$2); } 39331183Speter ; 39431183Speter 39531183Spetericmptype: 39631183Speter IL_ICMP_ECHOREPLY ';' { set_icmptype(ICMP_ECHOREPLY); } 39731183Speter | IL_ICMP_ECHOREPLY '{' icmpechoopts '}' ';' 39831183Speter | unreach 39931183Speter | IL_ICMP_SOURCEQUENCH ';' { set_icmptype(ICMP_SOURCEQUENCH); } 40031183Speter | redirect 40131183Speter | IL_ICMP_ROUTERADVERT ';' { set_icmptype(ICMP_ROUTERADVERT); } 40231183Speter | IL_ICMP_ROUTERSOLICIT ';' { set_icmptype(ICMP_ROUTERSOLICIT); } 40331183Speter | IL_ICMP_ECHO ';' { set_icmptype(ICMP_ECHO); } 40431183Speter | IL_ICMP_ECHO '{' icmpechoopts '}' ';' 40531183Speter | IL_ICMP_TIMXCEED ';' { set_icmptype(ICMP_TIMXCEED); } 40631183Speter | IL_ICMP_TIMXCEED '{' exceed '}' ';' 40731183Speter | IL_ICMP_TSTAMP ';' { set_icmptype(ICMP_TSTAMP); } 40831183Speter | IL_ICMP_TSTAMPREPLY ';' { set_icmptype(ICMP_TSTAMPREPLY); } 40931183Speter | IL_ICMP_TSTAMPREPLY '{' icmptsopts '}' ';' 41031183Speter | IL_ICMP_IREQ ';' { set_icmptype(ICMP_IREQ); } 41131183Speter | IL_ICMP_IREQREPLY ';' { set_icmptype(ICMP_IREQREPLY); } 41231183Speter | IL_ICMP_IREQREPLY '{' data dataline '}' ';' 41331183Speter | IL_ICMP_MASKREQ ';' { set_icmptype(ICMP_MASKREQ); } 41431183Speter | IL_ICMP_MASKREPLY ';' { set_icmptype(ICMP_MASKREPLY); } 41531183Speter | IL_ICMP_MASKREPLY '{' token '}' ';' 41631183Speter | IL_ICMP_PARAMPROB ';' { set_icmptype(ICMP_PARAMPROB); } 41731183Speter | IL_ICMP_PARAMPROB '{' paramprob '}' ';' 41834739Speter | IL_TOKEN ';' { set_icmptypetok(&$1); } 41931183Speter ; 42031183Speter 42131183Spetericmpechoopts: 42231183Speter | icmpechoopts icmpecho 42331183Speter ; 42431183Speter 42531183Spetericmpecho: 42634739Speter IL_ICMP_SEQ number { set_icmpseq($2); } 42734739Speter | IL_ICMP_ID number { set_icmpid($2); } 42831183Speter ; 42931183Speter 43031183Spetericmptsopts: 43131183Speter | icmptsopts icmpts ';' 43231183Speter ; 43331183Speter 43434739Spetericmpts: IL_ICMP_OTIME number { set_icmpotime($2); } 43534739Speter | IL_ICMP_RTIME number { set_icmprtime($2); } 43634739Speter | IL_ICMP_TTIME number { set_icmpttime($2); } 43731183Speter ; 43831183Speter 43931183Speterunreach: 44031183Speter IL_ICMP_UNREACH 44131183Speter | IL_ICMP_UNREACH '{' unreachopts '}' ';' 44231183Speter ; 44331183Speter 44431183Speterunreachopts: 44531183Speter IL_ICMP_UNREACH_NET line 44631183Speter | IL_ICMP_UNREACH_HOST line 44731183Speter | IL_ICMP_UNREACH_PROTOCOL line 44831183Speter | IL_ICMP_UNREACH_PORT line 44934739Speter | IL_ICMP_UNREACH_NEEDFRAG number ';' { set_icmpmtu($2); } 45031183Speter | IL_ICMP_UNREACH_SRCFAIL line 45131183Speter | IL_ICMP_UNREACH_NET_UNKNOWN line 45231183Speter | IL_ICMP_UNREACH_HOST_UNKNOWN line 45331183Speter | IL_ICMP_UNREACH_ISOLATED line 45431183Speter | IL_ICMP_UNREACH_NET_PROHIB line 45531183Speter | IL_ICMP_UNREACH_HOST_PROHIB line 45631183Speter | IL_ICMP_UNREACH_TOSNET line 45731183Speter | IL_ICMP_UNREACH_TOSHOST line 45831183Speter | IL_ICMP_UNREACH_FILTER_PROHIB line 45931183Speter | IL_ICMP_UNREACH_HOST_PRECEDENCE line 46031183Speter | IL_ICMP_UNREACH_PRECEDENCE_CUTOFF line 46131183Speter ; 46231183Speter 46331183Speterredirect: 46431183Speter IL_ICMP_REDIRECT 46531183Speter | IL_ICMP_REDIRECT '{' redirectopts '}' ';' 46631183Speter ; 46731183Speter 46831183Speterredirectopts: 46934739Speter | IL_ICMP_REDIRECT_NET token { set_redir(0, &$2); } 47034739Speter | IL_ICMP_REDIRECT_HOST token { set_redir(1, &$2); } 47134739Speter | IL_ICMP_REDIRECT_TOSNET token { set_redir(2, &$2); } 47234739Speter | IL_ICMP_REDIRECT_TOSHOST token { set_redir(3, &$2); } 47331183Speter ; 47431183Speter 47531183Speterexceed: 47631183Speter IL_ICMP_TIMXCEED_INTRANS line 47731183Speter | IL_ICMP_TIMXCEED_REASS line 47831183Speter ; 47931183Speter 48031183Speterparamprob: 48131183Speter IL_ICMP_PARAMPROB_OPTABSENT 48231183Speter | IL_ICMP_PARAMPROB_OPTABSENT paraprobarg 48331183Speter 48431183Speterparaprobarg: 48534739Speter '{' number '}' ';' { set_icmppprob($2); } 48631183Speter ; 48731183Speter 48831183Speteripv4opt: IL_V4OPT { new_ipv4opt(); } 48931183Speter ; 49031183Speter 49131183Speteripv4optlist: 49231183Speter | ipv4opts ipv4optlist 49331183Speter ; 49431183Speter 49531183Speteripv4opts: 49631183Speter IL_IPO_NOP ';' { add_ipopt(IL_IPO_NOP, NULL); } 49734739Speter | IL_IPO_RR optnumber { add_ipopt(IL_IPO_RR, &$2); } 49831183Speter | IL_IPO_ZSU ';' { add_ipopt(IL_IPO_ZSU, NULL); } 49931183Speter | IL_IPO_MTUP ';' { add_ipopt(IL_IPO_MTUP, NULL); } 50031183Speter | IL_IPO_MTUR ';' { add_ipopt(IL_IPO_MTUR, NULL); } 50131183Speter | IL_IPO_ENCODE ';' { add_ipopt(IL_IPO_ENCODE, NULL); } 50231183Speter | IL_IPO_TS ';' { add_ipopt(IL_IPO_TS, NULL); } 50331183Speter | IL_IPO_TR ';' { add_ipopt(IL_IPO_TR, NULL); } 50431183Speter | IL_IPO_SEC ';' { add_ipopt(IL_IPO_SEC, NULL); } 50531183Speter | IL_IPO_SECCLASS secclass { add_ipopt(IL_IPO_SECCLASS, sclass); } 50634739Speter | IL_IPO_LSRR token { add_ipopt(IL_IPO_LSRR,&$2); } 50731183Speter | IL_IPO_ESEC ';' { add_ipopt(IL_IPO_ESEC, NULL); } 50831183Speter | IL_IPO_CIPSO ';' { add_ipopt(IL_IPO_CIPSO, NULL); } 50934739Speter | IL_IPO_SATID optnumber { add_ipopt(IL_IPO_SATID,&$2);} 51034739Speter | IL_IPO_SSRR token { add_ipopt(IL_IPO_SSRR,&$2); } 51131183Speter | IL_IPO_ADDEXT ';' { add_ipopt(IL_IPO_ADDEXT, NULL); } 51231183Speter | IL_IPO_VISA ';' { add_ipopt(IL_IPO_VISA, NULL); } 51331183Speter | IL_IPO_IMITD ';' { add_ipopt(IL_IPO_IMITD, NULL); } 51431183Speter | IL_IPO_EIP ';' { add_ipopt(IL_IPO_EIP, NULL); } 51531183Speter | IL_IPO_FINN ';' { add_ipopt(IL_IPO_FINN, NULL); } 51631183Speter ; 51731183Speter 51831183Spetersecclass: 51934739Speter IL_IPS_RESERV4 ';' { set_secclass(&$1); } 52034739Speter | IL_IPS_TOPSECRET ';' { set_secclass(&$1); } 52134739Speter | IL_IPS_SECRET ';' { set_secclass(&$1); } 52234739Speter | IL_IPS_RESERV3 ';' { set_secclass(&$1); } 52334739Speter | IL_IPS_CONFID ';' { set_secclass(&$1); } 52434739Speter | IL_IPS_UNCLASS ';' { set_secclass(&$1); } 52534739Speter | IL_IPS_RESERV2 ';' { set_secclass(&$1); } 52634739Speter | IL_IPS_RESERV1 ';' { set_secclass(&$1); } 52731183Speter ; 52831183Speter 52931183Speterdata: IL_DATA { new_data(); } 53031183Speter ; 53131183Speter 53231183Speterdataline: 53331183Speter '{' databody '}' ';' { end_data(); } 53431183Speter ; 53531183Speter 53631183Speterdatabody: dataopts 53731183Speter | dataopts databody 53831183Speter ; 53931183Speter 54031183Speterdataopts: 54134739Speter IL_DLEN token { set_datalen(&$2); } 54234739Speter | IL_DVALUE token { set_data(&$2); } 54334739Speter | IL_DFILE token { set_datafile(&$2); } 54431183Speter ; 54531183Speter 54631183Spetertoken: IL_TOKEN ';' 54731183Speter ; 54831183Speter 54931183Speteroptoken: ';' { $$ = ""; } 55031183Speter | token 55131183Speter ; 55231183Speter 55331183Speternumber: digits ';' 55431183Speter ; 55531183Speter 55631183Speteroptnumber: ';' { $$ = 0; } 55731183Speter | number 55831183Speter ; 55931183Speter 56031183Speterdigits: IL_NUMBER 56131183Speter | digits IL_NUMBER 56231183Speter ; 56331183Speter%% 56431183Speter 56531183Speterstruct statetoopt toipopts[] = { 56631183Speter { IL_IPO_NOP, IPOPT_NOP }, 56731183Speter { IL_IPO_RR, IPOPT_RR }, 56831183Speter { IL_IPO_ZSU, IPOPT_ZSU }, 56931183Speter { IL_IPO_MTUP, IPOPT_MTUP }, 57031183Speter { IL_IPO_MTUR, IPOPT_MTUR }, 57131183Speter { IL_IPO_ENCODE, IPOPT_ENCODE }, 57231183Speter { IL_IPO_TS, IPOPT_TS }, 57331183Speter { IL_IPO_TR, IPOPT_TR }, 57431183Speter { IL_IPO_SEC, IPOPT_SECURITY }, 57531183Speter { IL_IPO_SECCLASS, IPOPT_SECURITY }, 57631183Speter { IL_IPO_LSRR, IPOPT_LSRR }, 57731183Speter { IL_IPO_ESEC, IPOPT_E_SEC }, 57831183Speter { IL_IPO_CIPSO, IPOPT_CIPSO }, 57931183Speter { IL_IPO_SATID, IPOPT_SATID }, 58031183Speter { IL_IPO_SSRR, IPOPT_SSRR }, 58131183Speter { IL_IPO_ADDEXT, IPOPT_ADDEXT }, 58231183Speter { IL_IPO_VISA, IPOPT_VISA }, 58331183Speter { IL_IPO_IMITD, IPOPT_IMITD }, 58431183Speter { IL_IPO_EIP, IPOPT_EIP }, 58531183Speter { IL_IPO_FINN, IPOPT_FINN }, 58631183Speter { 0, 0 } 58731183Speter}; 58831183Speter 58931183Speterstruct statetoopt tosecopts[] = { 59031183Speter { IL_IPS_RESERV4, IPSO_CLASS_RES4 }, 59131183Speter { IL_IPS_TOPSECRET, IPSO_CLASS_TOPS }, 59231183Speter { IL_IPS_SECRET, IPSO_CLASS_SECR }, 59331183Speter { IL_IPS_RESERV3, IPSO_CLASS_RES3 }, 59431183Speter { IL_IPS_CONFID, IPSO_CLASS_CONF }, 59531183Speter { IL_IPS_UNCLASS, IPSO_CLASS_UNCL }, 59631183Speter { IL_IPS_RESERV2, IPSO_CLASS_RES2 }, 59731183Speter { IL_IPS_RESERV1, IPSO_CLASS_RES1 }, 59831183Speter { 0, 0 } 59931183Speter}; 60031183Speter 60131183Speter#ifdef bsdi 60231183Speterstruct ether_addr * 60331183Speterether_aton(s) 604255332Scy char *s; 60531183Speter{ 60631183Speter static struct ether_addr n; 60731183Speter u_int i[6]; 60831183Speter 60931183Speter if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1], 61031183Speter &i[2], &i[3], &i[4], &i[5]) == 6) { 61131183Speter n.ether_addr_octet[0] = (u_char)i[0]; 61231183Speter n.ether_addr_octet[1] = (u_char)i[1]; 61331183Speter n.ether_addr_octet[2] = (u_char)i[2]; 61431183Speter n.ether_addr_octet[3] = (u_char)i[3]; 61531183Speter n.ether_addr_octet[4] = (u_char)i[4]; 61631183Speter n.ether_addr_octet[5] = (u_char)i[5]; 61731183Speter return &n; 61831183Speter } 61931183Speter return NULL; 62031183Speter} 62131183Speter#endif 62231183Speter 62331183Speter 62431183Speterstruct in_addr getipv4addr(arg) 62531183Speterchar *arg; 62631183Speter{ 62731183Speter struct hostent *hp; 62831183Speter struct in_addr in; 62931183Speter 63031183Speter in.s_addr = 0xffffffff; 63131183Speter 63231183Speter if ((hp = gethostbyname(arg))) 63331183Speter bcopy(hp->h_addr, &in.s_addr, sizeof(struct in_addr)); 63431183Speter else 63531183Speter in.s_addr = inet_addr(arg); 63631183Speter return in; 63731183Speter} 63831183Speter 63931183Speter 64031183Speteru_short getportnum(pr, name) 64131183Speterchar *pr, *name; 64231183Speter{ 64331183Speter struct servent *sp; 64431183Speter 64531183Speter if (!(sp = getservbyname(name, pr))) 64634739Speter return htons(atoi(name)); 64731183Speter return sp->s_port; 64831183Speter} 64931183Speter 65031183Speter 65131183Speterstruct ether_addr *geteaddr(arg, buf) 65231183Speterchar *arg; 65331183Speterstruct ether_addr *buf; 65431183Speter{ 65531183Speter struct ether_addr *e; 65631183Speter 65731183Speter#if !defined(hpux) && !defined(linux) 65831183Speter e = ether_aton(arg); 65931183Speter if (!e) 66031183Speter fprintf(stderr, "Invalid ethernet address: %s\n", arg); 66131183Speter else 66231183Speter# ifdef __FreeBSD__ 66331183Speter bcopy(e->octet, buf->octet, sizeof(e->octet)); 66431183Speter# else 66531183Speter bcopy(e->ether_addr_octet, buf->ether_addr_octet, 66631183Speter sizeof(e->ether_addr_octet)); 66731183Speter# endif 66831183Speter return e; 66931183Speter#else 67031183Speter return NULL; 67131183Speter#endif 67231183Speter} 67331183Speter 67431183Speter 67531183Spetervoid *new_header(type) 67631183Speterint type; 67731183Speter{ 67831183Speter aniphdr_t *aip, *oip = canip; 67931183Speter int sz = 0; 68031183Speter 68131183Speter aip = (aniphdr_t *)calloc(1, sizeof(*aip)); 68231183Speter *aniptail = aip; 68331183Speter aniptail = &aip->ah_next; 68431183Speter aip->ah_p = type; 68531183Speter aip->ah_prev = oip; 68631183Speter canip = aip; 68731183Speter 68831183Speter if (type == IPPROTO_UDP) 68931183Speter sz = sizeof(udphdr_t); 69031183Speter else if (type == IPPROTO_TCP) 69131183Speter sz = sizeof(tcphdr_t); 69231183Speter else if (type == IPPROTO_ICMP) 69331183Speter sz = sizeof(icmphdr_t); 69431183Speter else if (type == IPPROTO_IP) 69531183Speter sz = sizeof(ip_t); 69631183Speter 69731183Speter if (oip) 69831183Speter canip->ah_data = oip->ah_data + oip->ah_len; 69931183Speter else 70031183Speter canip->ah_data = (char *)ipbuffer; 70131183Speter 70231183Speter /* 70331183Speter * Increase the size fields in all wrapping headers. 70431183Speter */ 70531183Speter for (aip = aniphead; aip; aip = aip->ah_next) { 70631183Speter aip->ah_len += sz; 70731183Speter if (aip->ah_p == IPPROTO_IP) 70831183Speter aip->ah_ip->ip_len += sz; 70931183Speter else if (aip->ah_p == IPPROTO_UDP) 71031183Speter aip->ah_udp->uh_ulen += sz; 71131183Speter } 71231183Speter return (void *)canip->ah_data; 71331183Speter} 71431183Speter 71531183Speter 71631183Spetervoid free_aniplist() 71731183Speter{ 71831183Speter aniphdr_t *aip, **aipp = &aniphead; 71931183Speter 72031183Speter while ((aip = *aipp)) { 72131183Speter *aipp = aip->ah_next; 72231183Speter free(aip); 72331183Speter } 72431183Speter aniptail = &aniphead; 72531183Speter} 72631183Speter 72731183Speter 72831183Spetervoid inc_anipheaders(inc) 72931183Speterint inc; 73031183Speter{ 73131183Speter aniphdr_t *aip; 73231183Speter 73331183Speter for (aip = aniphead; aip; aip = aip->ah_next) { 73431183Speter aip->ah_len += inc; 73531183Speter if (aip->ah_p == IPPROTO_IP) 73631183Speter aip->ah_ip->ip_len += inc; 73731183Speter else if (aip->ah_p == IPPROTO_UDP) 73831183Speter aip->ah_udp->uh_ulen += inc; 73931183Speter } 74031183Speter} 74131183Speter 74231183Speter 74331183Spetervoid new_data() 74431183Speter{ 74531183Speter (void) new_header(-1); 74631183Speter canip->ah_len = 0; 74731183Speter} 74831183Speter 74931183Speter 75031183Spetervoid set_datalen(arg) 75131183Speterchar **arg; 75231183Speter{ 75331183Speter int len; 75431183Speter 75531183Speter len = strtol(*arg, NULL, 0); 75631183Speter inc_anipheaders(len); 75731183Speter free(*arg); 75831183Speter *arg = NULL; 75931183Speter} 76031183Speter 76131183Speter 76231183Spetervoid set_data(arg) 76331183Speterchar **arg; 76431183Speter{ 76531183Speter u_char *s = (u_char *)*arg, *t = (u_char *)canip->ah_data, c; 76631183Speter int len = 0, todo = 0, quote = 0, val = 0; 76731183Speter 76831183Speter while ((c = *s++)) { 76931183Speter if (todo) { 770145519Sdarrenr if (ISDIGIT(c)) { 77131183Speter todo--; 77231183Speter if (c > '7') { 77331183Speter fprintf(stderr, "octal with %c!\n", c); 77431183Speter break; 77531183Speter } 77631183Speter val <<= 3; 77731183Speter val |= (c - '0'); 77831183Speter } 779145519Sdarrenr if (!ISDIGIT(c) || !todo) { 78031183Speter *t++ = (u_char)(val & 0xff); 78131183Speter todo = 0; 78231183Speter } 78337074Speter if (todo) 78437074Speter continue; 78531183Speter } 78631183Speter if (quote) { 787145519Sdarrenr if (ISDIGIT(c)) { 78831183Speter todo = 2; 78931183Speter if (c > '7') { 79031183Speter fprintf(stderr, "octal with %c!\n", c); 79131183Speter break; 79231183Speter } 79331183Speter val = (c - '0'); 79431183Speter } else { 79531183Speter switch (c) 79631183Speter { 79731183Speter case '\"' : 79831183Speter *t++ = '\"'; 79931183Speter break; 80031183Speter case '\\' : 80131183Speter *t++ = '\\'; 80231183Speter break; 80331183Speter case 'n' : 80431183Speter *t++ = '\n'; 80531183Speter break; 80631183Speter case 'r' : 80731183Speter *t++ = '\r'; 80831183Speter break; 80931183Speter case 't' : 81031183Speter *t++ = '\t'; 81131183Speter break; 81231183Speter } 81331183Speter } 81437074Speter quote = 0; 81531183Speter continue; 81631183Speter } 81731183Speter 81831183Speter if (c == '\\') 81931183Speter quote = 1; 82031183Speter else 82131183Speter *t++ = c; 82231183Speter } 82337074Speter if (todo) 82437074Speter *t++ = (u_char)(val & 0xff); 82531183Speter if (quote) 82631183Speter *t++ = '\\'; 82731183Speter len = t - (u_char *)canip->ah_data; 82831183Speter inc_anipheaders(len - canip->ah_len); 82931183Speter canip->ah_len = len; 83031183Speter} 83131183Speter 83231183Speter 83331183Spetervoid set_datafile(arg) 83431183Speterchar **arg; 83531183Speter{ 83631183Speter struct stat sb; 83731183Speter char *file = *arg; 83831183Speter int fd, len; 83931183Speter 84031183Speter if ((fd = open(file, O_RDONLY)) == -1) { 84131183Speter perror("open"); 84231183Speter exit(-1); 84331183Speter } 84431183Speter 84531183Speter if (fstat(fd, &sb) == -1) { 84631183Speter perror("fstat"); 84731183Speter exit(-1); 84831183Speter } 84931183Speter 85031183Speter if ((sb.st_size + aniphead->ah_len ) > 65535) { 85131183Speter fprintf(stderr, "data file %s too big to include.\n", file); 85231183Speter close(fd); 85331183Speter return; 85431183Speter } 85531183Speter if ((len = read(fd, canip->ah_data, sb.st_size)) == -1) { 85631183Speter perror("read"); 85731183Speter close(fd); 85831183Speter return; 85931183Speter } 86031183Speter inc_anipheaders(len); 86131183Speter canip->ah_len += len; 86231183Speter close(fd); 86331183Speter} 86431183Speter 86531183Speter 86631183Spetervoid new_packet() 86731183Speter{ 86831183Speter static u_short id = 0; 86931183Speter 87031183Speter if (!aniphead) 87131183Speter bzero((char *)ipbuffer, sizeof(ipbuffer)); 87231183Speter 87331183Speter ip = (ip_t *)new_header(IPPROTO_IP); 87431183Speter ip->ip_v = IPVERSION; 87531183Speter ip->ip_hl = sizeof(ip_t) >> 2; 87631183Speter ip->ip_len = sizeof(ip_t); 87731183Speter ip->ip_ttl = 63; 87831183Speter ip->ip_id = htons(id++); 87931183Speter} 88031183Speter 88131183Speter 88231183Spetervoid set_ipv4proto(arg) 88331183Speterchar **arg; 88431183Speter{ 88531183Speter struct protoent *pr; 88631183Speter 88731183Speter if ((pr = getprotobyname(*arg))) 88831183Speter ip->ip_p = pr->p_proto; 88931183Speter else 89031183Speter if (!(ip->ip_p = atoi(*arg))) 89131183Speter fprintf(stderr, "unknown protocol %s\n", *arg); 89231183Speter free(*arg); 89331183Speter *arg = NULL; 89431183Speter} 89531183Speter 89631183Speter 89731183Spetervoid set_ipv4src(arg) 89831183Speterchar **arg; 89931183Speter{ 90031183Speter ip->ip_src = getipv4addr(*arg); 90131183Speter free(*arg); 90231183Speter *arg = NULL; 90331183Speter} 90431183Speter 90531183Speter 90631183Spetervoid set_ipv4dst(arg) 90731183Speterchar **arg; 90831183Speter{ 90931183Speter ip->ip_dst = getipv4addr(*arg); 91031183Speter free(*arg); 91131183Speter *arg = NULL; 91231183Speter} 91331183Speter 91431183Speter 91531183Spetervoid set_ipv4off(arg) 91631183Speterchar **arg; 91731183Speter{ 91837074Speter ip->ip_off = htons(strtol(*arg, NULL, 0)); 91931183Speter free(*arg); 92031183Speter *arg = NULL; 92131183Speter} 92231183Speter 92331183Speter 92431183Spetervoid set_ipv4v(arg) 92531183Speterchar **arg; 92631183Speter{ 92731183Speter ip->ip_v = strtol(*arg, NULL, 0); 92831183Speter free(*arg); 92931183Speter *arg = NULL; 93031183Speter} 93131183Speter 93231183Speter 93331183Spetervoid set_ipv4hl(arg) 93431183Speterchar **arg; 93531183Speter{ 93631183Speter int newhl, inc; 93731183Speter 93831183Speter newhl = strtol(*arg, NULL, 0); 93931183Speter inc = (newhl - ip->ip_hl) << 2; 94031183Speter ip->ip_len += inc; 94131183Speter ip->ip_hl = newhl; 94231183Speter canip->ah_len += inc; 94331183Speter free(*arg); 94431183Speter *arg = NULL; 94531183Speter} 94631183Speter 94731183Speter 94831183Spetervoid set_ipv4ttl(arg) 94931183Speterchar **arg; 95031183Speter{ 95131183Speter ip->ip_ttl = strtol(*arg, NULL, 0); 95231183Speter free(*arg); 95331183Speter *arg = NULL; 95431183Speter} 95531183Speter 95631183Speter 95731183Spetervoid set_ipv4tos(arg) 95831183Speterchar **arg; 95931183Speter{ 96031183Speter ip->ip_tos = strtol(*arg, NULL, 0); 96131183Speter free(*arg); 96231183Speter *arg = NULL; 96331183Speter} 96431183Speter 96531183Speter 96631183Spetervoid set_ipv4id(arg) 96731183Speterchar **arg; 96831183Speter{ 96937074Speter ip->ip_id = htons(strtol(*arg, NULL, 0)); 97031183Speter free(*arg); 97131183Speter *arg = NULL; 97231183Speter} 97331183Speter 97431183Speter 97531183Spetervoid set_ipv4sum(arg) 97631183Speterchar **arg; 97731183Speter{ 97831183Speter ip->ip_sum = strtol(*arg, NULL, 0); 97931183Speter free(*arg); 98031183Speter *arg = NULL; 98131183Speter} 98231183Speter 98331183Speter 98431183Spetervoid set_ipv4len(arg) 98531183Speterchar **arg; 98631183Speter{ 98731183Speter int len; 98831183Speter 98931183Speter len = strtol(*arg, NULL, 0); 99031183Speter inc_anipheaders(len - ip->ip_len); 99131183Speter ip->ip_len = len; 99231183Speter free(*arg); 99331183Speter *arg = NULL; 99431183Speter} 99531183Speter 99631183Speter 99731183Spetervoid new_tcpheader() 99831183Speter{ 99931183Speter 100031183Speter if ((ip->ip_p) && (ip->ip_p != IPPROTO_TCP)) { 100131183Speter fprintf(stderr, "protocol %d specified with TCP!\n", ip->ip_p); 100231183Speter return; 100331183Speter } 100431183Speter ip->ip_p = IPPROTO_TCP; 100531183Speter 100631183Speter tcp = (tcphdr_t *)new_header(IPPROTO_TCP); 100737074Speter tcp->th_win = htons(4096); 100831183Speter tcp->th_off = sizeof(*tcp) >> 2; 100931183Speter} 101031183Speter 101131183Speter 101231183Spetervoid set_tcpsport(arg) 101331183Speterchar **arg; 101431183Speter{ 101531183Speter u_short *port; 101631183Speter char *pr; 101731183Speter 101831183Speter if (ip->ip_p == IPPROTO_UDP) { 101931183Speter port = &udp->uh_sport; 102031183Speter pr = "udp"; 102131183Speter } else { 102231183Speter port = &tcp->th_sport; 102331183Speter pr = "udp"; 102431183Speter } 102531183Speter 102631183Speter *port = getportnum(pr, *arg); 102731183Speter free(*arg); 102831183Speter *arg = NULL; 102931183Speter} 103031183Speter 103131183Speter 103231183Spetervoid set_tcpdport(arg) 103331183Speterchar **arg; 103431183Speter{ 103531183Speter u_short *port; 103631183Speter char *pr; 103731183Speter 103831183Speter if (ip->ip_p == IPPROTO_UDP) { 103931183Speter port = &udp->uh_dport; 104031183Speter pr = "udp"; 104131183Speter } else { 104231183Speter port = &tcp->th_dport; 104331183Speter pr = "udp"; 104431183Speter } 104531183Speter 104631183Speter *port = getportnum(pr, *arg); 104731183Speter free(*arg); 104831183Speter *arg = NULL; 104931183Speter} 105031183Speter 105131183Speter 105231183Spetervoid set_tcpseq(arg) 105331183Speterchar **arg; 105431183Speter{ 105537074Speter tcp->th_seq = htonl(strtol(*arg, NULL, 0)); 105631183Speter free(*arg); 105731183Speter *arg = NULL; 105831183Speter} 105931183Speter 106031183Speter 106131183Spetervoid set_tcpack(arg) 106231183Speterchar **arg; 106331183Speter{ 106437074Speter tcp->th_ack = htonl(strtol(*arg, NULL, 0)); 106531183Speter free(*arg); 106631183Speter *arg = NULL; 106731183Speter} 106831183Speter 106931183Speter 107031183Spetervoid set_tcpoff(arg) 107131183Speterchar **arg; 107231183Speter{ 107331183Speter int off; 107431183Speter 107531183Speter off = strtol(*arg, NULL, 0); 107631183Speter inc_anipheaders((off - tcp->th_off) << 2); 107731183Speter tcp->th_off = off; 107831183Speter free(*arg); 107931183Speter *arg = NULL; 108031183Speter} 108131183Speter 108231183Speter 108331183Spetervoid set_tcpurp(arg) 108431183Speterchar **arg; 108531183Speter{ 108637074Speter tcp->th_urp = htons(strtol(*arg, NULL, 0)); 108731183Speter free(*arg); 108831183Speter *arg = NULL; 108931183Speter} 109031183Speter 109131183Speter 109231183Spetervoid set_tcpwin(arg) 109331183Speterchar **arg; 109431183Speter{ 109537074Speter tcp->th_win = htons(strtol(*arg, NULL, 0)); 109631183Speter free(*arg); 109731183Speter *arg = NULL; 109831183Speter} 109931183Speter 110031183Speter 110131183Spetervoid set_tcpsum(arg) 110231183Speterchar **arg; 110331183Speter{ 110431183Speter tcp->th_sum = strtol(*arg, NULL, 0); 110531183Speter free(*arg); 110631183Speter *arg = NULL; 110731183Speter} 110831183Speter 110931183Speter 111031183Spetervoid set_tcpflags(arg) 111131183Speterchar **arg; 111231183Speter{ 111331183Speter static char flags[] = "ASURPF"; 111431183Speter static int flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH, 111531183Speter TH_FIN } ; 111631183Speter char *s, *t; 111731183Speter 111831183Speter for (s = *arg; *s; s++) 111931183Speter if (!(t = strchr(flags, *s))) { 112031183Speter if (s - *arg) { 112131183Speter fprintf(stderr, "unknown TCP flag %c\n", *s); 112231183Speter break; 112331183Speter } 112431183Speter tcp->th_flags = strtol(*arg, NULL, 0); 112531183Speter break; 112631183Speter } else 112731183Speter tcp->th_flags |= flagv[t - flags]; 112831183Speter free(*arg); 112931183Speter *arg = NULL; 113031183Speter} 113131183Speter 113231183Speter 113331183Spetervoid set_tcpopt(state, arg) 113431183Speterint state; 113531183Speterchar **arg; 113631183Speter{ 113731183Speter u_char *s; 113831183Speter int val, len, val2, pad, optval; 113931183Speter 114031183Speter if (arg && *arg) 114131183Speter val = atoi(*arg); 114231183Speter else 114331183Speter val = 0; 114431183Speter 114531183Speter s = (u_char *)tcp + sizeof(*tcp) + canip->ah_optlen; 114631183Speter switch (state) 114731183Speter { 114831183Speter case IL_TCPO_EOL : 114931183Speter optval = 0; 115031183Speter len = 1; 115131183Speter break; 115231183Speter case IL_TCPO_NOP : 115331183Speter optval = 1; 115431183Speter len = 1; 115531183Speter break; 115631183Speter case IL_TCPO_MSS : 115731183Speter optval = 2; 115831183Speter len = 4; 115931183Speter break; 116031183Speter case IL_TCPO_WSCALE : 116131183Speter optval = 3; 116231183Speter len = 3; 116331183Speter break; 116431183Speter case IL_TCPO_TS : 116531183Speter optval = 8; 116631183Speter len = 10; 116731183Speter break; 116831183Speter default : 116931183Speter optval = 0; 117031183Speter len = 0; 117131183Speter break; 117231183Speter } 117331183Speter 117431183Speter if (len > 1) { 117531183Speter /* 117631183Speter * prepend padding - if required. 117731183Speter */ 117831183Speter if (len & 3) 117931183Speter for (pad = 4 - (len & 3); pad; pad--) { 118031183Speter *s++ = 1; 118131183Speter canip->ah_optlen++; 118231183Speter } 118331183Speter /* 118431183Speter * build tcp option 118531183Speter */ 118631183Speter *s++ = (u_char)optval; 118731183Speter *s++ = (u_char)len; 118831183Speter if (len > 2) { 118931183Speter if (len == 3) { /* 1 byte - char */ 119031183Speter *s++ = (u_char)val; 119131183Speter } else if (len == 4) { /* 2 bytes - short */ 119231183Speter *s++ = (u_char)((val >> 8) & 0xff); 119331183Speter *s++ = (u_char)(val & 0xff); 119431183Speter } else if (len >= 6) { /* 4 bytes - long */ 119531183Speter val2 = htonl(val); 119631183Speter bcopy((char *)&val2, s, 4); 119731183Speter } 119831183Speter s += (len - 2); 119931183Speter } 120031183Speter } else 120131183Speter *s++ = (u_char)optval; 120231183Speter 120331183Speter canip->ah_lastopt = optval; 120431183Speter canip->ah_optlen += len; 120531183Speter 120631183Speter if (arg && *arg) { 120731183Speter free(*arg); 120831183Speter *arg = NULL; 120931183Speter } 121031183Speter} 121131183Speter 121231183Speter 121331183Spetervoid end_tcpopt() 121431183Speter{ 121531183Speter int pad; 121631183Speter char *s = (char *)tcp; 121731183Speter 121831183Speter s += sizeof(*tcp) + canip->ah_optlen; 121931183Speter /* 122031183Speter * pad out so that we have a multiple of 4 bytes in size fo the 122131183Speter * options. make sure last byte is EOL. 122231183Speter */ 122331183Speter if (canip->ah_optlen & 3) { 122431183Speter if (canip->ah_lastopt != 1) { 122531183Speter for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { 122631183Speter *s++ = 1; 122731183Speter canip->ah_optlen++; 122831183Speter } 122931183Speter canip->ah_optlen++; 123031183Speter } else { 123131183Speter s -= 1; 123231183Speter 123331183Speter for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { 123431183Speter *s++ = 1; 123531183Speter canip->ah_optlen++; 123631183Speter } 123731183Speter } 123831183Speter *s++ = 0; 123931183Speter } 124031183Speter tcp->th_off = (sizeof(*tcp) + canip->ah_optlen) >> 2; 124131183Speter inc_anipheaders(canip->ah_optlen); 124231183Speter} 124331183Speter 124431183Speter 124531183Spetervoid new_udpheader() 124631183Speter{ 124731183Speter if ((ip->ip_p) && (ip->ip_p != IPPROTO_UDP)) { 124831183Speter fprintf(stderr, "protocol %d specified with UDP!\n", ip->ip_p); 124931183Speter return; 125031183Speter } 125131183Speter ip->ip_p = IPPROTO_UDP; 125231183Speter 125331183Speter udp = (udphdr_t *)new_header(IPPROTO_UDP); 125431183Speter udp->uh_ulen = sizeof(*udp); 125531183Speter} 125631183Speter 125731183Speter 125831183Spetervoid set_udplen(arg) 125931183Speterchar **arg; 126031183Speter{ 126131183Speter int len; 126231183Speter 126331183Speter len = strtol(*arg, NULL, 0); 126431183Speter inc_anipheaders(len - udp->uh_ulen); 126531183Speter udp->uh_ulen = len; 126631183Speter free(*arg); 126731183Speter *arg = NULL; 126831183Speter} 126931183Speter 127031183Speter 127131183Spetervoid set_udpsum(arg) 127231183Speterchar **arg; 127331183Speter{ 127431183Speter udp->uh_sum = strtol(*arg, NULL, 0); 127531183Speter free(*arg); 127631183Speter *arg = NULL; 127731183Speter} 127831183Speter 127931183Speter 128031183Spetervoid prep_packet() 128131183Speter{ 128231183Speter iface_t *ifp; 128331183Speter struct in_addr gwip; 128431183Speter 128531183Speter ifp = sending.snd_if; 128631183Speter if (!ifp) { 128731183Speter fprintf(stderr, "no interface defined for sending!\n"); 128831183Speter return; 128931183Speter } 129031183Speter if (ifp->if_fd == -1) 1291145519Sdarrenr ifp->if_fd = initdevice(ifp->if_name, 5); 129231183Speter gwip = sending.snd_gw; 1293153881Sguido if (!gwip.s_addr) { 1294153881Sguido if (aniphead == NULL) { 1295153881Sguido fprintf(stderr, 1296153881Sguido "no destination address defined for sending\n"); 1297153881Sguido return; 1298153881Sguido } 129931183Speter gwip = aniphead->ah_ip->ip_dst; 1300153881Sguido } 130131183Speter (void) send_ip(ifp->if_fd, ifp->if_MTU, (ip_t *)ipbuffer, gwip, 2); 130231183Speter} 130331183Speter 130431183Speter 130531183Spetervoid packet_done() 130631183Speter{ 130731183Speter char outline[80]; 130831183Speter int i, j, k; 130931183Speter u_char *s = (u_char *)ipbuffer, *t = (u_char *)outline; 131031183Speter 131131183Speter if (opts & OPT_VERBOSE) { 131237074Speter ip->ip_len = htons(ip->ip_len); 131337074Speter for (i = ntohs(ip->ip_len), j = 0; i; i--, j++, s++) { 131431183Speter if (j && !(j & 0xf)) { 131531183Speter *t++ = '\n'; 131631183Speter *t = '\0'; 131731183Speter fputs(outline, stdout); 131831183Speter fflush(stdout); 131931183Speter t = (u_char *)outline; 132031183Speter *t = '\0'; 132131183Speter } 132231183Speter sprintf((char *)t, "%02x", *s & 0xff); 132331183Speter t += 2; 132431183Speter if (!((j + 1) & 0xf)) { 132531183Speter s -= 15; 132631183Speter sprintf((char *)t, " "); 132731183Speter t += 8; 132831183Speter for (k = 16; k; k--, s++) 1329255332Scy *t++ = (isprint(*s) ? *s : '.'); 133031183Speter s--; 133131183Speter } 133231183Speter 133331183Speter if ((j + 1) & 0xf) 133431183Speter *t++ = ' ';; 133531183Speter } 133631183Speter 133731183Speter if (j & 0xf) { 133831183Speter for (k = 16 - (j & 0xf); k; k--) { 133931183Speter *t++ = ' '; 134031183Speter *t++ = ' '; 134131183Speter *t++ = ' '; 134231183Speter } 134331183Speter sprintf((char *)t, " "); 134431183Speter t += 7; 134531183Speter s -= j & 0xf; 134631183Speter for (k = j & 0xf; k; k--, s++) 1347255332Scy *t++ = (isprint(*s) ? *s : '.'); 134831183Speter *t++ = '\n'; 134931183Speter *t = '\0'; 135031183Speter } 135131183Speter fputs(outline, stdout); 135231183Speter fflush(stdout); 135337074Speter ip->ip_len = ntohs(ip->ip_len); 135431183Speter } 135531183Speter 135631183Speter prep_packet(); 135731183Speter free_aniplist(); 135831183Speter} 135931183Speter 136031183Speter 136131183Spetervoid new_interface() 136231183Speter{ 136331183Speter cifp = (iface_t *)calloc(1, sizeof(iface_t)); 136431183Speter *iftail = cifp; 136531183Speter iftail = &cifp->if_next; 136631183Speter cifp->if_fd = -1; 136731183Speter} 136831183Speter 136931183Speter 137031183Spetervoid check_interface() 137131183Speter{ 137231183Speter if (!cifp->if_name || !*cifp->if_name) 137331183Speter fprintf(stderr, "No interface name given!\n"); 137431183Speter if (!cifp->if_MTU || !*cifp->if_name) 137531183Speter fprintf(stderr, "Interface %s has an MTU of 0!\n", 137631183Speter cifp->if_name); 137731183Speter} 137831183Speter 137931183Speter 138031183Spetervoid set_ifname(arg) 138131183Speterchar **arg; 138231183Speter{ 138331183Speter cifp->if_name = *arg; 138431183Speter *arg = NULL; 138531183Speter} 138631183Speter 138731183Speter 138831183Spetervoid set_ifmtu(arg) 138931183Speterint arg; 139031183Speter{ 139131183Speter cifp->if_MTU = arg; 139231183Speter} 139331183Speter 139431183Speter 139531183Spetervoid set_ifv4addr(arg) 139631183Speterchar **arg; 139731183Speter{ 139831183Speter cifp->if_addr = getipv4addr(*arg); 139931183Speter free(*arg); 140031183Speter *arg = NULL; 140131183Speter} 140231183Speter 140331183Speter 140431183Spetervoid set_ifeaddr(arg) 140531183Speterchar **arg; 140631183Speter{ 140731183Speter (void) geteaddr(*arg, &cifp->if_eaddr); 140831183Speter free(*arg); 140931183Speter *arg = NULL; 141031183Speter} 141131183Speter 141231183Speter 141331183Spetervoid new_arp() 141431183Speter{ 141531183Speter carp = (arp_t *)calloc(1, sizeof(arp_t)); 141631183Speter *arptail = carp; 141731183Speter arptail = &carp->arp_next; 141831183Speter} 141931183Speter 142031183Speter 142131183Spetervoid set_arpeaddr(arg) 142231183Speterchar **arg; 142331183Speter{ 142431183Speter (void) geteaddr(*arg, &carp->arp_eaddr); 142531183Speter free(*arg); 142631183Speter *arg = NULL; 142731183Speter} 142831183Speter 142931183Speter 143031183Spetervoid set_arpv4addr(arg) 143131183Speterchar **arg; 143231183Speter{ 143331183Speter carp->arp_addr = getipv4addr(*arg); 143431183Speter free(*arg); 143531183Speter *arg = NULL; 143631183Speter} 143731183Speter 143831183Speter 143953024Sguidoint arp_getipv4(ip, addr) 144053024Sguidochar *ip; 144153024Sguidochar *addr; 144253024Sguido{ 144353024Sguido arp_t *a; 144453024Sguido 144553024Sguido for (a = arplist; a; a = a->arp_next) 144653024Sguido if (!bcmp(ip, (char *)&a->arp_addr, 4)) { 144753024Sguido bcopy((char *)&a->arp_eaddr, addr, 6); 144853024Sguido return 0; 144953024Sguido } 145053024Sguido return -1; 145153024Sguido} 145253024Sguido 145353024Sguido 145431183Spetervoid reset_send() 145531183Speter{ 145631183Speter sending.snd_if = iflist; 145731183Speter sending.snd_gw = defrouter; 145831183Speter} 145931183Speter 146031183Speter 146131183Spetervoid set_sendif(arg) 146231183Speterchar **arg; 146331183Speter{ 146431183Speter iface_t *ifp; 146531183Speter 146631183Speter for (ifp = iflist; ifp; ifp = ifp->if_next) 146731183Speter if (ifp->if_name && !strcmp(ifp->if_name, *arg)) 146831183Speter break; 146931183Speter sending.snd_if = ifp; 147031183Speter if (!ifp) 147131183Speter fprintf(stderr, "couldn't find interface %s\n", *arg); 147231183Speter free(*arg); 147331183Speter *arg = NULL; 147431183Speter} 147531183Speter 147631183Speter 147731183Spetervoid set_sendvia(arg) 147831183Speterchar **arg; 147931183Speter{ 148031183Speter sending.snd_gw = getipv4addr(*arg); 148131183Speter free(*arg); 148231183Speter *arg = NULL; 148331183Speter} 148431183Speter 148531183Speter 148631183Spetervoid set_defaultrouter(arg) 148731183Speterchar **arg; 148831183Speter{ 148931183Speter defrouter = getipv4addr(*arg); 149031183Speter free(*arg); 149131183Speter *arg = NULL; 149231183Speter} 149331183Speter 149431183Speter 149531183Spetervoid new_icmpheader() 149631183Speter{ 149731183Speter if ((ip->ip_p) && (ip->ip_p != IPPROTO_ICMP)) { 149831183Speter fprintf(stderr, "protocol %d specified with ICMP!\n", 149931183Speter ip->ip_p); 150031183Speter return; 150131183Speter } 150231183Speter ip->ip_p = IPPROTO_ICMP; 150331183Speter icmp = (icmphdr_t *)new_header(IPPROTO_ICMP); 150431183Speter} 150531183Speter 150631183Speter 150731183Spetervoid set_icmpcode(code) 150831183Speterint code; 150931183Speter{ 151031183Speter icmp->icmp_code = code; 151131183Speter} 151231183Speter 151331183Speter 151431183Spetervoid set_icmptype(type) 151531183Speterint type; 151631183Speter{ 151731183Speter icmp->icmp_type = type; 151831183Speter} 151931183Speter 152031183Speter 152131183Spetervoid set_icmpcodetok(code) 152231183Speterchar **code; 152331183Speter{ 152431183Speter char *s; 152531183Speter int i; 152631183Speter 152731183Speter for (i = 0; (s = icmpcodes[i]); i++) 152831183Speter if (!strcmp(s, *code)) { 152931183Speter icmp->icmp_code = i; 153031183Speter break; 153131183Speter } 153231183Speter if (!s) 153331183Speter fprintf(stderr, "unknown ICMP code %s\n", *code); 153431183Speter free(*code); 153531183Speter *code = NULL; 153631183Speter} 153731183Speter 153831183Speter 153931183Spetervoid set_icmptypetok(type) 154031183Speterchar **type; 154131183Speter{ 154231183Speter char *s; 154331183Speter int i, done = 0; 154431183Speter 154531183Speter for (i = 0; !(s = icmptypes[i]) || strcmp(s, "END"); i++) 154631183Speter if (s && !strcmp(s, *type)) { 154731183Speter icmp->icmp_type = i; 154831183Speter done = 1; 154931183Speter break; 155031183Speter } 155131183Speter if (!done) 155231183Speter fprintf(stderr, "unknown ICMP type %s\n", *type); 155331183Speter free(*type); 155431183Speter *type = NULL; 155531183Speter} 155631183Speter 155731183Speter 155831183Spetervoid set_icmpid(arg) 155931183Speterint arg; 156031183Speter{ 156137074Speter icmp->icmp_id = htons(arg); 156231183Speter} 156331183Speter 156431183Speter 156531183Spetervoid set_icmpseq(arg) 156631183Speterint arg; 156731183Speter{ 156837074Speter icmp->icmp_seq = htons(arg); 156931183Speter} 157031183Speter 157131183Speter 157231183Spetervoid set_icmpotime(arg) 157331183Speterint arg; 157431183Speter{ 157537074Speter icmp->icmp_otime = htonl(arg); 157631183Speter} 157731183Speter 157831183Speter 157931183Spetervoid set_icmprtime(arg) 158031183Speterint arg; 158131183Speter{ 158237074Speter icmp->icmp_rtime = htonl(arg); 158331183Speter} 158431183Speter 158531183Speter 158631183Spetervoid set_icmpttime(arg) 158731183Speterint arg; 158831183Speter{ 158937074Speter icmp->icmp_ttime = htonl(arg); 159031183Speter} 159131183Speter 159231183Speter 159331183Spetervoid set_icmpmtu(arg) 159431183Speterint arg; 159531183Speter{ 159631183Speter#if BSD >= 199306 159737074Speter icmp->icmp_nextmtu = htons(arg); 159831183Speter#endif 159931183Speter} 160031183Speter 160131183Speter 160231183Spetervoid set_redir(redir, arg) 160331183Speterint redir; 160431183Speterchar **arg; 160531183Speter{ 160631183Speter icmp->icmp_code = redir; 160731183Speter icmp->icmp_gwaddr = getipv4addr(*arg); 160831183Speter free(*arg); 160931183Speter *arg = NULL; 161031183Speter} 161131183Speter 161231183Speter 161331183Spetervoid set_icmppprob(num) 161431183Speterint num; 161531183Speter{ 161631183Speter icmp->icmp_pptr = num; 161731183Speter} 161831183Speter 161931183Speter 162031183Spetervoid new_ipv4opt() 162131183Speter{ 162231183Speter new_header(-2); 162331183Speter} 162431183Speter 162531183Speter 162631183Spetervoid add_ipopt(state, ptr) 162731183Speterint state; 162831183Spetervoid *ptr; 162931183Speter{ 163031183Speter struct ipopt_names *io; 163131183Speter struct statetoopt *sto; 163231183Speter char numbuf[16], *arg, **param = ptr; 163331183Speter int inc, hlen; 163431183Speter 163531183Speter if (state == IL_IPO_RR || state == IL_IPO_SATID) { 163631183Speter if (param) 163731183Speter sprintf(numbuf, "%d", *(int *)param); 163831183Speter else 163931183Speter strcpy(numbuf, "0"); 164031183Speter arg = numbuf; 164131183Speter } else 164231183Speter arg = param ? *param : NULL; 164331183Speter 164431183Speter if (canip->ah_next) { 164531183Speter fprintf(stderr, "cannot specify options after data body\n"); 164631183Speter return; 164731183Speter } 164831183Speter for (sto = toipopts; sto->sto_st; sto++) 164931183Speter if (sto->sto_st == state) 165031183Speter break; 1651161357Sguido if (!sto->sto_st) { 165231183Speter fprintf(stderr, "No mapping for state %d to IP option\n", 165331183Speter state); 165431183Speter return; 165531183Speter } 165631183Speter 165731183Speter hlen = sizeof(ip_t) + canip->ah_optlen; 165831183Speter for (io = ionames; io->on_name; io++) 165931183Speter if (io->on_value == sto->sto_op) 166031183Speter break; 166131183Speter canip->ah_lastopt = io->on_value; 166231183Speter 166331183Speter if (io->on_name) { 166431183Speter inc = addipopt((char *)ip + hlen, io, hlen - sizeof(ip_t),arg); 166531183Speter if (inc > 0) { 166631183Speter while (inc & 3) { 166731183Speter ((char *)ip)[sizeof(*ip) + inc] = IPOPT_NOP; 166831183Speter canip->ah_lastopt = IPOPT_NOP; 166931183Speter inc++; 167031183Speter } 167131183Speter hlen += inc; 167231183Speter } 167331183Speter } 167431183Speter 167531183Speter canip->ah_optlen = hlen - sizeof(ip_t); 167631183Speter 167731183Speter if (state != IL_IPO_RR && state != IL_IPO_SATID) 167831183Speter if (param && *param) { 167931183Speter free(*param); 168031183Speter *param = NULL; 168131183Speter } 168231183Speter sclass = NULL; 168331183Speter} 168431183Speter 168531183Speter 168631183Spetervoid end_ipopt() 168731183Speter{ 168831183Speter int pad; 168931183Speter char *s, *buf = (char *)ip; 169031183Speter 169131183Speter /* 169231183Speter * pad out so that we have a multiple of 4 bytes in size fo the 169331183Speter * options. make sure last byte is EOL. 169431183Speter */ 169531183Speter if (canip->ah_lastopt == IPOPT_NOP) { 169631183Speter buf[sizeof(*ip) + canip->ah_optlen - 1] = IPOPT_EOL; 169731183Speter } else if (canip->ah_lastopt != IPOPT_EOL) { 169831183Speter s = buf + sizeof(*ip) + canip->ah_optlen; 169931183Speter 170031183Speter for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { 170131183Speter *s++ = IPOPT_NOP; 170231183Speter *s = IPOPT_EOL; 170331183Speter canip->ah_optlen++; 170431183Speter } 170531183Speter canip->ah_optlen++; 170631183Speter } else { 170731183Speter s = buf + sizeof(*ip) + canip->ah_optlen - 1; 170831183Speter 170931183Speter for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { 171031183Speter *s++ = IPOPT_NOP; 171131183Speter *s = IPOPT_EOL; 171231183Speter canip->ah_optlen++; 171331183Speter } 171431183Speter } 171531183Speter ip->ip_hl = (sizeof(*ip) + canip->ah_optlen) >> 2; 171631183Speter inc_anipheaders(canip->ah_optlen); 171731183Speter free_anipheader(); 171831183Speter} 171931183Speter 172031183Speter 172131183Spetervoid set_secclass(arg) 172231183Speterchar **arg; 172331183Speter{ 172431183Speter sclass = *arg; 172531183Speter *arg = NULL; 172631183Speter} 172731183Speter 172831183Speter 172931183Spetervoid free_anipheader() 173031183Speter{ 173131183Speter aniphdr_t *aip; 173231183Speter 173331183Speter aip = canip; 173431183Speter if ((canip = aip->ah_prev)) { 173531183Speter canip->ah_next = NULL; 173631183Speter aniptail = &canip->ah_next; 173731183Speter } 173834739Speter 173934739Speter if (canip) 174034739Speter free(aip); 174131183Speter} 174231183Speter 174331183Speter 174431183Spetervoid end_ipv4() 174531183Speter{ 174631183Speter aniphdr_t *aip; 174731183Speter 174831183Speter ip->ip_sum = 0; 174937074Speter ip->ip_len = htons(ip->ip_len); 175031183Speter ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2); 175137074Speter ip->ip_len = ntohs(ip->ip_len); 175231183Speter free_anipheader(); 175331183Speter for (aip = aniphead, ip = NULL; aip; aip = aip->ah_next) 175431183Speter if (aip->ah_p == IPPROTO_IP) 175531183Speter ip = aip->ah_ip; 175631183Speter} 175731183Speter 175831183Speter 175931183Spetervoid end_icmp() 176031183Speter{ 176131183Speter aniphdr_t *aip; 176231183Speter 176331183Speter icmp->icmp_cksum = 0; 176431183Speter icmp->icmp_cksum = chksum((u_short *)icmp, canip->ah_len); 176531183Speter free_anipheader(); 176631183Speter for (aip = aniphead, icmp = NULL; aip; aip = aip->ah_next) 176731183Speter if (aip->ah_p == IPPROTO_ICMP) 176831183Speter icmp = aip->ah_icmp; 176931183Speter} 177031183Speter 177131183Speter 177231183Spetervoid end_udp() 177331183Speter{ 177431183Speter u_long sum; 177531183Speter aniphdr_t *aip; 177631183Speter ip_t iptmp; 177731183Speter 177831183Speter bzero((char *)&iptmp, sizeof(iptmp)); 177931183Speter iptmp.ip_p = ip->ip_p; 178031183Speter iptmp.ip_src = ip->ip_src; 178131183Speter iptmp.ip_dst = ip->ip_dst; 178237074Speter iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2)); 178331183Speter sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp)); 178437074Speter udp->uh_ulen = htons(udp->uh_ulen); 178537074Speter udp->uh_sum = c_chksum((u_short *)udp, (u_int)ntohs(iptmp.ip_len), sum); 178631183Speter free_anipheader(); 178731183Speter for (aip = aniphead, udp = NULL; aip; aip = aip->ah_next) 178831183Speter if (aip->ah_p == IPPROTO_UDP) 178931183Speter udp = aip->ah_udp; 179031183Speter} 179131183Speter 179231183Speter 179331183Spetervoid end_tcp() 179431183Speter{ 179531183Speter u_long sum; 179631183Speter aniphdr_t *aip; 179731183Speter ip_t iptmp; 179831183Speter 179931183Speter bzero((char *)&iptmp, sizeof(iptmp)); 180031183Speter iptmp.ip_p = ip->ip_p; 180131183Speter iptmp.ip_src = ip->ip_src; 180231183Speter iptmp.ip_dst = ip->ip_dst; 180337074Speter iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2)); 180431183Speter sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp)); 180531183Speter tcp->th_sum = 0; 180637074Speter tcp->th_sum = c_chksum((u_short *)tcp, (u_int)ntohs(iptmp.ip_len), sum); 180731183Speter free_anipheader(); 180831183Speter for (aip = aniphead, tcp = NULL; aip; aip = aip->ah_next) 180931183Speter if (aip->ah_p == IPPROTO_TCP) 181031183Speter tcp = aip->ah_tcp; 181131183Speter} 181231183Speter 181331183Speter 181431183Spetervoid end_data() 181531183Speter{ 181631183Speter free_anipheader(); 181731183Speter} 181831183Speter 181931183Speter 182031183Spetervoid iplang(fp) 182131183SpeterFILE *fp; 182231183Speter{ 182331183Speter yyin = fp; 182431183Speter 182531183Speter yydebug = (opts & OPT_DEBUG) ? 1 : 0; 182631183Speter 182731183Speter while (!feof(fp)) 182831183Speter yyparse(); 182931183Speter} 183031183Speter 183131183Speter 183231183Speteru_short c_chksum(buf, len, init) 183331183Speteru_short *buf; 183431183Speteru_int len; 183531183Speteru_long init; 183631183Speter{ 183731183Speter u_long sum = init; 183831183Speter int nwords = len >> 1; 1839255332Scy 184031183Speter for(; nwords > 0; nwords--) 184131183Speter sum += *buf++; 184231183Speter sum = (sum>>16) + (sum & 0xffff); 184331183Speter sum += (sum >>16); 184431183Speter return (~sum); 184531183Speter} 184631183Speter 184731183Speter 184831183Speteru_long p_chksum(buf,len) 184931183Speteru_short *buf; 185031183Speteru_int len; 185131183Speter{ 185231183Speter u_long sum = 0; 185331183Speter int nwords = len >> 1; 1854255332Scy 185531183Speter for(; nwords > 0; nwords--) 185631183Speter sum += *buf++; 185731183Speter return sum; 185831183Speter} 1859