Closed gil-obradors closed 3 years ago
Found it!
I start to understand...
But may be must be more easy for final user? I come from pcap that isn't maintained and there exists some helper functions for that, for example:
https://github.com/pynetwork/pypcap/blob/a10cce7f4034e128ee257bf8f429e0ddc37cf54b/pcap.pyx#L510
Is the same method of bindings from pcap
and pypcap
?
;>I come from pcap that isn't maintained Take a look at: https://pypi.org/project/pcap-ct/ https://github.com/karpierz/pcap-ct libpcap is strictly lowest level (C level) package. It is a base for higher level pcap-ct (100% compatible with https://github.com/pynetwork/pypcap - de facto a fork of it, but based on libpcap/ctypes instead of Cython based bibding.) pypcap/pcap-ct is much more pythonic and much more easier to use than raw libpcap.
Ok! Thank you very much for your guidance!
This is an example to use on Linux to dump traffic to a file. Maybe it helps others to speed up their development.
Change maybe the interface_name
or filter_string
and you should end up with a capture file output.pcap
.
It will only work if there is traffic. Else it will stay in dispatch
.
The C interfacing might not be used as efficiently as it could be, but it should convey the idea.
import ctypes
import sys
import libpcap
pcap_filename = "output.pcap"
interface_name = "eth0"
filter_string = "src 192.168.1.1"
snaplen = 65536
promisc = 0
to_ms = 100
libpcap.config(LIBPCAP="tcpdump")
# encode the interface name on which to capture
interface = ctypes.c_char_p(interface_name.encode(encoding="utf-8"))
buffer_error = ctypes.create_string_buffer(libpcap.PCAP_ERRBUF_SIZE)
capture = libpcap.open_live(interface, snaplen, promisc, to_ms, buffer_error)
if not capture:
print(buffer_error.value.decode(encoding="utf-8"))
sys.exit(-1)
# get network interface information (xxx.xxx.xxx.xxx/xx)
netp = libpcap.bpf_u_int32()
maskp = libpcap.bpf_u_int32()
success = not libpcap.lookupnet(interface, netp, maskp, buffer_error)
if not success:
print(buffer_error.value.decode(encoding="utf-8"))
sys.exit(-1)
# setup the message filter
bpf_program = libpcap.bpf_program()
filter_string = ctypes.c_char_p(filter_string.encode("utf-8"))
success = not libpcap.compile(capture, bpf_program, filter_string, 1, maskp)
if not success:
print(f"Compiling \"{filter_string.value.decode('utf-8')}\" failed")
sys.exit(-1)
# set the filter
success = not libpcap.setfilter(capture, bpf_program)
if not success:
print(f"libpcap.setfilter failed")
sys.exit(-1)
# setup pcap dump file
file_name = ctypes.c_char_p(str(pcap_filename).encode("utf-8"))
dumper = libpcap.dump_open(capture, file_name)
if not dumper:
error = libpcap.geterr(capture).decode("utf-8")
print(f"dump_open on \"{file_name.value.decode('utf-8')}\" failed with \"{error}\"")
user = ctypes.c_ubyte(0)
packet_count_all = 0
packet_count_until_stop = 10
# on packet received callback
@ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_ubyte), ctypes.POINTER(libpcap.pkthdr), ctypes.POINTER(ctypes.c_ubyte))
def callback(user, packet_header, payload):
libpcap.dump(ctypes.cast(dumper, ctypes.POINTER(ctypes.c_ubyte)), packet_header, payload)
while True:
packet_count = libpcap.dispatch(capture, -1, callback, user)
packet_count_all += packet_count
print(f"Processed {packet_count} packets, overall {packet_count_all}")
if packet_count_all >= packet_count_until_stop:
break
libpcap.dump_close(dumper)
libpcap.close(capture)
Hi!
I'm trying to play with libpcap on Ubuntu 20, with tcpdump.
I have no experience with CFUNC and C Python bindings... Can you give me a trick why I can't discover devices ?
Output
The binding direct to C function is
why is falling? I have tried this... but nothing...
I can offer a doc page with examples for future users on Linux, but I need to understand the bindings...
Many thanks for the work!