diff --git a/contrib/ipfilter/iplang/iplang_y.y b/contrib/ipfilter/iplang/iplang_y.y index 98c8f1a983ea..f223b1eb8b32 100644 --- a/contrib/ipfilter/iplang/iplang_y.y +++ b/contrib/ipfilter/iplang/iplang_y.y @@ -1,1858 +1,1849 @@ /* $FreeBSD$ */ %{ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Id: iplang_y.y,v 2.9.2.4 2006/03/17 12:11:29 darrenr Exp $ * $FreeBSD$ */ #include #include #include #if !defined(__SVR4) && !defined(__svr4__) # include #else # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifndef linux # include # include # include #endif #include #include #include #include #include #include "ipsend.h" #include "ip_compat.h" #include "ipf.h" #include "iplang.h" -#if !defined(__NetBSD__) && (!defined(__FreeBSD_version) && \ - __FreeBSD_version < 400020) && (!SOLARIS || SOLARIS2 < 10) -extern struct ether_addr *ether_aton __P((char *)); -#endif - extern int opts; extern struct ipopt_names ionames[]; extern int state, state, lineNum, token; extern int yylineno; extern char yytext[]; extern FILE *yyin; int yylex __P((void)); #define YYDEBUG 1 -#if !defined(ultrix) && !defined(hpux) int yydebug = 1; -#else -extern int yydebug; -#endif iface_t *iflist = NULL, **iftail = &iflist; iface_t *cifp = NULL; arp_t *arplist = NULL, **arptail = &arplist, *carp = NULL; struct in_addr defrouter; send_t sending; char *sclass = NULL; u_short c_chksum __P((u_short *, u_int, u_long)); u_long p_chksum __P((u_short *, u_int)); u_long ipbuffer[67584/sizeof(u_long)]; /* 66K */ aniphdr_t *aniphead = NULL, *canip = NULL, **aniptail = &aniphead; ip_t *ip = NULL; udphdr_t *udp = NULL; tcphdr_t *tcp = NULL; icmphdr_t *icmp = NULL; struct statetoopt { int sto_st; int sto_op; }; struct in_addr getipv4addr __P((char *arg)); u_short getportnum __P((char *, char *)); struct ether_addr *geteaddr __P((char *, struct ether_addr *)); void *new_header __P((int)); void free_aniplist __P((void)); void inc_anipheaders __P((int)); void new_data __P((void)); void set_datalen __P((char **)); void set_datafile __P((char **)); void set_data __P((char **)); void new_packet __P((void)); void set_ipv4proto __P((char **)); void set_ipv4src __P((char **)); void set_ipv4dst __P((char **)); void set_ipv4off __P((char **)); void set_ipv4v __P((char **)); void set_ipv4hl __P((char **)); void set_ipv4ttl __P((char **)); void set_ipv4tos __P((char **)); void set_ipv4id __P((char **)); void set_ipv4sum __P((char **)); void set_ipv4len __P((char **)); void new_tcpheader __P((void)); void set_tcpsport __P((char **)); void set_tcpdport __P((char **)); void set_tcpseq __P((char **)); void set_tcpack __P((char **)); void set_tcpoff __P((char **)); void set_tcpurp __P((char **)); void set_tcpwin __P((char **)); void set_tcpsum __P((char **)); void set_tcpflags __P((char **)); void set_tcpopt __P((int, char **)); void end_tcpopt __P((void)); void new_udpheader __P((void)); void set_udplen __P((char **)); void set_udpsum __P((char **)); void prep_packet __P((void)); void packet_done __P((void)); void new_interface __P((void)); void check_interface __P((void)); void set_ifname __P((char **)); void set_ifmtu __P((int)); void set_ifv4addr __P((char **)); void set_ifeaddr __P((char **)); void new_arp __P((void)); void set_arpeaddr __P((char **)); void set_arpv4addr __P((char **)); void reset_send __P((void)); void set_sendif __P((char **)); void set_sendvia __P((char **)); void set_defaultrouter __P((char **)); void new_icmpheader __P((void)); void set_icmpcode __P((int)); void set_icmptype __P((int)); void set_icmpcodetok __P((char **)); void set_icmptypetok __P((char **)); void set_icmpid __P((int)); void set_icmpseq __P((int)); void set_icmpotime __P((int)); void set_icmprtime __P((int)); void set_icmpttime __P((int)); void set_icmpmtu __P((int)); void set_redir __P((int, char **)); void new_ipv4opt __P((void)); void set_icmppprob __P((int)); void add_ipopt __P((int, void *)); void end_ipopt __P((void)); void set_secclass __P((char **)); void free_anipheader __P((void)); void end_ipv4 __P((void)); void end_icmp __P((void)); void end_udp __P((void)); void end_tcp __P((void)); void end_data __P((void)); void yyerror __P((char *)); void iplang __P((FILE *)); int arp_getipv4 __P((char *, char *)); int yyparse __P((void)); %} %union { char *str; int num; } %token IL_NUMBER %type number digits optnumber %token IL_TOKEN %type token optoken %token IL_HEXDIGIT IL_COLON IL_DOT IL_EOF IL_COMMENT %token IL_INTERFACE IL_IFNAME IL_MTU IL_EADDR %token IL_IPV4 IL_V4PROTO IL_V4SRC IL_V4DST IL_V4OFF IL_V4V IL_V4HL IL_V4TTL %token IL_V4TOS IL_V4SUM IL_V4LEN IL_V4OPT IL_V4ID %token IL_TCP IL_SPORT IL_DPORT IL_TCPFL IL_TCPSEQ IL_TCPACK IL_TCPOFF %token IL_TCPWIN IL_TCPSUM IL_TCPURP IL_TCPOPT IL_TCPO_NOP IL_TCPO_EOL %token IL_TCPO_MSS IL_TCPO_WSCALE IL_TCPO_TS %token IL_UDP IL_UDPLEN IL_UDPSUM %token IL_ICMP IL_ICMPTYPE IL_ICMPCODE %token IL_SEND IL_VIA %token IL_ARP %token IL_DEFROUTER %token IL_SUM IL_OFF IL_LEN IL_V4ADDR IL_OPT %token IL_DATA IL_DLEN IL_DVALUE IL_DFILE %token IL_IPO_NOP IL_IPO_RR IL_IPO_ZSU IL_IPO_MTUP IL_IPO_MTUR IL_IPO_EOL %token IL_IPO_TS IL_IPO_TR IL_IPO_SEC IL_IPO_LSRR IL_IPO_ESEC %token IL_IPO_SATID IL_IPO_SSRR IL_IPO_ADDEXT IL_IPO_VISA IL_IPO_IMITD %token IL_IPO_EIP IL_IPO_FINN IL_IPO_SECCLASS IL_IPO_CIPSO IL_IPO_ENCODE %token IL_IPS_RESERV4 IL_IPS_TOPSECRET IL_IPS_SECRET IL_IPS_RESERV3 %token IL_IPS_CONFID IL_IPS_UNCLASS IL_IPS_RESERV2 IL_IPS_RESERV1 %token IL_ICMP_ECHOREPLY IL_ICMP_UNREACH IL_ICMP_UNREACH_NET %token IL_ICMP_UNREACH_HOST IL_ICMP_UNREACH_PROTOCOL IL_ICMP_UNREACH_PORT %token IL_ICMP_UNREACH_NEEDFRAG IL_ICMP_UNREACH_SRCFAIL %token IL_ICMP_UNREACH_NET_UNKNOWN IL_ICMP_UNREACH_HOST_UNKNOWN %token IL_ICMP_UNREACH_ISOLATED IL_ICMP_UNREACH_NET_PROHIB %token IL_ICMP_UNREACH_HOST_PROHIB IL_ICMP_UNREACH_TOSNET %token IL_ICMP_UNREACH_TOSHOST IL_ICMP_UNREACH_FILTER_PROHIB %token IL_ICMP_UNREACH_HOST_PRECEDENCE IL_ICMP_UNREACH_PRECEDENCE_CUTOFF %token IL_ICMP_SOURCEQUENCH IL_ICMP_REDIRECT IL_ICMP_REDIRECT_NET %token IL_ICMP_REDIRECT_HOST IL_ICMP_REDIRECT_TOSNET %token IL_ICMP_REDIRECT_TOSHOST IL_ICMP_ECHO IL_ICMP_ROUTERADVERT %token IL_ICMP_ROUTERSOLICIT IL_ICMP_TIMXCEED IL_ICMP_TIMXCEED_INTRANS %token IL_ICMP_TIMXCEED_REASS IL_ICMP_PARAMPROB IL_ICMP_PARAMPROB_OPTABSENT %token IL_ICMP_TSTAMP IL_ICMP_TSTAMPREPLY IL_ICMP_IREQ IL_ICMP_IREQREPLY %token IL_ICMP_MASKREQ IL_ICMP_MASKREPLY IL_ICMP_SEQ IL_ICMP_ID %token IL_ICMP_OTIME IL_ICMP_RTIME IL_ICMP_TTIME %% file: line | line file | IL_COMMENT | IL_COMMENT file ; line: iface | arp | send | defrouter | ipline ; iface: ifhdr '{' ifaceopts '}' ';' { check_interface(); } ; ifhdr: IL_INTERFACE { new_interface(); } ; ifaceopts: ifaceopt | ifaceopt ifaceopts ; ifaceopt: IL_IFNAME token { set_ifname(&$2); } | IL_MTU number { set_ifmtu($2); } | IL_V4ADDR token { set_ifv4addr(&$2); } | IL_EADDR token { set_ifeaddr(&$2); } ; send: sendhdr '{' sendbody '}' ';' { packet_done(); } | sendhdr ';' { packet_done(); } ; sendhdr: IL_SEND { reset_send(); } ; sendbody: sendopt | sendbody sendopt ; sendopt: IL_IFNAME token { set_sendif(&$2); } | IL_VIA token { set_sendvia(&$2); } ; arp: arphdr '{' arpbody '}' ';' ; arphdr: IL_ARP { new_arp(); } ; arpbody: arpopt | arpbody arpopt ; arpopt: IL_V4ADDR token { set_arpv4addr(&$2); } | IL_EADDR token { set_arpeaddr(&$2); } ; defrouter: IL_DEFROUTER token { set_defaultrouter(&$2); } ; bodyline: ipline | tcp tcpline | udp udpline | icmp icmpline | data dataline ; ipline: ipv4 '{' ipv4body '}' ';' { end_ipv4(); } ; ipv4: IL_IPV4 { new_packet(); } ipv4body: ipv4type | ipv4type ipv4body | bodyline ; ipv4type: IL_V4PROTO token { set_ipv4proto(&$2); } | IL_V4SRC token { set_ipv4src(&$2); } | IL_V4DST token { set_ipv4dst(&$2); } | IL_V4OFF token { set_ipv4off(&$2); } | IL_V4V token { set_ipv4v(&$2); } | IL_V4HL token { set_ipv4hl(&$2); } | IL_V4ID token { set_ipv4id(&$2); } | IL_V4TTL token { set_ipv4ttl(&$2); } | IL_V4TOS token { set_ipv4tos(&$2); } | IL_V4SUM token { set_ipv4sum(&$2); } | IL_V4LEN token { set_ipv4len(&$2); } | ipv4opt '{' ipv4optlist '}' ';' { end_ipopt(); } ; tcp: IL_TCP { new_tcpheader(); } ; tcpline: '{' tcpheader '}' ';' { end_tcp(); } ; tcpheader: tcpbody | tcpbody tcpheader | bodyline ; tcpbody: IL_SPORT token { set_tcpsport(&$2); } | IL_DPORT token { set_tcpdport(&$2); } | IL_TCPSEQ token { set_tcpseq(&$2); } | IL_TCPACK token { set_tcpack(&$2); } | IL_TCPOFF token { set_tcpoff(&$2); } | IL_TCPURP token { set_tcpurp(&$2); } | IL_TCPWIN token { set_tcpwin(&$2); } | IL_TCPSUM token { set_tcpsum(&$2); } | IL_TCPFL token { set_tcpflags(&$2); } | IL_TCPOPT '{' tcpopts '}' ';' { end_tcpopt(); } ; tcpopts: | tcpopt tcpopts ; tcpopt: IL_TCPO_NOP ';' { set_tcpopt(IL_TCPO_NOP, NULL); } | IL_TCPO_EOL ';' { set_tcpopt(IL_TCPO_EOL, NULL); } | IL_TCPO_MSS optoken { set_tcpopt(IL_TCPO_MSS,&$2);} | IL_TCPO_WSCALE optoken { set_tcpopt(IL_TCPO_WSCALE,&$2);} | IL_TCPO_TS optoken { set_tcpopt(IL_TCPO_TS, &$2);} ; udp: IL_UDP { new_udpheader(); } ; udpline: '{' udpheader '}' ';' { end_udp(); } ; udpheader: udpbody | udpbody udpheader | bodyline ; udpbody: IL_SPORT token { set_tcpsport(&$2); } | IL_DPORT token { set_tcpdport(&$2); } | IL_UDPLEN token { set_udplen(&$2); } | IL_UDPSUM token { set_udpsum(&$2); } ; icmp: IL_ICMP { new_icmpheader(); } ; icmpline: '{' icmpbody '}' ';' { end_icmp(); } ; icmpbody: icmpheader | icmpheader bodyline ; icmpheader: IL_ICMPTYPE icmptype | IL_ICMPTYPE icmptype icmpcode ; icmpcode: IL_ICMPCODE token { set_icmpcodetok(&$2); } ; icmptype: IL_ICMP_ECHOREPLY ';' { set_icmptype(ICMP_ECHOREPLY); } | IL_ICMP_ECHOREPLY '{' icmpechoopts '}' ';' | unreach | IL_ICMP_SOURCEQUENCH ';' { set_icmptype(ICMP_SOURCEQUENCH); } | redirect | IL_ICMP_ROUTERADVERT ';' { set_icmptype(ICMP_ROUTERADVERT); } | IL_ICMP_ROUTERSOLICIT ';' { set_icmptype(ICMP_ROUTERSOLICIT); } | IL_ICMP_ECHO ';' { set_icmptype(ICMP_ECHO); } | IL_ICMP_ECHO '{' icmpechoopts '}' ';' | IL_ICMP_TIMXCEED ';' { set_icmptype(ICMP_TIMXCEED); } | IL_ICMP_TIMXCEED '{' exceed '}' ';' | IL_ICMP_TSTAMP ';' { set_icmptype(ICMP_TSTAMP); } | IL_ICMP_TSTAMPREPLY ';' { set_icmptype(ICMP_TSTAMPREPLY); } | IL_ICMP_TSTAMPREPLY '{' icmptsopts '}' ';' | IL_ICMP_IREQ ';' { set_icmptype(ICMP_IREQ); } | IL_ICMP_IREQREPLY ';' { set_icmptype(ICMP_IREQREPLY); } | IL_ICMP_IREQREPLY '{' data dataline '}' ';' | IL_ICMP_MASKREQ ';' { set_icmptype(ICMP_MASKREQ); } | IL_ICMP_MASKREPLY ';' { set_icmptype(ICMP_MASKREPLY); } | IL_ICMP_MASKREPLY '{' token '}' ';' | IL_ICMP_PARAMPROB ';' { set_icmptype(ICMP_PARAMPROB); } | IL_ICMP_PARAMPROB '{' paramprob '}' ';' | IL_TOKEN ';' { set_icmptypetok(&$1); } ; icmpechoopts: | icmpechoopts icmpecho ; icmpecho: IL_ICMP_SEQ number { set_icmpseq($2); } | IL_ICMP_ID number { set_icmpid($2); } ; icmptsopts: | icmptsopts icmpts ';' ; icmpts: IL_ICMP_OTIME number { set_icmpotime($2); } | IL_ICMP_RTIME number { set_icmprtime($2); } | IL_ICMP_TTIME number { set_icmpttime($2); } ; unreach: IL_ICMP_UNREACH | IL_ICMP_UNREACH '{' unreachopts '}' ';' ; unreachopts: IL_ICMP_UNREACH_NET line | IL_ICMP_UNREACH_HOST line | IL_ICMP_UNREACH_PROTOCOL line | IL_ICMP_UNREACH_PORT line | IL_ICMP_UNREACH_NEEDFRAG number ';' { set_icmpmtu($2); } | IL_ICMP_UNREACH_SRCFAIL line | IL_ICMP_UNREACH_NET_UNKNOWN line | IL_ICMP_UNREACH_HOST_UNKNOWN line | IL_ICMP_UNREACH_ISOLATED line | IL_ICMP_UNREACH_NET_PROHIB line | IL_ICMP_UNREACH_HOST_PROHIB line | IL_ICMP_UNREACH_TOSNET line | IL_ICMP_UNREACH_TOSHOST line | IL_ICMP_UNREACH_FILTER_PROHIB line | IL_ICMP_UNREACH_HOST_PRECEDENCE line | IL_ICMP_UNREACH_PRECEDENCE_CUTOFF line ; redirect: IL_ICMP_REDIRECT | IL_ICMP_REDIRECT '{' redirectopts '}' ';' ; redirectopts: | IL_ICMP_REDIRECT_NET token { set_redir(0, &$2); } | IL_ICMP_REDIRECT_HOST token { set_redir(1, &$2); } | IL_ICMP_REDIRECT_TOSNET token { set_redir(2, &$2); } | IL_ICMP_REDIRECT_TOSHOST token { set_redir(3, &$2); } ; exceed: IL_ICMP_TIMXCEED_INTRANS line | IL_ICMP_TIMXCEED_REASS line ; paramprob: IL_ICMP_PARAMPROB_OPTABSENT | IL_ICMP_PARAMPROB_OPTABSENT paraprobarg paraprobarg: '{' number '}' ';' { set_icmppprob($2); } ; ipv4opt: IL_V4OPT { new_ipv4opt(); } ; ipv4optlist: | ipv4opts ipv4optlist ; ipv4opts: IL_IPO_NOP ';' { add_ipopt(IL_IPO_NOP, NULL); } | IL_IPO_RR optnumber { add_ipopt(IL_IPO_RR, &$2); } | IL_IPO_ZSU ';' { add_ipopt(IL_IPO_ZSU, NULL); } | IL_IPO_MTUP ';' { add_ipopt(IL_IPO_MTUP, NULL); } | IL_IPO_MTUR ';' { add_ipopt(IL_IPO_MTUR, NULL); } | IL_IPO_ENCODE ';' { add_ipopt(IL_IPO_ENCODE, NULL); } | IL_IPO_TS ';' { add_ipopt(IL_IPO_TS, NULL); } | IL_IPO_TR ';' { add_ipopt(IL_IPO_TR, NULL); } | IL_IPO_SEC ';' { add_ipopt(IL_IPO_SEC, NULL); } | IL_IPO_SECCLASS secclass { add_ipopt(IL_IPO_SECCLASS, sclass); } | IL_IPO_LSRR token { add_ipopt(IL_IPO_LSRR,&$2); } | IL_IPO_ESEC ';' { add_ipopt(IL_IPO_ESEC, NULL); } | IL_IPO_CIPSO ';' { add_ipopt(IL_IPO_CIPSO, NULL); } | IL_IPO_SATID optnumber { add_ipopt(IL_IPO_SATID,&$2);} | IL_IPO_SSRR token { add_ipopt(IL_IPO_SSRR,&$2); } | IL_IPO_ADDEXT ';' { add_ipopt(IL_IPO_ADDEXT, NULL); } | IL_IPO_VISA ';' { add_ipopt(IL_IPO_VISA, NULL); } | IL_IPO_IMITD ';' { add_ipopt(IL_IPO_IMITD, NULL); } | IL_IPO_EIP ';' { add_ipopt(IL_IPO_EIP, NULL); } | IL_IPO_FINN ';' { add_ipopt(IL_IPO_FINN, NULL); } ; secclass: IL_IPS_RESERV4 ';' { set_secclass(&$1); } | IL_IPS_TOPSECRET ';' { set_secclass(&$1); } | IL_IPS_SECRET ';' { set_secclass(&$1); } | IL_IPS_RESERV3 ';' { set_secclass(&$1); } | IL_IPS_CONFID ';' { set_secclass(&$1); } | IL_IPS_UNCLASS ';' { set_secclass(&$1); } | IL_IPS_RESERV2 ';' { set_secclass(&$1); } | IL_IPS_RESERV1 ';' { set_secclass(&$1); } ; data: IL_DATA { new_data(); } ; dataline: '{' databody '}' ';' { end_data(); } ; databody: dataopts | dataopts databody ; dataopts: IL_DLEN token { set_datalen(&$2); } | IL_DVALUE token { set_data(&$2); } | IL_DFILE token { set_datafile(&$2); } ; token: IL_TOKEN ';' ; optoken: ';' { $$ = ""; } | token ; number: digits ';' ; optnumber: ';' { $$ = 0; } | number ; digits: IL_NUMBER | digits IL_NUMBER ; %% struct statetoopt toipopts[] = { { IL_IPO_NOP, IPOPT_NOP }, { IL_IPO_RR, IPOPT_RR }, { IL_IPO_ZSU, IPOPT_ZSU }, { IL_IPO_MTUP, IPOPT_MTUP }, { IL_IPO_MTUR, IPOPT_MTUR }, { IL_IPO_ENCODE, IPOPT_ENCODE }, { IL_IPO_TS, IPOPT_TS }, { IL_IPO_TR, IPOPT_TR }, { IL_IPO_SEC, IPOPT_SECURITY }, { IL_IPO_SECCLASS, IPOPT_SECURITY }, { IL_IPO_LSRR, IPOPT_LSRR }, { IL_IPO_ESEC, IPOPT_E_SEC }, { IL_IPO_CIPSO, IPOPT_CIPSO }, { IL_IPO_SATID, IPOPT_SATID }, { IL_IPO_SSRR, IPOPT_SSRR }, { IL_IPO_ADDEXT, IPOPT_ADDEXT }, { IL_IPO_VISA, IPOPT_VISA }, { IL_IPO_IMITD, IPOPT_IMITD }, { IL_IPO_EIP, IPOPT_EIP }, { IL_IPO_FINN, IPOPT_FINN }, { 0, 0 } }; struct statetoopt tosecopts[] = { { IL_IPS_RESERV4, IPSO_CLASS_RES4 }, { IL_IPS_TOPSECRET, IPSO_CLASS_TOPS }, { IL_IPS_SECRET, IPSO_CLASS_SECR }, { IL_IPS_RESERV3, IPSO_CLASS_RES3 }, { IL_IPS_CONFID, IPSO_CLASS_CONF }, { IL_IPS_UNCLASS, IPSO_CLASS_UNCL }, { IL_IPS_RESERV2, IPSO_CLASS_RES2 }, { IL_IPS_RESERV1, IPSO_CLASS_RES1 }, { 0, 0 } }; #ifdef bsdi struct ether_addr * ether_aton(s) char *s; { static struct ether_addr n; u_int i[6]; if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1], &i[2], &i[3], &i[4], &i[5]) == 6) { n.ether_addr_octet[0] = (u_char)i[0]; n.ether_addr_octet[1] = (u_char)i[1]; n.ether_addr_octet[2] = (u_char)i[2]; n.ether_addr_octet[3] = (u_char)i[3]; n.ether_addr_octet[4] = (u_char)i[4]; n.ether_addr_octet[5] = (u_char)i[5]; return &n; } return NULL; } #endif struct in_addr getipv4addr(arg) char *arg; { struct hostent *hp; struct in_addr in; in.s_addr = 0xffffffff; if ((hp = gethostbyname(arg))) bcopy(hp->h_addr, &in.s_addr, sizeof(struct in_addr)); else in.s_addr = inet_addr(arg); return in; } u_short getportnum(pr, name) char *pr, *name; { struct servent *sp; if (!(sp = getservbyname(name, pr))) return htons(atoi(name)); return sp->s_port; } struct ether_addr *geteaddr(arg, buf) char *arg; struct ether_addr *buf; { struct ether_addr *e; #if !defined(hpux) && !defined(linux) e = ether_aton(arg); if (!e) fprintf(stderr, "Invalid ethernet address: %s\n", arg); else # ifdef __FreeBSD__ bcopy(e->octet, buf->octet, sizeof(e->octet)); # else bcopy(e->ether_addr_octet, buf->ether_addr_octet, sizeof(e->ether_addr_octet)); # endif return e; #else return NULL; #endif } void *new_header(type) int type; { aniphdr_t *aip, *oip = canip; int sz = 0; aip = (aniphdr_t *)calloc(1, sizeof(*aip)); *aniptail = aip; aniptail = &aip->ah_next; aip->ah_p = type; aip->ah_prev = oip; canip = aip; if (type == IPPROTO_UDP) sz = sizeof(udphdr_t); else if (type == IPPROTO_TCP) sz = sizeof(tcphdr_t); else if (type == IPPROTO_ICMP) sz = sizeof(icmphdr_t); else if (type == IPPROTO_IP) sz = sizeof(ip_t); if (oip) canip->ah_data = oip->ah_data + oip->ah_len; else canip->ah_data = (char *)ipbuffer; /* * Increase the size fields in all wrapping headers. */ for (aip = aniphead; aip; aip = aip->ah_next) { aip->ah_len += sz; if (aip->ah_p == IPPROTO_IP) aip->ah_ip->ip_len += sz; else if (aip->ah_p == IPPROTO_UDP) aip->ah_udp->uh_ulen += sz; } return (void *)canip->ah_data; } void free_aniplist() { aniphdr_t *aip, **aipp = &aniphead; while ((aip = *aipp)) { *aipp = aip->ah_next; free(aip); } aniptail = &aniphead; } void inc_anipheaders(inc) int inc; { aniphdr_t *aip; for (aip = aniphead; aip; aip = aip->ah_next) { aip->ah_len += inc; if (aip->ah_p == IPPROTO_IP) aip->ah_ip->ip_len += inc; else if (aip->ah_p == IPPROTO_UDP) aip->ah_udp->uh_ulen += inc; } } void new_data() { (void) new_header(-1); canip->ah_len = 0; } void set_datalen(arg) char **arg; { int len; len = strtol(*arg, NULL, 0); inc_anipheaders(len); free(*arg); *arg = NULL; } void set_data(arg) char **arg; { u_char *s = (u_char *)*arg, *t = (u_char *)canip->ah_data, c; int len = 0, todo = 0, quote = 0, val = 0; while ((c = *s++)) { if (todo) { if (ISDIGIT(c)) { todo--; if (c > '7') { fprintf(stderr, "octal with %c!\n", c); break; } val <<= 3; val |= (c - '0'); } if (!ISDIGIT(c) || !todo) { *t++ = (u_char)(val & 0xff); todo = 0; } if (todo) continue; } if (quote) { if (ISDIGIT(c)) { todo = 2; if (c > '7') { fprintf(stderr, "octal with %c!\n", c); break; } val = (c - '0'); } else { switch (c) { case '\"' : *t++ = '\"'; break; case '\\' : *t++ = '\\'; break; case 'n' : *t++ = '\n'; break; case 'r' : *t++ = '\r'; break; case 't' : *t++ = '\t'; break; } } quote = 0; continue; } if (c == '\\') quote = 1; else *t++ = c; } if (todo) *t++ = (u_char)(val & 0xff); if (quote) *t++ = '\\'; len = t - (u_char *)canip->ah_data; inc_anipheaders(len - canip->ah_len); canip->ah_len = len; } void set_datafile(arg) char **arg; { struct stat sb; char *file = *arg; int fd, len; if ((fd = open(file, O_RDONLY)) == -1) { perror("open"); exit(-1); } if (fstat(fd, &sb) == -1) { perror("fstat"); exit(-1); } if ((sb.st_size + aniphead->ah_len ) > 65535) { fprintf(stderr, "data file %s too big to include.\n", file); close(fd); return; } if ((len = read(fd, canip->ah_data, sb.st_size)) == -1) { perror("read"); close(fd); return; } inc_anipheaders(len); canip->ah_len += len; close(fd); } void new_packet() { static u_short id = 0; if (!aniphead) bzero((char *)ipbuffer, sizeof(ipbuffer)); ip = (ip_t *)new_header(IPPROTO_IP); ip->ip_v = IPVERSION; ip->ip_hl = sizeof(ip_t) >> 2; ip->ip_len = sizeof(ip_t); ip->ip_ttl = 63; ip->ip_id = htons(id++); } void set_ipv4proto(arg) char **arg; { struct protoent *pr; if ((pr = getprotobyname(*arg))) ip->ip_p = pr->p_proto; else if (!(ip->ip_p = atoi(*arg))) fprintf(stderr, "unknown protocol %s\n", *arg); free(*arg); *arg = NULL; } void set_ipv4src(arg) char **arg; { ip->ip_src = getipv4addr(*arg); free(*arg); *arg = NULL; } void set_ipv4dst(arg) char **arg; { ip->ip_dst = getipv4addr(*arg); free(*arg); *arg = NULL; } void set_ipv4off(arg) char **arg; { ip->ip_off = htons(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } void set_ipv4v(arg) char **arg; { ip->ip_v = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } void set_ipv4hl(arg) char **arg; { int newhl, inc; newhl = strtol(*arg, NULL, 0); inc = (newhl - ip->ip_hl) << 2; ip->ip_len += inc; ip->ip_hl = newhl; canip->ah_len += inc; free(*arg); *arg = NULL; } void set_ipv4ttl(arg) char **arg; { ip->ip_ttl = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } void set_ipv4tos(arg) char **arg; { ip->ip_tos = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } void set_ipv4id(arg) char **arg; { ip->ip_id = htons(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } void set_ipv4sum(arg) char **arg; { ip->ip_sum = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } void set_ipv4len(arg) char **arg; { int len; len = strtol(*arg, NULL, 0); inc_anipheaders(len - ip->ip_len); ip->ip_len = len; free(*arg); *arg = NULL; } void new_tcpheader() { if ((ip->ip_p) && (ip->ip_p != IPPROTO_TCP)) { fprintf(stderr, "protocol %d specified with TCP!\n", ip->ip_p); return; } ip->ip_p = IPPROTO_TCP; tcp = (tcphdr_t *)new_header(IPPROTO_TCP); tcp->th_win = htons(4096); tcp->th_off = sizeof(*tcp) >> 2; } void set_tcpsport(arg) char **arg; { u_short *port; char *pr; if (ip->ip_p == IPPROTO_UDP) { port = &udp->uh_sport; pr = "udp"; } else { port = &tcp->th_sport; pr = "udp"; } *port = getportnum(pr, *arg); free(*arg); *arg = NULL; } void set_tcpdport(arg) char **arg; { u_short *port; char *pr; if (ip->ip_p == IPPROTO_UDP) { port = &udp->uh_dport; pr = "udp"; } else { port = &tcp->th_dport; pr = "udp"; } *port = getportnum(pr, *arg); free(*arg); *arg = NULL; } void set_tcpseq(arg) char **arg; { tcp->th_seq = htonl(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } void set_tcpack(arg) char **arg; { tcp->th_ack = htonl(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } void set_tcpoff(arg) char **arg; { int off; off = strtol(*arg, NULL, 0); inc_anipheaders((off - tcp->th_off) << 2); tcp->th_off = off; free(*arg); *arg = NULL; } void set_tcpurp(arg) char **arg; { tcp->th_urp = htons(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } void set_tcpwin(arg) char **arg; { tcp->th_win = htons(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } void set_tcpsum(arg) char **arg; { tcp->th_sum = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } void set_tcpflags(arg) char **arg; { static char flags[] = "ASURPF"; static int flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH, TH_FIN } ; char *s, *t; for (s = *arg; *s; s++) if (!(t = strchr(flags, *s))) { if (s - *arg) { fprintf(stderr, "unknown TCP flag %c\n", *s); break; } tcp->th_flags = strtol(*arg, NULL, 0); break; } else tcp->th_flags |= flagv[t - flags]; free(*arg); *arg = NULL; } void set_tcpopt(state, arg) int state; char **arg; { u_char *s; int val, len, val2, pad, optval; if (arg && *arg) val = atoi(*arg); else val = 0; s = (u_char *)tcp + sizeof(*tcp) + canip->ah_optlen; switch (state) { case IL_TCPO_EOL : optval = 0; len = 1; break; case IL_TCPO_NOP : optval = 1; len = 1; break; case IL_TCPO_MSS : optval = 2; len = 4; break; case IL_TCPO_WSCALE : optval = 3; len = 3; break; case IL_TCPO_TS : optval = 8; len = 10; break; default : optval = 0; len = 0; break; } if (len > 1) { /* * prepend padding - if required. */ if (len & 3) for (pad = 4 - (len & 3); pad; pad--) { *s++ = 1; canip->ah_optlen++; } /* * build tcp option */ *s++ = (u_char)optval; *s++ = (u_char)len; if (len > 2) { if (len == 3) { /* 1 byte - char */ *s++ = (u_char)val; } else if (len == 4) { /* 2 bytes - short */ *s++ = (u_char)((val >> 8) & 0xff); *s++ = (u_char)(val & 0xff); } else if (len >= 6) { /* 4 bytes - long */ val2 = htonl(val); bcopy((char *)&val2, s, 4); } s += (len - 2); } } else *s++ = (u_char)optval; canip->ah_lastopt = optval; canip->ah_optlen += len; if (arg && *arg) { free(*arg); *arg = NULL; } } void end_tcpopt() { int pad; char *s = (char *)tcp; s += sizeof(*tcp) + canip->ah_optlen; /* * pad out so that we have a multiple of 4 bytes in size fo the * options. make sure last byte is EOL. */ if (canip->ah_optlen & 3) { if (canip->ah_lastopt != 1) { for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { *s++ = 1; canip->ah_optlen++; } canip->ah_optlen++; } else { s -= 1; for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { *s++ = 1; canip->ah_optlen++; } } *s++ = 0; } tcp->th_off = (sizeof(*tcp) + canip->ah_optlen) >> 2; inc_anipheaders(canip->ah_optlen); } void new_udpheader() { if ((ip->ip_p) && (ip->ip_p != IPPROTO_UDP)) { fprintf(stderr, "protocol %d specified with UDP!\n", ip->ip_p); return; } ip->ip_p = IPPROTO_UDP; udp = (udphdr_t *)new_header(IPPROTO_UDP); udp->uh_ulen = sizeof(*udp); } void set_udplen(arg) char **arg; { int len; len = strtol(*arg, NULL, 0); inc_anipheaders(len - udp->uh_ulen); udp->uh_ulen = len; free(*arg); *arg = NULL; } void set_udpsum(arg) char **arg; { udp->uh_sum = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } void prep_packet() { iface_t *ifp; struct in_addr gwip; ifp = sending.snd_if; if (!ifp) { fprintf(stderr, "no interface defined for sending!\n"); return; } if (ifp->if_fd == -1) ifp->if_fd = initdevice(ifp->if_name, 5); gwip = sending.snd_gw; if (!gwip.s_addr) { if (aniphead == NULL) { fprintf(stderr, "no destination address defined for sending\n"); return; } gwip = aniphead->ah_ip->ip_dst; } (void) send_ip(ifp->if_fd, ifp->if_MTU, (ip_t *)ipbuffer, gwip, 2); } void packet_done() { char outline[80]; int i, j, k; u_char *s = (u_char *)ipbuffer, *t = (u_char *)outline; if (opts & OPT_VERBOSE) { ip->ip_len = htons(ip->ip_len); for (i = ntohs(ip->ip_len), j = 0; i; i--, j++, s++) { if (j && !(j & 0xf)) { *t++ = '\n'; *t = '\0'; fputs(outline, stdout); fflush(stdout); t = (u_char *)outline; *t = '\0'; } sprintf((char *)t, "%02x", *s & 0xff); t += 2; if (!((j + 1) & 0xf)) { s -= 15; sprintf((char *)t, " "); t += 8; for (k = 16; k; k--, s++) *t++ = (isprint(*s) ? *s : '.'); s--; } if ((j + 1) & 0xf) *t++ = ' ';; } if (j & 0xf) { for (k = 16 - (j & 0xf); k; k--) { *t++ = ' '; *t++ = ' '; *t++ = ' '; } sprintf((char *)t, " "); t += 7; s -= j & 0xf; for (k = j & 0xf; k; k--, s++) *t++ = (isprint(*s) ? *s : '.'); *t++ = '\n'; *t = '\0'; } fputs(outline, stdout); fflush(stdout); ip->ip_len = ntohs(ip->ip_len); } prep_packet(); free_aniplist(); } void new_interface() { cifp = (iface_t *)calloc(1, sizeof(iface_t)); *iftail = cifp; iftail = &cifp->if_next; cifp->if_fd = -1; } void check_interface() { if (!cifp->if_name || !*cifp->if_name) fprintf(stderr, "No interface name given!\n"); if (!cifp->if_MTU || !*cifp->if_name) fprintf(stderr, "Interface %s has an MTU of 0!\n", cifp->if_name); } void set_ifname(arg) char **arg; { cifp->if_name = *arg; *arg = NULL; } void set_ifmtu(arg) int arg; { cifp->if_MTU = arg; } void set_ifv4addr(arg) char **arg; { cifp->if_addr = getipv4addr(*arg); free(*arg); *arg = NULL; } void set_ifeaddr(arg) char **arg; { (void) geteaddr(*arg, &cifp->if_eaddr); free(*arg); *arg = NULL; } void new_arp() { carp = (arp_t *)calloc(1, sizeof(arp_t)); *arptail = carp; arptail = &carp->arp_next; } void set_arpeaddr(arg) char **arg; { (void) geteaddr(*arg, &carp->arp_eaddr); free(*arg); *arg = NULL; } void set_arpv4addr(arg) char **arg; { carp->arp_addr = getipv4addr(*arg); free(*arg); *arg = NULL; } int arp_getipv4(ip, addr) char *ip; char *addr; { arp_t *a; for (a = arplist; a; a = a->arp_next) if (!bcmp(ip, (char *)&a->arp_addr, 4)) { bcopy((char *)&a->arp_eaddr, addr, 6); return 0; } return -1; } void reset_send() { sending.snd_if = iflist; sending.snd_gw = defrouter; } void set_sendif(arg) char **arg; { iface_t *ifp; for (ifp = iflist; ifp; ifp = ifp->if_next) if (ifp->if_name && !strcmp(ifp->if_name, *arg)) break; sending.snd_if = ifp; if (!ifp) fprintf(stderr, "couldn't find interface %s\n", *arg); free(*arg); *arg = NULL; } void set_sendvia(arg) char **arg; { sending.snd_gw = getipv4addr(*arg); free(*arg); *arg = NULL; } void set_defaultrouter(arg) char **arg; { defrouter = getipv4addr(*arg); free(*arg); *arg = NULL; } void new_icmpheader() { if ((ip->ip_p) && (ip->ip_p != IPPROTO_ICMP)) { fprintf(stderr, "protocol %d specified with ICMP!\n", ip->ip_p); return; } ip->ip_p = IPPROTO_ICMP; icmp = (icmphdr_t *)new_header(IPPROTO_ICMP); } void set_icmpcode(code) int code; { icmp->icmp_code = code; } void set_icmptype(type) int type; { icmp->icmp_type = type; } void set_icmpcodetok(code) char **code; { char *s; int i; for (i = 0; (s = icmpcodes[i]); i++) if (!strcmp(s, *code)) { icmp->icmp_code = i; break; } if (!s) fprintf(stderr, "unknown ICMP code %s\n", *code); free(*code); *code = NULL; } void set_icmptypetok(type) char **type; { char *s; int i, done = 0; for (i = 0; !(s = icmptypes[i]) || strcmp(s, "END"); i++) if (s && !strcmp(s, *type)) { icmp->icmp_type = i; done = 1; break; } if (!done) fprintf(stderr, "unknown ICMP type %s\n", *type); free(*type); *type = NULL; } void set_icmpid(arg) int arg; { icmp->icmp_id = htons(arg); } void set_icmpseq(arg) int arg; { icmp->icmp_seq = htons(arg); } void set_icmpotime(arg) int arg; { icmp->icmp_otime = htonl(arg); } void set_icmprtime(arg) int arg; { icmp->icmp_rtime = htonl(arg); } void set_icmpttime(arg) int arg; { icmp->icmp_ttime = htonl(arg); } void set_icmpmtu(arg) int arg; { #if BSD >= 199306 icmp->icmp_nextmtu = htons(arg); #endif } void set_redir(redir, arg) int redir; char **arg; { icmp->icmp_code = redir; icmp->icmp_gwaddr = getipv4addr(*arg); free(*arg); *arg = NULL; } void set_icmppprob(num) int num; { icmp->icmp_pptr = num; } void new_ipv4opt() { new_header(-2); } void add_ipopt(state, ptr) int state; void *ptr; { struct ipopt_names *io; struct statetoopt *sto; char numbuf[16], *arg, **param = ptr; int inc, hlen; if (state == IL_IPO_RR || state == IL_IPO_SATID) { if (param) sprintf(numbuf, "%d", *(int *)param); else strcpy(numbuf, "0"); arg = numbuf; } else arg = param ? *param : NULL; if (canip->ah_next) { fprintf(stderr, "cannot specify options after data body\n"); return; } for (sto = toipopts; sto->sto_st; sto++) if (sto->sto_st == state) break; if (!sto->sto_st) { fprintf(stderr, "No mapping for state %d to IP option\n", state); return; } hlen = sizeof(ip_t) + canip->ah_optlen; for (io = ionames; io->on_name; io++) if (io->on_value == sto->sto_op) break; canip->ah_lastopt = io->on_value; if (io->on_name) { inc = addipopt((char *)ip + hlen, io, hlen - sizeof(ip_t),arg); if (inc > 0) { while (inc & 3) { ((char *)ip)[sizeof(*ip) + inc] = IPOPT_NOP; canip->ah_lastopt = IPOPT_NOP; inc++; } hlen += inc; } } canip->ah_optlen = hlen - sizeof(ip_t); if (state != IL_IPO_RR && state != IL_IPO_SATID) if (param && *param) { free(*param); *param = NULL; } sclass = NULL; } void end_ipopt() { int pad; char *s, *buf = (char *)ip; /* * pad out so that we have a multiple of 4 bytes in size fo the * options. make sure last byte is EOL. */ if (canip->ah_lastopt == IPOPT_NOP) { buf[sizeof(*ip) + canip->ah_optlen - 1] = IPOPT_EOL; } else if (canip->ah_lastopt != IPOPT_EOL) { s = buf + sizeof(*ip) + canip->ah_optlen; for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { *s++ = IPOPT_NOP; *s = IPOPT_EOL; canip->ah_optlen++; } canip->ah_optlen++; } else { s = buf + sizeof(*ip) + canip->ah_optlen - 1; for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { *s++ = IPOPT_NOP; *s = IPOPT_EOL; canip->ah_optlen++; } } ip->ip_hl = (sizeof(*ip) + canip->ah_optlen) >> 2; inc_anipheaders(canip->ah_optlen); free_anipheader(); } void set_secclass(arg) char **arg; { sclass = *arg; *arg = NULL; } void free_anipheader() { aniphdr_t *aip; aip = canip; if ((canip = aip->ah_prev)) { canip->ah_next = NULL; aniptail = &canip->ah_next; } if (canip) free(aip); } void end_ipv4() { aniphdr_t *aip; ip->ip_sum = 0; ip->ip_len = htons(ip->ip_len); ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2); ip->ip_len = ntohs(ip->ip_len); free_anipheader(); for (aip = aniphead, ip = NULL; aip; aip = aip->ah_next) if (aip->ah_p == IPPROTO_IP) ip = aip->ah_ip; } void end_icmp() { aniphdr_t *aip; icmp->icmp_cksum = 0; icmp->icmp_cksum = chksum((u_short *)icmp, canip->ah_len); free_anipheader(); for (aip = aniphead, icmp = NULL; aip; aip = aip->ah_next) if (aip->ah_p == IPPROTO_ICMP) icmp = aip->ah_icmp; } void end_udp() { u_long sum; aniphdr_t *aip; ip_t iptmp; bzero((char *)&iptmp, sizeof(iptmp)); iptmp.ip_p = ip->ip_p; iptmp.ip_src = ip->ip_src; iptmp.ip_dst = ip->ip_dst; iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2)); sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp)); udp->uh_ulen = htons(udp->uh_ulen); udp->uh_sum = c_chksum((u_short *)udp, (u_int)ntohs(iptmp.ip_len), sum); free_anipheader(); for (aip = aniphead, udp = NULL; aip; aip = aip->ah_next) if (aip->ah_p == IPPROTO_UDP) udp = aip->ah_udp; } void end_tcp() { u_long sum; aniphdr_t *aip; ip_t iptmp; bzero((char *)&iptmp, sizeof(iptmp)); iptmp.ip_p = ip->ip_p; iptmp.ip_src = ip->ip_src; iptmp.ip_dst = ip->ip_dst; iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2)); sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp)); tcp->th_sum = 0; tcp->th_sum = c_chksum((u_short *)tcp, (u_int)ntohs(iptmp.ip_len), sum); free_anipheader(); for (aip = aniphead, tcp = NULL; aip; aip = aip->ah_next) if (aip->ah_p == IPPROTO_TCP) tcp = aip->ah_tcp; } void end_data() { free_anipheader(); } void iplang(fp) FILE *fp; { yyin = fp; yydebug = (opts & OPT_DEBUG) ? 1 : 0; while (!feof(fp)) yyparse(); } u_short c_chksum(buf, len, init) u_short *buf; u_int len; u_long init; { u_long sum = init; int nwords = len >> 1; for(; nwords > 0; nwords--) sum += *buf++; sum = (sum>>16) + (sum & 0xffff); sum += (sum >>16); return (~sum); } u_long p_chksum(buf,len) u_short *buf; u_int len; { u_long sum = 0; int nwords = len >> 1; for(; nwords > 0; nwords--) sum += *buf++; return sum; } diff --git a/contrib/ipfilter/ipsend/arp.c b/contrib/ipfilter/ipsend/arp.c index 05f255ea47d2..31b70d3e8987 100644 --- a/contrib/ipfilter/ipsend/arp.c +++ b/contrib/ipfilter/ipsend/arp.c @@ -1,139 +1,135 @@ /* $FreeBSD$ */ /* * arp.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include -#if !defined(ultrix) && !defined(hpux) && !defined(__hpux) && !defined(__osf__) && !defined(_AIX51) # include -#endif #include #include #include #include #include -#ifndef ultrix # include -#endif #include #include #include #include #include #include #include #include "ipsend.h" #include "iplang/iplang.h" /* * lookup host and return * its IP address in address * (4 bytes) */ int resolve(host, address) char *host, *address; { struct hostent *hp; u_long add; add = inet_addr(host); if (add == -1) { if (!(hp = gethostbyname(host))) { fprintf(stderr, "unknown host: %s\n", host); return -1; } bcopy((char *)hp->h_addr, (char *)address, 4); return 0; } bcopy((char*)&add, address, 4); return 0; } /* * ARP for the MAC address corresponding * to the IP address. This taken from * some BSD program, I cant remember which. */ int arp(ip, ether) char *ip; char *ether; { static int sfd = -1; static char ethersave[6], ipsave[4]; struct arpreq ar; struct sockaddr_in *sin, san; struct hostent *hp; int fd; #ifdef IPSEND if (arp_getipv4(ip, ether) == 0) return 0; #endif if (!bcmp(ipsave, ip, 4)) { bcopy(ethersave, ether, 6); return 0; } fd = -1; bzero((char *)&ar, sizeof(ar)); sin = (struct sockaddr_in *)&ar.arp_pa; sin->sin_family = AF_INET; bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); if ((hp = gethostbyaddr(ip, 4, AF_INET))) # if SOLARIS && (SOLARIS2 >= 10) if (!(ether_hostton(hp->h_name, (struct ether_addr *)ether))) # else if (!(ether_hostton(hp->h_name, ether))) # endif goto savearp; if (sfd == -1) if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("arp: socket"); return -1; } tryagain: if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1) { if (fd == -1) { bzero((char *)&san, sizeof(san)); san.sin_family = AF_INET; san.sin_port = htons(1); bcopy(ip, &san.sin_addr.s_addr, 4); fd = socket(AF_INET, SOCK_DGRAM, 0); (void) sendto(fd, ip, 4, 0, (struct sockaddr *)&san, sizeof(san)); sleep(1); (void) close(fd); goto tryagain; } fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); if (errno != ENXIO) perror("SIOCGARP"); return -1; } if ((ar.arp_ha.sa_data[0] == 0) && (ar.arp_ha.sa_data[1] == 0) && (ar.arp_ha.sa_data[2] == 0) && (ar.arp_ha.sa_data[3] == 0) && (ar.arp_ha.sa_data[4] == 0) && (ar.arp_ha.sa_data[5] == 0)) { fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); return -1; } bcopy(ar.arp_ha.sa_data, ether, 6); savearp: bcopy(ether, ethersave, 6); bcopy(ip, ipsave, 4); return 0; } diff --git a/contrib/ipfilter/ipsend/ipresend.c b/contrib/ipfilter/ipsend/ipresend.c index ea0b4211c101..1e7b9049169a 100644 --- a/contrib/ipfilter/ipsend/ipresend.c +++ b/contrib/ipfilter/ipsend/ipresend.c @@ -1,141 +1,133 @@ /* $FreeBSD$ */ /* * ipresend.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" extern char *optarg; extern int optind; #ifndef NO_IPF extern struct ipread pcap, iphex, iptext; #endif int opts = 0; #ifndef DEFAULT_DEVICE # ifdef sun char default_device[] = "le0"; # else -# ifdef ultrix -char default_device[] = "ln0"; -# else -# ifdef __bsdi__ -char default_device[] = "ef0"; -# else char default_device[] = "lan0"; -# endif -# endif # endif #else char default_device[] = DEFAULT_DEVICE; #endif static void usage __P((char *)); int main __P((int, char **)); static void usage(prog) char *prog; { fprintf(stderr, "Usage: %s [options] <-r filename|-R filename>\n\ \t\t-r filename\tsnoop data file to resend\n\ \t\t-R filename\tlibpcap data file to resend\n\ \toptions:\n\ \t\t-d device\tSend out on this device\n\ \t\t-g gateway\tIP gateway to use if non-local dest.\n\ \t\t-m mtu\t\tfake MTU to use when sending out\n\ ", prog); exit(1); } int main(argc, argv) int argc; char **argv; { struct in_addr gwip; struct ipread *ipr = NULL; char *name = argv[0], *gateway = NULL, *dev = NULL; char *resend = NULL; int mtu = 1500, c; while ((c = getopt(argc, argv, "EHPRSTXd:g:m:r:")) != -1) switch (c) { case 'd' : dev = optarg; break; case 'g' : gateway = optarg; break; case 'm' : mtu = atoi(optarg); if (mtu < 28) { fprintf(stderr, "mtu must be > 28\n"); exit(1); } case 'r' : resend = optarg; break; case 'R' : opts |= OPT_RAW; break; #ifndef NO_IPF case 'H' : ipr = &iphex; break; case 'P' : ipr = &pcap; break; case 'X' : ipr = &iptext; break; #endif default : fprintf(stderr, "Unknown option \"%c\"\n", c); usage(name); } if (!ipr || !resend) usage(name); gwip.s_addr = 0; if (gateway && resolve(gateway, (char *)&gwip) == -1) { fprintf(stderr,"Cant resolve %s\n", gateway); exit(2); } if (!dev) dev = default_device; printf("Device: %s\n", dev); printf("Gateway: %s\n", inet_ntoa(gwip)); printf("mtu: %d\n", mtu); return ip_resend(dev, mtu, ipr, gwip, resend); } diff --git a/contrib/ipfilter/ipsend/ipsend.c b/contrib/ipfilter/ipsend/ipsend.c index 95a1bb1e5c78..b7617734f66e 100644 --- a/contrib/ipfilter/ipsend/ipsend.c +++ b/contrib/ipfilter/ipsend/ipsend.c @@ -1,424 +1,416 @@ /* $FreeBSD$ */ /* * ipsend.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include # include #include "ipsend.h" #include "ipf.h" # include extern char *optarg; extern int optind; extern void iplang __P((FILE *)); char options[68]; int opts; -# ifdef ultrix -char default_device[] = "ln0"; -# else -# ifdef __bsdi__ -char default_device[] = "ef0"; -# else char default_device[] = "le0"; -# endif /* __bsdi__ */ -# endif /* ultrix */ static void usage __P((char *)); static void do_icmp __P((ip_t *, char *)); void udpcksum(ip_t *, struct udphdr *, int); int main __P((int, char **)); static void usage(prog) char *prog; { fprintf(stderr, "Usage: %s [options] dest [flags]\n\ \toptions:\n\ \t\t-d\tdebug mode\n\ \t\t-i device\tSend out on this device\n\ \t\t-f fragflags\tcan set IP_MF or IP_DF\n\ \t\t-g gateway\tIP gateway to use if non-local dest.\n\ \t\t-I code,type[,gw[,dst[,src]]]\tSet ICMP protocol\n\ \t\t-m mtu\t\tfake MTU to use when sending out\n\ \t\t-P protocol\tSet protocol by name\n\ \t\t-s src\t\tsource address for IP packet\n\ \t\t-T\t\tSet TCP protocol\n\ \t\t-t port\t\tdestination port\n\ \t\t-U\t\tSet UDP protocol\n\ \t\t-v\tverbose mode\n\ \t\t-w \tSet the TCP window size\n\ ", prog); fprintf(stderr, "Usage: %s [-dv] -L \n\ \toptions:\n\ \t\t-d\tdebug mode\n\ \t\t-L filename\tUse IP language for sending packets\n\ \t\t-v\tverbose mode\n\ ", prog); exit(1); } static void do_icmp(ip, args) ip_t *ip; char *args; { struct icmp *ic; char *s; ip->ip_p = IPPROTO_ICMP; ip->ip_len += sizeof(*ic); ic = (struct icmp *)(ip + 1); bzero((char *)ic, sizeof(*ic)); if (!(s = strchr(args, ','))) { fprintf(stderr, "ICMP args missing: ,\n"); return; } *s++ = '\0'; ic->icmp_type = atoi(args); ic->icmp_code = atoi(s); if (ic->icmp_type == ICMP_REDIRECT && strchr(s, ',')) { char *t; t = strtok(s, ","); t = strtok(NULL, ","); if (resolve(t, (char *)&ic->icmp_gwaddr) == -1) { fprintf(stderr,"Cant resolve %s\n", t); exit(2); } if ((t = strtok(NULL, ","))) { if (resolve(t, (char *)&ic->icmp_ip.ip_dst) == -1) { fprintf(stderr,"Cant resolve %s\n", t); exit(2); } if ((t = strtok(NULL, ","))) { if (resolve(t, (char *)&ic->icmp_ip.ip_src) == -1) { fprintf(stderr,"Cant resolve %s\n", t); exit(2); } } } } } int send_packets(dev, mtu, ip, gwip) char *dev; int mtu; ip_t *ip; struct in_addr gwip; { int wfd; wfd = initdevice(dev, 5); if (wfd == -1) return -1; return send_packet(wfd, mtu, ip, gwip); } void udpcksum(ip_t *ip, struct udphdr *udp, int len) { union pseudoh { struct hdr { u_short len; u_char ttl; u_char proto; u_32_t src; u_32_t dst; } h; u_short w[6]; } ph; u_32_t temp32; u_short *opts; ph.h.len = htons(len); ph.h.ttl = 0; ph.h.proto = IPPROTO_UDP; ph.h.src = ip->ip_src.s_addr; ph.h.dst = ip->ip_dst.s_addr; temp32 = 0; opts = &ph.w[0]; temp32 += opts[0] + opts[1] + opts[2] + opts[3] + opts[4] + opts[5]; temp32 = (temp32 >> 16) + (temp32 & 65535); temp32 += (temp32 >> 16); udp->uh_sum = temp32 & 65535; udp->uh_sum = chksum((u_short *)udp, len); if (udp->uh_sum == 0) udp->uh_sum = 0xffff; } int main(argc, argv) int argc; char **argv; { FILE *langfile = NULL; struct in_addr gwip; tcphdr_t *tcp; udphdr_t *udp; ip_t *ip; char *name = argv[0], host[MAXHOSTNAMELEN + 1]; char *gateway = NULL, *dev = NULL; char *src = NULL, *dst, *s; int mtu = 1500, olen = 0, c, nonl = 0; /* * 65535 is maximum packet size...you never know... */ ip = (ip_t *)calloc(1, 65536); tcp = (tcphdr_t *)(ip + 1); udp = (udphdr_t *)tcp; ip->ip_len = sizeof(*ip); IP_HL_A(ip, sizeof(*ip) >> 2); while ((c = getopt(argc, argv, "I:L:P:TUdf:i:g:m:o:s:t:vw:")) != -1) { switch (c) { case 'I' : nonl++; if (ip->ip_p) { fprintf(stderr, "Protocol already set: %d\n", ip->ip_p); break; } do_icmp(ip, optarg); break; case 'L' : if (nonl) { fprintf(stderr, "Incorrect usage of -L option.\n"); usage(name); } if (!strcmp(optarg, "-")) langfile = stdin; else if (!(langfile = fopen(optarg, "r"))) { fprintf(stderr, "can't open file %s\n", optarg); exit(1); } iplang(langfile); return 0; case 'P' : { struct protoent *p; nonl++; if (ip->ip_p) { fprintf(stderr, "Protocol already set: %d\n", ip->ip_p); break; } if ((p = getprotobyname(optarg))) ip->ip_p = p->p_proto; else fprintf(stderr, "Unknown protocol: %s\n", optarg); break; } case 'T' : nonl++; if (ip->ip_p) { fprintf(stderr, "Protocol already set: %d\n", ip->ip_p); break; } ip->ip_p = IPPROTO_TCP; ip->ip_len += sizeof(tcphdr_t); break; case 'U' : nonl++; if (ip->ip_p) { fprintf(stderr, "Protocol already set: %d\n", ip->ip_p); break; } ip->ip_p = IPPROTO_UDP; ip->ip_len += sizeof(udphdr_t); break; case 'd' : opts |= OPT_DEBUG; break; case 'f' : nonl++; ip->ip_off = strtol(optarg, NULL, 0); break; case 'g' : nonl++; gateway = optarg; break; case 'i' : nonl++; dev = optarg; break; case 'm' : nonl++; mtu = atoi(optarg); if (mtu < 28) { fprintf(stderr, "mtu must be > 28\n"); exit(1); } break; case 'o' : nonl++; olen = buildopts(optarg, options, (IP_HL(ip) - 5) << 2); break; case 's' : nonl++; src = optarg; break; case 't' : nonl++; if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) tcp->th_dport = htons(atoi(optarg)); break; case 'v' : opts |= OPT_VERBOSE; break; case 'w' : nonl++; if (ip->ip_p == IPPROTO_TCP) tcp->th_win = atoi(optarg); else fprintf(stderr, "set protocol to TCP first\n"); break; default : fprintf(stderr, "Unknown option \"%c\"\n", c); usage(name); } } if (argc - optind < 1) usage(name); dst = argv[optind++]; if (!src) { gethostname(host, sizeof(host)); src = host; } if (resolve(src, (char *)&ip->ip_src) == -1) { fprintf(stderr,"Cant resolve %s\n", src); exit(2); } if (resolve(dst, (char *)&ip->ip_dst) == -1) { fprintf(stderr,"Cant resolve %s\n", dst); exit(2); } if (!gateway) gwip = ip->ip_dst; else if (resolve(gateway, (char *)&gwip) == -1) { fprintf(stderr,"Cant resolve %s\n", gateway); exit(2); } if (olen) { int hlen; char *p; printf("Options: %d\n", olen); hlen = sizeof(*ip) + olen; IP_HL_A(ip, hlen >> 2); ip->ip_len += olen; p = (char *)malloc(65536); if (p == NULL) { fprintf(stderr, "malloc failed\n"); exit(2); } bcopy(ip, p, sizeof(*ip)); bcopy(options, p + sizeof(*ip), olen); bcopy(ip + 1, p + hlen, ip->ip_len - hlen); ip = (ip_t *)p; if (ip->ip_p == IPPROTO_TCP) { tcp = (tcphdr_t *)(p + hlen); } else if (ip->ip_p == IPPROTO_UDP) { udp = (udphdr_t *)(p + hlen); } } if (ip->ip_p == IPPROTO_TCP) for (s = argv[optind]; s && (c = *s); s++) switch(c) { case 'S' : case 's' : tcp->th_flags |= TH_SYN; break; case 'A' : case 'a' : tcp->th_flags |= TH_ACK; break; case 'F' : case 'f' : tcp->th_flags |= TH_FIN; break; case 'R' : case 'r' : tcp->th_flags |= TH_RST; break; case 'P' : case 'p' : tcp->th_flags |= TH_PUSH; break; case 'U' : case 'u' : tcp->th_flags |= TH_URG; break; } if (!dev) dev = default_device; printf("Device: %s\n", dev); printf("Source: %s\n", inet_ntoa(ip->ip_src)); printf("Dest: %s\n", inet_ntoa(ip->ip_dst)); printf("Gateway: %s\n", inet_ntoa(gwip)); if (ip->ip_p == IPPROTO_TCP && tcp->th_flags) printf("Flags: %#x\n", tcp->th_flags); printf("mtu: %d\n", mtu); if (ip->ip_p == IPPROTO_UDP) { udp->uh_sum = 0; udpcksum(ip, udp, ip->ip_len - (IP_HL(ip) << 2)); } #ifdef DOSOCKET if (ip->ip_p == IPPROTO_TCP && tcp->th_dport) return do_socket(dev, mtu, ip, gwip); #endif return send_packets(dev, mtu, ip, gwip); } diff --git a/contrib/ipfilter/ipsend/iptest.c b/contrib/ipfilter/ipsend/iptest.c index bc93106c8b89..ffabaf37b5bc 100644 --- a/contrib/ipfilter/ipsend/iptest.c +++ b/contrib/ipfilter/ipsend/iptest.c @@ -1,205 +1,197 @@ /* $FreeBSD$ */ /* * ipsend.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" extern char *optarg; extern int optind; char options[68]; # ifdef sun char default_device[] = "le0"; # else -# ifdef ultrix -char default_device[] = "ln0"; -# else -# ifdef __bsdi__ -char default_device[] = "ef0"; -# else char default_device[] = "lan0"; -# endif -# endif # endif static void usage __P((char *)); int main __P((int, char **)); static void usage(prog) char *prog; { fprintf(stderr, "Usage: %s [options] dest\n\ \toptions:\n\ \t\t-d device\tSend out on this device\n\ \t\t-g gateway\tIP gateway to use if non-local dest.\n\ \t\t-m mtu\t\tfake MTU to use when sending out\n\ \t\t-p pointtest\t\n\ \t\t-s src\t\tsource address for IP packet\n\ \t\t-1 \t\tPerform test 1 (IP header)\n\ \t\t-2 \t\tPerform test 2 (IP options)\n\ \t\t-3 \t\tPerform test 3 (ICMP)\n\ \t\t-4 \t\tPerform test 4 (UDP)\n\ \t\t-5 \t\tPerform test 5 (TCP)\n\ \t\t-6 \t\tPerform test 6 (overlapping fragments)\n\ \t\t-7 \t\tPerform test 7 (random packets)\n\ ", prog); exit(1); } int main(argc, argv) int argc; char **argv; { struct tcpiphdr *ti; struct in_addr gwip; ip_t *ip; char *name = argv[0], host[MAXHOSTNAMELEN + 1]; char *gateway = NULL, *dev = NULL; char *src = NULL, *dst; int mtu = 1500, tests = 0, pointtest = 0, c; /* * 65535 is maximum packet size...you never know... */ ip = (ip_t *)calloc(1, 65536); ti = (struct tcpiphdr *)ip; ip->ip_len = sizeof(*ip); IP_HL_A(ip, sizeof(*ip) >> 2); while ((c = getopt(argc, argv, "1234567d:g:m:p:s:")) != -1) switch (c) { case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : tests = c - '0'; break; case 'd' : dev = optarg; break; case 'g' : gateway = optarg; break; case 'm' : mtu = atoi(optarg); if (mtu < 28) { fprintf(stderr, "mtu must be > 28\n"); exit(1); } break; case 'p' : pointtest = atoi(optarg); break; case 's' : src = optarg; break; default : fprintf(stderr, "Unknown option \"%c\"\n", c); usage(name); } if ((argc <= optind) || !argv[optind]) usage(name); dst = argv[optind++]; if (!src) { gethostname(host, sizeof(host)); host[sizeof(host) - 1] = '\0'; src = host; } if (resolve(dst, (char *)&ip->ip_dst) == -1) { fprintf(stderr,"Cant resolve %s\n", dst); exit(2); } if (resolve(src, (char *)&ip->ip_src) == -1) { fprintf(stderr,"Cant resolve %s\n", src); exit(2); } if (!gateway) gwip = ip->ip_dst; else if (resolve(gateway, (char *)&gwip) == -1) { fprintf(stderr,"Cant resolve %s\n", gateway); exit(2); } if (!dev) dev = default_device; printf("Device: %s\n", dev); printf("Source: %s\n", inet_ntoa(ip->ip_src)); printf("Dest: %s\n", inet_ntoa(ip->ip_dst)); printf("Gateway: %s\n", inet_ntoa(gwip)); printf("mtu: %d\n", mtu); switch (tests) { case 1 : ip_test1(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 2 : ip_test2(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 3 : ip_test3(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 4 : ip_test4(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 5 : ip_test5(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 6 : ip_test6(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 7 : ip_test7(dev, mtu, (ip_t *)ti, gwip, pointtest); break; default : ip_test1(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test2(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test3(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test4(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test5(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test6(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test7(dev, mtu, (ip_t *)ti, gwip, pointtest); break; } return 0; } diff --git a/contrib/ipfilter/ipsend/iptests.c b/contrib/ipfilter/ipsend/iptests.c index af8772cc2097..86b850d319bb 100644 --- a/contrib/ipfilter/ipsend/iptests.c +++ b/contrib/ipfilter/ipsend/iptests.c @@ -1,1404 +1,1397 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #if defined(__NetBSD__) && defined(__vax__) /* * XXX need to declare boolean_t for _KERNEL * which ends up including for vax. See PR#32907 * for further details. */ typedef int boolean_t; #endif #include # ifdef __NetBSD__ # include # include # endif # define _KERNEL # define KERNEL # if !defined(solaris) && !defined(linux) && !defined(__sgi) && !defined(hpux) # include # else # ifdef solaris # include # endif # endif # undef _KERNEL # undef KERNEL -#if !defined(solaris) && !defined(linux) && !defined(__sgi) +#if !defined(solaris) # include # include # include #endif -#if !defined(ultrix) && !defined(hpux) && !defined(linux) && \ - !defined(__sgi) && !defined(__osf__) && !defined(_AIX51) # include -#endif -#ifndef ultrix # include -#endif #if defined(solaris) # include #else # include #endif #ifdef sun #include #include #endif -#if BSD >= 199103 # include # include # include -#endif #include #include #include # if defined(__FreeBSD__) # include "radix_ipf.h" # endif # if !defined(solaris) # include # endif #include #include #include -#if defined(__SVR4) || defined(__svr4__) || defined(__sgi) +#if defined(__SVR4) || defined(__svr4__) # include #endif #include #include #include #include # include -# if !defined(__hpux) && !defined(solaris) +# if !defined(solaris) # include # endif #include "ipsend.h" # include # include #if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106000000) # define USE_NANOSLEEP #endif #ifdef USE_NANOSLEEP # define PAUSE() ts.tv_sec = 0; ts.tv_nsec = 10000000; \ (void) nanosleep(&ts, NULL) #else # define PAUSE() tv.tv_sec = 0; tv.tv_usec = 10000; \ (void) select(0, NULL, NULL, NULL, &tv) #endif void ip_test1(dev, mtu, ip, gwip, ptest) char *dev; int mtu; ip_t *ip; struct in_addr gwip; int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif udphdr_t *u; int nfd, i = 0, len, id = getpid(); IP_HL_A(ip, sizeof(*ip) >> 2); IP_V_A(ip, IPVERSION); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = 60; ip->ip_p = IPPROTO_UDP; ip->ip_sum = 0; u = (udphdr_t *)(ip + 1); u->uh_sport = htons(1); u->uh_dport = htons(9); u->uh_sum = 0; u->uh_ulen = htons(sizeof(*u) + 4); ip->ip_len = sizeof(*ip) + ntohs(u->uh_ulen); len = ip->ip_len; nfd = initdevice(dev, 1); if (nfd == -1) return; if (!ptest || (ptest == 1)) { /* * Part1: hl < len */ ip->ip_id = 0; printf("1.1. sending packets with ip_hl < ip_len\n"); for (i = 0; i < ((sizeof(*ip) + ntohs(u->uh_ulen)) >> 2); i++) { IP_HL_A(ip, i >> 2); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 2)) { /* * Part2: hl > len */ ip->ip_id = 0; printf("1.2. sending packets with ip_hl > ip_len\n"); for (; i < ((sizeof(*ip) * 2 + ntohs(u->uh_ulen)) >> 2); i++) { IP_HL_A(ip, i >> 2); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 3)) { /* * Part3: v < 4 */ ip->ip_id = 0; printf("1.3. ip_v < 4\n"); IP_HL_A(ip, sizeof(*ip) >> 2); for (i = 0; i < 4; i++) { IP_V_A(ip, i); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 4)) { /* * Part4: v > 4 */ ip->ip_id = 0; printf("1.4. ip_v > 4\n"); for (i = 5; i < 16; i++) { IP_V_A(ip, i); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 5)) { /* * Part5: len < packet */ ip->ip_id = 0; IP_V_A(ip, IPVERSION); i = ip->ip_len + 1; printf("1.5.0 ip_len < packet size (size++, long packets)\n"); for (; i < (ip->ip_len * 2); i++) { ip->ip_id = htons(id++); ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); (void) send_ether(nfd, (char *)ip, i, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); printf("1.5.1 ip_len < packet size (ip_len-, short packets)\n"); for (i = len; i > 0; i--) { ip->ip_id = htons(id++); ip->ip_len = i; ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); (void) send_ether(nfd, (char *)ip, len, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 6)) { /* * Part6: len > packet */ ip->ip_id = 0; printf("1.6.0 ip_len > packet size (increase ip_len)\n"); for (i = len + 1; i < (len * 2); i++) { ip->ip_id = htons(id++); ip->ip_len = i; ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); (void) send_ether(nfd, (char *)ip, len, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); ip->ip_len = len; printf("1.6.1 ip_len > packet size (size--, short packets)\n"); for (i = len; i > 0; i--) { ip->ip_id = htons(id++); ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); (void) send_ether(nfd, (char *)ip, i, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 7)) { /* * Part7: 0 length fragment */ printf("1.7.0 Zero length fragments (ip_off = 0x2000)\n"); ip->ip_id = 0; ip->ip_len = sizeof(*ip); ip->ip_off = htons(IP_MF); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("1.7.1 Zero length fragments (ip_off = 0x3000)\n"); ip->ip_id = 0; ip->ip_len = sizeof(*ip); ip->ip_off = htons(IP_MF); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("1.7.2 Zero length fragments (ip_off = 0xa000)\n"); ip->ip_id = 0; ip->ip_len = sizeof(*ip); ip->ip_off = htons(0xa000); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("1.7.3 Zero length fragments (ip_off = 0x0100)\n"); ip->ip_id = 0; ip->ip_len = sizeof(*ip); ip->ip_off = htons(0x0100); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 8)) { struct timeval tv; gettimeofday(&tv, NULL); srand(tv.tv_sec ^ getpid() ^ tv.tv_usec); /* * Part8.1: 63k packet + 1k fragment at offset 0x1ffe * Mark it as being ICMP (so it doesn't get junked), but * don't bother about the ICMP header, we're not worrying * about that here. */ ip->ip_p = IPPROTO_ICMP; ip->ip_off = htons(IP_MF); u->uh_dport = htons(9); ip->ip_id = htons(id++); printf("1.8.1 63k packet + 1k fragment at offset 0x1ffe\n"); ip->ip_len = 768 + 20 + 8; (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); ip->ip_len = MIN(768 + 20, mtu - 68); i = 512; for (; i < (63 * 1024 + 768); i += 768) { ip->ip_off = htons(IP_MF | (i >> 3)); (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } ip->ip_len = 896 + 20; ip->ip_off = htons(i >> 3); (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); putchar('\n'); fflush(stdout); /* * Part8.2: 63k packet + 1k fragment at offset 0x1ffe * Mark it as being ICMP (so it doesn't get junked), but * don't bother about the ICMP header, we're not worrying * about that here. (Lossage here) */ ip->ip_p = IPPROTO_ICMP; ip->ip_off = htons(IP_MF); u->uh_dport = htons(9); ip->ip_id = htons(id++); printf("1.8.2 63k packet + 1k fragment at offset 0x1ffe\n"); ip->ip_len = 768 + 20 + 8; if ((rand() & 0x1f) != 0) { (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); } else printf("skip 0\n"); ip->ip_len = MIN(768 + 20, mtu - 68); i = 512; for (; i < (63 * 1024 + 768); i += 768) { ip->ip_off = htons(IP_MF | (i >> 3)); if ((rand() & 0x1f) != 0) { (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); } else printf("skip %d\n", i); fflush(stdout); PAUSE(); } ip->ip_len = 896 + 20; ip->ip_off = htons(i >> 3); if ((rand() & 0x1f) != 0) { (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); } else printf("skip\n"); putchar('\n'); fflush(stdout); /* * Part8.3: 33k packet - test for not dealing with -ve length * Mark it as being ICMP (so it doesn't get junked), but * don't bother about the ICMP header, we're not worrying * about that here. */ ip->ip_p = IPPROTO_ICMP; ip->ip_off = htons(IP_MF); u->uh_dport = htons(9); ip->ip_id = htons(id++); printf("1.8.3 33k packet\n"); ip->ip_len = 768 + 20 + 8; (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); ip->ip_len = MIN(768 + 20, mtu - 68); i = 512; for (; i < (32 * 1024 + 768); i += 768) { ip->ip_off = htons(IP_MF | (i >> 3)); (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } ip->ip_len = 896 + 20; ip->ip_off = htons(i >> 3); (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); putchar('\n'); fflush(stdout); } ip->ip_len = len; ip->ip_off = 0; if (!ptest || (ptest == 9)) { /* * Part9: off & 0x8000 == 0x8000 */ ip->ip_id = 0; ip->ip_off = htons(0x8000); printf("1.9. ip_off & 0x8000 == 0x8000\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } ip->ip_off = 0; if (!ptest || (ptest == 10)) { /* * Part10: ttl = 255 */ ip->ip_id = 0; ip->ip_ttl = 255; printf("1.10.0 ip_ttl = 255\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); ip->ip_ttl = 128; printf("1.10.1 ip_ttl = 128\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); ip->ip_ttl = 0; printf("1.10.2 ip_ttl = 0\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } (void) close(nfd); } void ip_test2(dev, mtu, ip, gwip, ptest) char *dev; int mtu; ip_t *ip; struct in_addr gwip; int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif int nfd; u_char *s; nfd = initdevice(dev, 1); if (nfd == -1) return; IP_HL_A(ip, 6); ip->ip_len = IP_HL(ip) << 2; s = (u_char *)(ip + 1); s[IPOPT_OPTVAL] = IPOPT_NOP; s++; if (!ptest || (ptest == 1)) { /* * Test 1: option length > packet length, * header length == packet length */ s[IPOPT_OPTVAL] = IPOPT_TS; s[IPOPT_OLEN] = 4; s[IPOPT_OFFSET] = IPOPT_MINOFF; ip->ip_p = IPPROTO_IP; printf("2.1 option length > packet length\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } IP_HL_A(ip, 7); ip->ip_len = IP_HL(ip) << 2; if (!ptest || (ptest == 1)) { /* * Test 2: options have length = 0 */ printf("2.2.1 option length = 0, RR\n"); s[IPOPT_OPTVAL] = IPOPT_RR; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.2 option length = 0, TS\n"); s[IPOPT_OPTVAL] = IPOPT_TS; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.3 option length = 0, SECURITY\n"); s[IPOPT_OPTVAL] = IPOPT_SECURITY; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.4 option length = 0, LSRR\n"); s[IPOPT_OPTVAL] = IPOPT_LSRR; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.5 option length = 0, SATID\n"); s[IPOPT_OPTVAL] = IPOPT_SATID; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.6 option length = 0, SSRR\n"); s[IPOPT_OPTVAL] = IPOPT_SSRR; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } (void) close(nfd); } /* * test 3 (ICMP) */ void ip_test3(dev, mtu, ip, gwip, ptest) char *dev; int mtu; ip_t *ip; struct in_addr gwip; int ptest; { static int ict1[10] = { 8, 9, 10, 13, 14, 15, 16, 17, 18, 0 }; static int ict2[8] = { 3, 9, 10, 13, 14, 17, 18, 0 }; #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif struct icmp *icp; int nfd, i; IP_HL_A(ip, sizeof(*ip) >> 2); IP_V_A(ip, IPVERSION); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = 60; ip->ip_p = IPPROTO_ICMP; ip->ip_sum = 0; ip->ip_len = sizeof(*ip) + sizeof(*icp); icp = (struct icmp *)((char *)ip + (IP_HL(ip) << 2)); nfd = initdevice(dev, 1); if (nfd == -1) return; if (!ptest || (ptest == 1)) { /* * Type 0 - 31, 255, code = 0 */ bzero((char *)icp, sizeof(*icp)); for (i = 0; i < 32; i++) { icp->icmp_type = i; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.1.%d ICMP type %d code 0 (all 0's)\r", i, i); } icp->icmp_type = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.1.%d ICMP type %d code 0 (all 0's)\r", i, 255); putchar('\n'); } if (!ptest || (ptest == 2)) { /* * Type 3, code = 0 - 31 */ icp->icmp_type = 3; for (i = 0; i < 32; i++) { icp->icmp_code = i; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.2.%d ICMP type 3 code %d (all 0's)\r", i, i); } } if (!ptest || (ptest == 3)) { /* * Type 4, code = 0,127,128,255 */ icp->icmp_type = 4; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.3.1 ICMP type 4 code 0 (all 0's)\r"); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.3.2 ICMP type 4 code 127 (all 0's)\r"); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.3.3 ICMP type 4 code 128 (all 0's)\r"); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.3.4 ICMP type 4 code 255 (all 0's)\r"); } if (!ptest || (ptest == 4)) { /* * Type 5, code = 0,127,128,255 */ icp->icmp_type = 5; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.4.1 ICMP type 5 code 0 (all 0's)\r"); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.4.2 ICMP type 5 code 127 (all 0's)\r"); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.4.3 ICMP type 5 code 128 (all 0's)\r"); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.4.4 ICMP type 5 code 255 (all 0's)\r"); } if (!ptest || (ptest == 5)) { /* * Type 8-10;13-18, code - 0,127,128,255 */ for (i = 0; ict1[i]; i++) { icp->icmp_type = ict1[i]; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type 5 code 0 (all 0's)\r", i * 4); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type 5 code 127 (all 0's)\r", i * 4 + 1); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type 5 code 128 (all 0's)\r", i * 4 + 2); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type 5 code 255 (all 0's)\r", i * 4 + 3); } putchar('\n'); } if (!ptest || (ptest == 6)) { /* * Type 12, code - 0,127,128,129,255 */ icp->icmp_type = 12; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.1 ICMP type 12 code 0 (all 0's)\r"); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.2 ICMP type 12 code 127 (all 0's)\r"); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.3 ICMP type 12 code 128 (all 0's)\r"); icp->icmp_code = 129; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.4 ICMP type 12 code 129 (all 0's)\r"); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.5 ICMP type 12 code 255 (all 0's)\r"); putchar('\n'); } if (!ptest || (ptest == 7)) { /* * Type 3;9-10;13-14;17-18 - shorter packets */ ip->ip_len = sizeof(*ip) + sizeof(*icp) / 2; for (i = 0; ict2[i]; i++) { icp->icmp_type = ict1[i]; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type %d code 0 (all 0's)\r", i * 4, icp->icmp_type); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type %d code 127 (all 0's)\r", i * 4 + 1, icp->icmp_type); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type %d code 128 (all 0's)\r", i * 4 + 2, icp->icmp_type); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type %d code 127 (all 0's)\r", i * 4 + 3, icp->icmp_type); } putchar('\n'); } } /* Perform test 4 (UDP) */ void ip_test4(dev, mtu, ip, gwip, ptest) char *dev; int mtu; ip_t *ip; struct in_addr gwip; int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif udphdr_t *u; int nfd, i; IP_HL_A(ip, sizeof(*ip) >> 2); IP_V_A(ip, IPVERSION); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = 60; ip->ip_p = IPPROTO_UDP; ip->ip_sum = 0; u = (udphdr_t *)((char *)ip + (IP_HL(ip) << 2)); u->uh_sport = htons(1); u->uh_dport = htons(1); u->uh_ulen = htons(sizeof(*u) + 4); nfd = initdevice(dev, 1); if (nfd == -1) return; if (!ptest || (ptest == 1)) { /* * Test 1. ulen > packet */ u->uh_ulen = htons(sizeof(*u) + 4); ip->ip_len = (IP_HL(ip) << 2) + ntohs(u->uh_ulen); printf("4.1 UDP uh_ulen > packet size - short packets\n"); for (i = ntohs(u->uh_ulen) * 2; i > sizeof(*u) + 4; i--) { u->uh_ulen = htons(i); (void) send_udp(nfd, 1500, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 2)) { /* * Test 2. ulen < packet */ u->uh_ulen = htons(sizeof(*u) + 4); ip->ip_len = (IP_HL(ip) << 2) + ntohs(u->uh_ulen); printf("4.2 UDP uh_ulen < packet size - short packets\n"); for (i = ntohs(u->uh_ulen) * 2; i > sizeof(*u) + 4; i--) { ip->ip_len = i; (void) send_udp(nfd, 1500, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 3)) { /* * Test 3: sport = 0, sport = 1, sport = 32767 * sport = 32768, sport = 65535 */ u->uh_ulen = sizeof(*u) + 4; ip->ip_len = (IP_HL(ip) << 2) + ntohs(u->uh_ulen); printf("4.3.1 UDP sport = 0\n"); u->uh_sport = 0; (void) send_udp(nfd, 1500, ip, gwip); printf("0\n"); fflush(stdout); PAUSE(); printf("4.3.2 UDP sport = 1\n"); u->uh_sport = htons(1); (void) send_udp(nfd, 1500, ip, gwip); printf("1\n"); fflush(stdout); PAUSE(); printf("4.3.3 UDP sport = 32767\n"); u->uh_sport = htons(32767); (void) send_udp(nfd, 1500, ip, gwip); printf("32767\n"); fflush(stdout); PAUSE(); printf("4.3.4 UDP sport = 32768\n"); u->uh_sport = htons(32768); (void) send_udp(nfd, 1500, ip, gwip); printf("32768\n"); putchar('\n'); fflush(stdout); PAUSE(); printf("4.3.5 UDP sport = 65535\n"); u->uh_sport = htons(65535); (void) send_udp(nfd, 1500, ip, gwip); printf("65535\n"); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 4)) { /* * Test 4: dport = 0, dport = 1, dport = 32767 * dport = 32768, dport = 65535 */ u->uh_ulen = ntohs(sizeof(*u) + 4); u->uh_sport = htons(1); ip->ip_len = (IP_HL(ip) << 2) + ntohs(u->uh_ulen); printf("4.4.1 UDP dport = 0\n"); u->uh_dport = 0; (void) send_udp(nfd, 1500, ip, gwip); printf("0\n"); fflush(stdout); PAUSE(); printf("4.4.2 UDP dport = 1\n"); u->uh_dport = htons(1); (void) send_udp(nfd, 1500, ip, gwip); printf("1\n"); fflush(stdout); PAUSE(); printf("4.4.3 UDP dport = 32767\n"); u->uh_dport = htons(32767); (void) send_udp(nfd, 1500, ip, gwip); printf("32767\n"); fflush(stdout); PAUSE(); printf("4.4.4 UDP dport = 32768\n"); u->uh_dport = htons(32768); (void) send_udp(nfd, 1500, ip, gwip); printf("32768\n"); fflush(stdout); PAUSE(); printf("4.4.5 UDP dport = 65535\n"); u->uh_dport = htons(65535); (void) send_udp(nfd, 1500, ip, gwip); printf("65535\n"); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 5)) { /* * Test 5: sizeof(ip_t) <= MTU <= sizeof(udphdr_t) + * sizeof(ip_t) */ printf("4.5 UDP 20 <= MTU <= 32\n"); for (i = sizeof(*ip); i <= ntohs(u->uh_ulen); i++) { (void) send_udp(nfd, i, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } } /* Perform test 5 (TCP) */ void ip_test5(dev, mtu, ip, gwip, ptest) char *dev; int mtu; ip_t *ip; struct in_addr gwip; int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif tcphdr_t *t; int nfd, i; t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); t->th_x2 = 0; TCP_OFF_A(t, 0); t->th_sport = htons(1); t->th_dport = htons(1); t->th_win = htons(4096); t->th_urp = 0; t->th_sum = 0; t->th_seq = htonl(1); t->th_ack = 0; ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t); nfd = initdevice(dev, 1); if (nfd == -1) return; if (!ptest || (ptest == 1)) { /* * Test 1: flags variations, 0 - 3f */ TCP_OFF_A(t, sizeof(*t) >> 2); printf("5.1 Test TCP flag combinations\n"); for (i = 0; i <= (TH_URG|TH_ACK|TH_PUSH|TH_RST|TH_SYN|TH_FIN); i++) { t->th_flags = i; (void) send_tcp(nfd, mtu, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 2)) { t->th_flags = TH_SYN; /* * Test 2: seq = 0, seq = 1, seq = 0x7fffffff, seq=0x80000000, * seq = 0xa000000, seq = 0xffffffff */ printf("5.2.1 TCP seq = 0\n"); t->th_seq = htonl(0); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.2 TCP seq = 1\n"); t->th_seq = htonl(1); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.3 TCP seq = 0x7fffffff\n"); t->th_seq = htonl(0x7fffffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.4 TCP seq = 0x80000000\n"); t->th_seq = htonl(0x80000000); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.5 TCP seq = 0xc0000000\n"); t->th_seq = htonl(0xc0000000); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.6 TCP seq = 0xffffffff\n"); t->th_seq = htonl(0xffffffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 3)) { t->th_flags = TH_ACK; /* * Test 3: ack = 0, ack = 1, ack = 0x7fffffff, ack = 0x8000000 * ack = 0xa000000, ack = 0xffffffff */ printf("5.3.1 TCP ack = 0\n"); t->th_ack = 0; (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.2 TCP ack = 1\n"); t->th_ack = htonl(1); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.3 TCP ack = 0x7fffffff\n"); t->th_ack = htonl(0x7fffffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.4 TCP ack = 0x80000000\n"); t->th_ack = htonl(0x80000000); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.5 TCP ack = 0xc0000000\n"); t->th_ack = htonl(0xc0000000); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.6 TCP ack = 0xffffffff\n"); t->th_ack = htonl(0xffffffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 4)) { t->th_flags = TH_SYN; /* * Test 4: win = 0, win = 32768, win = 65535 */ printf("5.4.1 TCP win = 0\n"); t->th_seq = htonl(0); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.4.2 TCP win = 32768\n"); t->th_seq = htonl(0x7fff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.4.3 TCP win = 65535\n"); t->th_win = htons(0xffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } #if !defined(linux) && !defined(__SVR4) && !defined(__svr4__) && \ !defined(__sgi) && !defined(__hpux) && !defined(__osf__) { struct tcpcb *tcbp, tcb; struct tcpiphdr ti; struct sockaddr_in sin; int fd; socklen_t slen; bzero((char *)&sin, sizeof(sin)); for (i = 1; i < 63; i++) { fd = socket(AF_INET, SOCK_STREAM, 0); bzero((char *)&sin, sizeof(sin)); sin.sin_addr.s_addr = ip->ip_dst.s_addr; sin.sin_port = htons(i); sin.sin_family = AF_INET; if (!connect(fd, (struct sockaddr *)&sin, sizeof(sin))) break; close(fd); } if (i == 63) { printf("Couldn't open a TCP socket between ports 1 and 63\n"); printf("to host %s for test 5 and 6 - skipping.\n", inet_ntoa(ip->ip_dst)); goto skip_five_and_six; } bcopy((char *)ip, (char *)&ti, sizeof(*ip)); t->th_dport = htons(i); slen = sizeof(sin); if (!getsockname(fd, (struct sockaddr *)&sin, &slen)) t->th_sport = sin.sin_port; if (!(tcbp = find_tcp(fd, &ti))) { printf("Can't find PCB\n"); goto skip_five_and_six; } KMCPY(&tcb, tcbp, sizeof(tcb)); ti.ti_win = tcb.rcv_adv; ti.ti_seq = htonl(tcb.snd_nxt - 1); ti.ti_ack = tcb.rcv_nxt; if (!ptest || (ptest == 5)) { /* * Test 5: urp */ t->th_flags = TH_ACK|TH_URG; printf("5.5.1 TCP Urgent pointer, sport %hu dport %hu\n", ntohs(t->th_sport), ntohs(t->th_dport)); t->th_urp = htons(1); (void) send_tcp(nfd, mtu, ip, gwip); PAUSE(); t->th_seq = htonl(tcb.snd_nxt); ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t) + 1; t->th_urp = htons(0x7fff); (void) send_tcp(nfd, mtu, ip, gwip); PAUSE(); t->th_urp = htons(0x8000); (void) send_tcp(nfd, mtu, ip, gwip); PAUSE(); t->th_urp = htons(0xffff); (void) send_tcp(nfd, mtu, ip, gwip); PAUSE(); t->th_urp = 0; t->th_flags &= ~TH_URG; ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t); } if (!ptest || (ptest == 6)) { /* * Test 6: data offset, off = 0, off is inside, off is outside */ t->th_flags = TH_ACK; printf("5.6.1 TCP off = 1-15, len = 40\n"); for (i = 1; i < 16; i++) { TCP_OFF_A(t, ntohs(i)); (void) send_tcp(nfd, mtu, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t); } (void) close(fd); } skip_five_and_six: #endif t->th_seq = htonl(1); t->th_ack = htonl(1); TCP_OFF_A(t, 0); if (!ptest || (ptest == 7)) { t->th_flags = TH_SYN; /* * Test 7: sport = 0, sport = 1, sport = 32767 * sport = 32768, sport = 65535 */ printf("5.7.1 TCP sport = 0\n"); t->th_sport = 0; (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.7.2 TCP sport = 1\n"); t->th_sport = htons(1); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.7.3 TCP sport = 32767\n"); t->th_sport = htons(32767); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.7.4 TCP sport = 32768\n"); t->th_sport = htons(32768); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.7.5 TCP sport = 65535\n"); t->th_sport = htons(65535); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 8)) { t->th_sport = htons(1); t->th_flags = TH_SYN; /* * Test 8: dport = 0, dport = 1, dport = 32767 * dport = 32768, dport = 65535 */ printf("5.8.1 TCP dport = 0\n"); t->th_dport = 0; (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.8.2 TCP dport = 1\n"); t->th_dport = htons(1); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.8.3 TCP dport = 32767\n"); t->th_dport = htons(32767); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.8.4 TCP dport = 32768\n"); t->th_dport = htons(32768); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.8.5 TCP dport = 65535\n"); t->th_dport = htons(65535); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } /* LAND attack - self connect, so make src & dst ip/port the same */ if (!ptest || (ptest == 9)) { printf("5.9 TCP LAND attack. sport = 25, dport = 25\n"); /* chose SMTP port 25 */ t->th_sport = htons(25); t->th_dport = htons(25); t->th_flags = TH_SYN; ip->ip_src = ip->ip_dst; (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } /* TCP options header checking */ /* 0 length options, etc */ } /* Perform test 6 (exhaust mbuf test) */ void ip_test6(dev, mtu, ip, gwip, ptest) char *dev; int mtu; ip_t *ip; struct in_addr gwip; int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif udphdr_t *u; int nfd, i, j, k; IP_V_A(ip, IPVERSION); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = 60; ip->ip_p = IPPROTO_UDP; ip->ip_sum = 0; u = (udphdr_t *)(ip + 1); u->uh_sport = htons(1); u->uh_dport = htons(9); u->uh_sum = 0; nfd = initdevice(dev, 1); if (nfd == -1) return; u->uh_ulen = htons(7168); printf("6. Exhaustive mbuf test.\n"); printf(" Send 7k packet in 768 & 128 byte fragments, 128 times.\n"); printf(" Total of around 8,900 packets\n"); for (i = 0; i < 128; i++) { /* * First send the entire packet in 768 byte chunks. */ ip->ip_len = sizeof(*ip) + 768 + sizeof(*u); IP_HL_A(ip, sizeof(*ip) >> 2); ip->ip_off = htons(IP_MF); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d %d\r", i, 0); fflush(stdout); PAUSE(); /* * And again using 128 byte chunks. */ ip->ip_len = sizeof(*ip) + 128 + sizeof(*u); ip->ip_off = htons(IP_MF); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d %d\r", i, 0); fflush(stdout); PAUSE(); for (j = 768; j < 3584; j += 768) { ip->ip_len = sizeof(*ip) + 768; ip->ip_off = htons(IP_MF|(j>>3)); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d %d\r", i, j); fflush(stdout); PAUSE(); ip->ip_len = sizeof(*ip) + 128; for (k = j - 768; k < j; k += 128) { ip->ip_off = htons(IP_MF|(k>>3)); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d %d\r", i, k); fflush(stdout); PAUSE(); } } } putchar('\n'); } /* Perform test 7 (random packets) */ static u_long tbuf[64]; void ip_test7(dev, mtu, ip, gwip, ptest) char *dev; int mtu; ip_t *ip; struct in_addr gwip; int ptest; { ip_t *pip; #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif int nfd, i, j; u_char *s; nfd = initdevice(dev, 1); if (nfd == -1) return; pip = (ip_t *)tbuf; srand(time(NULL) ^ (getpid() * getppid())); printf("7. send 1024 random IP packets.\n"); for (i = 0; i < 512; i++) { for (s = (u_char *)pip, j = 0; j < sizeof(tbuf); j++, s++) *s = (rand() >> 13) & 0xff; IP_V_A(pip, IPVERSION); bcopy((char *)&ip->ip_dst, (char *)&pip->ip_dst, sizeof(struct in_addr)); pip->ip_sum = 0; pip->ip_len &= 0xff; (void) send_ip(nfd, mtu, pip, gwip, 0); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); for (i = 0; i < 512; i++) { for (s = (u_char *)pip, j = 0; j < sizeof(tbuf); j++, s++) *s = (rand() >> 13) & 0xff; IP_V_A(pip, IPVERSION); pip->ip_off &= htons(0xc000); bcopy((char *)&ip->ip_dst, (char *)&pip->ip_dst, sizeof(struct in_addr)); pip->ip_sum = 0; pip->ip_len &= 0xff; (void) send_ip(nfd, mtu, pip, gwip, 0); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } diff --git a/contrib/ipfilter/ipsend/sock.c b/contrib/ipfilter/ipsend/sock.c index d7eae8a13196..66e1a0aa897e 100644 --- a/contrib/ipfilter/ipsend/sock.c +++ b/contrib/ipfilter/ipsend/sock.c @@ -1,455 +1,322 @@ /* $FreeBSD$ */ /* * sock.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #if defined(__NetBSD__) && defined(__vax__) /* * XXX need to declare boolean_t for _KERNEL * which ends up including for vax. See PR#32907 * for further details. */ typedef int boolean_t; #endif -#ifndef ultrix #include -#endif -#if (__FreeBSD_version >= 300000) # include -#else -# include -#endif # ifdef __NetBSD__ # include # endif # ifdef __FreeBSD__ # define _WANT_FILE # else # define _KERNEL # define KERNEL # endif -# ifdef ultrix -# undef LOCORE -# include -# endif # include # ifdef __FreeBSD__ # undef _WANT_FILE # else # undef _KERNEL # undef KERNEL # endif #include #include #include #include #include -#if !defined(ultrix) && !defined(hpux) && !defined(__osf__) # include -#endif #ifdef sun #include #include #endif -#if BSD >= 199103 #include #include #include -#endif #include #include #include #include #include #include # include #include #define _WANT_INPCB #include #include #define _WANT_TCPCB #include #include #include #include #include #include #include #include "ipsend.h" int nproc; struct proc *proc; #ifndef KMEM # ifdef _PATH_KMEM # define KMEM _PATH_KMEM # endif #endif #ifndef KERNEL # ifdef _PATH_UNIX # define KERNEL _PATH_UNIX # endif #endif #ifndef KMEM # define KMEM "/dev/kmem" #endif #ifndef KERNEL # define KERNEL "/vmunix" #endif #if BSD < 199103 static struct proc *getproc __P((void)); #else static struct kinfo_proc *getproc __P((void)); #endif int kmemcpy(buf, pos, n) char *buf; void *pos; int n; { static int kfd = -1; off_t offset = (u_long)pos; if (kfd == -1) kfd = open(KMEM, O_RDONLY); if (lseek(kfd, offset, SEEK_SET) == -1) { perror("lseek"); return -1; } if (read(kfd, buf, n) == -1) { perror("read"); return -1; } return n; } struct nlist names[4] = { { "_proc" }, { "_nproc" }, -#ifdef ultrix - { "_u" }, -#else { NULL }, -#endif { NULL } }; -#if BSD < 199103 -static struct proc *getproc() -{ - struct proc *p; - pid_t pid = getpid(); - int siz, n; - - n = nlist(KERNEL, names); - if (n != 0) - { - fprintf(stderr, "nlist(%#x) == %d\n", names, n); - return NULL; - } - if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) - { - fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); - return NULL; - } - siz = nproc * sizeof(struct proc); - if (KMCPY(&p, names[0].n_value, sizeof(p)) == -1) - { - fprintf(stderr, "read(%#x,%#x,%d) proc\n", - names[0].n_value, &p, sizeof(p)); - return NULL; - } - proc = (struct proc *)malloc(siz); - if (KMCPY(proc, p, siz) == -1) - { - fprintf(stderr, "read(%#x,%#x,%d) proc\n", - p, proc, siz); - return NULL; - } - - p = proc; - - for (n = nproc; n; n--, p++) - if (p->p_pid == pid) - break; - if (!n) - return NULL; - - return p; -} - - -struct tcpcb *find_tcp(fd, ti) - int fd; - struct tcpiphdr *ti; -{ - struct tcpcb *t; - struct inpcb *i; - struct socket *s; - struct user *up; - struct proc *p; - struct file *f, **o; - - if (!(p = getproc())) - return NULL; - up = (struct user *)malloc(sizeof(*up)); -#ifndef ultrix - if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1) - { - fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea); - return NULL; - } -#else - if (KMCPY(up, names[2].n_value, sizeof(*up)) == -1) - { - fprintf(stderr, "read(%#x,%#x) failed\n", p, names[2].n_value); - return NULL; - } -#endif - - o = (struct file **)calloc(up->u_lastfile + 1, sizeof(*o)); - if (KMCPY(o, up->u_ofile, (up->u_lastfile + 1) * sizeof(*o)) == -1) - { - fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n", - up->u_ofile, o, sizeof(*o)); - return NULL; - } - f = (struct file *)calloc(1, sizeof(*f)); - if (KMCPY(f, o[fd], sizeof(*f)) == -1) - { - fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", - up->u_ofile[fd], f, sizeof(*f)); - return NULL; - } - - s = (struct socket *)calloc(1, sizeof(*s)); - if (KMCPY(s, f->f_data, sizeof(*s)) == -1) - { - fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n", - o[fd], s, sizeof(*s)); - return NULL; - } - - i = (struct inpcb *)calloc(1, sizeof(*i)); - if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) - { - fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n", - s->so_pcb, i, sizeof(*i)); - return NULL; - } - - t = (struct tcpcb *)calloc(1, sizeof(*t)); - if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) - { - fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n", - i->inp_ppcb, t, sizeof(*t)); - return NULL; - } - return (struct tcpcb *)i->inp_ppcb; -} -#else static struct kinfo_proc *getproc() { static struct kinfo_proc kp; pid_t pid = getpid(); int mib[4]; size_t n; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = pid; n = sizeof(kp); if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) { perror("sysctl"); return NULL; } return &kp; } struct tcpcb *find_tcp(tfd, ti) int tfd; struct tcpiphdr *ti; { struct tcpcb *t; struct inpcb *i; struct socket *s; struct filedesc *fd; struct kinfo_proc *p; struct file *f, **o; if (!(p = getproc())) return NULL; fd = (struct filedesc *)malloc(sizeof(*fd)); if (fd == NULL) return NULL; -#if defined( __FreeBSD_version) && __FreeBSD_version >= 500013 +#if defined( __FreeBSD_version) if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) { fprintf(stderr, "read(%#lx,%#lx) failed\n", (u_long)p, (u_long)p->ki_fd); free(fd); return NULL; } #else if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) { fprintf(stderr, "read(%#lx,%#lx) failed\n", (u_long)p, (u_long)p->kp_proc.p_fd); free(fd); return NULL; } #endif o = NULL; f = NULL; s = NULL; i = NULL; t = NULL; o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o)); if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); goto finderror; } f = (struct file *)calloc(1, sizeof(*f)); if (KMCPY(f, o[tfd], sizeof(*f)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); goto finderror; } s = (struct socket *)calloc(1, sizeof(*s)); if (KMCPY(s, f->f_data, sizeof(*s)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); goto finderror; } i = (struct inpcb *)calloc(1, sizeof(*i)); if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) { fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); goto finderror; } t = (struct tcpcb *)calloc(1, sizeof(*t)); if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); goto finderror; } return (struct tcpcb *)i->inp_ppcb; finderror: if (o != NULL) free(o); if (f != NULL) free(f); if (s != NULL) free(s); if (i != NULL) free(i); if (t != NULL) free(t); return NULL; } -#endif /* BSD < 199301 */ int do_socket(dev, mtu, ti, gwip) char *dev; int mtu; struct tcpiphdr *ti; struct in_addr gwip; { struct sockaddr_in rsin, lsin; struct tcpcb *t, tcb; int fd, nfd; socklen_t len; printf("Dest. Port: %d\n", ti->ti_dport); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("socket"); return -1; } if (fcntl(fd, F_SETFL, FNDELAY) == -1) { perror("fcntl"); return -1; } bzero((char *)&lsin, sizeof(lsin)); lsin.sin_family = AF_INET; bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, sizeof(struct in_addr)); if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) { perror("bind"); return -1; } len = sizeof(lsin); (void) getsockname(fd, (struct sockaddr *)&lsin, &len); ti->ti_sport = lsin.sin_port; printf("sport %d\n", ntohs(lsin.sin_port)); nfd = initdevice(dev, 1); if (nfd == -1) return -1; if (!(t = find_tcp(fd, ti))) return -1; bzero((char *)&rsin, sizeof(rsin)); rsin.sin_family = AF_INET; bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, sizeof(struct in_addr)); rsin.sin_port = ti->ti_dport; if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && errno != EINPROGRESS) { perror("connect"); return -1; } KMCPY(&tcb, t, sizeof(tcb)); ti->ti_win = tcb.rcv_adv; ti->ti_seq = tcb.snd_nxt - 1; ti->ti_ack = tcb.rcv_nxt; if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) return -1; (void)write(fd, "Hello World\n", 12); sleep(2); close(fd); return 0; }