Python

 

 

 

 

Python - Socket - Raw IPv4

 

NOTE 1 : All the examples in this page are written in Python 3.x. It may not work if you use Pyton 2.x

NOTE 2 : All the examples in this page are assumed to be written/run on Windows 7 unless specifically mentioned. You MAY (or may not) need to modify the syntax a little bit if you are running on other operating system.

 

Example 01 > ========================================================

 

In this example, I only created the sendor script and I didn't create the reciever script. I connected two PC with LAN cable and ran this script on sendor PC and used Wireshark on reciever PC to confirm the packet reception.

 

# import necessary package

import socket

import binascii

 

# destination ip

dst = '1.1.1.1'

 

# protocol number. This value will be set in Protocol field in IPv4 header.

# This value will be interprested as 'Unknown' protocol by wireshark and it would not try decode the payload.

# I intentionally used this value to prevent Wireshark from decoding the payload in strange way

proto = 253

 

# Open a raw socket.

print("Opening Socket..")

s = socket.socket(socket.AF_INET, socket.SOCK_RAW,proto)

 

print("Socket Info = ",s)

 

msgStr = "Hello World!"

bArray = bytearray(msgStr.encode('ascii'))

 

s.sendto(bArray, (dst, 0))

 

print("Sent complete")

 

 

Result :----------------------------------------------------------------------------

 

Opening Socket..

Socket Info =  <socket.socket fd=256, family=AddressFamily.AF_INET, type=SocketK

ind.SOCK_RAW, proto=253>

Sent complete

 

NOTE : If you compare the IP packet captured on Sender PC and Reciever PC

 

You may see HeaderChecksum error on Sender PC depending on the operating system or Network Interface Card. It would be because NIC calculate the checksum and wireshark captured the packet at the stage before NIC add checksum. But if you see the packet captured on reciever PC, you will see Checksum value is properly inserted.

 

< Packet captured by Sender PC >

 

No.     Time               Source                Destination           Protocol Length Info

     25 03:09:24.749326000 1.1.1.100             1.1.1.1               IPv4     46     Unknown (253)

 

Frame 25: 46 bytes on wire (368 bits), 46 bytes captured (368 bits) on interface 0

    Interface id: 0

    Encapsulation type: Ethernet (1)

    Arrival Time: Mar 29, 2016 23:09:24.749326000 Eastern Daylight Time

    [Time shift for this packet: 0.000000000 seconds]

    Epoch Time: 1459307364.749326000 seconds

    [Time delta from previous captured frame: 0.000008000 seconds]

    [Time delta from previous displayed frame: 0.000008000 seconds]

    [Time since reference or first frame: 135.151637000 seconds]

    Frame Number: 25

    Frame Length: 46 bytes (368 bits)

    Capture Length: 46 bytes (368 bits)

    [Frame is marked: False]

    [Frame is ignored: False]

    [Protocols in frame: eth:ip:data]

    [Coloring Rule Name: Checksum Errors]

    [Coloring Rule String: eth.fcs_bad==1 || ip.checksum_bad==1 || tcp.checksum_bad==1 || udp.checksum_bad==1 || sctp.checksum_bad==1 || mstp.checksum_bad==1 || cdp.checksum_bad==1 || edp.checksum_bad==1 || wlan.fcs_bad==1]

Ethernet II, Src: DellPcba_28:8d:92 (f0:1f:af:28:8d:92), Dst: Anritsu_06:41:e1 (00:00:91:06:41:e1)

    Destination: Anritsu_06:41:e1 (00:00:91:06:41:e1)

        Address: Anritsu_06:41:e1 (00:00:91:06:41:e1)

        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)

        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)

    Source: DellPcba_28:8d:92 (f0:1f:af:28:8d:92)

        Address: DellPcba_28:8d:92 (f0:1f:af:28:8d:92)

        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)

        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)

    Type: IP (0x0800)

Internet Protocol Version 4, Src: 1.1.1.100 (1.1.1.100), Dst: 1.1.1.1 (1.1.1.1)

    Version: 4

    Header length: 20 bytes

    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))

        0000 00.. = Differentiated Services Codepoint: Default (0x00)

        .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)

    Total Length: 32

    Identification: 0x02aa (682)

    Flags: 0x00

        0... .... = Reserved bit: Not set

        .0.. .... = Don't fragment: Not set

        ..0. .... = More fragments: Not set

    Fragment offset: 0

    Time to live: 128

    Protocol: Unknown (253)

    Header checksum: 0x0000 [incorrect, should be 0x32d1 (may be caused by "IP checksum offload"?)]

        [Good: False]

        [Bad: True]

            [Expert Info (Error/Checksum): Bad checksum]

                [Message: Bad checksum]

                [Severity level: Error]

                [Group: Checksum]

    Source: 1.1.1.100 (1.1.1.100)

    Destination: 1.1.1.1 (1.1.1.1)

    [Source GeoIP: Unknown]

    [Destination GeoIP: Unknown]

Data (12 bytes)

 

0000  48 65 6c 6c 6f 20 57 6f 72 6c 64 21               Hello World!

    Data: 48656c6c6f20576f726c6421

    [Length: 12]

 

 

< Packet captured by Reciever PC >

 

No.     Time               Source                Destination           Protocol Length Info

    931 18:48:42.432656000 1.1.1.100             1.1.1.1               IPv4     60     Unknown (253)

 

