added in/outdev getters and performance improvements.

This commit is contained in:
DOWRIGHT 2022-04-16 12:17:40 -07:00
parent a3dedaea57
commit c530f1bd94
3 changed files with 62 additions and 1 deletions

View File

@ -154,6 +154,8 @@ cdef extern from "libnetfilter_queue/libnetfilter_queue.h":
int nfq_get_timestamp(nfq_data *nfad, timeval *tv)
nfqnl_msg_packet_hw *nfq_get_packet_hw(nfq_data *nfad)
int nfq_get_nfmark (nfq_data *nfad)
u_int8_t nfq_get_indev(nfq_data *nfad)
u_int8_t nfq_get_outdev(nfq_data *nfad)
nfnl_handle *nfq_nfnlh(nfq_handle *h)
# Dummy defines from linux/socket.h:
@ -193,6 +195,8 @@ cdef class Packet:
cdef bytes _given_payload # New payload of packet, or null
cdef bytes _owned_payload
cdef nfq_data *_nfa
# From NFQ packet header:
cdef readonly u_int32_t id
cdef readonly u_int16_t hw_protocol
@ -215,6 +219,8 @@ cdef class Packet:
cdef set_nfq_data(self, NetfilterQueue queue, nfq_data *nfa)
cdef drop_refs(self)
cdef int verdict(self, u_int8_t verdict) except -1
cpdef get_indev(self, bint name=*)
cpdef get_outdev(self, bint name=*)
cpdef Py_ssize_t get_payload_len(self)
cpdef double get_timestamp(self)
cpdef bytes get_payload(self)

View File

@ -12,6 +12,8 @@ class Packet:
id: int
mark: int
def get_hw(self) -> Optional[bytes]: ...
def get_indev(self, name: bool = False): ...
def get_outdev(self, name: bool = False): ...
def get_payload(self) -> bytes: ...
def get_payload_len(self) -> int: ...
def get_timestamp(self) -> float: ...

View File

@ -4,9 +4,16 @@ function.
Copyright: (c) 2011, Kerkhoff Technologies Inc.
License: MIT; see LICENSE.txt
Expanded features and performance improvements from downstream development
of DNXFIREWALL.
- DOWRIGHT @ Wright Network Solutions, LLC.
"""
# Constants for module users
import Cython
import socket
COPY_NONE = 0
COPY_META = 1
COPY_PACKET = 2
@ -41,7 +48,9 @@ cdef int global_callback(nfq_q_handle *qh, nfgenmsg *nfmsg,
# so just ignore the packet. The kernel will drop it once we
# unbind.
return 1
packet = Packet()
# skipping call to __init__.
packet = Packet.__new__(Packet)
packet.set_nfq_data(nfqueue, nfa)
try:
user_callback(packet)
@ -49,6 +58,8 @@ cdef int global_callback(nfq_q_handle *qh, nfgenmsg *nfmsg,
packet.drop_refs()
return 1
# pre allocated memory for Packet object.
@Cython.freelist(8)
cdef class Packet:
"""A packet received from NetfilterQueue."""
def __cinit__(self):
@ -69,6 +80,8 @@ cdef class Packet:
cdef nfqnl_msg_packet_hw *hw
cdef nfqnl_msg_packet_hdr *hdr
self._nfa = nfa
hdr = nfq_get_msg_packet_hdr(nfa)
self._queue = queue
self.id = ntohl(hdr.packet_id)
@ -129,6 +142,46 @@ cdef class Packet:
self._verdict_is_set = True
cpdef get_indev(self, bint name=False):
"""Returns the index of the inbound interface of the packet. If the packet
sourced from localhost or the input interface is not known, 0/unknown will
be returned respectively.
if name=True, socket.if_indextoname() will be returned.
"""
cdef object in_interface_name
in_interface = nfq_get_indev(self._nfa)
if not name:
return in_interface
try:
in_interface_name = socket.if_indextoname(in_interface)
except OSError:
in_interface_name = 'unknown'
return in_interface_name
cpdef get_outdev(self, bint name=False):
"""Returns the index of the outbound interface of the packet. If the packet
sourced from localhost or the input interface is not known, 0/unknown will
be returned respectively.
if name=True, socket.if_indextoname() will be returned.
"""
cdef object out_interface_name
out_interface = nfq_get_outdev(self._nfa)
if not name:
return out_interface
try:
out_interface_name = socket.if_indextoname(out_interface)
except OSError:
out_interface_name = 'unknown'
return out_interface_name
def get_hw(self):
"""Return the packet's source MAC address as a Python bytestring, or
None if it's not available.