void bpf_try_compile(const char *rulefile, struct sock_fprog *bpf, uint32_t link_type) { int i, ret; const struct bpf_insn *ins; struct sock_filter *out; struct bpf_program _bpf; ret = pcap_compile_nopcap(65535, link_type, &_bpf, rulefile, 1, 0xffffffff); if (ret < 0) panic("Cannot compile filter %s\n", rulefile); bpf->len = _bpf.bf_len; bpf->filter = xrealloc(bpf->filter, 1, bpf->len * sizeof(*out)); for (i = 0, ins = _bpf.bf_insns, out = bpf->filter; i < bpf->len; ++i, ++ins, ++out) { out->code = ins->code; out->jt = ins->jt; out->jf = ins->jf; out->k = ins->k; if (out->code == 0x06 && out->k > 0) out->k = 0xFFFFFFFF; } pcap_freecode(&_bpf); if (__bpf_validate(bpf) == 0) panic("This is not a valid BPF program!\n"); }
void bpf_parse_rules(char *rulefile, struct sock_fprog *bpf, uint32_t link_type) { int ret; char buff[256]; struct sock_filter sf_single = { 0x06, 0, 0, 0xFFFFFFFF }; FILE *fp; if (rulefile == NULL) { bpf->len = 1; bpf->filter = xmalloc(sizeof(sf_single)); fmemcpy(&bpf->filter[0], &sf_single, sizeof(sf_single)); return; } fp = fopen(rulefile, "r"); if (!fp) { bpf_try_compile(rulefile, bpf, link_type); return; } fmemset(buff, 0, sizeof(buff)); while (fgets(buff, sizeof(buff), fp) != NULL) { buff[sizeof(buff) - 1] = 0; if (buff[0] != '{') { fmemset(buff, 0, sizeof(buff)); continue; } fmemset(&sf_single, 0, sizeof(sf_single)); ret = sscanf(buff, "{ 0x%x, %u, %u, 0x%08x },", (unsigned int *) &sf_single.code, (unsigned int *) &sf_single.jt, (unsigned int *) &sf_single.jf, (unsigned int *) &sf_single.k); if (unlikely(ret != 4)) panic("BPF syntax error!\n"); bpf->len++; bpf->filter = xrealloc(bpf->filter, 1, bpf->len * sizeof(sf_single)); fmemcpy(&bpf->filter[bpf->len - 1], &sf_single, sizeof(sf_single)); fmemset(buff, 0, sizeof(buff)); } fclose(fp); if (unlikely(__bpf_validate(bpf) == 0)) panic("This is not a valid BPF program!\n"); }
void bpf_parse_rules(char *dev, char *rulefile, struct sock_fprog *bpf) { int ret; char buff[256]; struct sock_filter sf_single = { 0x06, 0, 0, 0xFFFFFFFF }; FILE *fp; if (rulefile == NULL) { bpf->len = 1; bpf->filter = xmalloc(sizeof(sf_single)); fmemcpy(&bpf->filter[0], &sf_single, sizeof(sf_single)); return; } fp = fopen(rulefile, "r"); if (!fp) #ifdef __WITH_TCPDUMP_LIKE_FILTER goto try_compile_str; #else panic("Cannot open file %s!\n", rulefile); #endif fmemset(buff, 0, sizeof(buff)); while (fgets(buff, sizeof(buff), fp) != NULL) { buff[sizeof(buff) - 1] = 0; if (buff[0] != '{') { fmemset(buff, 0, sizeof(buff)); continue; } fmemset(&sf_single, 0, sizeof(sf_single)); ret = sscanf(buff, "{ 0x%x, %u, %u, 0x%08x },", (unsigned int *) &sf_single.code, (unsigned int *) &sf_single.jt, (unsigned int *) &sf_single.jf, (unsigned int *) &sf_single.k); if (ret != 4) panic("BPF syntax error!\n"); bpf->len++; bpf->filter = xrealloc(bpf->filter, 1, bpf->len * sizeof(sf_single)); fmemcpy(&bpf->filter[bpf->len - 1], &sf_single, sizeof(sf_single)); fmemset(buff, 0, sizeof(buff)); } fclose(fp); if (__bpf_validate(bpf) == 0) panic("This is not a valid BPF program!\n"); return; #ifdef __WITH_TCPDUMP_LIKE_FILTER try_compile_str: { int i; struct bpf_program bpfp; struct pcap *fd; /* For users, who want to have a tcpdump-sytle filter syntax */ fd = pcap_open_live(dev, 60, 0, 1000, NULL); if (!fd) panic("Cannot open any device!\n"); ret = pcap_compile(fd, &bpfp, rulefile, 1, 0xffffffff); if (ret < 0) panic("Cannot compile filter %s: %s\n", rulefile, pcap_geterr(fd)); pcap_close(fd); bpf->len = bpfp.bf_len; bpf->filter = xrealloc(bpf->filter, 1, bpf->len * sizeof(sf_single)); for (i = 0; i < bpf->len; ++i) { bpf->filter[i].code = bpfp.bf_insns[i].code; bpf->filter[i].jt = bpfp.bf_insns[i].jt; bpf->filter[i].jf = bpfp.bf_insns[i].jf; bpf->filter[i].k = bpfp.bf_insns[i].k; if (bpf->filter[i].code == 0x06 && bpf->filter[i].k > 0) bpf->filter[i].k = 0xFFFFFFFF; } } #endif }