Frame 931: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface 0

    Interface id: 0

    WTAP_ENCAP: 1

    Arrival Time: Mar 29, 2016 18:48:42.432656000 Eastern Daylight Time

    [Time shift for this packet: 0.000000000 seconds]

    Epoch Time: 1459291722.432656000 seconds

    [Time delta from previous captured frame: 0.009614000 seconds]

    [Time delta from previous displayed frame: 0.009614000 seconds]

    [Time since reference or first frame: 12.930574000 seconds]

    Frame Number: 931

    Frame Length: 60 bytes (480 bits)

    Capture Length: 60 bytes (480 bits)

    [Frame is marked: False]

    [Frame is ignored: False]

    [Protocols in frame: eth:ip:data]

Ethernet II, Src: f0:1f:af:28:8d:92 (f0:1f:af:28:8d:92), Dst: Anritsu_06:41:e1 (00:00:91:06:41:e1)

    Destination: Anritsu_06:41:e1 (00:00:91:06:41:e1)

        Address: Anritsu_06:41:e1 (00:00:91:06:41:e1)

        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)

        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)

    Source: f0:1f:af:28:8d:92 (f0:1f:af:28:8d:92)

        Address: f0:1f:af:28:8d:92 (f0:1f:af:28:8d:92)

        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)

        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)

    Type: IP (0x0800)

    Padding: 0000000000000000000000000000

Internet Protocol Version 4, Src: 1.1.1.100 (1.1.1.100), Dst: 1.1.1.1 (1.1.1.1)

    Version: 4

    Header length: 20 bytes

    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))

        0000 00.. = Differentiated Services Codepoint: Default (0x00)

        .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)

    Total Length: 32

    Identification: 0x0a76 (2678)

    Flags: 0x00

        0... .... = Reserved bit: Not set

        .0.. .... = Don't fragment: Not set

        ..0. .... = More fragments: Not set

    Fragment offset: 0

    Time to live: 128

    Protocol: Unknown (253)

    Header checksum: 0x2b05 [correct]

        [Good: True]

 

 

NOTE : If you have errors as follows.

 

In some case, you may have following error messsage when you run the scrip. This is because you don't have enough permission to get access to RAW socket data.

If you are running this on Linux, try with su. If you are running this on Windows PC, run 'cmd.exe' windows with 'Run as administrator' and run the script as command line.

 

OSError: [WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions

 

 

Example 02 > ========================================================

 

In this example, I will create a script for both Sender and Reciever, so that you can check on the received packet without using Wireshark.

 

< Script on Sender PC >

 

import socket

import binascii

 

dst = '1.1.1.1'

proto = 253

 

# Open a raw socket.

print("Opening Socket..")

s = socket.socket(socket.AF_INET, socket.SOCK_RAW,proto)

 

print("Socket Info = ",s)

 

while 1 :

  msgStr = input("Type in the message to send : ")

  bArray = bytearray(msgStr.encode('ascii'))

  s.sendto(bArray, (dst, 0))

  if msgStr.upper() == "QUIT" :

     break

 

 

< Script on Reciever PC >

 

import socket

import binascii

 

proto = 253

 

### Open a raw socket.

print("Opening Socket..")

s = socket.socket(socket.AF_INET, socket.SOCK_RAW,proto)

 

# Based on my test on Windows, you have to specify the specific explicit IP address assigned to a NIC

# the local IP 127.0.0.1 didn't work in case of Raw Socket.

# Since Raw IP does not have port number field, you can use any port number

# In reciever script, you need to execute bind() whereas you may not need bind() in sender script

s.bind(('1.1.1.1',0))

 

print("Socket Info = ",s)

 

while 1 :

   recvBytes = s.recv(4096)  # This read all the data including IP header. Does not include Ethernet Frame.

   if len(recvBytes) > 0 :

       recvByteHex=binascii.b2a_hex(recvBytes)   # Convert recived data into Hex String

       print(recvByteHex)

       header = recvBytes[0:20]  # Take out IP Header. This assumes that IP header is 20 bytes

       payLoad = recvBytes[20:len(recvBytes)] # Take out payload part. This is still a bytearray

       payLoadStr = payLoad.decode('ascii') # Convert the payload from Bytearray format to a String format

       print(payLoadStr)

       if payLoadStr.upper().find("QUIT") >= 0 : # Exit the while loop if it recieves "QUIT"

           break

 

 

Result :----------------------------------------------------------------------------

 

< Result on Sender PC >

 

NOTE : The green part is what I typed in during the execution.

 

Opening Socket..

Socket Info =  <socket.socket fd=256, family=AddressFamily.AF_INET, type=SocketK

ind.SOCK_RAW, proto=253>

Type in the message to send : Hello World !

Type in the message to send : Hi

Type in the message to send : How are you ?

Type in the message to send : Quit

 

 

< Result on Reciever PC >

 

Opening Socket..

Socket Info =  <socket.socket fd=284, family=AddressFamily.AF_INET, type=SocketKind.SOCK_RAW, proto=253, laddr=('1.1.1.1', 0)>

b'4500002136c8000080fdfeb1010101640101010148656c6c6f20576f726c642021'

Hello World !

b'4500001636dd000080fdfea701010164010101014869'

Hi

b'450000213716000080fdfe630101016401010101486f772061726520796f75203f'

How are you ?

b'450000183760000080fdfe22010101640101010151756974'

Quit