File: pcapsource.cc

package info (click to toggle)
kismet 1.4.2-4
  • links: PTS
  • area: main
  • in suites: woody
  • size: 504 kB
  • ctags: 435
  • sloc: cpp: 2,741; makefile: 126; sh: 29
file content (91 lines) | stat: -rw-r--r-- 2,165 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <unistd.h>
#include <fcntl.h>

#include "config.h"
#include "pcapsource.h"

#ifdef HAVE_LIBPCAP

// I hate libpcap, I really really do.  Stupid callbacks...
pcap_pkthdr callback_header;
u_char callback_data[MAX_PACKET_LEN];


int PcapSource::OpenSource(const char *dev) {
    snprintf(type, 64, "libpcap device %s", dev);

    char unconst_dev[64];
    snprintf(unconst_dev, 64, "%s", dev);

    errstr[0] = '\0';
    pd = pcap_open_live(unconst_dev, MAX_PACKET_LEN, 1, 1000, errstr);

    if (strlen(errstr) > 0)
        return -1; // Error is already in errstr

    errstr[0] = '\0';

#ifdef HAVE_PCAP_NONBLOCK
    pcap_setnonblock(pd, 1, errstr);
#else
    // do something clever  (Thanks to Guy Harris for suggesting this).
    int save_mode = fcntl(pcap_fileno(pd), F_GETFL, 0);
    fcntl(pcap_fileno(pd), F_SETFL, save_mode | O_NONBLOCK);
#endif

    if (strlen(errstr) > 0)
        return -1; // Ditto

    snprintf(errstr, 1024, "Pcap Source opened %s", dev);
    return 1;
}

int PcapSource::CloseSource() {
    pcap_close(pd);
    return 1;
}

void PcapSource::Callback(u_char *bp, const struct pcap_pkthdr *header,
                                 const u_char *data) {
    memcpy(&callback_header, header, sizeof(pcap_pkthdr));
    memcpy(callback_data, data, header->len);
}

int PcapSource::FetchPacket(pkthdr *in_header, u_char *in_data) {
    int ret;
    unsigned char *udata = '\0';

    if ((ret = pcap_dispatch(pd, 1, PcapSource::Callback, udata)) < 0) {
        snprintf(errstr, 1024, "Pcap Get Packet pcap_dispatch() failed");
        return -1;
    }

    if (ret == 0)
        return 0;

    Pcap2Common(in_header, in_data);

    return(in_header->len);
}

int PcapSource::Pcap2Common(pkthdr *in_header, u_char *in_data) {

    memset(in_header, 0, sizeof(pkthdr));
    memset(in_data, 0, MAX_PACKET_LEN);

    in_header->caplen = callback_header.caplen;

    if (callback_header.len > MAX_PACKET_LEN)
        in_header->len = MAX_PACKET_LEN;
    else
        in_header->len = callback_header.len;

    // in_header->pkt_encap = WTAP_ENCAP_IEEE_802_11;

    memcpy(in_data, callback_data, in_header->len);

    return 1;
}

#endif