--- libaitio/example/bpf.c 2013/06/25 09:22:10 1.1.2.2 +++ libaitio/example/bpf.c 2016/08/18 09:06:31 1.5 @@ -10,13 +10,17 @@ #include #include #include -#include #include #include #include #include +#ifndef __linux__ +#include #include #include +#else +#include +#endif #ifdef __FreeBSD__ #include @@ -61,7 +65,7 @@ static void * ShowPkt(void *buffer) { char Proto = 0, szStr[BUFSIZ], szLine[BUFSIZ], szWrk[BUFSIZ], szShow[USHRT_MAX] = { 0 }; - struct bpf_hdr *bpf = buffer; +#ifndef __linux__ #ifdef __FreeBSD__ struct bpf_zbuf_header *bzh = buffer; struct icmphdr *icmp; @@ -69,7 +73,12 @@ ShowPkt(void *buffer) #ifdef __OpenBSD__ struct icmp *icmp; #endif + struct ether_header *eth; +#else + struct icmphdr *icmp; + struct ethhdr *eth; +#endif struct ip *ip; struct ip6_hdr *ipv6; struct arphdr *arp; @@ -78,17 +87,20 @@ ShowPkt(void *buffer) assert(buffer); -#ifdef __FreeBSD__ - snprintf(szLine, BUFSIZ, "#Packet length: %d\n>>> Ethernet ...\n", flg ? bzh->bzh_kernel_len : bpf->bh_datalen); - strlcat(szShow, szLine, USHRT_MAX); - eth = (struct ether_header *) (buffer + (flg ? bzh->bzh_kernel_len : bpf->bh_hdrlen)); -#else - snprintf(szLine, BUFSIZ, "#Packet length: %d\n>>> Ethernet ...\n", bpf->bh_datalen); - strlcat(szShow, szLine, USHRT_MAX); - eth = (struct ether_header *) (buffer + bpf->bh_hdrlen); -#endif +#ifndef __linux__ + eth = (struct ether_header *) buffer; switch (ntohs(eth->ether_type)) { +#else +#define ETHERTYPE_ARP 0x0806 +#define ETHERTYPE_IP 0x0800 +#define ETHERTYPE_IPV6 0x86dd +#define ETHER_HDR_LEN sizeof(struct ethhdr) + + eth = (struct ethhdr *) buffer; + + switch (ntohs(eth->h_proto)) { +#endif case ETHERTYPE_ARP: strlcpy(szWrk, "(ARP)", sizeof szWrk); break; @@ -101,16 +113,35 @@ ShowPkt(void *buffer) default: memset(szWrk, 0, sizeof szWrk); } +#ifndef __linux__ snprintf(szStr, BUFSIZ, "%02x:%02x:%02x:%02x:%02x:%02x", eth->ether_shost[0], eth->ether_shost[1], eth->ether_shost[2], eth->ether_shost[3], eth->ether_shost[4], eth->ether_shost[5]); snprintf(szLine, BUFSIZ, "ether_type: %04x%s, src_mac: %s, ", ntohs(eth->ether_type), szWrk, szStr); strlcat(szShow, szLine, USHRT_MAX); snprintf(szStr, BUFSIZ, "%02x:%02x:%02x:%02x:%02x:%02x", eth->ether_dhost[0], eth->ether_dhost[1], eth->ether_dhost[2], eth->ether_dhost[3], eth->ether_dhost[4], eth->ether_dhost[5]); +#else + snprintf(szStr, BUFSIZ, "%02x:%02x:%02x:%02x:%02x:%02x", eth->h_source[0], eth->h_source[1], + eth->h_source[2], eth->h_source[3], eth->h_source[4], eth->h_source[5]); + snprintf(szLine, BUFSIZ, "ether_type: %04x%s, src_mac: %s, ", ntohs(eth->h_proto), szWrk, szStr); + strlcat(szShow, szLine, USHRT_MAX); + snprintf(szStr, BUFSIZ, "%02x:%02x:%02x:%02x:%02x:%02x", eth->h_dest[0], eth->h_dest[1], + eth->h_dest[2], eth->h_dest[3], eth->h_dest[4], eth->h_dest[5]); +#endif snprintf(szLine, BUFSIZ, "dst_mac: %s\n", szStr); strlcat(szShow, szLine, USHRT_MAX); +#ifndef __linux__ switch (ntohs(eth->ether_type)) { +#else +#define ARPOP_REVREQUEST 3 +#define ARPOP_REVREPLY 4 +#define ARPOP_INVREQUEST 8 +#define ARPOP_INVREPLY 9 +#define IPV6_FLOWLABEL_MASK 0x000fffff + + switch (ntohs(eth->h_proto)) { +#endif case ETHERTYPE_ARP: arp = (struct arphdr*) (((caddr_t) eth) + ETHER_HDR_LEN); strlcat(szShow, "\t>>> ARP ...\n", USHRT_MAX); @@ -179,15 +210,24 @@ ShowPkt(void *buffer) break; } +#ifndef __linux__ if (Proto && (ntohs(eth->ether_type) == ETHERTYPE_IP || ntohs(eth->ether_type) == ETHERTYPE_IPV6)) +#else + if (Proto && (ntohs(eth->h_proto) == ETHERTYPE_IP || ntohs(eth->h_proto) == ETHERTYPE_IPV6)) +#endif switch (Proto) { case IPPROTO_TCP: strlcat(szShow, "\t\t>>> TCP ...\n", USHRT_MAX); +#ifndef __linux__ if (ntohs(eth->ether_type) == ETHERTYPE_IPV6) +#else + if (ntohs(eth->h_proto) == ETHERTYPE_IPV6) +#endif tcp = (struct tcphdr*) (((caddr_t) ipv6) + sizeof(struct ip6_hdr)); else tcp = (struct tcphdr*) (((caddr_t) ip) + sizeof(struct ip)); +#ifndef __linux__ snprintf(szLine, BUFSIZ, "\t\tsrc_port: %d, dst_port: %d, seq: %u, ack: %u\n", ntohs(tcp->th_sport), ntohs(tcp->th_dport), tcp->th_seq, tcp->th_ack); strlcat(szShow, szLine, USHRT_MAX); @@ -210,18 +250,54 @@ ShowPkt(void *buffer) strlcat(szWrk, "|CWR", sizeof szWrk); snprintf(szLine, BUFSIZ, "\t\toff: %s, win: %d, urp: %04x, cksum: %04x\n", szWrk, ntohs(tcp->th_win), ntohs(tcp->th_urp), ntohs(tcp->th_sum)); +#else + snprintf(szLine, BUFSIZ, "\t\tsrc_port: %d, dst_port: %d, seq: %u, ack: %u\n", + ntohs(tcp->source), ntohs(tcp->dest), tcp->seq, tcp->ack); strlcat(szShow, szLine, USHRT_MAX); + snprintf(szWrk, BUFSIZ, "%d", (u_char) tcp->doff); + if (tcp->fin) + strlcat(szWrk, "|FIN", sizeof szWrk); + if (tcp->syn) + strlcat(szWrk, "|SYN", sizeof szWrk); + if (tcp->rst) + strlcat(szWrk, "|RST", sizeof szWrk); + if (tcp->psh) + strlcat(szWrk, "|PUSH", sizeof szWrk); + if (tcp->ack) + strlcat(szWrk, "|ACK", sizeof szWrk); + if (tcp->urg) + strlcat(szWrk, "|URG", sizeof szWrk); + /* + if (tcp->ece) + strlcat(szWrk, "|ECE", sizeof szWrk); + if (tcp->cwr) + strlcat(szWrk, "|CWR", sizeof szWrk); + */ + snprintf(szLine, BUFSIZ, "\t\toff: %s, win: %d, urp: %04x, cksum: %04x\n", + szWrk, ntohs(tcp->window), ntohs(tcp->urg_ptr), ntohs(tcp->check)); +#endif + strlcat(szShow, szLine, USHRT_MAX); break; case IPPROTO_UDP: strlcat(szShow, "\t\t>>> UDP ...\n", USHRT_MAX); +#ifndef __linux__ if (ntohs(eth->ether_type) == ETHERTYPE_IPV6) +#else + if (ntohs(eth->h_proto) == ETHERTYPE_IPV6) +#endif udp = (struct udphdr*) (((caddr_t) ipv6) + sizeof(struct ip6_hdr)); else udp = (struct udphdr*) (((caddr_t) ip) + sizeof(struct ip)); +#ifndef __linux__ snprintf(szLine, BUFSIZ, "\t\tsrc_port: %d, dst_port: %d, len: %d, cksum: %04x\n", ntohs(udp->uh_sport), ntohs(udp->uh_dport), ntohs(udp->uh_ulen), ntohs(udp->uh_sum)); +#else + snprintf(szLine, BUFSIZ, "\t\tsrc_port: %d, dst_port: %d, len: %d, cksum: %04x\n", + ntohs(udp->source), ntohs(udp->dest), + ntohs(udp->len), ntohs(udp->check)); +#endif strlcat(szShow, szLine, USHRT_MAX); break; case IPPROTO_ICMP: @@ -239,14 +315,19 @@ ShowPkt(void *buffer) icmp = (struct icmp*) (((caddr_t) ip) + sizeof(struct ip)); #endif +#ifndef __linux__ snprintf(szLine, BUFSIZ, "\t\ttype: %d, code: %d: cksum: %04x\n", icmp->icmp_type, icmp->icmp_code, ntohs(icmp->icmp_cksum)); +#else + snprintf(szLine, BUFSIZ, "\t\ttype: %d, code: %d: cksum: %04x\n", + icmp->type, icmp->code, ntohs(icmp->checksum)); +#endif strlcat(szShow, szLine, USHRT_MAX); break; } printf("%s===\n", szShow); - pthread_exit(NULL); + return NULL; } // ---------------------- @@ -263,9 +344,8 @@ main(int argc, char **argv) pthread_t tid; char ch, mode = 'R'; struct timespec ts_start, ts_end; -#ifdef __FreeBSD__ - struct bpf_zbuf *bz; -#endif + void *bz = NULL; + ether_addr_t ea; while ((ch = getopt(argc, argv, "hvwzs:p:f:")) != -1) switch (ch) { @@ -301,174 +381,84 @@ main(int argc, char **argv) else strlcpy(szStr, *argv, sizeof szStr); -#ifdef __FreeBSD_ - dev = io_etherOpen(szStr, O_RDWR | O_NONBLOCK, 42, &siz, &bz); +#ifndef __linux__ +#ifdef __FreeBSD__ + dev = io_etherOpen(szStr, O_RDWR | O_NONBLOCK, 42, 0, (u_int*) &siz, (flg) ? &bz : NULL); + if (dev == -1) + dev = io_etherOpen(szStr, O_RDWR | O_NONBLOCK, 42, 0, (u_int*) &siz, NULL); #else - dev = io_etherOpen(szStr, O_RDWR | O_NONBLOCK, 42, &siz, NULL); + dev = io_etherOpen(szStr, O_RDWR, 42, 0, (u_int*) &siz, NULL); #endif +#else + dev = io_etherOpen(szStr, 0, 42, 0, (u_int*) &siz, NULL); +#endif if (dev == -1) { printf("Error:: #%d - %s\n", io_GetErrno(), io_GetError()); return 1; } else printf("dev=%d(%s)\n", dev, szStr); - if (ioctl(dev, BIOCGBLEN, &n) == -1) { +#ifndef __linux__ + if (ioctl(dev, BIOCGBLEN, &siz) == -1) { perror("ioctl(BIOCGBLEN)"); - close(dev); + io_etherClose(dev, &bz); return 1; } else - printf("BPF buffer len=%d\n", n); - -#if 0 -#ifdef __FreeBSD__ - ret = BPF_BUFMODE_ZBUF; - if (flg && !ioctl(dev, BIOCSETBUFMODE, (u_int*) &ret)) { - if (ioctl(dev, BIOCGETZMAX, &ret) == -1) { - perror("ioctl(BIOCGETZMAX)"); - close(dev); - return 1; - } - memset(&bz, 0, sizeof bz); - bz.bz_buflen = roundup(MIN(n, ret), getpagesize()); - bz.bz_bufa = mmap(NULL, bz.bz_buflen, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); - bz.bz_bufb = mmap(NULL, bz.bz_buflen, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); - if (bz.bz_bufa == MAP_FAILED || bz.bz_bufb == MAP_FAILED) { - perror("mmap()"); - close(dev); - return 1; - } - - if (ioctl(dev, BIOCSETZBUF, &bz) == -1) { - perror("ioctl(BIOCSETZBUF)"); - munmap(bz.bz_bufa, bz.bz_buflen); - munmap(bz.bz_bufb, bz.bz_buflen); - close(dev); - return 1; - } else - siz = bz.bz_buflen; - } else { + printf("BPF buffer len=%d\n", siz); #endif - flg = 0; - if (siz) { - if (ioctl(dev, BIOCSBLEN, &siz) == -1) { - perror("ioctl(BIOCSBLEN)"); - close(dev); - return 1; - } - } else - siz = n; -#ifdef __FreeBSD__ - } -#endif - printf("Set buffer len to %d\n", siz); - if (!flg) { - if (*szMap) { - fd = open(szMap, O_RDWR); - if (fd == -1) { - perror("open(map)"); - close(dev); - return 1; - } - buffer = mmap(NULL, siz, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - close(fd); - } else - buffer = mmap(NULL, siz, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); - if (buffer == MAP_FAILED) { - perror("mmap()"); - close(dev); + if (*szMap) { + fd = open(szMap, O_RDWR); + if (fd == -1) { + perror("open(map)"); + io_etherClose(dev, &bz); return 1; } - } - - memset(&ifr, 0, sizeof ifr); - strlcpy(ifr.ifr_name, szStr, sizeof ifr.ifr_name); - if (ioctl(dev, BIOCSETIF, (char*) &ifr) == -1) { - perror("ioctl(BIOCSETIF)"); - close(dev); -#ifdef __FreeBSD__ - if (flg) { - munmap(bz.bz_bufa, bz.bz_buflen); - munmap(bz.bz_bufb, bz.bz_buflen); - } else -#endif - munmap(buffer, siz); + buffer = mmap(NULL, siz, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + close(fd); + } else + buffer = mmap(NULL, siz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (buffer == MAP_FAILED) { + perror("mmap()"); + io_etherClose(dev, &bz); return 1; } - n = 1; - if (ioctl(dev, BIOCSHDRCMPLT, &n) == -1) { - perror("ioctl(BIOCSHDRCMPLT)"); - close(dev); -#ifdef __FreeBSD__ - if (flg) { - munmap(bz.bz_bufa, bz.bz_buflen); - munmap(bz.bz_bufb, bz.bz_buflen); - } else -#endif - munmap(buffer, siz); - return 1; - } - if (ioctl(dev, BIOCIMMEDIATE, &n) == -1) { - perror("ioctl(BIOCIMMEDIATE)"); - close(dev); -#ifdef __FreeBSD__ - if (flg) { - munmap(bz.bz_bufa, bz.bz_buflen); - munmap(bz.bz_bufb, bz.bz_buflen); - } else -#endif - munmap(buffer, siz); - return 1; - } pfd.fd = dev; assert(!clock_gettime(CLOCK_REALTIME, &ts_start)); if (mode == 'R') { pfd.events = POLLIN; for (i = 0; i < count; i++) { - if (poll(&pfd, 1, -1) == -1) + if ((ret = poll(&pfd, 1, -1)) == -1) break; -#ifdef __FreeBSD__ - if (flg) { - if (!NEXT_zbuf((void**) &buffer, &bz, &ret)) - continue; - if (Verbose) { - printf("+readed %d bytes\n", ret); - pthread_create(&tid, NULL, ShowPkt, buffer); - } - } else { -#endif - ret = read(dev, buffer, siz); - if (ret == -1) - printf("%d) read(%d) #%d - %s\n", i, ret, errno, strerror(errno)); - if (Verbose) { - printf("%d) +readed %d bytes\n", i, ret); - pthread_create(&tid, NULL, ShowPkt, buffer); - } -#ifdef __FreeBSD__ + ret = io_etherRecv(dev, buffer, siz, bz); + if (!ret) + continue; + if (ret == -1) + printf("%d) io_etherRecv(%d) #%d - %s\n", i, ret, + io_GetErrno(), io_GetError()); + if (Verbose) { + printf("%d) +readed %d bytes\n", i, ret); + ShowPkt(buffer); } -#endif } } else { pfd.events = POLLOUT; for (i = 0; i < count; i++) { -#ifdef __FreeBSD__ if (poll(&pfd, 1, -1) == -1) break; -#endif - ret = write(dev, buffer, siz); + ret = io_etherSend(dev, buffer, siz); if (ret == -1) - printf("write(%d) #%d - %s\n", ret, errno, strerror(errno)); + printf("io_etherSend(%d) #%d - %s\n", ret, io_GetErrno(), io_GetError()); if (Verbose) printf("+writed %d bytes\n", ret); } } assert(!clock_gettime(CLOCK_REALTIME, &ts_end)); -#endif -// munmap(buffer, siz); + munmap(buffer, siz); io_etherClose(dev, &bz); time_spec_sub(&ts_end, &ts_start);