diff options
author | darrenr <darrenr@FreeBSD.org> | 2004-06-21 22:53:03 +0000 |
---|---|---|
committer | darrenr <darrenr@FreeBSD.org> | 2004-06-21 22:53:03 +0000 |
commit | a444d606d5af7d0dd9ff970754ad95595a3b64f3 (patch) | |
tree | 8c812415a26f6e084b0a0b81079b87781f9eb672 /contrib/ipfilter/ipsend | |
parent | ac063842a53f02c0a131cdb35e49e784a4d881ac (diff) | |
download | FreeBSD-src-a444d606d5af7d0dd9ff970754ad95595a3b64f3.zip FreeBSD-src-a444d606d5af7d0dd9ff970754ad95595a3b64f3.tar.gz |
Committ changes from 3.4.31 -> 3.4.35
* fix bug parsing port comparisons in proxy rules
* make parsing errors in ipf/ipnat return an error rather than return
indicating success.
* make parsing errors in ipf/ipnat return an error rather than return
indicating success.
* make ipfstat work as a set{g,u}id thing - gave up privs before opening
/dev/ipl
* fix ipfstat -A
* make "ipfstat -f" output more informative
* various changes to ipsend for sending packets with ipv4 options
* ipmon was not correctly calculating the length of the IPv6 packet (excluded
ipv6 header length)
MFC: 1 week
Diffstat (limited to 'contrib/ipfilter/ipsend')
-rw-r--r-- | contrib/ipfilter/ipsend/ipsend.5 | 11 | ||||
-rw-r--r-- | contrib/ipfilter/ipsend/ipsend.c | 83 |
2 files changed, 73 insertions, 21 deletions
diff --git a/contrib/ipfilter/ipsend/ipsend.5 b/contrib/ipfilter/ipsend/ipsend.5 index 1e4e82e..40b186a 100644 --- a/contrib/ipfilter/ipsend/ipsend.5 +++ b/contrib/ipfilter/ipsend/ipsend.5 @@ -1,3 +1,4 @@ +.\" $FreeBSD$ .TH IPSEND 5 .SH NAME ipsend \- IP packet description language @@ -102,7 +103,7 @@ route installed in the kernel. is used to describe an IP (version 4) packet. IP header fields can be specified, including options, followed by a data section which may contain further protocol headers. -.SH IPV4 +.SH IPv4 .TP .B hl <number> manually specifies the IP header length (automatically adjusts with the @@ -116,7 +117,7 @@ set the type of service (TOS) field in the IP header. Default is 0. .TP .B len <number> manually specifies the length of the IP packet. The length will automatically -be adjusted to accomodate data or further protocol headers. +be adjusted to accommodate data or further protocol headers. .TP .B off <number> sets the fragment offset field of the IP packet. Default is 0. @@ -158,7 +159,7 @@ is used to indicate the a ICMP protocol header is to follow. See the is used to indicate that raw data is to be included in the IP packet. See the \fBDATA\fP section for details on options available. .SH "IPv4 Options" -these keywords indicate that the releveant IP option should be added to the +these keywords indicate that the relevant IP option should be added to the IP header (the header length field will be adjusted appropriately). .TP .B nop @@ -210,7 +211,7 @@ Strict Source Route [RFC 791]. Address Extension .TP .B visa -Expermental Access Control. +Experimental Access Control. .TP .B imitd IMI Traffic Descriptor. @@ -314,7 +315,7 @@ bytes with any particular data). indicates that the string provided should be added to the current packet as data. A string may be a consecutive list of characters and numbers (with no white spaces) or bounded by "'s (may not contain them, even if \\'d). -The \\ charcater is recognised with the appropriate C escaped values, including +The \\ character is recognised with the appropriate C escaped values, including octal numbers. .TP .B file <filename> diff --git a/contrib/ipfilter/ipsend/ipsend.c b/contrib/ipfilter/ipsend/ipsend.c index 8c9be57..80faef2 100644 --- a/contrib/ipfilter/ipsend/ipsend.c +++ b/contrib/ipfilter/ipsend/ipsend.c @@ -25,8 +25,10 @@ #include <arpa/inet.h> #include <netinet/in_systm.h> #include <netinet/ip.h> +#include <netinet/ip_var.h> #include <netinet/tcp.h> #include <netinet/udp.h> +#include <netinet/udp_var.h> #include <netinet/ip_icmp.h> #ifndef linux #include <netinet/ip_var.h> @@ -71,6 +73,7 @@ char default_device[] = "lan0"; 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 **)); @@ -170,6 +173,37 @@ struct in_addr gwip; 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 cksum, *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; @@ -177,8 +211,10 @@ char **argv; { FILE *langfile = NULL; struct tcpiphdr *ti; + struct udpiphdr *ui; 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; @@ -190,7 +226,10 @@ char **argv; */ ip = (ip_t *)calloc(1, 65536); ti = (struct tcpiphdr *)ip; + ui = (struct udpiphdr *)ip; tcp = (tcphdr_t *)&ti->ti_sport; + udp = (udphdr_t *)&ui->ui_sport; + ui->ui_ulen = htons(sizeof(*udp)); ip->ip_len = sizeof(*ip); ip->ip_hl = sizeof(*ip) >> 2; @@ -344,27 +383,35 @@ char **argv; exit(2); } + if (ip->ip_p != IPPROTO_TCP && ip->ip_p != IPPROTO_UDP) { + fprintf(stderr,"Unsupported protocol %d\n", ip->ip_p); + exit(2); + } + if (olen) { - caddr_t ipo = (caddr_t)ip; + int hlen; + char *p; printf("Options: %d\n", olen); - ti = (struct tcpiphdr *)malloc(olen + ip->ip_len); - if(!ti) + hlen = sizeof(*ip) + olen; + ip->ip_hl = hlen >> 2; + ip->ip_len += olen; + p = (char *)malloc(65536); + if(!p) { fprintf(stderr,"malloc failed\n"); exit(2); } - - bcopy((char *)ip, (char *)ti, sizeof(*ip)); - ip = (ip_t *)ti; - ip->ip_hl = (olen >> 2); - bcopy(options, (char *)(ip + 1), olen); - bcopy((char *)tcp, (char *)(ip + 1) + olen, sizeof(*tcp)); - ip->ip_len += olen; - bcopy((char *)ip, (char *)ipo, ip->ip_len); - ip = (ip_t *)ipo; - tcp = (tcphdr_t *)((char *)(ip + 1) + olen); + 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 *)((char *)ip + hlen); + } else { + udp = (udphdr_t *)((char *)ip + hlen); + } } if (ip->ip_p == IPPROTO_TCP) @@ -401,9 +448,13 @@ char **argv; 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->ip_hl << 2)); + } #ifdef DOSOCKET - if (tcp->th_dport) - return do_socket(dev, mtu, ti, gwip); + if (ip->ip_p == IPPROTO_TCP && tcp->th_dport) + return do_socket(dev, mtu, (struct tcpiphdr *)ip, gwip); #endif - return send_packets(dev, mtu, (ip_t *)ti, gwip); + return send_packets(dev, mtu, ip, gwip); } |