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
|