1*f52ace7aSdarrenr /* $NetBSD: iplang_y.y,v 1.2 2012/07/22 14:27:35 darrenr Exp $ */
226945a25Schristos
326945a25Schristos %{
426945a25Schristos /*
5c50c2f6fSdarrenr * Copyright (C) 2012 by Darren Reed.
626945a25Schristos *
726945a25Schristos * See the IPFILTER.LICENCE file for details on licencing.
826945a25Schristos *
9*f52ace7aSdarrenr * Id: iplang_y.y,v 1.1.1.2 2012/07/22 13:44:34 darrenr Exp $
1026945a25Schristos */
1126945a25Schristos
1226945a25Schristos #include <stdio.h>
1326945a25Schristos #include <string.h>
1426945a25Schristos #include <fcntl.h>
1526945a25Schristos #if !defined(__SVR4) && !defined(__svr4__)
1626945a25Schristos # include <strings.h>
1726945a25Schristos #else
1826945a25Schristos # include <sys/byteorder.h>
1926945a25Schristos #endif
2026945a25Schristos #include <sys/types.h>
2126945a25Schristos #include <sys/stat.h>
2226945a25Schristos #include <sys/param.h>
2326945a25Schristos #include <sys/time.h>
2426945a25Schristos #include <stdlib.h>
2526945a25Schristos #include <unistd.h>
2626945a25Schristos #include <stddef.h>
2726945a25Schristos #include <sys/socket.h>
2826945a25Schristos #include <net/if.h>
2926945a25Schristos #include <netinet/in.h>
3026945a25Schristos #include <netinet/in_systm.h>
3126945a25Schristos #include <netinet/ip.h>
3226945a25Schristos #ifndef linux
3326945a25Schristos # include <netinet/ip_var.h>
3426945a25Schristos # include <net/route.h>
3526945a25Schristos # include <netinet/if_ether.h>
3626945a25Schristos #endif
3726945a25Schristos #include <netdb.h>
3826945a25Schristos #include <arpa/nameser.h>
3926945a25Schristos #include <arpa/inet.h>
4026945a25Schristos #include <resolv.h>
4126945a25Schristos #include <ctype.h>
4226945a25Schristos #include "ipsend.h"
4326945a25Schristos #include "ip_compat.h"
4426945a25Schristos #include "ipf.h"
4526945a25Schristos #include "iplang.h"
4626945a25Schristos
4726945a25Schristos #if !defined(__NetBSD__) && (!defined(__FreeBSD_version) && \
4826945a25Schristos __FreeBSD_version < 400020) && (!SOLARIS || SOLARIS2 < 10)
4926945a25Schristos extern struct ether_addr *ether_aton __P((char *));
5026945a25Schristos #endif
5126945a25Schristos
5226945a25Schristos extern int opts;
5326945a25Schristos extern struct ipopt_names ionames[];
5426945a25Schristos extern int state, state, lineNum, token;
5526945a25Schristos extern int yylineno;
5626945a25Schristos extern char yytext[];
5726945a25Schristos extern FILE *yyin;
5826945a25Schristos int yylex __P((void));
5926945a25Schristos #define YYDEBUG 1
6026945a25Schristos #if !defined(ultrix) && !defined(hpux)
6126945a25Schristos int yydebug = 1;
6226945a25Schristos #else
6326945a25Schristos extern int yydebug;
6426945a25Schristos #endif
6526945a25Schristos
6626945a25Schristos iface_t *iflist = NULL, **iftail = &iflist;
6726945a25Schristos iface_t *cifp = NULL;
6826945a25Schristos arp_t *arplist = NULL, **arptail = &arplist, *carp = NULL;
6926945a25Schristos struct in_addr defrouter;
7026945a25Schristos send_t sending;
7126945a25Schristos char *sclass = NULL;
7226945a25Schristos u_short c_chksum __P((u_short *, u_int, u_long));
7326945a25Schristos u_long p_chksum __P((u_short *, u_int));
7426945a25Schristos
7526945a25Schristos u_long ipbuffer[67584/sizeof(u_long)]; /* 66K */
7626945a25Schristos aniphdr_t *aniphead = NULL, *canip = NULL, **aniptail = &aniphead;
7726945a25Schristos ip_t *ip = NULL;
7826945a25Schristos udphdr_t *udp = NULL;
7926945a25Schristos tcphdr_t *tcp = NULL;
8026945a25Schristos icmphdr_t *icmp = NULL;
8126945a25Schristos
8226945a25Schristos struct statetoopt {
8326945a25Schristos int sto_st;
8426945a25Schristos int sto_op;
8526945a25Schristos };
8626945a25Schristos
8726945a25Schristos struct in_addr getipv4addr __P((char *arg));
8826945a25Schristos u_short getportnum __P((char *, char *));
8926945a25Schristos struct ether_addr *geteaddr __P((char *, struct ether_addr *));
9026945a25Schristos void *new_header __P((int));
9126945a25Schristos void free_aniplist __P((void));
9226945a25Schristos void inc_anipheaders __P((int));
9326945a25Schristos void new_data __P((void));
9426945a25Schristos void set_datalen __P((char **));
9526945a25Schristos void set_datafile __P((char **));
9626945a25Schristos void set_data __P((char **));
9726945a25Schristos void new_packet __P((void));
9826945a25Schristos void set_ipv4proto __P((char **));
9926945a25Schristos void set_ipv4src __P((char **));
10026945a25Schristos void set_ipv4dst __P((char **));
10126945a25Schristos void set_ipv4off __P((char **));
10226945a25Schristos void set_ipv4v __P((char **));
10326945a25Schristos void set_ipv4hl __P((char **));
10426945a25Schristos void set_ipv4ttl __P((char **));
10526945a25Schristos void set_ipv4tos __P((char **));
10626945a25Schristos void set_ipv4id __P((char **));
10726945a25Schristos void set_ipv4sum __P((char **));
10826945a25Schristos void set_ipv4len __P((char **));
10926945a25Schristos void new_tcpheader __P((void));
11026945a25Schristos void set_tcpsport __P((char **));
11126945a25Schristos void set_tcpdport __P((char **));
11226945a25Schristos void set_tcpseq __P((char **));
11326945a25Schristos void set_tcpack __P((char **));
11426945a25Schristos void set_tcpoff __P((char **));
11526945a25Schristos void set_tcpurp __P((char **));
11626945a25Schristos void set_tcpwin __P((char **));
11726945a25Schristos void set_tcpsum __P((char **));
11826945a25Schristos void set_tcpflags __P((char **));
11926945a25Schristos void set_tcpopt __P((int, char **));
12026945a25Schristos void end_tcpopt __P((void));
12126945a25Schristos void new_udpheader __P((void));
12226945a25Schristos void set_udplen __P((char **));
12326945a25Schristos void set_udpsum __P((char **));
12426945a25Schristos void prep_packet __P((void));
12526945a25Schristos void packet_done __P((void));
12626945a25Schristos void new_interface __P((void));
12726945a25Schristos void check_interface __P((void));
12826945a25Schristos void set_ifname __P((char **));
12926945a25Schristos void set_ifmtu __P((int));
13026945a25Schristos void set_ifv4addr __P((char **));
13126945a25Schristos void set_ifeaddr __P((char **));
13226945a25Schristos void new_arp __P((void));
13326945a25Schristos void set_arpeaddr __P((char **));
13426945a25Schristos void set_arpv4addr __P((char **));
13526945a25Schristos void reset_send __P((void));
13626945a25Schristos void set_sendif __P((char **));
13726945a25Schristos void set_sendvia __P((char **));
13826945a25Schristos void set_defaultrouter __P((char **));
13926945a25Schristos void new_icmpheader __P((void));
14026945a25Schristos void set_icmpcode __P((int));
14126945a25Schristos void set_icmptype __P((int));
14226945a25Schristos void set_icmpcodetok __P((char **));
14326945a25Schristos void set_icmptypetok __P((char **));
14426945a25Schristos void set_icmpid __P((int));
14526945a25Schristos void set_icmpseq __P((int));
14626945a25Schristos void set_icmpotime __P((int));
14726945a25Schristos void set_icmprtime __P((int));
14826945a25Schristos void set_icmpttime __P((int));
14926945a25Schristos void set_icmpmtu __P((int));
15026945a25Schristos void set_redir __P((int, char **));
15126945a25Schristos void new_ipv4opt __P((void));
15226945a25Schristos void set_icmppprob __P((int));
15326945a25Schristos void add_ipopt __P((int, void *));
15426945a25Schristos void end_ipopt __P((void));
15526945a25Schristos void set_secclass __P((char **));
15626945a25Schristos void free_anipheader __P((void));
15726945a25Schristos void end_ipv4 __P((void));
15826945a25Schristos void end_icmp __P((void));
15926945a25Schristos void end_udp __P((void));
16026945a25Schristos void end_tcp __P((void));
16126945a25Schristos void end_data __P((void));
16226945a25Schristos void yyerror __P((char *));
16326945a25Schristos void iplang __P((FILE *));
16426945a25Schristos int arp_getipv4 __P((char *, char *));
16526945a25Schristos int yyparse __P((void));
16626945a25Schristos %}
16726945a25Schristos %union {
16826945a25Schristos char *str;
16926945a25Schristos int num;
17026945a25Schristos }
17126945a25Schristos %token <num> IL_NUMBER
17226945a25Schristos %type <num> number digits optnumber
17326945a25Schristos %token <str> IL_TOKEN
17426945a25Schristos %type <str> token optoken
17526945a25Schristos %token IL_HEXDIGIT IL_COLON IL_DOT IL_EOF IL_COMMENT
17626945a25Schristos %token IL_INTERFACE IL_IFNAME IL_MTU IL_EADDR
17726945a25Schristos %token IL_IPV4 IL_V4PROTO IL_V4SRC IL_V4DST IL_V4OFF IL_V4V IL_V4HL IL_V4TTL
17826945a25Schristos %token IL_V4TOS IL_V4SUM IL_V4LEN IL_V4OPT IL_V4ID
17926945a25Schristos %token IL_TCP IL_SPORT IL_DPORT IL_TCPFL IL_TCPSEQ IL_TCPACK IL_TCPOFF
18026945a25Schristos %token IL_TCPWIN IL_TCPSUM IL_TCPURP IL_TCPOPT IL_TCPO_NOP IL_TCPO_EOL
18126945a25Schristos %token IL_TCPO_MSS IL_TCPO_WSCALE IL_TCPO_TS
18226945a25Schristos %token IL_UDP IL_UDPLEN IL_UDPSUM
18326945a25Schristos %token IL_ICMP IL_ICMPTYPE IL_ICMPCODE
18426945a25Schristos %token IL_SEND IL_VIA
18526945a25Schristos %token IL_ARP
18626945a25Schristos %token IL_DEFROUTER
18726945a25Schristos %token IL_SUM IL_OFF IL_LEN IL_V4ADDR IL_OPT
18826945a25Schristos %token IL_DATA IL_DLEN IL_DVALUE IL_DFILE
18926945a25Schristos %token IL_IPO_NOP IL_IPO_RR IL_IPO_ZSU IL_IPO_MTUP IL_IPO_MTUR IL_IPO_EOL
19026945a25Schristos %token IL_IPO_TS IL_IPO_TR IL_IPO_SEC IL_IPO_LSRR IL_IPO_ESEC
19126945a25Schristos %token IL_IPO_SATID IL_IPO_SSRR IL_IPO_ADDEXT IL_IPO_VISA IL_IPO_IMITD
19226945a25Schristos %token IL_IPO_EIP IL_IPO_FINN IL_IPO_SECCLASS IL_IPO_CIPSO IL_IPO_ENCODE
19326945a25Schristos %token <str> IL_IPS_RESERV4 IL_IPS_TOPSECRET IL_IPS_SECRET IL_IPS_RESERV3
19426945a25Schristos %token <str> IL_IPS_CONFID IL_IPS_UNCLASS IL_IPS_RESERV2 IL_IPS_RESERV1
19526945a25Schristos %token IL_ICMP_ECHOREPLY IL_ICMP_UNREACH IL_ICMP_UNREACH_NET
19626945a25Schristos %token IL_ICMP_UNREACH_HOST IL_ICMP_UNREACH_PROTOCOL IL_ICMP_UNREACH_PORT
19726945a25Schristos %token IL_ICMP_UNREACH_NEEDFRAG IL_ICMP_UNREACH_SRCFAIL
19826945a25Schristos %token IL_ICMP_UNREACH_NET_UNKNOWN IL_ICMP_UNREACH_HOST_UNKNOWN
19926945a25Schristos %token IL_ICMP_UNREACH_ISOLATED IL_ICMP_UNREACH_NET_PROHIB
20026945a25Schristos %token IL_ICMP_UNREACH_HOST_PROHIB IL_ICMP_UNREACH_TOSNET
20126945a25Schristos %token IL_ICMP_UNREACH_TOSHOST IL_ICMP_UNREACH_FILTER_PROHIB
20226945a25Schristos %token IL_ICMP_UNREACH_HOST_PRECEDENCE IL_ICMP_UNREACH_PRECEDENCE_CUTOFF
20326945a25Schristos %token IL_ICMP_SOURCEQUENCH IL_ICMP_REDIRECT IL_ICMP_REDIRECT_NET
20426945a25Schristos %token IL_ICMP_REDIRECT_HOST IL_ICMP_REDIRECT_TOSNET
20526945a25Schristos %token IL_ICMP_REDIRECT_TOSHOST IL_ICMP_ECHO IL_ICMP_ROUTERADVERT
20626945a25Schristos %token IL_ICMP_ROUTERSOLICIT IL_ICMP_TIMXCEED IL_ICMP_TIMXCEED_INTRANS
20726945a25Schristos %token IL_ICMP_TIMXCEED_REASS IL_ICMP_PARAMPROB IL_ICMP_PARAMPROB_OPTABSENT
20826945a25Schristos %token IL_ICMP_TSTAMP IL_ICMP_TSTAMPREPLY IL_ICMP_IREQ IL_ICMP_IREQREPLY
20926945a25Schristos %token IL_ICMP_MASKREQ IL_ICMP_MASKREPLY IL_ICMP_SEQ IL_ICMP_ID
21026945a25Schristos %token IL_ICMP_OTIME IL_ICMP_RTIME IL_ICMP_TTIME
21126945a25Schristos
21226945a25Schristos %%
21326945a25Schristos file: line
21426945a25Schristos | line file
21526945a25Schristos | IL_COMMENT
21626945a25Schristos | IL_COMMENT file
21726945a25Schristos ;
21826945a25Schristos
21926945a25Schristos line: iface
22026945a25Schristos | arp
22126945a25Schristos | send
22226945a25Schristos | defrouter
22326945a25Schristos | ipline
22426945a25Schristos ;
22526945a25Schristos
22626945a25Schristos iface: ifhdr '{' ifaceopts '}' ';' { check_interface(); }
22726945a25Schristos ;
22826945a25Schristos
22926945a25Schristos ifhdr: IL_INTERFACE { new_interface(); }
23026945a25Schristos ;
23126945a25Schristos
23226945a25Schristos ifaceopts:
23326945a25Schristos ifaceopt
23426945a25Schristos | ifaceopt ifaceopts
23526945a25Schristos ;
23626945a25Schristos
23726945a25Schristos ifaceopt:
23826945a25Schristos IL_IFNAME token { set_ifname(&$2); }
23926945a25Schristos | IL_MTU number { set_ifmtu($2); }
24026945a25Schristos | IL_V4ADDR token { set_ifv4addr(&$2); }
24126945a25Schristos | IL_EADDR token { set_ifeaddr(&$2); }
24226945a25Schristos ;
24326945a25Schristos
24426945a25Schristos send: sendhdr '{' sendbody '}' ';' { packet_done(); }
24526945a25Schristos | sendhdr ';' { packet_done(); }
24626945a25Schristos ;
24726945a25Schristos
24826945a25Schristos sendhdr:
24926945a25Schristos IL_SEND { reset_send(); }
25026945a25Schristos ;
25126945a25Schristos
25226945a25Schristos sendbody:
25326945a25Schristos sendopt
25426945a25Schristos | sendbody sendopt
25526945a25Schristos ;
25626945a25Schristos
25726945a25Schristos sendopt:
25826945a25Schristos IL_IFNAME token { set_sendif(&$2); }
25926945a25Schristos | IL_VIA token { set_sendvia(&$2); }
26026945a25Schristos ;
26126945a25Schristos
26226945a25Schristos arp: arphdr '{' arpbody '}' ';'
26326945a25Schristos ;
26426945a25Schristos
26526945a25Schristos arphdr: IL_ARP { new_arp(); }
26626945a25Schristos ;
26726945a25Schristos
26826945a25Schristos arpbody:
26926945a25Schristos arpopt
27026945a25Schristos | arpbody arpopt
27126945a25Schristos ;
27226945a25Schristos
27326945a25Schristos arpopt: IL_V4ADDR token { set_arpv4addr(&$2); }
27426945a25Schristos | IL_EADDR token { set_arpeaddr(&$2); }
27526945a25Schristos ;
27626945a25Schristos
27726945a25Schristos defrouter:
27826945a25Schristos IL_DEFROUTER token { set_defaultrouter(&$2); }
27926945a25Schristos ;
28026945a25Schristos
28126945a25Schristos bodyline:
28226945a25Schristos ipline
28326945a25Schristos | tcp tcpline
28426945a25Schristos | udp udpline
28526945a25Schristos | icmp icmpline
28626945a25Schristos | data dataline
28726945a25Schristos ;
28826945a25Schristos
28926945a25Schristos ipline: ipv4 '{' ipv4body '}' ';' { end_ipv4(); }
29026945a25Schristos ;
29126945a25Schristos
29226945a25Schristos ipv4: IL_IPV4 { new_packet(); }
29326945a25Schristos
29426945a25Schristos ipv4body:
29526945a25Schristos ipv4type
29626945a25Schristos | ipv4type ipv4body
29726945a25Schristos | bodyline
29826945a25Schristos ;
29926945a25Schristos
30026945a25Schristos ipv4type:
30126945a25Schristos IL_V4PROTO token { set_ipv4proto(&$2); }
30226945a25Schristos | IL_V4SRC token { set_ipv4src(&$2); }
30326945a25Schristos | IL_V4DST token { set_ipv4dst(&$2); }
30426945a25Schristos | IL_V4OFF token { set_ipv4off(&$2); }
30526945a25Schristos | IL_V4V token { set_ipv4v(&$2); }
30626945a25Schristos | IL_V4HL token { set_ipv4hl(&$2); }
30726945a25Schristos | IL_V4ID token { set_ipv4id(&$2); }
30826945a25Schristos | IL_V4TTL token { set_ipv4ttl(&$2); }
30926945a25Schristos | IL_V4TOS token { set_ipv4tos(&$2); }
31026945a25Schristos | IL_V4SUM token { set_ipv4sum(&$2); }
31126945a25Schristos | IL_V4LEN token { set_ipv4len(&$2); }
31226945a25Schristos | ipv4opt '{' ipv4optlist '}' ';' { end_ipopt(); }
31326945a25Schristos ;
31426945a25Schristos
31526945a25Schristos tcp: IL_TCP { new_tcpheader(); }
31626945a25Schristos ;
31726945a25Schristos
31826945a25Schristos tcpline:
31926945a25Schristos '{' tcpheader '}' ';' { end_tcp(); }
32026945a25Schristos ;
32126945a25Schristos
32226945a25Schristos tcpheader:
32326945a25Schristos tcpbody
32426945a25Schristos | tcpbody tcpheader
32526945a25Schristos | bodyline
32626945a25Schristos ;
32726945a25Schristos
32826945a25Schristos tcpbody:
32926945a25Schristos IL_SPORT token { set_tcpsport(&$2); }
33026945a25Schristos | IL_DPORT token { set_tcpdport(&$2); }
33126945a25Schristos | IL_TCPSEQ token { set_tcpseq(&$2); }
33226945a25Schristos | IL_TCPACK token { set_tcpack(&$2); }
33326945a25Schristos | IL_TCPOFF token { set_tcpoff(&$2); }
33426945a25Schristos | IL_TCPURP token { set_tcpurp(&$2); }
33526945a25Schristos | IL_TCPWIN token { set_tcpwin(&$2); }
33626945a25Schristos | IL_TCPSUM token { set_tcpsum(&$2); }
33726945a25Schristos | IL_TCPFL token { set_tcpflags(&$2); }
33826945a25Schristos | IL_TCPOPT '{' tcpopts '}' ';' { end_tcpopt(); }
33926945a25Schristos ;
34026945a25Schristos
34126945a25Schristos tcpopts:
34226945a25Schristos | tcpopt tcpopts
34326945a25Schristos ;
34426945a25Schristos
34526945a25Schristos tcpopt: IL_TCPO_NOP ';' { set_tcpopt(IL_TCPO_NOP, NULL); }
34626945a25Schristos | IL_TCPO_EOL ';' { set_tcpopt(IL_TCPO_EOL, NULL); }
34726945a25Schristos | IL_TCPO_MSS optoken { set_tcpopt(IL_TCPO_MSS,&$2);}
34826945a25Schristos | IL_TCPO_WSCALE optoken { set_tcpopt(IL_TCPO_WSCALE,&$2);}
34926945a25Schristos | IL_TCPO_TS optoken { set_tcpopt(IL_TCPO_TS, &$2);}
35026945a25Schristos ;
35126945a25Schristos
35226945a25Schristos udp: IL_UDP { new_udpheader(); }
35326945a25Schristos ;
35426945a25Schristos
35526945a25Schristos udpline:
35626945a25Schristos '{' udpheader '}' ';' { end_udp(); }
35726945a25Schristos ;
35826945a25Schristos
35926945a25Schristos
36026945a25Schristos udpheader:
36126945a25Schristos udpbody
36226945a25Schristos | udpbody udpheader
36326945a25Schristos | bodyline
36426945a25Schristos ;
36526945a25Schristos
36626945a25Schristos udpbody:
36726945a25Schristos IL_SPORT token { set_tcpsport(&$2); }
36826945a25Schristos | IL_DPORT token { set_tcpdport(&$2); }
36926945a25Schristos | IL_UDPLEN token { set_udplen(&$2); }
37026945a25Schristos | IL_UDPSUM token { set_udpsum(&$2); }
37126945a25Schristos ;
37226945a25Schristos
37326945a25Schristos icmp: IL_ICMP { new_icmpheader(); }
37426945a25Schristos ;
37526945a25Schristos
37626945a25Schristos icmpline:
37726945a25Schristos '{' icmpbody '}' ';' { end_icmp(); }
37826945a25Schristos ;
37926945a25Schristos
38026945a25Schristos icmpbody:
38126945a25Schristos icmpheader
38226945a25Schristos | icmpheader bodyline
38326945a25Schristos ;
38426945a25Schristos
38526945a25Schristos icmpheader:
38626945a25Schristos IL_ICMPTYPE icmptype
38726945a25Schristos | IL_ICMPTYPE icmptype icmpcode
38826945a25Schristos ;
38926945a25Schristos
39026945a25Schristos icmpcode:
39126945a25Schristos IL_ICMPCODE token { set_icmpcodetok(&$2); }
39226945a25Schristos ;
39326945a25Schristos
39426945a25Schristos icmptype:
39526945a25Schristos IL_ICMP_ECHOREPLY ';' { set_icmptype(ICMP_ECHOREPLY); }
39626945a25Schristos | IL_ICMP_ECHOREPLY '{' icmpechoopts '}' ';'
39726945a25Schristos | unreach
39826945a25Schristos | IL_ICMP_SOURCEQUENCH ';' { set_icmptype(ICMP_SOURCEQUENCH); }
39926945a25Schristos | redirect
40026945a25Schristos | IL_ICMP_ROUTERADVERT ';' { set_icmptype(ICMP_ROUTERADVERT); }
40126945a25Schristos | IL_ICMP_ROUTERSOLICIT ';' { set_icmptype(ICMP_ROUTERSOLICIT); }
40226945a25Schristos | IL_ICMP_ECHO ';' { set_icmptype(ICMP_ECHO); }
40326945a25Schristos | IL_ICMP_ECHO '{' icmpechoopts '}' ';'
40426945a25Schristos | IL_ICMP_TIMXCEED ';' { set_icmptype(ICMP_TIMXCEED); }
40526945a25Schristos | IL_ICMP_TIMXCEED '{' exceed '}' ';'
40626945a25Schristos | IL_ICMP_TSTAMP ';' { set_icmptype(ICMP_TSTAMP); }
40726945a25Schristos | IL_ICMP_TSTAMPREPLY ';' { set_icmptype(ICMP_TSTAMPREPLY); }
40826945a25Schristos | IL_ICMP_TSTAMPREPLY '{' icmptsopts '}' ';'
40926945a25Schristos | IL_ICMP_IREQ ';' { set_icmptype(ICMP_IREQ); }
41026945a25Schristos | IL_ICMP_IREQREPLY ';' { set_icmptype(ICMP_IREQREPLY); }
41126945a25Schristos | IL_ICMP_IREQREPLY '{' data dataline '}' ';'
41226945a25Schristos | IL_ICMP_MASKREQ ';' { set_icmptype(ICMP_MASKREQ); }
41326945a25Schristos | IL_ICMP_MASKREPLY ';' { set_icmptype(ICMP_MASKREPLY); }
41426945a25Schristos | IL_ICMP_MASKREPLY '{' token '}' ';'
41526945a25Schristos | IL_ICMP_PARAMPROB ';' { set_icmptype(ICMP_PARAMPROB); }
41626945a25Schristos | IL_ICMP_PARAMPROB '{' paramprob '}' ';'
41726945a25Schristos | IL_TOKEN ';' { set_icmptypetok(&$1); }
41826945a25Schristos ;
41926945a25Schristos
42026945a25Schristos icmpechoopts:
42126945a25Schristos | icmpechoopts icmpecho
42226945a25Schristos ;
42326945a25Schristos
42426945a25Schristos icmpecho:
42526945a25Schristos IL_ICMP_SEQ number { set_icmpseq($2); }
42626945a25Schristos | IL_ICMP_ID number { set_icmpid($2); }
42726945a25Schristos ;
42826945a25Schristos
42926945a25Schristos icmptsopts:
43026945a25Schristos | icmptsopts icmpts ';'
43126945a25Schristos ;
43226945a25Schristos
43326945a25Schristos icmpts: IL_ICMP_OTIME number { set_icmpotime($2); }
43426945a25Schristos | IL_ICMP_RTIME number { set_icmprtime($2); }
43526945a25Schristos | IL_ICMP_TTIME number { set_icmpttime($2); }
43626945a25Schristos ;
43726945a25Schristos
43826945a25Schristos unreach:
43926945a25Schristos IL_ICMP_UNREACH
44026945a25Schristos | IL_ICMP_UNREACH '{' unreachopts '}' ';'
44126945a25Schristos ;
44226945a25Schristos
44326945a25Schristos unreachopts:
44426945a25Schristos IL_ICMP_UNREACH_NET line
44526945a25Schristos | IL_ICMP_UNREACH_HOST line
44626945a25Schristos | IL_ICMP_UNREACH_PROTOCOL line
44726945a25Schristos | IL_ICMP_UNREACH_PORT line
44826945a25Schristos | IL_ICMP_UNREACH_NEEDFRAG number ';' { set_icmpmtu($2); }
44926945a25Schristos | IL_ICMP_UNREACH_SRCFAIL line
45026945a25Schristos | IL_ICMP_UNREACH_NET_UNKNOWN line
45126945a25Schristos | IL_ICMP_UNREACH_HOST_UNKNOWN line
45226945a25Schristos | IL_ICMP_UNREACH_ISOLATED line
45326945a25Schristos | IL_ICMP_UNREACH_NET_PROHIB line
45426945a25Schristos | IL_ICMP_UNREACH_HOST_PROHIB line
45526945a25Schristos | IL_ICMP_UNREACH_TOSNET line
45626945a25Schristos | IL_ICMP_UNREACH_TOSHOST line
45726945a25Schristos | IL_ICMP_UNREACH_FILTER_PROHIB line
45826945a25Schristos | IL_ICMP_UNREACH_HOST_PRECEDENCE line
45926945a25Schristos | IL_ICMP_UNREACH_PRECEDENCE_CUTOFF line
46026945a25Schristos ;
46126945a25Schristos
46226945a25Schristos redirect:
46326945a25Schristos IL_ICMP_REDIRECT
46426945a25Schristos | IL_ICMP_REDIRECT '{' redirectopts '}' ';'
46526945a25Schristos ;
46626945a25Schristos
46726945a25Schristos redirectopts:
46826945a25Schristos | IL_ICMP_REDIRECT_NET token { set_redir(0, &$2); }
46926945a25Schristos | IL_ICMP_REDIRECT_HOST token { set_redir(1, &$2); }
47026945a25Schristos | IL_ICMP_REDIRECT_TOSNET token { set_redir(2, &$2); }
47126945a25Schristos | IL_ICMP_REDIRECT_TOSHOST token { set_redir(3, &$2); }
47226945a25Schristos ;
47326945a25Schristos
47426945a25Schristos exceed:
47526945a25Schristos IL_ICMP_TIMXCEED_INTRANS line
47626945a25Schristos | IL_ICMP_TIMXCEED_REASS line
47726945a25Schristos ;
47826945a25Schristos
47926945a25Schristos paramprob:
48026945a25Schristos IL_ICMP_PARAMPROB_OPTABSENT
48126945a25Schristos | IL_ICMP_PARAMPROB_OPTABSENT paraprobarg
48226945a25Schristos
48326945a25Schristos paraprobarg:
48426945a25Schristos '{' number '}' ';' { set_icmppprob($2); }
48526945a25Schristos ;
48626945a25Schristos
48726945a25Schristos ipv4opt: IL_V4OPT { new_ipv4opt(); }
48826945a25Schristos ;
48926945a25Schristos
49026945a25Schristos ipv4optlist:
49126945a25Schristos | ipv4opts ipv4optlist
49226945a25Schristos ;
49326945a25Schristos
49426945a25Schristos ipv4opts:
49526945a25Schristos IL_IPO_NOP ';' { add_ipopt(IL_IPO_NOP, NULL); }
49626945a25Schristos | IL_IPO_RR optnumber { add_ipopt(IL_IPO_RR, &$2); }
49726945a25Schristos | IL_IPO_ZSU ';' { add_ipopt(IL_IPO_ZSU, NULL); }
49826945a25Schristos | IL_IPO_MTUP ';' { add_ipopt(IL_IPO_MTUP, NULL); }
49926945a25Schristos | IL_IPO_MTUR ';' { add_ipopt(IL_IPO_MTUR, NULL); }
50026945a25Schristos | IL_IPO_ENCODE ';' { add_ipopt(IL_IPO_ENCODE, NULL); }
50126945a25Schristos | IL_IPO_TS ';' { add_ipopt(IL_IPO_TS, NULL); }
50226945a25Schristos | IL_IPO_TR ';' { add_ipopt(IL_IPO_TR, NULL); }
50326945a25Schristos | IL_IPO_SEC ';' { add_ipopt(IL_IPO_SEC, NULL); }
50426945a25Schristos | IL_IPO_SECCLASS secclass { add_ipopt(IL_IPO_SECCLASS, sclass); }
50526945a25Schristos | IL_IPO_LSRR token { add_ipopt(IL_IPO_LSRR,&$2); }
50626945a25Schristos | IL_IPO_ESEC ';' { add_ipopt(IL_IPO_ESEC, NULL); }
50726945a25Schristos | IL_IPO_CIPSO ';' { add_ipopt(IL_IPO_CIPSO, NULL); }
50826945a25Schristos | IL_IPO_SATID optnumber { add_ipopt(IL_IPO_SATID,&$2);}
50926945a25Schristos | IL_IPO_SSRR token { add_ipopt(IL_IPO_SSRR,&$2); }
51026945a25Schristos | IL_IPO_ADDEXT ';' { add_ipopt(IL_IPO_ADDEXT, NULL); }
51126945a25Schristos | IL_IPO_VISA ';' { add_ipopt(IL_IPO_VISA, NULL); }
51226945a25Schristos | IL_IPO_IMITD ';' { add_ipopt(IL_IPO_IMITD, NULL); }
51326945a25Schristos | IL_IPO_EIP ';' { add_ipopt(IL_IPO_EIP, NULL); }
51426945a25Schristos | IL_IPO_FINN ';' { add_ipopt(IL_IPO_FINN, NULL); }
51526945a25Schristos ;
51626945a25Schristos
51726945a25Schristos secclass:
51826945a25Schristos IL_IPS_RESERV4 ';' { set_secclass(&$1); }
51926945a25Schristos | IL_IPS_TOPSECRET ';' { set_secclass(&$1); }
52026945a25Schristos | IL_IPS_SECRET ';' { set_secclass(&$1); }
52126945a25Schristos | IL_IPS_RESERV3 ';' { set_secclass(&$1); }
52226945a25Schristos | IL_IPS_CONFID ';' { set_secclass(&$1); }
52326945a25Schristos | IL_IPS_UNCLASS ';' { set_secclass(&$1); }
52426945a25Schristos | IL_IPS_RESERV2 ';' { set_secclass(&$1); }
52526945a25Schristos | IL_IPS_RESERV1 ';' { set_secclass(&$1); }
52626945a25Schristos ;
52726945a25Schristos
52826945a25Schristos data: IL_DATA { new_data(); }
52926945a25Schristos ;
53026945a25Schristos
53126945a25Schristos dataline:
53226945a25Schristos '{' databody '}' ';' { end_data(); }
53326945a25Schristos ;
53426945a25Schristos
53526945a25Schristos databody: dataopts
53626945a25Schristos | dataopts databody
53726945a25Schristos ;
53826945a25Schristos
53926945a25Schristos dataopts:
54026945a25Schristos IL_DLEN token { set_datalen(&$2); }
54126945a25Schristos | IL_DVALUE token { set_data(&$2); }
54226945a25Schristos | IL_DFILE token { set_datafile(&$2); }
54326945a25Schristos ;
54426945a25Schristos
54526945a25Schristos token: IL_TOKEN ';'
54626945a25Schristos ;
54726945a25Schristos
54826945a25Schristos optoken: ';' { $$ = ""; }
54926945a25Schristos | token
55026945a25Schristos ;
55126945a25Schristos
55226945a25Schristos number: digits ';'
55326945a25Schristos ;
55426945a25Schristos
55526945a25Schristos optnumber: ';' { $$ = 0; }
55626945a25Schristos | number
55726945a25Schristos ;
55826945a25Schristos
55926945a25Schristos digits: IL_NUMBER
56026945a25Schristos | digits IL_NUMBER
56126945a25Schristos ;
56226945a25Schristos %%
56326945a25Schristos
56426945a25Schristos struct statetoopt toipopts[] = {
56526945a25Schristos { IL_IPO_NOP, IPOPT_NOP },
56626945a25Schristos { IL_IPO_RR, IPOPT_RR },
56726945a25Schristos { IL_IPO_ZSU, IPOPT_ZSU },
56826945a25Schristos { IL_IPO_MTUP, IPOPT_MTUP },
56926945a25Schristos { IL_IPO_MTUR, IPOPT_MTUR },
57026945a25Schristos { IL_IPO_ENCODE, IPOPT_ENCODE },
57126945a25Schristos { IL_IPO_TS, IPOPT_TS },
57226945a25Schristos { IL_IPO_TR, IPOPT_TR },
57326945a25Schristos { IL_IPO_SEC, IPOPT_SECURITY },
57426945a25Schristos { IL_IPO_SECCLASS, IPOPT_SECURITY },
57526945a25Schristos { IL_IPO_LSRR, IPOPT_LSRR },
57626945a25Schristos { IL_IPO_ESEC, IPOPT_E_SEC },
57726945a25Schristos { IL_IPO_CIPSO, IPOPT_CIPSO },
57826945a25Schristos { IL_IPO_SATID, IPOPT_SATID },
57926945a25Schristos { IL_IPO_SSRR, IPOPT_SSRR },
58026945a25Schristos { IL_IPO_ADDEXT, IPOPT_ADDEXT },
58126945a25Schristos { IL_IPO_VISA, IPOPT_VISA },
58226945a25Schristos { IL_IPO_IMITD, IPOPT_IMITD },
58326945a25Schristos { IL_IPO_EIP, IPOPT_EIP },
58426945a25Schristos { IL_IPO_FINN, IPOPT_FINN },
58526945a25Schristos { 0, 0 }
58626945a25Schristos };
58726945a25Schristos
58826945a25Schristos struct statetoopt tosecopts[] = {
58926945a25Schristos { IL_IPS_RESERV4, IPSO_CLASS_RES4 },
59026945a25Schristos { IL_IPS_TOPSECRET, IPSO_CLASS_TOPS },
59126945a25Schristos { IL_IPS_SECRET, IPSO_CLASS_SECR },
59226945a25Schristos { IL_IPS_RESERV3, IPSO_CLASS_RES3 },
59326945a25Schristos { IL_IPS_CONFID, IPSO_CLASS_CONF },
59426945a25Schristos { IL_IPS_UNCLASS, IPSO_CLASS_UNCL },
59526945a25Schristos { IL_IPS_RESERV2, IPSO_CLASS_RES2 },
59626945a25Schristos { IL_IPS_RESERV1, IPSO_CLASS_RES1 },
59726945a25Schristos { 0, 0 }
59826945a25Schristos };
59926945a25Schristos
60026945a25Schristos #ifdef bsdi
60126945a25Schristos struct ether_addr *
ether_aton(s)60226945a25Schristos ether_aton(s)
60326945a25Schristos char *s;
60426945a25Schristos {
60526945a25Schristos static struct ether_addr n;
60626945a25Schristos u_int i[6];
60726945a25Schristos
60826945a25Schristos if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
60926945a25Schristos &i[2], &i[3], &i[4], &i[5]) == 6) {
61026945a25Schristos n.ether_addr_octet[0] = (u_char)i[0];
61126945a25Schristos n.ether_addr_octet[1] = (u_char)i[1];
61226945a25Schristos n.ether_addr_octet[2] = (u_char)i[2];
61326945a25Schristos n.ether_addr_octet[3] = (u_char)i[3];
61426945a25Schristos n.ether_addr_octet[4] = (u_char)i[4];
61526945a25Schristos n.ether_addr_octet[5] = (u_char)i[5];
61626945a25Schristos return &n;
61726945a25Schristos }
61826945a25Schristos return NULL;
61926945a25Schristos }
62026945a25Schristos #endif
62126945a25Schristos
62226945a25Schristos
getipv4addr(arg)62326945a25Schristos struct in_addr getipv4addr(arg)
62426945a25Schristos char *arg;
62526945a25Schristos {
62626945a25Schristos struct hostent *hp;
62726945a25Schristos struct in_addr in;
62826945a25Schristos
62926945a25Schristos in.s_addr = 0xffffffff;
63026945a25Schristos
63126945a25Schristos if ((hp = gethostbyname(arg)))
63226945a25Schristos bcopy(hp->h_addr, &in.s_addr, sizeof(struct in_addr));
63326945a25Schristos else
63426945a25Schristos in.s_addr = inet_addr(arg);
63526945a25Schristos return in;
63626945a25Schristos }
63726945a25Schristos
63826945a25Schristos
getportnum(pr,name)63926945a25Schristos u_short getportnum(pr, name)
64026945a25Schristos char *pr, *name;
64126945a25Schristos {
64226945a25Schristos struct servent *sp;
64326945a25Schristos
64426945a25Schristos if (!(sp = getservbyname(name, pr)))
64526945a25Schristos return htons(atoi(name));
64626945a25Schristos return sp->s_port;
64726945a25Schristos }
64826945a25Schristos
64926945a25Schristos
geteaddr(arg,buf)65026945a25Schristos struct ether_addr *geteaddr(arg, buf)
65126945a25Schristos char *arg;
65226945a25Schristos struct ether_addr *buf;
65326945a25Schristos {
65426945a25Schristos struct ether_addr *e;
65526945a25Schristos
65626945a25Schristos #if !defined(hpux) && !defined(linux)
65726945a25Schristos e = ether_aton(arg);
65826945a25Schristos if (!e)
65926945a25Schristos fprintf(stderr, "Invalid ethernet address: %s\n", arg);
66026945a25Schristos else
66126945a25Schristos # ifdef __FreeBSD__
66226945a25Schristos bcopy(e->octet, buf->octet, sizeof(e->octet));
66326945a25Schristos # else
66426945a25Schristos bcopy(e->ether_addr_octet, buf->ether_addr_octet,
66526945a25Schristos sizeof(e->ether_addr_octet));
66626945a25Schristos # endif
66726945a25Schristos return e;
66826945a25Schristos #else
66926945a25Schristos return NULL;
67026945a25Schristos #endif
67126945a25Schristos }
67226945a25Schristos
67326945a25Schristos
new_header(type)67426945a25Schristos void *new_header(type)
67526945a25Schristos int type;
67626945a25Schristos {
67726945a25Schristos aniphdr_t *aip, *oip = canip;
67826945a25Schristos int sz = 0;
67926945a25Schristos
68026945a25Schristos aip = (aniphdr_t *)calloc(1, sizeof(*aip));
68126945a25Schristos *aniptail = aip;
68226945a25Schristos aniptail = &aip->ah_next;
68326945a25Schristos aip->ah_p = type;
68426945a25Schristos aip->ah_prev = oip;
68526945a25Schristos canip = aip;
68626945a25Schristos
68726945a25Schristos if (type == IPPROTO_UDP)
68826945a25Schristos sz = sizeof(udphdr_t);
68926945a25Schristos else if (type == IPPROTO_TCP)
69026945a25Schristos sz = sizeof(tcphdr_t);
69126945a25Schristos else if (type == IPPROTO_ICMP)
69226945a25Schristos sz = sizeof(icmphdr_t);
69326945a25Schristos else if (type == IPPROTO_IP)
69426945a25Schristos sz = sizeof(ip_t);
69526945a25Schristos
69626945a25Schristos if (oip)
69726945a25Schristos canip->ah_data = oip->ah_data + oip->ah_len;
69826945a25Schristos else
69926945a25Schristos canip->ah_data = (char *)ipbuffer;
70026945a25Schristos
70126945a25Schristos /*
70226945a25Schristos * Increase the size fields in all wrapping headers.
70326945a25Schristos */
70426945a25Schristos for (aip = aniphead; aip; aip = aip->ah_next) {
70526945a25Schristos aip->ah_len += sz;
70626945a25Schristos if (aip->ah_p == IPPROTO_IP)
70726945a25Schristos aip->ah_ip->ip_len += sz;
70826945a25Schristos else if (aip->ah_p == IPPROTO_UDP)
70926945a25Schristos aip->ah_udp->uh_ulen += sz;
71026945a25Schristos }
71126945a25Schristos return (void *)canip->ah_data;
71226945a25Schristos }
71326945a25Schristos
71426945a25Schristos
free_aniplist()71526945a25Schristos void free_aniplist()
71626945a25Schristos {
71726945a25Schristos aniphdr_t *aip, **aipp = &aniphead;
71826945a25Schristos
71926945a25Schristos while ((aip = *aipp)) {
72026945a25Schristos *aipp = aip->ah_next;
72126945a25Schristos free(aip);
72226945a25Schristos }
72326945a25Schristos aniptail = &aniphead;
72426945a25Schristos }
72526945a25Schristos
72626945a25Schristos
inc_anipheaders(inc)72726945a25Schristos void inc_anipheaders(inc)
72826945a25Schristos int inc;
72926945a25Schristos {
73026945a25Schristos aniphdr_t *aip;
73126945a25Schristos
73226945a25Schristos for (aip = aniphead; aip; aip = aip->ah_next) {
73326945a25Schristos aip->ah_len += inc;
73426945a25Schristos if (aip->ah_p == IPPROTO_IP)
73526945a25Schristos aip->ah_ip->ip_len += inc;
73626945a25Schristos else if (aip->ah_p == IPPROTO_UDP)
73726945a25Schristos aip->ah_udp->uh_ulen += inc;
73826945a25Schristos }
73926945a25Schristos }
74026945a25Schristos
74126945a25Schristos
new_data()74226945a25Schristos void new_data()
74326945a25Schristos {
74426945a25Schristos (void) new_header(-1);
74526945a25Schristos canip->ah_len = 0;
74626945a25Schristos }
74726945a25Schristos
74826945a25Schristos
set_datalen(arg)74926945a25Schristos void set_datalen(arg)
75026945a25Schristos char **arg;
75126945a25Schristos {
75226945a25Schristos int len;
75326945a25Schristos
75426945a25Schristos len = strtol(*arg, NULL, 0);
75526945a25Schristos inc_anipheaders(len);
75626945a25Schristos free(*arg);
75726945a25Schristos *arg = NULL;
75826945a25Schristos }
75926945a25Schristos
76026945a25Schristos
set_data(arg)76126945a25Schristos void set_data(arg)
76226945a25Schristos char **arg;
76326945a25Schristos {
76426945a25Schristos u_char *s = (u_char *)*arg, *t = (u_char *)canip->ah_data, c;
76526945a25Schristos int len = 0, todo = 0, quote = 0, val = 0;
76626945a25Schristos
76726945a25Schristos while ((c = *s++)) {
76826945a25Schristos if (todo) {
76926945a25Schristos if (ISDIGIT(c)) {
77026945a25Schristos todo--;
77126945a25Schristos if (c > '7') {
77226945a25Schristos fprintf(stderr, "octal with %c!\n", c);
77326945a25Schristos break;
77426945a25Schristos }
77526945a25Schristos val <<= 3;
77626945a25Schristos val |= (c - '0');
77726945a25Schristos }
77826945a25Schristos if (!ISDIGIT(c) || !todo) {
77926945a25Schristos *t++ = (u_char)(val & 0xff);
78026945a25Schristos todo = 0;
78126945a25Schristos }
78226945a25Schristos if (todo)
78326945a25Schristos continue;
78426945a25Schristos }
78526945a25Schristos if (quote) {
78626945a25Schristos if (ISDIGIT(c)) {
78726945a25Schristos todo = 2;
78826945a25Schristos if (c > '7') {
78926945a25Schristos fprintf(stderr, "octal with %c!\n", c);
79026945a25Schristos break;
79126945a25Schristos }
79226945a25Schristos val = (c - '0');
79326945a25Schristos } else {
79426945a25Schristos switch (c)
79526945a25Schristos {
79626945a25Schristos case '\"' :
79726945a25Schristos *t++ = '\"';
79826945a25Schristos break;
79926945a25Schristos case '\\' :
80026945a25Schristos *t++ = '\\';
80126945a25Schristos break;
80226945a25Schristos case 'n' :
80326945a25Schristos *t++ = '\n';
80426945a25Schristos break;
80526945a25Schristos case 'r' :
80626945a25Schristos *t++ = '\r';
80726945a25Schristos break;
80826945a25Schristos case 't' :
80926945a25Schristos *t++ = '\t';
81026945a25Schristos break;
81126945a25Schristos }
81226945a25Schristos }
81326945a25Schristos quote = 0;
81426945a25Schristos continue;
81526945a25Schristos }
81626945a25Schristos
81726945a25Schristos if (c == '\\')
81826945a25Schristos quote = 1;
81926945a25Schristos else
82026945a25Schristos *t++ = c;
82126945a25Schristos }
82226945a25Schristos if (todo)
82326945a25Schristos *t++ = (u_char)(val & 0xff);
82426945a25Schristos if (quote)
82526945a25Schristos *t++ = '\\';
82626945a25Schristos len = t - (u_char *)canip->ah_data;
82726945a25Schristos inc_anipheaders(len - canip->ah_len);
82826945a25Schristos canip->ah_len = len;
82926945a25Schristos }
83026945a25Schristos
83126945a25Schristos
set_datafile(arg)83226945a25Schristos void set_datafile(arg)
83326945a25Schristos char **arg;
83426945a25Schristos {
83526945a25Schristos struct stat sb;
83626945a25Schristos char *file = *arg;
83726945a25Schristos int fd, len;
83826945a25Schristos
83926945a25Schristos if ((fd = open(file, O_RDONLY)) == -1) {
84026945a25Schristos perror("open");
84126945a25Schristos exit(-1);
84226945a25Schristos }
84326945a25Schristos
84426945a25Schristos if (fstat(fd, &sb) == -1) {
84526945a25Schristos perror("fstat");
84626945a25Schristos exit(-1);
84726945a25Schristos }
84826945a25Schristos
84926945a25Schristos if ((sb.st_size + aniphead->ah_len ) > 65535) {
85026945a25Schristos fprintf(stderr, "data file %s too big to include.\n", file);
85126945a25Schristos close(fd);
85226945a25Schristos return;
85326945a25Schristos }
85426945a25Schristos if ((len = read(fd, canip->ah_data, sb.st_size)) == -1) {
85526945a25Schristos perror("read");
85626945a25Schristos close(fd);
85726945a25Schristos return;
85826945a25Schristos }
85926945a25Schristos inc_anipheaders(len);
86026945a25Schristos canip->ah_len += len;
86126945a25Schristos close(fd);
86226945a25Schristos }
86326945a25Schristos
86426945a25Schristos
new_packet()86526945a25Schristos void new_packet()
86626945a25Schristos {
86726945a25Schristos static u_short id = 0;
86826945a25Schristos
86926945a25Schristos if (!aniphead)
87026945a25Schristos bzero((char *)ipbuffer, sizeof(ipbuffer));
87126945a25Schristos
87226945a25Schristos ip = (ip_t *)new_header(IPPROTO_IP);
87326945a25Schristos ip->ip_v = IPVERSION;
87426945a25Schristos ip->ip_hl = sizeof(ip_t) >> 2;
87526945a25Schristos ip->ip_len = sizeof(ip_t);
87626945a25Schristos ip->ip_ttl = 63;
87726945a25Schristos ip->ip_id = htons(id++);
87826945a25Schristos }
87926945a25Schristos
88026945a25Schristos
set_ipv4proto(arg)88126945a25Schristos void set_ipv4proto(arg)
88226945a25Schristos char **arg;
88326945a25Schristos {
88426945a25Schristos struct protoent *pr;
88526945a25Schristos
88626945a25Schristos if ((pr = getprotobyname(*arg)))
88726945a25Schristos ip->ip_p = pr->p_proto;
88826945a25Schristos else
88926945a25Schristos if (!(ip->ip_p = atoi(*arg)))
89026945a25Schristos fprintf(stderr, "unknown protocol %s\n", *arg);
89126945a25Schristos free(*arg);
89226945a25Schristos *arg = NULL;
89326945a25Schristos }
89426945a25Schristos
89526945a25Schristos
set_ipv4src(arg)89626945a25Schristos void set_ipv4src(arg)
89726945a25Schristos char **arg;
89826945a25Schristos {
89926945a25Schristos ip->ip_src = getipv4addr(*arg);
90026945a25Schristos free(*arg);
90126945a25Schristos *arg = NULL;
90226945a25Schristos }
90326945a25Schristos
90426945a25Schristos
set_ipv4dst(arg)90526945a25Schristos void set_ipv4dst(arg)
90626945a25Schristos char **arg;
90726945a25Schristos {
90826945a25Schristos ip->ip_dst = getipv4addr(*arg);
90926945a25Schristos free(*arg);
91026945a25Schristos *arg = NULL;
91126945a25Schristos }
91226945a25Schristos
91326945a25Schristos
set_ipv4off(arg)91426945a25Schristos void set_ipv4off(arg)
91526945a25Schristos char **arg;
91626945a25Schristos {
91726945a25Schristos ip->ip_off = htons(strtol(*arg, NULL, 0));
91826945a25Schristos free(*arg);
91926945a25Schristos *arg = NULL;
92026945a25Schristos }
92126945a25Schristos
92226945a25Schristos
set_ipv4v(arg)92326945a25Schristos void set_ipv4v(arg)
92426945a25Schristos char **arg;
92526945a25Schristos {
92626945a25Schristos ip->ip_v = strtol(*arg, NULL, 0);
92726945a25Schristos free(*arg);
92826945a25Schristos *arg = NULL;
92926945a25Schristos }
93026945a25Schristos
93126945a25Schristos
set_ipv4hl(arg)93226945a25Schristos void set_ipv4hl(arg)
93326945a25Schristos char **arg;
93426945a25Schristos {
93526945a25Schristos int newhl, inc;
93626945a25Schristos
93726945a25Schristos newhl = strtol(*arg, NULL, 0);
93826945a25Schristos inc = (newhl - ip->ip_hl) << 2;
93926945a25Schristos ip->ip_len += inc;
94026945a25Schristos ip->ip_hl = newhl;
94126945a25Schristos canip->ah_len += inc;
94226945a25Schristos free(*arg);
94326945a25Schristos *arg = NULL;
94426945a25Schristos }
94526945a25Schristos
94626945a25Schristos
set_ipv4ttl(arg)94726945a25Schristos void set_ipv4ttl(arg)
94826945a25Schristos char **arg;
94926945a25Schristos {
95026945a25Schristos ip->ip_ttl = strtol(*arg, NULL, 0);
95126945a25Schristos free(*arg);
95226945a25Schristos *arg = NULL;
95326945a25Schristos }
95426945a25Schristos
95526945a25Schristos
set_ipv4tos(arg)95626945a25Schristos void set_ipv4tos(arg)
95726945a25Schristos char **arg;
95826945a25Schristos {
95926945a25Schristos ip->ip_tos = strtol(*arg, NULL, 0);
96026945a25Schristos free(*arg);
96126945a25Schristos *arg = NULL;
96226945a25Schristos }
96326945a25Schristos
96426945a25Schristos
set_ipv4id(arg)96526945a25Schristos void set_ipv4id(arg)
96626945a25Schristos char **arg;
96726945a25Schristos {
96826945a25Schristos ip->ip_id = htons(strtol(*arg, NULL, 0));
96926945a25Schristos free(*arg);
97026945a25Schristos *arg = NULL;
97126945a25Schristos }
97226945a25Schristos
97326945a25Schristos
set_ipv4sum(arg)97426945a25Schristos void set_ipv4sum(arg)
97526945a25Schristos char **arg;
97626945a25Schristos {
97726945a25Schristos ip->ip_sum = strtol(*arg, NULL, 0);
97826945a25Schristos free(*arg);
97926945a25Schristos *arg = NULL;
98026945a25Schristos }
98126945a25Schristos
98226945a25Schristos
set_ipv4len(arg)98326945a25Schristos void set_ipv4len(arg)
98426945a25Schristos char **arg;
98526945a25Schristos {
98626945a25Schristos int len;
98726945a25Schristos
98826945a25Schristos len = strtol(*arg, NULL, 0);
98926945a25Schristos inc_anipheaders(len - ip->ip_len);
99026945a25Schristos ip->ip_len = len;
99126945a25Schristos free(*arg);
99226945a25Schristos *arg = NULL;
99326945a25Schristos }
99426945a25Schristos
99526945a25Schristos
new_tcpheader()99626945a25Schristos void new_tcpheader()
99726945a25Schristos {
99826945a25Schristos
99926945a25Schristos if ((ip->ip_p) && (ip->ip_p != IPPROTO_TCP)) {
100026945a25Schristos fprintf(stderr, "protocol %d specified with TCP!\n", ip->ip_p);
100126945a25Schristos return;
100226945a25Schristos }
100326945a25Schristos ip->ip_p = IPPROTO_TCP;
100426945a25Schristos
100526945a25Schristos tcp = (tcphdr_t *)new_header(IPPROTO_TCP);
100626945a25Schristos tcp->th_win = htons(4096);
100726945a25Schristos tcp->th_off = sizeof(*tcp) >> 2;
100826945a25Schristos }
100926945a25Schristos
101026945a25Schristos
set_tcpsport(arg)101126945a25Schristos void set_tcpsport(arg)
101226945a25Schristos char **arg;
101326945a25Schristos {
101426945a25Schristos u_short *port;
101526945a25Schristos char *pr;
101626945a25Schristos
101726945a25Schristos if (ip->ip_p == IPPROTO_UDP) {
101826945a25Schristos port = &udp->uh_sport;
101926945a25Schristos pr = "udp";
102026945a25Schristos } else {
102126945a25Schristos port = &tcp->th_sport;
102226945a25Schristos pr = "udp";
102326945a25Schristos }
102426945a25Schristos
102526945a25Schristos *port = getportnum(pr, *arg);
102626945a25Schristos free(*arg);
102726945a25Schristos *arg = NULL;
102826945a25Schristos }
102926945a25Schristos
103026945a25Schristos
set_tcpdport(arg)103126945a25Schristos void set_tcpdport(arg)
103226945a25Schristos char **arg;
103326945a25Schristos {
103426945a25Schristos u_short *port;
103526945a25Schristos char *pr;
103626945a25Schristos
103726945a25Schristos if (ip->ip_p == IPPROTO_UDP) {
103826945a25Schristos port = &udp->uh_dport;
103926945a25Schristos pr = "udp";
104026945a25Schristos } else {
104126945a25Schristos port = &tcp->th_dport;
104226945a25Schristos pr = "udp";
104326945a25Schristos }
104426945a25Schristos
104526945a25Schristos *port = getportnum(pr, *arg);
104626945a25Schristos free(*arg);
104726945a25Schristos *arg = NULL;
104826945a25Schristos }
104926945a25Schristos
105026945a25Schristos
set_tcpseq(arg)105126945a25Schristos void set_tcpseq(arg)
105226945a25Schristos char **arg;
105326945a25Schristos {
105426945a25Schristos tcp->th_seq = htonl(strtol(*arg, NULL, 0));
105526945a25Schristos free(*arg);
105626945a25Schristos *arg = NULL;
105726945a25Schristos }
105826945a25Schristos
105926945a25Schristos
set_tcpack(arg)106026945a25Schristos void set_tcpack(arg)
106126945a25Schristos char **arg;
106226945a25Schristos {
106326945a25Schristos tcp->th_ack = htonl(strtol(*arg, NULL, 0));
106426945a25Schristos free(*arg);
106526945a25Schristos *arg = NULL;
106626945a25Schristos }
106726945a25Schristos
106826945a25Schristos
set_tcpoff(arg)106926945a25Schristos void set_tcpoff(arg)
107026945a25Schristos char **arg;
107126945a25Schristos {
107226945a25Schristos int off;
107326945a25Schristos
107426945a25Schristos off = strtol(*arg, NULL, 0);
107526945a25Schristos inc_anipheaders((off - tcp->th_off) << 2);
107626945a25Schristos tcp->th_off = off;
107726945a25Schristos free(*arg);
107826945a25Schristos *arg = NULL;
107926945a25Schristos }
108026945a25Schristos
108126945a25Schristos
set_tcpurp(arg)108226945a25Schristos void set_tcpurp(arg)
108326945a25Schristos char **arg;
108426945a25Schristos {
108526945a25Schristos tcp->th_urp = htons(strtol(*arg, NULL, 0));
108626945a25Schristos free(*arg);
108726945a25Schristos *arg = NULL;
108826945a25Schristos }
108926945a25Schristos
109026945a25Schristos
set_tcpwin(arg)109126945a25Schristos void set_tcpwin(arg)
109226945a25Schristos char **arg;
109326945a25Schristos {
109426945a25Schristos tcp->th_win = htons(strtol(*arg, NULL, 0));
109526945a25Schristos free(*arg);
109626945a25Schristos *arg = NULL;
109726945a25Schristos }
109826945a25Schristos
109926945a25Schristos
set_tcpsum(arg)110026945a25Schristos void set_tcpsum(arg)
110126945a25Schristos char **arg;
110226945a25Schristos {
110326945a25Schristos tcp->th_sum = strtol(*arg, NULL, 0);
110426945a25Schristos free(*arg);
110526945a25Schristos *arg = NULL;
110626945a25Schristos }
110726945a25Schristos
110826945a25Schristos
set_tcpflags(arg)110926945a25Schristos void set_tcpflags(arg)
111026945a25Schristos char **arg;
111126945a25Schristos {
111226945a25Schristos static char flags[] = "ASURPF";
111326945a25Schristos static int flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH,
111426945a25Schristos TH_FIN } ;
111526945a25Schristos char *s, *t;
111626945a25Schristos
111726945a25Schristos for (s = *arg; *s; s++)
111826945a25Schristos if (!(t = strchr(flags, *s))) {
111926945a25Schristos if (s - *arg) {
112026945a25Schristos fprintf(stderr, "unknown TCP flag %c\n", *s);
112126945a25Schristos break;
112226945a25Schristos }
112326945a25Schristos tcp->th_flags = strtol(*arg, NULL, 0);
112426945a25Schristos break;
112526945a25Schristos } else
112626945a25Schristos tcp->th_flags |= flagv[t - flags];
112726945a25Schristos free(*arg);
112826945a25Schristos *arg = NULL;
112926945a25Schristos }
113026945a25Schristos
113126945a25Schristos
set_tcpopt(state,arg)113226945a25Schristos void set_tcpopt(state, arg)
113326945a25Schristos int state;
113426945a25Schristos char **arg;
113526945a25Schristos {
113626945a25Schristos u_char *s;
113726945a25Schristos int val, len, val2, pad, optval;
113826945a25Schristos
113926945a25Schristos if (arg && *arg)
114026945a25Schristos val = atoi(*arg);
114126945a25Schristos else
114226945a25Schristos val = 0;
114326945a25Schristos
114426945a25Schristos s = (u_char *)tcp + sizeof(*tcp) + canip->ah_optlen;
114526945a25Schristos switch (state)
114626945a25Schristos {
114726945a25Schristos case IL_TCPO_EOL :
114826945a25Schristos optval = 0;
114926945a25Schristos len = 1;
115026945a25Schristos break;
115126945a25Schristos case IL_TCPO_NOP :
115226945a25Schristos optval = 1;
115326945a25Schristos len = 1;
115426945a25Schristos break;
115526945a25Schristos case IL_TCPO_MSS :
115626945a25Schristos optval = 2;
115726945a25Schristos len = 4;
115826945a25Schristos break;
115926945a25Schristos case IL_TCPO_WSCALE :
116026945a25Schristos optval = 3;
116126945a25Schristos len = 3;
116226945a25Schristos break;
116326945a25Schristos case IL_TCPO_TS :
116426945a25Schristos optval = 8;
116526945a25Schristos len = 10;
116626945a25Schristos break;
116726945a25Schristos default :
116826945a25Schristos optval = 0;
116926945a25Schristos len = 0;
117026945a25Schristos break;
117126945a25Schristos }
117226945a25Schristos
117326945a25Schristos if (len > 1) {
117426945a25Schristos /*
117526945a25Schristos * prepend padding - if required.
117626945a25Schristos */
117726945a25Schristos if (len & 3)
117826945a25Schristos for (pad = 4 - (len & 3); pad; pad--) {
117926945a25Schristos *s++ = 1;
118026945a25Schristos canip->ah_optlen++;
118126945a25Schristos }
118226945a25Schristos /*
118326945a25Schristos * build tcp option
118426945a25Schristos */
118526945a25Schristos *s++ = (u_char)optval;
118626945a25Schristos *s++ = (u_char)len;
118726945a25Schristos if (len > 2) {
118826945a25Schristos if (len == 3) { /* 1 byte - char */
118926945a25Schristos *s++ = (u_char)val;
119026945a25Schristos } else if (len == 4) { /* 2 bytes - short */
119126945a25Schristos *s++ = (u_char)((val >> 8) & 0xff);
119226945a25Schristos *s++ = (u_char)(val & 0xff);
119326945a25Schristos } else if (len >= 6) { /* 4 bytes - long */
119426945a25Schristos val2 = htonl(val);
119526945a25Schristos bcopy((char *)&val2, s, 4);
119626945a25Schristos }
119726945a25Schristos s += (len - 2);
119826945a25Schristos }
119926945a25Schristos } else
120026945a25Schristos *s++ = (u_char)optval;
120126945a25Schristos
120226945a25Schristos canip->ah_lastopt = optval;
120326945a25Schristos canip->ah_optlen += len;
120426945a25Schristos
120526945a25Schristos if (arg && *arg) {
120626945a25Schristos free(*arg);
120726945a25Schristos *arg = NULL;
120826945a25Schristos }
120926945a25Schristos }
121026945a25Schristos
121126945a25Schristos
end_tcpopt()121226945a25Schristos void end_tcpopt()
121326945a25Schristos {
121426945a25Schristos int pad;
121526945a25Schristos char *s = (char *)tcp;
121626945a25Schristos
121726945a25Schristos s += sizeof(*tcp) + canip->ah_optlen;
121826945a25Schristos /*
121926945a25Schristos * pad out so that we have a multiple of 4 bytes in size fo the
122026945a25Schristos * options. make sure last byte is EOL.
122126945a25Schristos */
122226945a25Schristos if (canip->ah_optlen & 3) {
122326945a25Schristos if (canip->ah_lastopt != 1) {
122426945a25Schristos for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
122526945a25Schristos *s++ = 1;
122626945a25Schristos canip->ah_optlen++;
122726945a25Schristos }
122826945a25Schristos canip->ah_optlen++;
122926945a25Schristos } else {
123026945a25Schristos s -= 1;
123126945a25Schristos
123226945a25Schristos for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
123326945a25Schristos *s++ = 1;
123426945a25Schristos canip->ah_optlen++;
123526945a25Schristos }
123626945a25Schristos }
123726945a25Schristos *s++ = 0;
123826945a25Schristos }
123926945a25Schristos tcp->th_off = (sizeof(*tcp) + canip->ah_optlen) >> 2;
124026945a25Schristos inc_anipheaders(canip->ah_optlen);
124126945a25Schristos }
124226945a25Schristos
124326945a25Schristos
new_udpheader()124426945a25Schristos void new_udpheader()
124526945a25Schristos {
124626945a25Schristos if ((ip->ip_p) && (ip->ip_p != IPPROTO_UDP)) {
124726945a25Schristos fprintf(stderr, "protocol %d specified with UDP!\n", ip->ip_p);
124826945a25Schristos return;
124926945a25Schristos }
125026945a25Schristos ip->ip_p = IPPROTO_UDP;
125126945a25Schristos
125226945a25Schristos udp = (udphdr_t *)new_header(IPPROTO_UDP);
125326945a25Schristos udp->uh_ulen = sizeof(*udp);
125426945a25Schristos }
125526945a25Schristos
125626945a25Schristos
set_udplen(arg)125726945a25Schristos void set_udplen(arg)
125826945a25Schristos char **arg;
125926945a25Schristos {
126026945a25Schristos int len;
126126945a25Schristos
126226945a25Schristos len = strtol(*arg, NULL, 0);
126326945a25Schristos inc_anipheaders(len - udp->uh_ulen);
126426945a25Schristos udp->uh_ulen = len;
126526945a25Schristos free(*arg);
126626945a25Schristos *arg = NULL;
126726945a25Schristos }
126826945a25Schristos
126926945a25Schristos
set_udpsum(arg)127026945a25Schristos void set_udpsum(arg)
127126945a25Schristos char **arg;
127226945a25Schristos {
127326945a25Schristos udp->uh_sum = strtol(*arg, NULL, 0);
127426945a25Schristos free(*arg);
127526945a25Schristos *arg = NULL;
127626945a25Schristos }
127726945a25Schristos
127826945a25Schristos
prep_packet()127926945a25Schristos void prep_packet()
128026945a25Schristos {
128126945a25Schristos iface_t *ifp;
128226945a25Schristos struct in_addr gwip;
128326945a25Schristos
128426945a25Schristos ifp = sending.snd_if;
128526945a25Schristos if (!ifp) {
128626945a25Schristos fprintf(stderr, "no interface defined for sending!\n");
128726945a25Schristos return;
128826945a25Schristos }
128926945a25Schristos if (ifp->if_fd == -1)
129026945a25Schristos ifp->if_fd = initdevice(ifp->if_name, 5);
129126945a25Schristos gwip = sending.snd_gw;
129226945a25Schristos if (!gwip.s_addr) {
129326945a25Schristos if (aniphead == NULL) {
129426945a25Schristos fprintf(stderr,
129526945a25Schristos "no destination address defined for sending\n");
129626945a25Schristos return;
129726945a25Schristos }
129826945a25Schristos gwip = aniphead->ah_ip->ip_dst;
129926945a25Schristos }
130026945a25Schristos (void) send_ip(ifp->if_fd, ifp->if_MTU, (ip_t *)ipbuffer, gwip, 2);
130126945a25Schristos }
130226945a25Schristos
130326945a25Schristos
packet_done()130426945a25Schristos void packet_done()
130526945a25Schristos {
130626945a25Schristos char outline[80];
130726945a25Schristos int i, j, k;
130826945a25Schristos u_char *s = (u_char *)ipbuffer, *t = (u_char *)outline;
130926945a25Schristos
131026945a25Schristos if (opts & OPT_VERBOSE) {
131126945a25Schristos ip->ip_len = htons(ip->ip_len);
131226945a25Schristos for (i = ntohs(ip->ip_len), j = 0; i; i--, j++, s++) {
131326945a25Schristos if (j && !(j & 0xf)) {
131426945a25Schristos *t++ = '\n';
131526945a25Schristos *t = '\0';
131626945a25Schristos fputs(outline, stdout);
131726945a25Schristos fflush(stdout);
131826945a25Schristos t = (u_char *)outline;
131926945a25Schristos *t = '\0';
132026945a25Schristos }
132126945a25Schristos sprintf((char *)t, "%02x", *s & 0xff);
132226945a25Schristos t += 2;
132326945a25Schristos if (!((j + 1) & 0xf)) {
132426945a25Schristos s -= 15;
132526945a25Schristos sprintf((char *)t, " ");
132626945a25Schristos t += 8;
132726945a25Schristos for (k = 16; k; k--, s++)
1328c50c2f6fSdarrenr *t++ = (isprint(*s) ? *s : '.');
132926945a25Schristos s--;
133026945a25Schristos }
133126945a25Schristos
133226945a25Schristos if ((j + 1) & 0xf)
133326945a25Schristos *t++ = ' ';;
133426945a25Schristos }
133526945a25Schristos
133626945a25Schristos if (j & 0xf) {
133726945a25Schristos for (k = 16 - (j & 0xf); k; k--) {
133826945a25Schristos *t++ = ' ';
133926945a25Schristos *t++ = ' ';
134026945a25Schristos *t++ = ' ';
134126945a25Schristos }
134226945a25Schristos sprintf((char *)t, " ");
134326945a25Schristos t += 7;
134426945a25Schristos s -= j & 0xf;
134526945a25Schristos for (k = j & 0xf; k; k--, s++)
1346c50c2f6fSdarrenr *t++ = (isprint(*s) ? *s : '.');
134726945a25Schristos *t++ = '\n';
134826945a25Schristos *t = '\0';
134926945a25Schristos }
135026945a25Schristos fputs(outline, stdout);
135126945a25Schristos fflush(stdout);
135226945a25Schristos ip->ip_len = ntohs(ip->ip_len);
135326945a25Schristos }
135426945a25Schristos
135526945a25Schristos prep_packet();
135626945a25Schristos free_aniplist();
135726945a25Schristos }
135826945a25Schristos
135926945a25Schristos
new_interface()136026945a25Schristos void new_interface()
136126945a25Schristos {
136226945a25Schristos cifp = (iface_t *)calloc(1, sizeof(iface_t));
136326945a25Schristos *iftail = cifp;
136426945a25Schristos iftail = &cifp->if_next;
136526945a25Schristos cifp->if_fd = -1;
136626945a25Schristos }
136726945a25Schristos
136826945a25Schristos
check_interface()136926945a25Schristos void check_interface()
137026945a25Schristos {
137126945a25Schristos if (!cifp->if_name || !*cifp->if_name)
137226945a25Schristos fprintf(stderr, "No interface name given!\n");
137326945a25Schristos if (!cifp->if_MTU || !*cifp->if_name)
137426945a25Schristos fprintf(stderr, "Interface %s has an MTU of 0!\n",
137526945a25Schristos cifp->if_name);
137626945a25Schristos }
137726945a25Schristos
137826945a25Schristos
set_ifname(arg)137926945a25Schristos void set_ifname(arg)
138026945a25Schristos char **arg;
138126945a25Schristos {
138226945a25Schristos cifp->if_name = *arg;
138326945a25Schristos *arg = NULL;
138426945a25Schristos }
138526945a25Schristos
138626945a25Schristos
set_ifmtu(arg)138726945a25Schristos void set_ifmtu(arg)
138826945a25Schristos int arg;
138926945a25Schristos {
139026945a25Schristos cifp->if_MTU = arg;
139126945a25Schristos }
139226945a25Schristos
139326945a25Schristos
set_ifv4addr(arg)139426945a25Schristos void set_ifv4addr(arg)
139526945a25Schristos char **arg;
139626945a25Schristos {
139726945a25Schristos cifp->if_addr = getipv4addr(*arg);
139826945a25Schristos free(*arg);
139926945a25Schristos *arg = NULL;
140026945a25Schristos }
140126945a25Schristos
140226945a25Schristos
set_ifeaddr(arg)140326945a25Schristos void set_ifeaddr(arg)
140426945a25Schristos char **arg;
140526945a25Schristos {
140626945a25Schristos (void) geteaddr(*arg, &cifp->if_eaddr);
140726945a25Schristos free(*arg);
140826945a25Schristos *arg = NULL;
140926945a25Schristos }
141026945a25Schristos
141126945a25Schristos
new_arp()141226945a25Schristos void new_arp()
141326945a25Schristos {
141426945a25Schristos carp = (arp_t *)calloc(1, sizeof(arp_t));
141526945a25Schristos *arptail = carp;
141626945a25Schristos arptail = &carp->arp_next;
141726945a25Schristos }
141826945a25Schristos
141926945a25Schristos
set_arpeaddr(arg)142026945a25Schristos void set_arpeaddr(arg)
142126945a25Schristos char **arg;
142226945a25Schristos {
142326945a25Schristos (void) geteaddr(*arg, &carp->arp_eaddr);
142426945a25Schristos free(*arg);
142526945a25Schristos *arg = NULL;
142626945a25Schristos }
142726945a25Schristos
142826945a25Schristos
set_arpv4addr(arg)142926945a25Schristos void set_arpv4addr(arg)
143026945a25Schristos char **arg;
143126945a25Schristos {
143226945a25Schristos carp->arp_addr = getipv4addr(*arg);
143326945a25Schristos free(*arg);
143426945a25Schristos *arg = NULL;
143526945a25Schristos }
143626945a25Schristos
143726945a25Schristos
arp_getipv4(ip,addr)143826945a25Schristos int arp_getipv4(ip, addr)
143926945a25Schristos char *ip;
144026945a25Schristos char *addr;
144126945a25Schristos {
144226945a25Schristos arp_t *a;
144326945a25Schristos
144426945a25Schristos for (a = arplist; a; a = a->arp_next)
144526945a25Schristos if (!bcmp(ip, (char *)&a->arp_addr, 4)) {
144626945a25Schristos bcopy((char *)&a->arp_eaddr, addr, 6);
144726945a25Schristos return 0;
144826945a25Schristos }
144926945a25Schristos return -1;
145026945a25Schristos }
145126945a25Schristos
145226945a25Schristos
reset_send()145326945a25Schristos void reset_send()
145426945a25Schristos {
145526945a25Schristos sending.snd_if = iflist;
145626945a25Schristos sending.snd_gw = defrouter;
145726945a25Schristos }
145826945a25Schristos
145926945a25Schristos
set_sendif(arg)146026945a25Schristos void set_sendif(arg)
146126945a25Schristos char **arg;
146226945a25Schristos {
146326945a25Schristos iface_t *ifp;
146426945a25Schristos
146526945a25Schristos for (ifp = iflist; ifp; ifp = ifp->if_next)
146626945a25Schristos if (ifp->if_name && !strcmp(ifp->if_name, *arg))
146726945a25Schristos break;
146826945a25Schristos sending.snd_if = ifp;
146926945a25Schristos if (!ifp)
147026945a25Schristos fprintf(stderr, "couldn't find interface %s\n", *arg);
147126945a25Schristos free(*arg);
147226945a25Schristos *arg = NULL;
147326945a25Schristos }
147426945a25Schristos
147526945a25Schristos
set_sendvia(arg)147626945a25Schristos void set_sendvia(arg)
147726945a25Schristos char **arg;
147826945a25Schristos {
147926945a25Schristos sending.snd_gw = getipv4addr(*arg);
148026945a25Schristos free(*arg);
148126945a25Schristos *arg = NULL;
148226945a25Schristos }
148326945a25Schristos
148426945a25Schristos
set_defaultrouter(arg)148526945a25Schristos void set_defaultrouter(arg)
148626945a25Schristos char **arg;
148726945a25Schristos {
148826945a25Schristos defrouter = getipv4addr(*arg);
148926945a25Schristos free(*arg);
149026945a25Schristos *arg = NULL;
149126945a25Schristos }
149226945a25Schristos
149326945a25Schristos
new_icmpheader()149426945a25Schristos void new_icmpheader()
149526945a25Schristos {
149626945a25Schristos if ((ip->ip_p) && (ip->ip_p != IPPROTO_ICMP)) {
149726945a25Schristos fprintf(stderr, "protocol %d specified with ICMP!\n",
149826945a25Schristos ip->ip_p);
149926945a25Schristos return;
150026945a25Schristos }
150126945a25Schristos ip->ip_p = IPPROTO_ICMP;
150226945a25Schristos icmp = (icmphdr_t *)new_header(IPPROTO_ICMP);
150326945a25Schristos }
150426945a25Schristos
150526945a25Schristos
set_icmpcode(code)150626945a25Schristos void set_icmpcode(code)
150726945a25Schristos int code;
150826945a25Schristos {
150926945a25Schristos icmp->icmp_code = code;
151026945a25Schristos }
151126945a25Schristos
151226945a25Schristos
set_icmptype(type)151326945a25Schristos void set_icmptype(type)
151426945a25Schristos int type;
151526945a25Schristos {
151626945a25Schristos icmp->icmp_type = type;
151726945a25Schristos }
151826945a25Schristos
151926945a25Schristos
set_icmpcodetok(code)152026945a25Schristos void set_icmpcodetok(code)
152126945a25Schristos char **code;
152226945a25Schristos {
152326945a25Schristos char *s;
152426945a25Schristos int i;
152526945a25Schristos
152626945a25Schristos for (i = 0; (s = icmpcodes[i]); i++)
152726945a25Schristos if (!strcmp(s, *code)) {
152826945a25Schristos icmp->icmp_code = i;
152926945a25Schristos break;
153026945a25Schristos }
153126945a25Schristos if (!s)
153226945a25Schristos fprintf(stderr, "unknown ICMP code %s\n", *code);
153326945a25Schristos free(*code);
153426945a25Schristos *code = NULL;
153526945a25Schristos }
153626945a25Schristos
153726945a25Schristos
set_icmptypetok(type)153826945a25Schristos void set_icmptypetok(type)
153926945a25Schristos char **type;
154026945a25Schristos {
154126945a25Schristos char *s;
154226945a25Schristos int i, done = 0;
154326945a25Schristos
154426945a25Schristos for (i = 0; !(s = icmptypes[i]) || strcmp(s, "END"); i++)
154526945a25Schristos if (s && !strcmp(s, *type)) {
154626945a25Schristos icmp->icmp_type = i;
154726945a25Schristos done = 1;
154826945a25Schristos break;
154926945a25Schristos }
155026945a25Schristos if (!done)
155126945a25Schristos fprintf(stderr, "unknown ICMP type %s\n", *type);
155226945a25Schristos free(*type);
155326945a25Schristos *type = NULL;
155426945a25Schristos }
155526945a25Schristos
155626945a25Schristos
set_icmpid(arg)155726945a25Schristos void set_icmpid(arg)
155826945a25Schristos int arg;
155926945a25Schristos {
156026945a25Schristos icmp->icmp_id = htons(arg);
156126945a25Schristos }
156226945a25Schristos
156326945a25Schristos
set_icmpseq(arg)156426945a25Schristos void set_icmpseq(arg)
156526945a25Schristos int arg;
156626945a25Schristos {
156726945a25Schristos icmp->icmp_seq = htons(arg);
156826945a25Schristos }
156926945a25Schristos
157026945a25Schristos
set_icmpotime(arg)157126945a25Schristos void set_icmpotime(arg)
157226945a25Schristos int arg;
157326945a25Schristos {
157426945a25Schristos icmp->icmp_otime = htonl(arg);
157526945a25Schristos }
157626945a25Schristos
157726945a25Schristos
set_icmprtime(arg)157826945a25Schristos void set_icmprtime(arg)
157926945a25Schristos int arg;
158026945a25Schristos {
158126945a25Schristos icmp->icmp_rtime = htonl(arg);
158226945a25Schristos }
158326945a25Schristos
158426945a25Schristos
set_icmpttime(arg)158526945a25Schristos void set_icmpttime(arg)
158626945a25Schristos int arg;
158726945a25Schristos {
158826945a25Schristos icmp->icmp_ttime = htonl(arg);
158926945a25Schristos }
159026945a25Schristos
159126945a25Schristos
set_icmpmtu(arg)159226945a25Schristos void set_icmpmtu(arg)
159326945a25Schristos int arg;
159426945a25Schristos {
159526945a25Schristos #if BSD >= 199306
159626945a25Schristos icmp->icmp_nextmtu = htons(arg);
159726945a25Schristos #endif
159826945a25Schristos }
159926945a25Schristos
160026945a25Schristos
set_redir(redir,arg)160126945a25Schristos void set_redir(redir, arg)
160226945a25Schristos int redir;
160326945a25Schristos char **arg;
160426945a25Schristos {
160526945a25Schristos icmp->icmp_code = redir;
160626945a25Schristos icmp->icmp_gwaddr = getipv4addr(*arg);
160726945a25Schristos free(*arg);
160826945a25Schristos *arg = NULL;
160926945a25Schristos }
161026945a25Schristos
161126945a25Schristos
set_icmppprob(num)161226945a25Schristos void set_icmppprob(num)
161326945a25Schristos int num;
161426945a25Schristos {
161526945a25Schristos icmp->icmp_pptr = num;
161626945a25Schristos }
161726945a25Schristos
161826945a25Schristos
new_ipv4opt()161926945a25Schristos void new_ipv4opt()
162026945a25Schristos {
162126945a25Schristos new_header(-2);
162226945a25Schristos }
162326945a25Schristos
162426945a25Schristos
add_ipopt(state,ptr)162526945a25Schristos void add_ipopt(state, ptr)
162626945a25Schristos int state;
162726945a25Schristos void *ptr;
162826945a25Schristos {
162926945a25Schristos struct ipopt_names *io;
163026945a25Schristos struct statetoopt *sto;
163126945a25Schristos char numbuf[16], *arg, **param = ptr;
163226945a25Schristos int inc, hlen;
163326945a25Schristos
163426945a25Schristos if (state == IL_IPO_RR || state == IL_IPO_SATID) {
163526945a25Schristos if (param)
163626945a25Schristos sprintf(numbuf, "%d", *(int *)param);
163726945a25Schristos else
163826945a25Schristos strcpy(numbuf, "0");
163926945a25Schristos arg = numbuf;
164026945a25Schristos } else
164126945a25Schristos arg = param ? *param : NULL;
164226945a25Schristos
164326945a25Schristos if (canip->ah_next) {
164426945a25Schristos fprintf(stderr, "cannot specify options after data body\n");
164526945a25Schristos return;
164626945a25Schristos }
164726945a25Schristos for (sto = toipopts; sto->sto_st; sto++)
164826945a25Schristos if (sto->sto_st == state)
164926945a25Schristos break;
165026945a25Schristos if (!sto->sto_st) {
165126945a25Schristos fprintf(stderr, "No mapping for state %d to IP option\n",
165226945a25Schristos state);
165326945a25Schristos return;
165426945a25Schristos }
165526945a25Schristos
165626945a25Schristos hlen = sizeof(ip_t) + canip->ah_optlen;
165726945a25Schristos for (io = ionames; io->on_name; io++)
165826945a25Schristos if (io->on_value == sto->sto_op)
165926945a25Schristos break;
166026945a25Schristos canip->ah_lastopt = io->on_value;
166126945a25Schristos
166226945a25Schristos if (io->on_name) {
166326945a25Schristos inc = addipopt((char *)ip + hlen, io, hlen - sizeof(ip_t),arg);
166426945a25Schristos if (inc > 0) {
166526945a25Schristos while (inc & 3) {
166626945a25Schristos ((char *)ip)[sizeof(*ip) + inc] = IPOPT_NOP;
166726945a25Schristos canip->ah_lastopt = IPOPT_NOP;
166826945a25Schristos inc++;
166926945a25Schristos }
167026945a25Schristos hlen += inc;
167126945a25Schristos }
167226945a25Schristos }
167326945a25Schristos
167426945a25Schristos canip->ah_optlen = hlen - sizeof(ip_t);
167526945a25Schristos
167626945a25Schristos if (state != IL_IPO_RR && state != IL_IPO_SATID)
167726945a25Schristos if (param && *param) {
167826945a25Schristos free(*param);
167926945a25Schristos *param = NULL;
168026945a25Schristos }
168126945a25Schristos sclass = NULL;
168226945a25Schristos }
168326945a25Schristos
168426945a25Schristos
end_ipopt()168526945a25Schristos void end_ipopt()
168626945a25Schristos {
168726945a25Schristos int pad;
168826945a25Schristos char *s, *buf = (char *)ip;
168926945a25Schristos
169026945a25Schristos /*
169126945a25Schristos * pad out so that we have a multiple of 4 bytes in size fo the
169226945a25Schristos * options. make sure last byte is EOL.
169326945a25Schristos */
169426945a25Schristos if (canip->ah_lastopt == IPOPT_NOP) {
169526945a25Schristos buf[sizeof(*ip) + canip->ah_optlen - 1] = IPOPT_EOL;
169626945a25Schristos } else if (canip->ah_lastopt != IPOPT_EOL) {
169726945a25Schristos s = buf + sizeof(*ip) + canip->ah_optlen;
169826945a25Schristos
169926945a25Schristos for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
170026945a25Schristos *s++ = IPOPT_NOP;
170126945a25Schristos *s = IPOPT_EOL;
170226945a25Schristos canip->ah_optlen++;
170326945a25Schristos }
170426945a25Schristos canip->ah_optlen++;
170526945a25Schristos } else {
170626945a25Schristos s = buf + sizeof(*ip) + canip->ah_optlen - 1;
170726945a25Schristos
170826945a25Schristos for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
170926945a25Schristos *s++ = IPOPT_NOP;
171026945a25Schristos *s = IPOPT_EOL;
171126945a25Schristos canip->ah_optlen++;
171226945a25Schristos }
171326945a25Schristos }
171426945a25Schristos ip->ip_hl = (sizeof(*ip) + canip->ah_optlen) >> 2;
171526945a25Schristos inc_anipheaders(canip->ah_optlen);
171626945a25Schristos free_anipheader();
171726945a25Schristos }
171826945a25Schristos
171926945a25Schristos
set_secclass(arg)172026945a25Schristos void set_secclass(arg)
172126945a25Schristos char **arg;
172226945a25Schristos {
172326945a25Schristos sclass = *arg;
172426945a25Schristos *arg = NULL;
172526945a25Schristos }
172626945a25Schristos
172726945a25Schristos
free_anipheader()172826945a25Schristos void free_anipheader()
172926945a25Schristos {
173026945a25Schristos aniphdr_t *aip;
173126945a25Schristos
173226945a25Schristos aip = canip;
173326945a25Schristos if ((canip = aip->ah_prev)) {
173426945a25Schristos canip->ah_next = NULL;
173526945a25Schristos aniptail = &canip->ah_next;
173626945a25Schristos }
173726945a25Schristos
173826945a25Schristos if (canip)
173926945a25Schristos free(aip);
174026945a25Schristos }
174126945a25Schristos
174226945a25Schristos
end_ipv4()174326945a25Schristos void end_ipv4()
174426945a25Schristos {
174526945a25Schristos aniphdr_t *aip;
174626945a25Schristos
174726945a25Schristos ip->ip_sum = 0;
174826945a25Schristos ip->ip_len = htons(ip->ip_len);
174926945a25Schristos ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2);
175026945a25Schristos ip->ip_len = ntohs(ip->ip_len);
175126945a25Schristos free_anipheader();
175226945a25Schristos for (aip = aniphead, ip = NULL; aip; aip = aip->ah_next)
175326945a25Schristos if (aip->ah_p == IPPROTO_IP)
175426945a25Schristos ip = aip->ah_ip;
175526945a25Schristos }
175626945a25Schristos
175726945a25Schristos
end_icmp()175826945a25Schristos void end_icmp()
175926945a25Schristos {
176026945a25Schristos aniphdr_t *aip;
176126945a25Schristos
176226945a25Schristos icmp->icmp_cksum = 0;
176326945a25Schristos icmp->icmp_cksum = chksum((u_short *)icmp, canip->ah_len);
176426945a25Schristos free_anipheader();
176526945a25Schristos for (aip = aniphead, icmp = NULL; aip; aip = aip->ah_next)
176626945a25Schristos if (aip->ah_p == IPPROTO_ICMP)
176726945a25Schristos icmp = aip->ah_icmp;
176826945a25Schristos }
176926945a25Schristos
177026945a25Schristos
end_udp()177126945a25Schristos void end_udp()
177226945a25Schristos {
177326945a25Schristos u_long sum;
177426945a25Schristos aniphdr_t *aip;
177526945a25Schristos ip_t iptmp;
177626945a25Schristos
177726945a25Schristos bzero((char *)&iptmp, sizeof(iptmp));
177826945a25Schristos iptmp.ip_p = ip->ip_p;
177926945a25Schristos iptmp.ip_src = ip->ip_src;
178026945a25Schristos iptmp.ip_dst = ip->ip_dst;
178126945a25Schristos iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2));
178226945a25Schristos sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp));
178326945a25Schristos udp->uh_ulen = htons(udp->uh_ulen);
178426945a25Schristos udp->uh_sum = c_chksum((u_short *)udp, (u_int)ntohs(iptmp.ip_len), sum);
178526945a25Schristos free_anipheader();
178626945a25Schristos for (aip = aniphead, udp = NULL; aip; aip = aip->ah_next)
178726945a25Schristos if (aip->ah_p == IPPROTO_UDP)
178826945a25Schristos udp = aip->ah_udp;
178926945a25Schristos }
179026945a25Schristos
179126945a25Schristos
end_tcp()179226945a25Schristos void end_tcp()
179326945a25Schristos {
179426945a25Schristos u_long sum;
179526945a25Schristos aniphdr_t *aip;
179626945a25Schristos ip_t iptmp;
179726945a25Schristos
179826945a25Schristos bzero((char *)&iptmp, sizeof(iptmp));
179926945a25Schristos iptmp.ip_p = ip->ip_p;
180026945a25Schristos iptmp.ip_src = ip->ip_src;
180126945a25Schristos iptmp.ip_dst = ip->ip_dst;
180226945a25Schristos iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2));
180326945a25Schristos sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp));
180426945a25Schristos tcp->th_sum = 0;
180526945a25Schristos tcp->th_sum = c_chksum((u_short *)tcp, (u_int)ntohs(iptmp.ip_len), sum);
180626945a25Schristos free_anipheader();
180726945a25Schristos for (aip = aniphead, tcp = NULL; aip; aip = aip->ah_next)
180826945a25Schristos if (aip->ah_p == IPPROTO_TCP)
180926945a25Schristos tcp = aip->ah_tcp;
181026945a25Schristos }
181126945a25Schristos
181226945a25Schristos
end_data()181326945a25Schristos void end_data()
181426945a25Schristos {
181526945a25Schristos free_anipheader();
181626945a25Schristos }
181726945a25Schristos
181826945a25Schristos
iplang(fp)181926945a25Schristos void iplang(fp)
182026945a25Schristos FILE *fp;
182126945a25Schristos {
182226945a25Schristos yyin = fp;
182326945a25Schristos
182426945a25Schristos yydebug = (opts & OPT_DEBUG) ? 1 : 0;
182526945a25Schristos
182626945a25Schristos while (!feof(fp))
182726945a25Schristos yyparse();
182826945a25Schristos }
182926945a25Schristos
183026945a25Schristos
c_chksum(buf,len,init)183126945a25Schristos u_short c_chksum(buf, len, init)
183226945a25Schristos u_short *buf;
183326945a25Schristos u_int len;
183426945a25Schristos u_long init;
183526945a25Schristos {
183626945a25Schristos u_long sum = init;
183726945a25Schristos int nwords = len >> 1;
183826945a25Schristos
183926945a25Schristos for(; nwords > 0; nwords--)
184026945a25Schristos sum += *buf++;
184126945a25Schristos sum = (sum>>16) + (sum & 0xffff);
184226945a25Schristos sum += (sum >>16);
184326945a25Schristos return (~sum);
184426945a25Schristos }
184526945a25Schristos
184626945a25Schristos
p_chksum(buf,len)184726945a25Schristos u_long p_chksum(buf,len)
184826945a25Schristos u_short *buf;
184926945a25Schristos u_int len;
185026945a25Schristos {
185126945a25Schristos u_long sum = 0;
185226945a25Schristos int nwords = len >> 1;
185326945a25Schristos
185426945a25Schristos for(; nwords > 0; nwords--)
185526945a25Schristos sum += *buf++;
185626945a25Schristos return sum;
185726945a25Schristos }
1858