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
|
||