Python packet sniffer using ctypes crashes when copying socket buffer -
i'm trying capture first 20 bytes (full packet minus options) of ip packet, populate struct
of ctype
members, , print information want screen (protocol, source , destination address). ip class follows:
import socket import os import struct ctypes import * # host listen on host = "192.168.0.187" # our ip header class ip(structure): _fields_ = [ ("ihl", c_ubyte, 4), ("version", c_ubyte, 4), ("tos", c_ubyte), ("len", c_ushort), ("id", c_ushort), ("offset", c_ushort), ("ttl", c_ubyte), ("protocol_num", c_ubyte), ("sum", c_ushort), ("src", c_ulong), ("dst", c_ulong) ] def __new__(self, socket_buffer=none): return self.from_buffer_copy(socket_buffer) def __init__(self, socket_buffer=none): # map protocol constants names self.protocol_map = {1:"icmp", 6:"tcp", 17:"udp"} # human readable ip addresses self.src_address = socket.inet_ntoa(struct.pack("<l",self.src)) self.dst_address = socket.inet_ntoa(struct.pack("<l",self.dst)) # human readable protocol try: self.protocol = self.protocol_map[self.protocol_num] except: self.protocol = str(self.protocol_num)
now, create socket, bind host, , loop packets:
# create socket , bind public interface (os dependent) if os.name == "nt": socket_protocol = socket.ipproto_ip else: socket_protocol = socket.ipproto_icmp # create raw socket sniffer = socket.socket(socket.af_inet, socket.sock_raw, socket_protocol) sniffer.bind((host, 0)) # include header information sniffer.setsockopt(socket.ipproto_ip, socket.ip_hdrincl, 1) if os.name == "nt": sniffer.ioctl(socket.sio_rcvall, socket.rcvall_on) try: while true: # read in packet raw_buffer = sniffer.recvfrom(65565)[0] # create ip header first 20 bytes of buffer ip_header = ip(raw_buffer[0:20]) # print out protocol detected , hosts print "protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_¬ address, ip_header.dst_address) # handle ctrl-c except keyboardinterrupt: # if we're using windows, turn off promiscuous mode if os.name == "nt": sniffer.ioctl(socket.sio_rcvall, socket.rcvall_off)
when run using c_ulong
data type "src"
, "dst"
_fields_
struct
members, following error (running in 1 terminal while pinging nostarch.com in another):
i postulated perhaps size of c_ulong
larger byte, throwing off requirement first 20 bytes (i'm new python). changed c_ulong
c_ushort
, ran again:
actual ping path:
so, while script ran without error, it's cutting off src
, dst
addresses.
why asking @ least 32 bytes when i'm telling want first 20?
(i'm in kali64 vbox vm, running on win7 host, using python 2.7)
any appreciated.
the size of ip
should verified, i.e.
print(sizeof(ip))
should return 20 bytes. since ctypes.u_long
8 in case of 64bit linux, size 32 bytes (4 bytes due padding, 8 bytes due integer sizes). either use ctypes.u_int
or explicit sizes follows:
from ctypes import * class ip(structure): _fields_ = [ ("version", c_uint8, 4), ("ihl", c_uint8, 4), ("tos", c_uint8), ("len", c_uint16), ("id", c_uint16), ("offset", c_uint16), ("ttl", c_uint8), ("protocol_num", c_uint8), ("sum", c_uint16), ("src", c_uint32), ("dst", c_uint32) ] print(sizeof(ip))
Comments
Post a Comment