aboutsummaryrefslogtreecommitdiffstats
path: root/gg_sniff/pcap.c
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2012-12-02 22:52:32 +0100
committerLaurent Ghigonis <laurent@p1sec.com>2012-12-02 22:52:32 +0100
commit219a6f3c65800b71d02941302e5b31861ef2739a (patch)
treeb1b8fe4bc0e3060501f85188f35396feda624568 /gg_sniff/pcap.c
parentoops, fix _gg_trackproc user (diff)
downloadglouglou-219a6f3c65800b71d02941302e5b31861ef2739a.tar.xz
glouglou-219a6f3c65800b71d02941302e5b31861ef2739a.zip
work in progress on gg_sniff
Diffstat (limited to 'gg_sniff/pcap.c')
-rw-r--r--gg_sniff/pcap.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/gg_sniff/pcap.c b/gg_sniff/pcap.c
new file mode 100644
index 0000000..b13a486
--- /dev/null
+++ b/gg_sniff/pcap.c
@@ -0,0 +1,146 @@
+#define PCAP_INTERFACE "lo"
+#define PCAP_SNAPLEN 100
+#define PCAP_FILTER "not port 4430 and not port 53"
+#define PCAP_COUNT 20
+#define PCAP_TO 300
+
+static pcap_t *
+ggsniff_pcap_init(void)
+{
+ pcap = my_pcap_open_live(PCAP_INTERFACE, PCAP_SNAPLEN, 1, PCAP_TO, errbuf, -1, 0);
+ if (pcap == NULL)
+ fatal("capture: pcap_open_live failed on interface %s\n"
+ "with snaplen %d : %s",
+ PCAP_INTERFACE, PCAP_SNAPLEN, errbuf);
+ if (pcap_compile(pcap, &bprog, PCAP_FILTER, 0, 0) < 0)
+ fatal("capture: pcap_compile failed with filter %s : %s",
+ PCAP_FILTER, pcap_geterr(pcap));
+ if (pcap_setfilter(pcap, &bprog) < 0)
+ fatal("capture: pcap_setfilter failed : %s",
+ pcap_geterr(pcap));
+}
+
+/*
+ * reimplement pcap_open_live with more restrictions on the bpf fd :
+ * - open device read only
+ * - lock the fd
+ * based on OpenBSD tcpdump, privsep_pcap.c v1.16
+ */
+
+static pcap_t *
+my_pcap_open_live(const char *dev, int slen, int promisc, int to_ms,
+ char *ebuf, u_int dlt, u_int dirfilt)
+{
+#if defined(__OpenBSD__)
+ struct bpf_version bv;
+ u_int v;
+ pcap_t *p;
+ char bpf[sizeof "/dev/bpf0000000000"];
+ int fd, n = 0;
+ struct ifreq ifr;
+
+ p = xmalloc(sizeof(*p));
+ bzero(p, sizeof(*p));
+
+ /* priv part */
+
+ do {
+ snprintf(bpf, sizeof(bpf), "/dev/bpf%d", n++);
+ fd = open(bpf, O_RDONLY);
+ } while (fd < 0 && errno == EBUSY);
+ if (fd < 0)
+ return NULL;
+
+ v = 32768; /* XXX this should be a user-accessible hook */
+ ioctl(fd, BIOCSBLEN, &v);
+
+ strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
+ if (ioctl(fd, BIOCSETIF, &ifr) < 0)
+ return NULL;
+
+ if (dlt != (u_int) -1 && ioctl(fd, BIOCSDLT, &dlt))
+ return NULL;
+
+ if (promisc)
+ /* this is allowed to fail */
+ ioctl(fd, BIOCPROMISC, NULL);
+ if (ioctl(fd, BIOCSDIRFILT, &dirfilt) < 0)
+ return NULL;
+
+ /* lock the descriptor */
+ if (ioctl(fd, BIOCLOCK, NULL) < 0)
+ return NULL;
+
+ /* end of priv part */
+
+ /* fd is locked, can only use 'safe' ioctls */
+ if (ioctl(fd, BIOCVERSION, &bv) < 0) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
+ pcap_strerror(errno));
+ return NULL;
+ }
+
+ if (bv.bv_major != BPF_MAJOR_VERSION ||
+ bv.bv_minor < BPF_MINOR_VERSION) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "kernel bpf filter out of date");
+ return NULL;
+ }
+
+ p->fd = fd;
+ p->snapshot = slen;
+
+ /* Get the data link layer type. */
+ if (ioctl(fd, BIOCGDLT, &v) < 0) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
+ pcap_strerror(errno));
+ return NULL;
+ }
+#if _BSDI_VERSION - 0 >= 199510
+ /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
+ switch (v) {
+
+ case DLT_SLIP:
+ v = DLT_SLIP_BSDOS;
+ break;
+
+ case DLT_PPP:
+ v = DLT_PPP_BSDOS;
+ break;
+ }
+#endif
+ p->linktype = v;
+
+ /* XXX hack from tcpdump */
+ if (p->linktype == DLT_PFLOG && p->snapshot < 160)
+ p->snapshot = 160;
+
+ /* set timeout */
+ if (to_ms != 0) {
+ struct timeval to;
+ to.tv_sec = to_ms / 1000;
+ to.tv_usec = (to_ms * 1000) % 1000000;
+ if (ioctl(p->fd, BIOCSRTIMEOUT, &to) < 0) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
+ pcap_strerror(errno));
+ return NULL;
+ }
+ }
+
+ if (ioctl(fd, BIOCGBLEN, &v) < 0) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
+ pcap_strerror(errno));
+ return NULL;
+ }
+ p->bufsize = v;
+ p->buffer = (u_char *)malloc(p->bufsize);
+ if (p->buffer == NULL) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ return NULL;
+ }
+ return p;
+#else /* defined(__OpenBSD__) */
+ return pcap_open_live(dev, slen, promisc, to_ms, ebuf);
+#endif
+}