[tcpdump-workers] filters do not work in my program

ikuzar RABE ikuzar9295 at gmail.com
Wed Nov 30 07:14:10 EST 2016


Hi all,

I work on Debian 8, with linux version 3.16.0-4-amd64, libpcap.1.8.1,
gcc-4.9.2
I write a little program in C langage which reads a pcap file, apply
filter, and write the result into a new pcap file.

The problem: all filters do not work (I use capture filters and not display
filters).
the first filter: *tcp port 80 and host 192.168.10.11* do not work whereas the
second: *vlan 254*, *vlan 255*, etc. work fine. My traffic contains vlan
254, tcp, udp, port 80, port 443 and many ip address including
192.168.10.11. But when I apply the first one, the pcap result file
contains nothing. (I opened it with wireshark).

My program does not print any error except if the filter syntax is not
correct.
At the beginning I thought my filter syntax was wrong (I tried with display
filter, i.e tcp.port==80 and ip.src==192.168.10..1) but pcap_compile does
not accept it.

My questions:
1) According to me, I have to apply *capture filter* because I "capture"
packets from pcap file. Am I wrong ? Have I to use *display filter *instead
?
2) is it correct to compile filter with pcap_t issued from
pcap_open_offline() ? May be I have to do it before dumping, i.e with
pcap_t issued from pcap_open_dead() ?
3) Is there something wrong in my program ?

Here is the skeleton of my program:

#define MAX_FILTER_LEN     2048
#define MAX_SNAPLEN        1500

char filter[MAX_FILTER_LEN] = "\0";
int snaplen = MAX_SNAPLEN;
struct bpf_program bpf = { 0 };
pcap_dumper_t *dumper = NULL;

typedef struct param {
    pcap_dumper_t *dumper;
    pcap_t *pcap_hdlr;
    size_t capture_size_max;
    int snaplen;
} * param_t;

param_t create_param(pcap_t *pcap_hdlr, pcap_dumper_t * dumper, size_t
capture_size_max, int snaplen)
{
    param_t param = (param_t) malloc(sizeof(struct param));
    param->pcap_hdlr = pcap_hdlr;
    param->dumper = dumper;
    param->capture_size_max = capture_size_max;
    param->snaplen = snaplen;

    return param;
}

void set_snaplen(struct pcap_pkthdr *hdr, int snaplen)
{
    hdr->caplen = snaplen;
}

void write_pkts(u_char *user_data, const struct pcap_pkthdr *pkt_hdr, const
u_char *pkt_data)
{
    param_t param = (param_t) user_data;
    if (pcap_dump_ftell(param->dumper) > param->capture_size_max) {
        pcap_breakloop(param->pcap_hdlr);
    }
    else {
        set_snaplen(pkt_hdr, param->snaplen);
        pcap_dump((u_char *)(param->dumper), pkt_hdr, pkt_data);
    }
}

int
main(int argc, char *argv[])
{
    /* ...
     * at this stage I use getopt to get filter. I print it, it's OK.
     * ...
    */

    in_pcap_hdlr = pcap_open_offline(input_file_name, pcap_errbuf);
    if (in_pcap_hdlr != NULL) {
        if (pcap_compile(in_pcap_hdlr, &bpf, filter, 0, 0) == 0) {
            if (pcap_setfilter(in_pcap_hdlr, &bpf) != 0) {
                printf("ERROR with pcap_setfilter");
                return -1;
            }
        }
        else {
            printf("ERROR with pcap_compile");
            return -1;
        }
        int link_layer_type = pcap_datalink(in_pcap_hdlr);
        if (link_layer_type != PCAP_ERROR_NOT_ACTIVATED) {
            out_pcap_hdlr = pcap_open_dead(link_layer_type, snaplen);
            if (out_pcap_hdlr != NULL) {
                dumper = pcap_dump_open(out_pcap_hdlr, output_file_name);
                if (dumper == NULL) {
                    printf("ERROR dumper is NULL");
                    return -1;
                }
            }
        }
    }
    else {
        printf("ERROR with pcap_open_offline");
        return -1;
    }

    /* capture_size_max = 524288000 // 500 MB
     * snaplen = 64 // 64 Bytes
     */

    param_t param = create_param(in_pcap_hdlr, dumper, capture_size_max,
snaplen);
    pcap_loop_ret = pcap_loop(in_pcap_hdlr, -1, write_pkts, (u_char *)
param);

    // here I treat pcap_loop_ret

    return 0;
}


in_pcap_hdlr = pcap_open_offline(input_file_name, pcap_errbuf);
struct bpf_program bpf = { 0 };
pcap_compile(capture_handles_tab[i], &bpf, filter, 0, 0)
pcap_setfilter(in_pcap_hdlr, &bpf);

Thanks for your help.


More information about the tcpdump-workers mailing list