0

I am using libpcap via ctypes in python. I've written a little wrapper, so I can access the pcap functions more convenient. For e.g. pcap_geterr it looks like

# char  *pcap_geterr(pcap_t *p);
geterr = _pcap.pcap_geterr
geterr.argtypes = [ctypes.c_void_p]
geterr.restype = ctypes.c_char_p

But now I need to use pcap_stats and I'm having trouble passing the pcap_stat struct to the function.

The code looks like

class pcap_stat(ctypes.Structure):
    '''
    struct pcap_stat {
        u_int ps_recv;        /* number of packets received */
        u_int ps_drop;        /* number of packets dropped */
        u_int ps_ifdrop;    /* drops by interface, not yet supported */
        #ifdef WIN32
        u_int bs_capt;        /* number of packets that reach the application */
        #endif /* WIN32 */
    };
    '''
    _fields_ = [("ps_recv", ctypes.c_uint), ("ps_drop", ctypes.c_uint), ("ps_ifdrop", ctypes.c_uint)]

# int   pcap_stats(pcap_t *p, struct pcap_stat *ps);
stats = _pcap.pcap_stats
stats.argtypes = [ctypes.c_void_p, ctypes.c_void_p] # is the second argument right?
stats.restype = ctypes.c_uint

I am not sure if the second argument type for stats is right and then how to pass a C struct to the function in python. In C it would probably look like

struct pcap_stat stat;
pcap_stats(handle, &stat);

But how the heck in python?

Cravid
  • 653
  • 2
  • 7
  • 22

1 Answers1

1

You need to declare the correct type of any pointer argument; notably struct pcap_stat *ps becomes ctypes.POINTER(pcap_stat).

Then: s = pcap_stat(); pcap_stats(handle, ctypes.byref(s)).

See also http://cffi.readthedocs.org for a different interface that might be simpler to use than ctypes.

Armin Rigo
  • 12,048
  • 37
  • 48
  • ahh dammit... it took me about 3 hours now and your answer to notice a not commented out pcap_close before pcap_stats... thats why it always return -1 and "bad file descriptor". Thank you. – Cravid Jan 21 '13 at 17:44