work on new packet
This commit is contained in:
parent
0ac7dd537c
commit
4fb6eda8b8
@ -26,29 +26,25 @@ cdef extern from "netinet/ip.h":
|
||||
u_int32_t daddr
|
||||
|
||||
# cython define
|
||||
cdef extern from "netinet/tcp.h":
|
||||
struct tcphdr:
|
||||
u_int16_t th_sport
|
||||
u_int16_t th_dport
|
||||
u_int32_t th_seq
|
||||
u_int32_t th_ack
|
||||
struct tcphdr:
|
||||
u_int16_t th_sport
|
||||
u_int16_t th_dport
|
||||
u_int32_t th_seq
|
||||
u_int32_t th_ack
|
||||
|
||||
u_int8_t th_x2
|
||||
u_int8_t th_off
|
||||
u_int8_t th_off
|
||||
|
||||
u_int8_t th_flags
|
||||
|
||||
u_int16_t th_win
|
||||
u_int16_t th_sum
|
||||
u_int16_t th_urp
|
||||
u_int8_t th_flags
|
||||
u_int16_t th_win
|
||||
u_int16_t th_sum
|
||||
u_int16_t th_urp
|
||||
|
||||
# cython define
|
||||
cdef extern from "netinet/udp.h":
|
||||
struct udphdr:
|
||||
u_int16_t uh_sport
|
||||
u_int16_t uh_dport
|
||||
u_int16_t uh_ulen
|
||||
u_int16_t uh_sum
|
||||
struct udphdr:
|
||||
u_int16_t uh_sport
|
||||
u_int16_t uh_dport
|
||||
u_int16_t uh_ulen
|
||||
u_int16_t uh_sum
|
||||
|
||||
cdef struct icmphdr:
|
||||
u_int8_t type
|
||||
@ -182,7 +178,6 @@ cdef class CPacket:
|
||||
|
||||
cdef u_int32_t id
|
||||
|
||||
|
||||
# protocol headers
|
||||
cdef iphdr *ip_header
|
||||
cdef tcphdr *tcp_header
|
||||
@ -195,6 +190,7 @@ cdef class CPacket:
|
||||
# Packet details:
|
||||
cdef Py_ssize_t data_len
|
||||
cdef readonly unsigned char *data
|
||||
cdef unsigned char *payload
|
||||
cdef timeval timestamp
|
||||
cdef u_int8_t hw_addr[8]
|
||||
|
||||
|
@ -24,9 +24,9 @@ cdef int nf_callback(nfq_q_handle *qh, nfgenmsg *nfmsg, nfq_data *nfa, void *dat
|
||||
|
||||
packet = CPacket()
|
||||
with nogil:
|
||||
packet.parse(qh, nfa)
|
||||
cdef u_int32_t mark = packet.parse(qh, nfa)
|
||||
|
||||
user_callback(packet)
|
||||
user_callback(packet, mark)
|
||||
|
||||
return 1
|
||||
|
||||
@ -46,7 +46,7 @@ cdef class CPacket:
|
||||
self._verdict_is_set = False
|
||||
self._mark = 0
|
||||
|
||||
# self.protocol = 0
|
||||
self.payload = 0
|
||||
|
||||
# def __str__(self):
|
||||
# cdef iphdr *hdr = <iphdr*>self.payload
|
||||
@ -55,7 +55,7 @@ cdef class CPacket:
|
||||
# return "%s packet, %s bytes" % (protocol, self.payload_len)
|
||||
|
||||
# NOTE: this will be callback target for nfqueue
|
||||
cdef void parse(self, nfq_q_handle *qh, nfq_data *nfa) nogil:
|
||||
cdef u_int32_t parse(self, nfq_q_handle *qh, nfq_data *nfa) nogil:
|
||||
'''Alternate constructor. Used to start listener/proxy instances using nfqueue bindings.'''
|
||||
|
||||
'''Assign a packet from NFQ to this object. Parse the header and load local values.'''
|
||||
@ -67,7 +67,7 @@ cdef class CPacket:
|
||||
|
||||
nfqnl_msg_packet_hdr *hdr = nfq_get_msg_packet_hdr(nfa)
|
||||
self.id = ntohl(hdr.packet_id)
|
||||
# NOTE: these are not needing at this moment.
|
||||
# NOTE: these are not needed at this moment.
|
||||
# self.hw_protocol = ntohs(hdr.hw_protocol)
|
||||
# self.hook = hdr.hook
|
||||
|
||||
@ -81,6 +81,8 @@ cdef class CPacket:
|
||||
|
||||
self._mark = nfq_get_nfmark(nfa)
|
||||
|
||||
return self._mark
|
||||
|
||||
# splitting packet by tcp/ip layers
|
||||
self._parse()
|
||||
|
||||
@ -92,23 +94,29 @@ cdef class CPacket:
|
||||
the before_exit method will be called before returning, which can be used to create
|
||||
subclass specific objects like namedtuples or application layer data.'''
|
||||
|
||||
cdef iphdr *ip_header = <iphdr*>self.data
|
||||
self.ip_header = <iphdr*>self.data
|
||||
|
||||
cdef u_int8_t iphdr_len = (ip_header.tos & 15) * 4
|
||||
|
||||
cdef tcphdr *tcp_header
|
||||
cdef udphdr *udp_header
|
||||
cdef icmphdr *icmp_header
|
||||
cdef u_int8_t tcphdr_len
|
||||
cdef u_int8_t udphdr_len
|
||||
|
||||
self.ip_header = ip_header
|
||||
if (ip_header.protocol == IPPROTO_TCP):
|
||||
|
||||
self.tcp_header = <tcphdr*>self.data[iphdr_len]
|
||||
|
||||
tcphdr_len = (self.tcp_header.th_off & 15) * 4
|
||||
|
||||
self.payload = self.data[iphdr_len+tcphdr_len:self.data_len]
|
||||
|
||||
if (ip_header.protocol == IPPROTO_UDP):
|
||||
|
||||
self.udp_header = <udphdr*>self.data[iphdr_len]
|
||||
|
||||
udphdr_len = 8
|
||||
|
||||
self.payload = self.data[iphdr_len + udphdr_len:self.data_len]
|
||||
|
||||
if (ip_header.protocol == IPPROTO_ICMP):
|
||||
|
||||
self.icmp_header = <icmphdr*>self.data[iphdr_len]
|
||||
@ -116,16 +124,9 @@ cdef class CPacket:
|
||||
cdef void verdict(self, u_int32_t verdict):
|
||||
'''Call appropriate set_verdict... function on packet.'''
|
||||
|
||||
# TODO: figure out what to do about this. maybe just printf instead?
|
||||
if self._verdict_is_set:
|
||||
raise RuntimeWarning("Verdict already given for this packet.")
|
||||
|
||||
# cdef u_int32_t modified_payload_len = 0
|
||||
# cdef unsigned char *modified_payload = NULL
|
||||
|
||||
# rewriting payload data/len
|
||||
# if self._given_payload:
|
||||
# modified_payload_len = len(self._given_payload)
|
||||
# modified_payload = self._given_payload
|
||||
raise RuntimeWarning('Verdict already given for this packet.')
|
||||
|
||||
if self._modified_mark:
|
||||
nfq_set_verdict2(
|
||||
@ -145,17 +146,17 @@ cdef class CPacket:
|
||||
return self.data[:self.data_len]
|
||||
|
||||
def get_ip_header(self):
|
||||
'''return layer3 of packet data as a tuple converted directly from C struct.'''
|
||||
'''Return layer3 of packet data as a tuple converted directly from C struct.'''
|
||||
|
||||
cdef tuple ip_header
|
||||
|
||||
ip_header = (
|
||||
self.ip_header.tos,
|
||||
self.ip_header.tot_len,
|
||||
self.ip_header.id,
|
||||
ntohs(self.ip_header.tot_len),
|
||||
ntohs(self.ip_header.id),
|
||||
self.ip_header.frag_off,
|
||||
self.ip_header.ttl,
|
||||
self.ip_header.protocol,
|
||||
ntohs(self.ip_header.protocol),
|
||||
self.ip_header.check,
|
||||
ntohl(self.ip_header.saddr),
|
||||
ntohl(self.ip_header.daddr)
|
||||
@ -164,7 +165,51 @@ cdef class CPacket:
|
||||
return ip_header
|
||||
|
||||
def get_proto_header(self):
|
||||
'''return layer4 of packet data as a tuple converted directly from C struct.'''
|
||||
'''Return layer4 of packet data as a tuple converted directly from C struct.'''
|
||||
|
||||
cdef tuple proto_header
|
||||
|
||||
if (ip_header.protocol == IPPROTO_TCP):
|
||||
|
||||
proto_header = (
|
||||
ntohs(self.tcp_header.th_sport),
|
||||
ntohs(self.tcp_header.th_dport),
|
||||
ntohl(self.tcp_header.th_seq),
|
||||
ntohl(self.tcp_header.th_ack),
|
||||
|
||||
self.tcp_header.th_off,
|
||||
|
||||
self.tcp_header.th_flags,
|
||||
ntohs(self.tcp_header.th_win),
|
||||
ntohs(self.tcp_header.th_sum),
|
||||
self.tcp_header.th_urp
|
||||
)
|
||||
|
||||
elif (ip_header.protocol == IPPROTO_UDP):
|
||||
|
||||
proto_header = (
|
||||
ntohs(proto_header.uh_sport),
|
||||
ntohs(proto_header.uh_dport),
|
||||
ntohs(proto_header.uh_ulen),
|
||||
ntohs(proto_header.uh_sum),
|
||||
)
|
||||
|
||||
elif (ip_header.protocol == IPPROTO_ICMP):
|
||||
|
||||
proto_header = (
|
||||
self.ip_header.type,
|
||||
)
|
||||
|
||||
return proto_header
|
||||
|
||||
def get_payload(self):
|
||||
'''Return payload as Python bytes.'''
|
||||
|
||||
cdef object payload
|
||||
|
||||
payload = self.payload[:self.payload_len]
|
||||
|
||||
return payload
|
||||
|
||||
# def _before_exit(self):
|
||||
# '''executes before returning from parse call.
|
||||
@ -255,8 +300,6 @@ cdef class NetfilterQueue:
|
||||
with nogil:
|
||||
rv = recv(fd, buf, sizeof(buf), recv_flags)
|
||||
|
||||
print(rv)
|
||||
|
||||
if (rv >= 0):
|
||||
nfq_handle_packet(self.h, buf, rv)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user