Python wrapper for libnetfilter_conntrack.
To listen to conntrack events, refer to the following snippet:
importlibnetfilterconntrackimportsocketimportstructdefcallback_ct(nfmsgtype, conntrack):
ct_id, =struct.unpack('!I', conntrack.id)
(orig_l3proto, orig_l4proto,
repl_l3proto, repl_l4proto) = \
struct.unpack('!BBBB', conntrack.orig_l3proto+conntrack.orig_l4proto+conntrack.repl_l3proto+conntrack.repl_l4proto)
iforig_l4protoin (socket.IPPROTO_TCP, socket.IPPROTO_UDP):
orig_ipv4_src=socket.inet_ntoa(conntrack.orig_ipv4_src)
orig_ipv4_dst=socket.inet_ntoa(conntrack.orig_ipv4_dst)
repl_ipv4_src=socket.inet_ntoa(conntrack.repl_ipv4_src)
repl_ipv4_dst=socket.inet_ntoa(conntrack.repl_ipv4_dst)
(orig_port_src, orig_port_dst,
repl_port_src, repl_port_dst) = \
struct.unpack('!HHHH', conntrack.orig_port_src+conntrack.orig_port_dst+conntrack.repl_port_src+conntrack.repl_port_dst)
print' | '.join(('conntrack', 'id: %s', 'type: %s',
'orig (3: %s, 4: %s): %s:%s => %s:%s',
'repl (3: %s, 4: %s): %s:%s => %s:%s')) % \
(ct_id, nfmsgtype,
orig_l3proto, orig_l4proto,
orig_ipv4_src, orig_port_src,
orig_ipv4_dst, orig_port_dst,
repl_l3proto, repl_l4proto,
repl_ipv4_src, repl_port_src,
repl_ipv4_dst, repl_port_dst)
returnlibnetfilterconntrack.NFCT_CB_CONTINUEdefcallback_exp(nfmsgtype, expect):
master=expect.master()
(master_l3proto,
master_l4proto) =struct.unpack('!BB', master.l3proto+master.l4proto)
ifmaster_l4protoin (socket.IPPROTO_TCP, socket.IPPROTO_UDP):
master_ipv4_src=socket.inet_ntoa(master.ipv4_src)
master_ipv4_dst=socket.inet_ntoa(master.ipv4_dst)
(master_port_src,
master_port_dst) =struct.unpack('!HH', master.port_src+master.port_dst)
print' | '.join(('expect', 'master',
'3: %s, 4: %s',
'%s:%s => %s:%s')) % \
(master_l3proto, master_l4proto,
master_ipv4_src, master_port_src,
master_ipv4_dst, master_port_dst)
returnlibnetfilterconntrack.NFCT_CB_CONTINUEsubsystem=libnetfilterconntrack.NFNL_SUBSYS_NONEgroups= (libnetfilterconntrack.NF_NETLINK_CONNTRACK_CT_ALL|libnetfilterconntrack.NF_NETLINK_CONNTRACK_EXP_ALL)
handle=libnetfilterconntrack.open(subsystem, groups)
handle.ct_callback_set(libnetfilterconntrack.NFCT_T_ALL, callback_ct)
handle.exp_callback_set(libnetfilterconntrack.NFCT_T_ALL, callback_exp)
try:
sock=socket.fromfd(handle.fd(),
socket.AF_NETLINK,
socket.SOCK_RAW)
whileTrue:
try:
data, address=sock.recvfrom(8192)
ifhandle.handle(data, address):
continuebreakexceptsocket.errorase:
ife.errnoissocket.errno.ENOBUFS:
print'Unable to hold processed packets'continueraisefinally:
sock.close()
handle.ct_callback_clear()
handle.exp_callback_clear()
handle.close()To query conntrack objects, refer to the following snippet:
importlibnetfilterconntrackimportsocketimportstructdefquery_ct(protocols, source, destination):
l3proto, l4proto=protocolssrc_addr, src_port=sourcedst_addr, dst_port=destinationl3proto, l4proto=struct.pack('!BB', l3proto, l4proto)
src_addr, src_port=socket.inet_aton(src_addr), struct.pack('!H', src_port)
dst_addr, dst_port=socket.inet_aton(dst_addr), struct.pack('!H', dst_port)
ct_req=libnetfilterconntrack.ct_new()
ct_req.l3proto=l3protoct_req.ipv4_src=src_addrct_req.ipv4_dst=dst_addrct_req.l4proto=l4protoct_req.port_src=src_portct_req.port_dst=dst_portsubsystem=libnetfilterconntrack.NFNL_SUBSYS_CTNETLINK_CTdefcatch_ct(nfmsgtype, ct_res):
libnetfilterconntrack.ct_copy(ct_req, ct_res, libnetfilterconntrack.NFCT_CP_ALL)
returnlibnetfilterconntrack.NFCT_CB_STOPhandle=libnetfilterconntrack.open(subsystem, 0)
handle.ct_callback_set(libnetfilterconntrack.NFCT_T_ALL, catch_ct)
handle.ct_send(libnetfilterconntrack.NFCT_Q_GET, ct_req)
try:
sock=socket.fromfd(handle.fd(),
socket.AF_NETLINK,
socket.SOCK_RAW)
sock.settimeout(0)
whileTrue:
try:
data, address=sock.recvfrom(8192)
ifhandle.handle(data, address):
continuebreakexceptsocket.errorase:
ife.errnoissocket.errno.EWOULDBLOCK:
ct_req.destroy()
returnNoneife.errnoissocket.errno.ENOBUFS:
print'Unable to hold processed packets'continueraisefinally:
sock.close()
handle.ct_callback_clear()
handle.close()
returnct_reqconntrack=query_ct((socket.AF_INET, socket.IPPROTO_TCP),
('192.168.50.40', 58198),
('192.168.50.50', 21))
ifconntrack:
ct_id, =struct.unpack('!I', conntrack.id)
(orig_l3proto, orig_l4proto,
repl_l3proto, repl_l4proto) = \
struct.unpack('!BBBB', conntrack.orig_l3proto+conntrack.orig_l4proto+conntrack.repl_l3proto+conntrack.repl_l4proto)
iforig_l4protoin (socket.IPPROTO_TCP, socket.IPPROTO_UDP):
orig_ipv4_src=socket.inet_ntoa(conntrack.orig_ipv4_src)
orig_ipv4_dst=socket.inet_ntoa(conntrack.orig_ipv4_dst)
repl_ipv4_src=socket.inet_ntoa(conntrack.repl_ipv4_src)
repl_ipv4_dst=socket.inet_ntoa(conntrack.repl_ipv4_dst)
(orig_port_src, orig_port_dst,
repl_port_src, repl_port_dst) = \
struct.unpack('!HHHH', conntrack.orig_port_src+conntrack.orig_port_dst+conntrack.repl_port_src+conntrack.repl_port_dst)
print' | '.join(('response', 'id: %s',
'orig (3: %s, 4: %s): %s:%s => %s:%s',
'repl (3: %s, 4: %s): %s:%s => %s:%s')) % \
(ct_id,
orig_l3proto, orig_l4proto,
orig_ipv4_src, orig_port_src,
orig_ipv4_dst, orig_port_dst,
repl_l3proto, repl_l4proto,
repl_ipv4_src, repl_port_src,
repl_ipv4_dst, repl_port_dst)
conntrack.destroy()To dump conntrack objects, refer to the following snippet:
importlibnetfilterconntrackimportsocketimportstructsubsystem=libnetfilterconntrack.NFNL_SUBSYS_CTNETLINK_CTdefcallback_ct(nfmsgtype, conntrack):
ct_id, =struct.unpack('!I', conntrack.id)
(orig_l3proto, orig_l4proto,
repl_l3proto, repl_l4proto) = \
struct.unpack('!BBBB', conntrack.orig_l3proto+conntrack.orig_l4proto+conntrack.repl_l3proto+conntrack.repl_l4proto)
iforig_l4protoin (socket.IPPROTO_TCP, socket.IPPROTO_UDP):
orig_ipv4_src=socket.inet_ntoa(conntrack.orig_ipv4_src)
orig_ipv4_dst=socket.inet_ntoa(conntrack.orig_ipv4_dst)
repl_ipv4_src=socket.inet_ntoa(conntrack.repl_ipv4_src)
repl_ipv4_dst=socket.inet_ntoa(conntrack.repl_ipv4_dst)
(orig_port_src, orig_port_dst,
repl_port_src, repl_port_dst) = \
struct.unpack('!HHHH', conntrack.orig_port_src+conntrack.orig_port_dst+conntrack.repl_port_src+conntrack.repl_port_dst)
print' | '.join(('conntrack', 'id: %s', 'type: %s',
'orig (3: %s, 4: %s): %s:%s => %s:%s',
'repl (3: %s, 4: %s): %s:%s => %s:%s')) % \
(ct_id, nfmsgtype,
orig_l3proto, orig_l4proto,
orig_ipv4_src, orig_port_src,
orig_ipv4_dst, orig_port_dst,
repl_l3proto, repl_l4proto,
repl_ipv4_src, repl_port_src,
repl_ipv4_dst, repl_port_dst)
returnlibnetfilterconntrack.NFCT_CB_CONTINUEhandle=libnetfilterconntrack.open(subsystem, 0)
handle.ct_callback_set(libnetfilterconntrack.NFCT_T_ALL, callback_ct)
handle.ct_send(libnetfilterconntrack.NFCT_Q_DUMP, socket.AF_INET)
try:
sock=socket.fromfd(handle.fd(),
socket.AF_NETLINK,
socket.SOCK_RAW)
sock.settimeout(0)
whileTrue:
try:
data, address=sock.recvfrom(8192)
ifhandle.handle(data, address):
continuebreakexceptsocket.errorase:
ife.errnoissocket.errno.EWOULDBLOCK:
breakife.errnoissocket.errno.ENOBUFS:
print'Unable to hold processed packets'continueraisefinally:
sock.close()
handle.ct_callback_clear()
handle.close()