Skip to content

Commit

Permalink
add pcap_{get,set}nonblock, to work around BPF b0rkage on OS X, FreeB…
Browse files Browse the repository at this point in the history
…SD, etc.
  • Loading branch information
dugsong committed Aug 29, 2005
1 parent db2fc55 commit 1d0b8b1
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 9 deletions.
23 changes: 19 additions & 4 deletions pcap.pyx
Expand Up @@ -63,11 +63,13 @@ cdef extern from "pcap.h":

cdef extern from "pcap_ex.h":
# XXX - hrr, sync with libdnet and libevent
void pcap_ex_immediate(pcap_t *p)
int pcap_ex_immediate(pcap_t *p)
char *pcap_ex_name(char *name)
char *pcap_ex_lookupdev(char *ebuf)
int pcap_ex_fileno(pcap_t *p)
void pcap_ex_setup(pcap_t *p)
void pcap_ex_setnonblock(pcap_t *p, int nonblock, char *ebuf)
int pcap_ex_getnonblock(pcap_t *p, char *ebuf)
int pcap_ex_next(pcap_t *p, pcap_pkthdr **hdr, char **pkt)
int pcap_ex_compile_nopcap(int snaplen, int dlt,
bpf_program *fp, char *str,
Expand Down Expand Up @@ -163,7 +165,7 @@ cdef class pcap:
if not name:
p = pcap_ex_lookupdev(self.__ebuf)
if p == NULL:
raise OSError, "couldn't lookup device"
raise OSError, self.__ebuf
else:
p = name

Expand All @@ -178,8 +180,8 @@ cdef class pcap:
self.__filter = strdup("")
try: self.__dloff = dltoff[pcap_datalink(self.__pcap)]
except KeyError: pass
if immediate:
pcap_ex_immediate(self.__pcap)
if immediate and pcap_ex_immediate(self.__pcap) < 0:
raise OSError, "couldn't set BPF immediate mode"

property name:
"""Network interface or dumpfile name."""
Expand Down Expand Up @@ -220,6 +222,19 @@ cdef class pcap:
if pcap_setfilter(self.__pcap, &fcode) < 0:
raise OSError, pcap_geterr(self.__pcap)
pcap_freecode(&fcode)

def setnonblock(self, nonblock=True):
"""Set non-blocking capture mode."""
pcap_ex_setnonblock(self.__pcap, nonblock, self.__ebuf)

def getnonblock(self):
"""Return non-blocking capture mode as boolean."""
ret = pcap_ex_getnonblock(self.__pcap, self.__ebuf)
if ret < 0:
raise OSError, self.__ebuf
elif ret:
return True
return False

def datalink(self):
"""Return datalink type (DLT_* values)."""
Expand Down
29 changes: 26 additions & 3 deletions pcap_ex.c
Expand Up @@ -28,11 +28,15 @@ int PyGILState_Ensure() { return (0); }
void PyGILState_Release(int gil) { }
#endif

void
int
pcap_ex_immediate(pcap_t *pcap)
{
#ifdef BIOCIMMEDIATE
ioctl(pcap_fileno(pcap), BIOCIMMEDIATE, 1);
int n = 1;

return ioctl(pcap_fileno(pcap), BIOCIMMEDIATE, &n);
#else
return (0);
#endif
}

Expand Down Expand Up @@ -196,16 +200,35 @@ pcap_ex_setup(pcap_t *pcap)
#ifdef _WIN32
SetConsoleCtrlHandler(__pcap_ex_ctrl, TRUE);
#else
#if 0
int fd, n;

fd = pcap_fileno(pcap);
n = fcntl(fd, F_GETFL, 0) | O_NONBLOCK;
fcntl(fd, F_SETFL, n);

#endif
signal(SIGINT, __pcap_ex_signal);
#endif
}

void
pcap_ex_setnonblock(pcap_t *pcap, int nonblock, char *ebuf)
{
#ifdef HAVE_PCAP_SETNONBLOCK
pcap_setnonblock(pcap, nonblock, ebuf);
#endif
}

int
pcap_ex_getnonblock(pcap_t *pcap, char *ebuf)
{
#ifdef HAVE_PCAP_SETNONBLOCK
return (pcap_getnonblock(pcap, ebuf));
#else
return (0);
#endif
}

/* return codes: 1 = pkt, 0 = timeout, -1 = error, -2 = EOF */
int
pcap_ex_next(pcap_t *pcap, struct pcap_pkthdr **hdr, u_char **pkt)
Expand Down
4 changes: 3 additions & 1 deletion pcap_ex.h
Expand Up @@ -3,11 +3,13 @@
#ifndef PCAP_EX_H
#define PCAP_EX_H

void pcap_ex_immediate(pcap_t *pcap);
int pcap_ex_immediate(pcap_t *pcap);
char *pcap_ex_name(char *name);
char *pcap_ex_lookupdev(char *ebuf);
int pcap_ex_fileno(pcap_t *pcap);
void pcap_ex_setup(pcap_t *pcap);
void pcap_ex_setnonblock(pcap_t *pcap, int nonblock, char *ebuf);
int pcap_ex_getnonblock(pcap_t *pcap, char *ebuf);
int pcap_ex_next(pcap_t *pcap, struct pcap_pkthdr **hdr, u_char **pkt);
int pcap_ex_compile_nopcap(int snaplen, int dlt, struct bpf_program *fp,
char *str, int optimize, unsigned int netmask);
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Expand Up @@ -30,6 +30,8 @@ def _write_config_h(self, cfg):
d['HAVE_PCAP_FILE'] = 1
if buf.find('pcap_compile_nopcap(') != -1:
d['HAVE_PCAP_COMPILE_NOPCAP'] = 1
if buf.find('pcap_setnonblock(') != -1:
d['HAVE_PCAP_SETNONBLOCK'] = 1
f = open('config.h', 'w')
for k, v in d.iteritems():
f.write('#define %s %s\n' % (k, v))
Expand Down Expand Up @@ -90,7 +92,7 @@ def run(self):
pcap_cmds = { 'config':config_pcap, 'clean':clean_pcap }

setup(name='pcap',
version='0.6',
version='1.0',
author='Dug Song',
author_email='dugsong@monkey.org',
url='http://monkey.org/~dugsong/pypcap/',
Expand Down

0 comments on commit 1d0b8b1

Please sign in to comment.