Date: Tue, 20 May 2003 17:11:04 +0200 From: gianz@security.dico.unimi.it To: freebsd-net@freebsd.org Subject: Re: [BPF Read and Write] Strange behaviour? Message-ID: <20030520151104.GA14857@idea.sec.dico.unimi.it> In-Reply-To: <20030520132042.GA16689@radiance.it> References: <20030520132042.GA16689@radiance.it>
next in thread | previous in thread | raw e-mail | index | archive | help
Sorry... that's the file: #include "common.h" #include "link_layer.h" int LINK_LAYER_open_device(char *device, int to) { int i, fd; struct ifreq ifr; u_int t; struct timeval tv; char pf[sizeof "/dev/bpf0000000000"]; i = 0; do { (void)snprintf(pf, sizeof(pf), "/dev/bpf%d", i++); fd = open(pf, O_RDWR); } while (fd < 0 && errno == EBUSY); if(fd >= 0) { for (t = 65536; t != 0; t >>= 1) { (void) ioctl(fd, BIOCSBLEN, &t); (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) break; if (errno != ENOBUFS) { return EXIT_FAILURE; } } if(verb) { printf("opening %s\n", device); } t=1; if(ioctl(fd, BIOCPROMISC, &t)==-1) { perror("ioctl"); return EXIT_FAILURE; } if(ioctl(fd, BIOCSHDRCMPLT, &t)==-1) { perror("ioctl"); return EXIT_FAILURE; } if(to == 0) { if(ioctl(fd, BIOCIMMEDIATE, &t)==-1) { perror("ioctl"); return EXIT_FAILURE; } } else { tv.tv_sec = to / 1000; tv.tv_usec = (to % 1000) * 1000; if(verb) { printf("timeout: %ld secs %ld usecs\n", tv.tv_sec, tv.tv_usec); } if(ioctl(fd, BIOCSRTIMEOUT, &tv)==-1) { perror("ioctl"); return EXIT_FAILURE; } } } else { printf("cannot open %s\n", device); perror(pf); return EXIT_FAILURE; } return fd; } int LINK_LAYER_read( int readfd, int writefd, unsigned char *buf, int len, PACKET_DATA *p_data, void (*do_nat)(PACKET_DATA *data, char *buf, int len, int fd) ) { int count; struct bpf_hdr *p; struct bpf_hdr *e; again: count = read(readfd, buf, len); p = (struct bpf_hdr *)buf; e = (struct bpf_hdr *)(buf + count); if(count<0) { switch(errno) { case EINTR: printf("read interrupted\n"); goto again; case EAGAIN: return 0; default: return -1; } } if(count > 0) { while(p < e) { if(p->bh_caplen != p->bh_datalen) { printf("warning: truncated packet\n"); } do_nat(p_data, (char *)p + p->bh_hdrlen, p->bh_caplen, writefd); p = (struct bpf_hdr *)((char *)p + BPF_WORDALIGN(p->bh_hdrlen + p->bh_caplen)); } } return count; } unsigned char *LINK_LAYER_alloc_buffer(int fd, int *len) { if(ioctl(fd, BIOCGBLEN, len)==-1) { perror("ioctl"); return NULL; } return malloc(*len); } int LINK_LAYER_accept_from(int fd, unsigned char *mac) { unsigned long head; unsigned short tail; struct bpf_program bpfp; ((char *)(&head))[0] = mac[3]; ((char *)(&head))[1] = mac[2]; ((char *)(&head))[2] = mac[1]; ((char *)(&head))[3] = mac[0]; mac += sizeof(unsigned long); ((char *)(&tail))[0] = mac[1]; ((char *)(&tail))[1] = mac[0]; struct bpf_insn filter[] = { BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, head, 0, 3), BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 10), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, tail, 0, 1), BPF_STMT(BPF_RET+BPF_K, ((u_int)-1)), BPF_STMT(BPF_RET+BPF_K, 0) }; bpfp.bf_insns = filter; bpfp.bf_len = 6; if(ioctl(fd, BIOCSETF, &bpfp)==-1) { perror("BIOCSETF"); return -1; } return 1; } int LINK_LAYER_reject_from(int fd, unsigned char *mac) { unsigned long head; unsigned short tail; struct bpf_program bpfp; ((char *)(&head))[0] = mac[3]; ((char *)(&head))[1] = mac[2]; ((char *)(&head))[2] = mac[1]; ((char *)(&head))[3] = mac[0]; mac += sizeof(unsigned long); ((char *)(&tail))[0] = mac[1]; ((char *)(&tail))[1] = mac[0]; struct bpf_insn filter[] = { BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, head, 0, 3), BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 10), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, tail, 0, 1), BPF_STMT(BPF_RET+BPF_K, 0), BPF_STMT(BPF_RET+BPF_K, ((u_int)-1)) }; bpfp.bf_insns = filter; bpfp.bf_len = 6; if(ioctl(fd, BIOCSETF, &bpfp)==-1) { perror("BIOCSETF"); return -1; } return 1; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030520151104.GA14857>