2016-08-05 18 views
0

IPパケットの最初の20バイト(フルパケットからオプションを除いたもの)をキャプチャし、structのメンバーをctypeに設定して、画面(プロトコル、送信元および宛先アドレス)。次のように私のIPクラスは次のとおりです。ソケットバッファをコピーするときにctypesを使用するPythonパケットスニッファーがクラッシュする

import socket 
import os 
import struct 
from ctypes import * 

# host to 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 to their 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) 

、私はホストにバインド、ソケットを作成し、ループパケットを取得するには:

# create socket and bind to 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 a packet 
     raw_buffer = sniffer.recvfrom(65565)[0] 
     # create an IP header from the first 20 bytes of the buffer 
     ip_header = IP(raw_buffer[0:20]) 
     # print out the protocol that was detected and the 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) 

のデータ型としてc_ulongを使用して実行すると、 (他にnostarch.comにpingを送信しながら、一つの端末で実行されている)"src""dst"_fields_structメンバーは、私は次のエラーを取得する:

enter image description here

私はおそらくc_ulongのサイズが1バイトよりも大きかったと仮定して、最初の20バイト(私は非常に新しいPythonです)のための私の要件をスローします。私はその後c_ushortc_ulongを変えて、もう一度それを実行しました:

enter image description here

実際のpingパス:スクリプトがエラーなしで走っている間

enter image description here

そう、それはsrcdstを切断していますアドレス。

なぜ私は最初の20だけを欲しいと言っているのですか?

すべてのヘルプは高く評価され

(Iは、Python 2.7を使用して、Win7のホスト上で実行されている、Kali64 VBoxのVMでね)。

答えて

1

IPのサイズを確認する必要があり、即ち

print(sizeof(IP)) 

20のバイトを返すべきです。 ctypes.u_longは64ビットLinuxの場合8であるため、サイズは32バイト(パディングのため4バイト余分、整数サイズのため8バイト)になります。 ctypes.u_intまたは明示的なサイズを次のように使用してください:

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)) 
+0

完璧、ありがとう – corporateWhore

関連する問題