Python |
||
Python - Decoding IPv6 Header/ICMPv6/TCP Header
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 > =============================================================
This example will show you the very simple and straightfoward way to decode IPv6 header. This example is designed for getting familiar with structure of IPv6 header and number/string manipulation in Python. I don't think this is very efficient code, but it would be very simple/easy to understand. For simplicity, I gave a precaptured IPv6 byte array to decode. But if you can combine the skills explained in Raw Packet : IPv4 page, you can modify the code so that the script can decode IPv6 header directly from a network card.
The purpose of this example is to decode Byte Array marked in Red in the wireshark log shown below. Compare the program output with Wireshark log.
No. Time Source Destination Protocol Length Info 2 16:42:34.164000 fe80::11 ff02::2 ICMPv6 62 Router Solicitation
Frame 2: 62 bytes on wire (496 bits), 62 bytes captured (496 bits) Encapsulation type: Ethernet (1) Arrival Time: Oct 21, 2015 12:42:34.164000000 Eastern Daylight Time [Time shift for this packet: 0.000000000 seconds] Epoch Time: 1445445754.164000000 seconds [Time delta from previous captured frame: 57.164000000 seconds] [Time delta from previous displayed frame: 57.164000000 seconds] [Time since reference or first frame: 57.164000000 seconds] Frame Number: 2 Frame Length: 62 bytes (496 bits) Capture Length: 62 bytes (496 bits) [Frame is marked: False] [Frame is ignored: False] [Protocols in frame: eth:ipv6:icmpv6] [Coloring Rule Name: ICMP] [Coloring Rule String: icmp || icmpv6] Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00) Destination: 00:00:00_00:00:00 (00:00:00:00:00:00) Address: 00:00:00_00:00:00 (00:00:00:00:00:00) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Source: 00:00:00_00:00:00 (00:00:00:00:00:00) Address: 00:00:00_00:00:00 (00:00:00:00:00:00) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) Type: IPv6 (0x86dd) Internet Protocol Version 6, Src: fe80::11 (fe80::11), Dst: ff02::2 (ff02::2) 0110 .... = Version: 6 [0110 .... = This field makes the filter "ip.version == 6" possible: 6] .... 0000 0000 .... .... .... .... .... = Traffic class: 0x00000000 .... 0000 00.. .... .... .... .... .... = Differentiated Services Field: Default (0x00000000) .... .... ..0. .... .... .... .... .... = ECN-Capable Transport (ECT): Not set .... .... ...0 .... .... .... .... .... = ECN-CE: Not set .... .... .... 0000 0000 0000 0000 0000 = Flowlabel: 0x00000000 Payload length: 8 Next header: ICMPv6 (58) Hop limit: 255 Source: fe80::11 (fe80::11) Destination: ff02::2 (ff02::2) [Source GeoIP: Unknown] [Destination GeoIP: Unknown] Internet Control Message Protocol v6 Type: Router Solicitation (133) Code: 0 Checksum: 0x7d26 [correct] Reserved: 00000000
0000 00 00 00 00 00 00 00 00 00 00 00 00 86 dd 60 00 ..............`. 0010 00 00 00 08 3a ff fe 80 00 00 00 00 00 00 00 00 ....:........... 0020 00 00 00 00 00 11 ff 02 00 00 00 00 00 00 00 00 ................ 0030 00 00 00 00 00 02 85 00 7d 26 00 00 00 00 ........}&....
If you understand only a few Python syntax, you would be able to read the code directly. Followings are some syntax you may refer to if you have difficulties understanding this code.
# Following is the source code for this example. Understanding this code is very simple.
import binascii
def decodeIPv6Header(pktBytes) :
headerLength = 40 headerBytes = pktBytes[0:headerLength] headerInt = int.from_bytes(headerBytes, 'big') headerBin = '{0:0{1}b}'.format(headerInt,headerLength*8) #print("Header in Binary = ",headerBin)
version = int(headerBin[0:4],2) print("Version : ",version)
trafficClass = int(headerBin[4:12],2) print("Traffic Class : ",headerBin[4:12],"(Bin)")
FlowLabel = int(headerBin[12:32],2) print("FlowLabel : ",headerBin[12:32],"(Bin)")
payloadLen = int(headerBin[32:32+16],2) print("Payload Length : ",payloadLen,"(Dec)")
nextHeader = int(headerBin[32+16:32+24],2) print("Next Header : ",nextHeader,"(Dec) :", NextHeaderKeyword(nextHeader))
hopLimit = int(headerBin[32+24:32+32],2) print("hopLimit : ",hopLimit,"(Dec)")
srcAddString = '{0:X}'.format(int(headerBin[2*32:2*32+16],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[2*32+16:2*32+32],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[3*32:3*32+16],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[3*32+16:3*32+32],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[4*32:4*32+16],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[4*32+16:4*32+32],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[5*32:5*32+16],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[5*32+16:5*32+32],2)) print("Source Address : ",srcAddString)
dstAddString = '{0:X}'.format(int(headerBin[6*32:6*32+16],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[6*32+16:6*32+32],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[7*32:7*32+16],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[7*32+16:7*32+32],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[8*32:8*32+16],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[8*32+16:8*32+32],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[9*32:9*32+16],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[9*32+16:9*32+32],2)) print("Destination Address : ",dstAddString)
return nextHeader
def NextHeaderKeyword(headerIndex): switcher = { 0: "HOPOPT", 1: "ICMP", 17: "UDP", 50: "ESP", 58: "ICMPv6", 142 : "ROHC", } return switcher.get(headerIndex, "nothing")
# Beginning of Main Routine ByteAry = b'\x60\x00\x00\x00\x00\x08\x3a\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11 \xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x85' HexStr=binascii.b2a_hex(ByteAry)
if((ByteAry[0] & 0xF0) == 0x60) : decodeIPv6Header(ByteAry) else : print("The packet given is not IPv6 header")
Result :----------------------------------------------------------------
Version : 6 Traffic Class : 00000000 (Bin) FlowLabel : 00000000000000000000 (Bin) Payload Length : 8 (Dec) Next Header : 58 (Dec) : ICMPv6 hopLimit : 255 (Dec) Source Address : FE80:0:0:0:0:0:0:11 Destination Address : FF02:0:0:0:0:0:0:2
Example 02 > =============================================================
import binascii import sys import ctypes import math
# Function to decode IPv6 Header ####################3################### def decodeIPv6Header(pktBytes, fOut) :
headerLength = 40 headerBytes = pktBytes[0:headerLength] headerInt = int.from_bytes(headerBytes, 'big') headerBin = '{0:0{1}b}'.format(headerInt,headerLength*8)
outStr = "IPv6 Header ====================================================" fOut.write(outStr + "\n") print(outStr)
version = int(headerBin[0:4],2) outStr = "Version : " + '{0:d}'.format(version) fOut.write(outStr + "\n") print(outStr)
trafficClass = int(headerBin[4:12],2) outStr = "Traffic Class : " + '{0:08b}'.format(trafficClass) + "(Bin)" fOut.write(outStr + "\n") print(outStr)
FlowLabel = int(headerBin[12:32],2) outStr = "FlowLabel : " + '{0:020b}'.format(FlowLabel) + "(Bin)" fOut.write(outStr + "\n") print(outStr)
payloadLen = int(headerBin[32:32+16],2) outStr = "payloadLen : " + '{0:d}'.format(payloadLen) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
nextHeader = int(headerBin[32+16:32+24],2) outStr = "Next Header : " + '{0:d}'.format(nextHeader) + "(Dec) : " + NextHeaderKeyword(nextHeader) fOut.write(outStr + "\n") print(outStr)
hopLimit = int(headerBin[32+24:32+32],2) outStr = "Hop Limit : " + '{0:d}'.format(hopLimit) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
srcAddString = '{0:X}'.format(int(headerBin[2*32:2*32+16],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[2*32+16:2*32+32],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[3*32:3*32+16],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[3*32+16:3*32+32],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[4*32:4*32+16],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[4*32+16:4*32+32],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[5*32:5*32+16],2)) srcAddString = srcAddString + ":" + '{0:X}'.format(int(headerBin[5*32+16:5*32+32],2)) outStr = "Source Address : " + srcAddString fOut.write(outStr + "\n") print(outStr)
dstAddString = '{0:X}'.format(int(headerBin[6*32:6*32+16],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[6*32+16:6*32+32],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[7*32:7*32+16],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[7*32+16:7*32+32],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[8*32:8*32+16],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[8*32+16:8*32+32],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[9*32:9*32+16],2)) dstAddString = dstAddString + ":" + '{0:X}'.format(int(headerBin[9*32+16:9*32+32],2)) outStr = "Destination Address : " + dstAddString fOut.write(outStr + "\n") print(outStr)
return payloadLen,nextHeader
# Function to return NextHeader (Protocol) String from Next Header Number ###### def NextHeaderKeyword(headerIndex): switcher = { 0: "HOPOPT", 1: "ICMP", 6: "TCP", 17: "UDP", 50: "ESP", 58: "ICMPv6", 142 : "ROHC", } return switcher.get(headerIndex, "nothing")
# Function to return ICMPv6 String from IcmpType Number ################### def getICMPv6TypeString(IcmpType): switcher = { 1: "Destination Unreachable", 2: "Packet Too Big", 3: "Time Exceeded", 4: "Parameter Problem", 100: "Private experimentation", 101 : "Private experimentation", 127 : "Reserved for expansion of ICMPv6 error messages", 128 : "Echo Request", 129 : "Echo Reply", 133 : "Router Solicitation (NDP)", 134 : "Router Advertisement (NDP)", 135 : "Neighbor Solicitation (NDP)", 136 : "Neighbor Advertisement (NDP)", 138 : "Redirect Message (NDP)", 139 : "ICMP Node Information Query", 140 : "ICMP Node Information Response", 141 : "Inverse Neighbor Discovery Solicitation Message", 142 : "Inverse Neighbor Discovery Advertisement Message", 144 : "Home Agent Address Discovery Request Message", 145 : "Home Agent Address Discovery Reply Message", 146 : "Mobile Prefix Solicitation", 147 : "Mobile Prefix Advertisement", 148 : "Certification Path Solicitation (SEND)", 149 : "Certification Path Advertisement (SEND)", 151 : "Multicast Router Advertisement (MRD)", 152 : "Multicast Router Solicitation (MRD)", 153 : "Multicast Router Termination (MRD)", 200 : "Private experimentation", 201 : "Private experimentation", 255 : "Reserved for expansion of ICMPv6 informational messages", } return switcher.get(IcmpType, "nothing")
# Function to decode Router Solicitation Packet ################### def decodeRouterSolicitation(pktBytes,fOut) : pktLength = len(pktBytes) rsBytes = pktBytes[0:pktLength] rsInt = int.from_bytes(rsBytes, 'big') rsBin = '{0:0{1}b}'.format(rsInt,pktLength*8)
outStr = "Router Solcitation =========================================" fOut.write(outStr + "\n") print(outStr)
rsType = int(rsBin[0:8],2) outStr = "Type : " + '{0:d}'.format(rsType) + "(Dec) : " + getICMPv6TypeString(rsType) fOut.write(outStr + "\n") print(outStr)
rsCode = int(rsBin[8:16],2) outStr = "Code : " + '{0:d}'.format(rsCode) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
rsCheckSum = int(rsBin[16:32],2) outStr = "Checksum : " + '{0:#x}'.format(rsCheckSum) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
rsReserved = int(rsBin[32:32+32],2) outStr = "Reserved : " + '{0:08x}'.format(rsReserved) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
return 1
# Function to decode Link Address Option in RA Packet ################### def decodeRaOptionLinkAddress(pktBytes,fOut) :
pktLength = len(pktBytes) raBytes = pktBytes[0:pktLength] raInt = int.from_bytes(raBytes, 'big') raBin = '{0:0{1}b}'.format(raInt,pktLength*8)
outStr = "Link Address ----------------------------------------" fOut.write(outStr + "\n") print(outStr)
optType = int(raBin[0:8],2) outStr = "Type : " + '{0:d}'.format(optType) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
linkAddressLength = int(raBin[8:16],2) outStr = "Length : " + '{0:d}'.format(linkAddressLength) + "(Dec) - " + '{0:d}'.format(linkAddressLength*8) + " Bytes" fOut.write(outStr + "\n") print(outStr)
linkAddString = '{0:02X}'.format(int(raBin[16:24],2)) linkAddString = linkAddString + ":" + '{0:02X}'.format(int(raBin[24:32],2)) linkAddString = linkAddString + ":" + '{0:02X}'.format(int(raBin[32:32+8],2)) linkAddString = linkAddString + ":" + '{0:02X}'.format(int(raBin[32+8:32+16],2)) linkAddString = linkAddString + ":" + '{0:02X}'.format(int(raBin[32+16:32+24],2)) linkAddString = linkAddString + ":" + '{0:02X}'.format(int(raBin[32+24:32+32],2)) outStr = "Link Address : " + linkAddString fOut.write(outStr + "\n") print(outStr)
unusedBytes = pktBytes[linkAddressLength*8 : pktLength]; return unusedBytes
# Function to decode MTU Option in RA Packet ################### def decodeRaOptionMTU(pktBytes,fOut) :
pktLength = len(pktBytes) raBytes = pktBytes[0:pktLength] raInt = int.from_bytes(raBytes, 'big') raBin = '{0:0{1}b}'.format(raInt,pktLength*8)
outStr = "MTU ------------------------------------------------" fOut.write(outStr + "\n") print(outStr)
optType = int(raBin[0:8],2) outStr = "Type : MTU : " + '{0:d}'.format(optType) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
mtuByteLength = int(raBin[8:16],2) outStr = "Length : " + '{0:d}'.format(mtuByteLength) + "(" + '{0:d}'.format(mtuByteLength*8)+ " Bytes)" fOut.write(outStr + "\n") print(outStr)
mtuByteReserved = int(raBin[16:32],2) outStr = "Reserved : " + '{0:04X}'.format(mtuByteReserved) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
mtuSize = int(raBin[32*1+0:32*1+32],2) outStr = "MTU : " + '{0:d}'.format(mtuSize) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
unusedBytes = pktBytes[mtuByteLength*8 : pktLength]; return unusedBytes
# Function to decode Prefix Information Option in RA Packet ################### def decodeRaOptionPrefixInformation(pktBytes,fOut) :
pktLength = len(pktBytes) raBytes = pktBytes[0:pktLength] raInt = int.from_bytes(raBytes, 'big') raBin = '{0:0{1}b}'.format(raInt,pktLength*8)
outStr = "Prefix Information ------------------------------------------------" fOut.write(outStr + "\n") print(outStr)
optType = int(raBin[0:8],2) outStr = "Type : Prefix Information : " + '{0:d}'.format(optType) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
prefixLength = int(raBin[8:16],2) outStr = "Length : " + '{0:d}'.format(prefixLength) + "(" + '{0:d}'.format(prefixLength*8)+ " Bytes)" fOut.write(outStr + "\n") print(outStr)
prefixBitLength = int(raBin[16:24],2) outStr = "Prefix Length : " + '{0:d}'.format(prefixBitLength) + "bits" fOut.write(outStr + "\n") print(outStr)
flag = int(raBin[24:32],2) outStr = "Flags : " + '{0:08b}'.format(flag) + "(BIN)" fOut.write(outStr + "\n") print(outStr)
validLifeTime = int(raBin[32*1+0:32*1+32],2) outStr = "Valid Lifetime : " + '{0:d}'.format(validLifeTime) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
preferredLifeTime = int(raBin[32*2+0:32*2+32],2) outStr = "Preferred Lifetime : " + '{0:d}'.format(preferredLifeTime) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
reserved = int(raBin[32*3+0:32*3+32],2) outStr = "Reserved : " + '{0:08X}'.format(reserved) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
prefixAddString = '{0:X}'.format(int(raBin[32*4+0:32*4+16],2)) prefixAddString = prefixAddString + ":" + '{0:X}'.format(int(raBin[32*4+16:32*4+32],2)) prefixAddString = prefixAddString + ":" + '{0:X}'.format(int(raBin[32*5+0:32*5+16],2)) prefixAddString = prefixAddString + ":" + '{0:X}'.format(int(raBin[32*5+16:32*5+32],2)) prefixAddString = prefixAddString + ":" + '{0:X}'.format(int(raBin[32*6+0:32*6+16],2)) prefixAddString = prefixAddString + ":" + '{0:X}'.format(int(raBin[32*6+16:32*6+32],2)) prefixAddString = prefixAddString + ":" + '{0:X}'.format(int(raBin[32*7+0:32*7+16],2)) prefixAddString = prefixAddString + ":" + '{0:X}'.format(int(raBin[32*7+16:32*7+32],2)) outStr = "Prefix Address : " + prefixAddString fOut.write(outStr + "\n") print(outStr)
unusedBytes = pktBytes[prefixLength*8 : pktLength]; return unusedBytes
# Function to decode Router Advertisement Option Fields ########################## def decodeRaOption(pktBytes,fOut) :
pktLength = len(pktBytes)
if pktLength <= 1 : return 1
raBytes = pktBytes[0:pktLength] raInt = int.from_bytes(raBytes, 'big') raBin = '{0:0{1}b}'.format(raInt,pktLength*8)
optType = int(raBin[0:8],2) unusedBytes = pktBytes
if optType == 1 : unusedBytes = decodeRaOptionLinkAddress(unusedBytes,fOut)
if optType == 3 : unusedBytes = decodeRaOptionPrefixInformation(unusedBytes,fOut)
if optType == 5 : unusedBytes = decodeRaOptionMTU(unusedBytes,fOut)
decodeRaOption(unusedBytes,fOut)
return 1
# Function to decode Router Advertisement ###################################### def decodeRouterAdvertisement(pktBytes,fOut) : pktLength = len(pktBytes) rsBytes = pktBytes[0:pktLength] rsInt = int.from_bytes(rsBytes, 'big') raBin = '{0:0{1}b}'.format(rsInt,pktLength*8)
outStr = "Router Advertisement =========================================" fOut.write(outStr + "\n") print(outStr)
rsType = int(raBin[0:8],2) outStr = "Type : " + '{0:d}'.format(rsType) + "(Dec) : " + getICMPv6TypeString(rsType) fOut.write(outStr + "\n") print(outStr)
rsCode = int(raBin[8:16],2) outStr = "Code : " + '{0:d}'.format(rsCode) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
rsCheckSum = int(raBin[16:32],2) outStr = "Checksum : " + '{0:#x}'.format(rsCheckSum) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
currentHoplimit = int(raBin[32:32+8],2) outStr = "Current Hop Limit : " + '{0:d}'.format(currentHoplimit) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
autoConfigFlag = int(raBin[32+8:32+16],2) outStr = "AutoConfig Flag : " + '{0:08b}'.format(autoConfigFlag) + "(Bin)" fOut.write(outStr + "\n") print(outStr)
routerLifeTime = int(raBin[32+16:32+32],2) outStr = "Router Life Time : " + '{0:d}'.format(routerLifeTime) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
reachableTime = int(raBin[32*2:32*2+32],2) outStr = "Reachable Time : " + '{0:d}'.format(reachableTime) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
retransmissionTimer = int(raBin[32*3:32*3+32],2) outStr = "Retransmission Timer : " + '{0:d}'.format(retransmissionTimer) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
unusedBytes = pktBytes[4*4:pktLength] decodeRaOption(unusedBytes,fOut)
return 1
# Function to decode TCP Packet ###################################### def decodeTcpHeader(pktBytes,fOut) : pktLength = len(pktBytes) tcpBytes = pktBytes[0:pktLength] tcpInt = int.from_bytes(tcpBytes, 'big') tcpBin = '{0:0{1}b}'.format(tcpInt,pktLength*8)
outStr = "TCP Header =========================================" fOut.write(outStr + "\n") print(outStr)
sourcePort = int(tcpBin[0:16],2) outStr = "Source Port : " + '{0:d}'.format(sourcePort) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
destinationPort = int(tcpBin[16:32],2) outStr = "Destination Port : " + '{0:d}'.format(destinationPort) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
sequenceNumber = int(tcpBin[32*1+0:32*1+32],2) outStr = "Sequence Number : " + '{0:08X}'.format(sequenceNumber) + "(HEX) - " + '{0:d}'.format(sequenceNumber) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
acknowledgementNumber = int(tcpBin[32*2+0:32*2+32],2) outStr = "Acknowledgement Number : " + '{0:08X}'.format(acknowledgementNumber) + "(HEX) - " + '{0:d}'.format(acknowledgementNumber) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
dataOffset = int(tcpBin[32*3+0:32*3+4],2) outStr = "Data Offset (Header Length) : " + '{0:d}'.format(dataOffset * 4) + "(Bytes)" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4:32*3+16],2) outStr = "Flags : "+'{0:03X}'.format(flag)+"(HEX) : " +'{0:012b}'.format(flag)+ "(BIN)-----" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4:32*3+4+3],2) outStr =" " + '{0:03b}'.format(flag)+". .... ...." + " = Reserved" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+3:32*3+4+4],2) outStr =" " + "..."+'{0:01b}'.format(flag)+" .... ...." + " = Nonce" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+4:32*3+4+5],2) outStr =" " + ".... "+'{0:01b}'.format(flag)+"... ...." + " = Congestion Window Reduced(CWR)" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+5:32*3+4+6],2) outStr =" " + ".... ."+'{0:01b}'.format(flag)+".. ...." + " = ECN-Echo" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+6:32*3+4+7],2) outStr =" " + ".... .."+'{0:01b}'.format(flag)+". ...." + " = Urgent" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+7:32*3+4+8],2) outStr =" " + ".... ..."+'{0:01b}'.format(flag)+" ...." + " = Acknowlegment" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+8:32*3+4+9],2) outStr =" " + ".... .... "+'{0:01b}'.format(flag)+"..." + " = Push" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+9:32*3+4+10],2) outStr =" " + ".... .... ."+'{0:01b}'.format(flag)+".." + " = Reset" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+10:32*3+4+11],2) outStr = " " + ".... .... .."+'{0:01b}'.format(flag)+"." + " = Syn" fOut.write(outStr + "\n") print(outStr)
flag = int(tcpBin[32*3+4+11:32*3+4+12],2) outStr = " " + ".... .... ..."+'{0:01b}'.format(flag)+ "" + " = Fin" fOut.write(outStr + "\n") print(outStr)
windowSize = int(tcpBin[32*3+16:32*3+32],2) outStr = "Window Size Value : " + '{0:d}'.format(windowSize) + "(DEC)" fOut.write(outStr + "\n") print(outStr)
checkSum = int(tcpBin[32*4+0:32*4+16],2) outStr = "Checksum : " + '{0:04X}'.format(checkSum) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
urgentPointer = int(tcpBin[32*4+16:32*4+32],2) outStr = "Urgent Pointer : " + '{0:04X}'.format(urgentPointer) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
option = int(tcpBin[32*5+0:(dataOffset*4)*8],2) outStr = "TCP Option : " + '{0:0{1}X}'.format(option,2*(dataOffset*4-20)) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
unusedBytes = pktBytes[dataOffset*4:pktLength]
return unusedBytes
# Function to decode UDP Packet ###################################### def decodeUdpHeader(pktBytes,fOut) : pktLength = len(pktBytes) udpBytes = pktBytes[0:pktLength] udpInt = int.from_bytes(udpBytes, 'big') udpBin = '{0:0{1}b}'.format(udpInt,pktLength*8)
outStr = "UDP Header =========================================" fOut.write(outStr + "\n") print(outStr)
sourcePort = int(udpBin[0:16],2) outStr = "Source Port : " + '{0:d}'.format(sourcePort) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
destinationPort = int(udpBin[16:32],2) outStr = "Destination Port : " + '{0:d}'.format(destinationPort) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
udpLength = int(udpBin[32*1+0:32*1+16],2) outStr = "Length : " + '{0:d}'.format(udpLength) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
checkSum = int(udpBin[32*1+16:32*1+32],2) outStr = "Checksum : " + '{0:04X}'.format(checkSum) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
unusedBytes = pktBytes[8:pktLength]
return unusedBytes
# Function to decode ICMPv6\Ping Request ###################################### def decodePing6Request(pktBytes,fOut) : pktLength = len(pktBytes) icmpBytes = pktBytes[0:pktLength] icmpInt = int.from_bytes(icmpBytes, 'big') icmpBin = '{0:0{1}b}'.format(icmpInt,pktLength*8)
outStr = "Ping Request =========================================" fOut.write(outStr + "\n") print(outStr)
icmpType = int(icmpBin[0:8],2) outStr = "Type : " + '{0:d}'.format(icmpType) + "(Dec) : " + getICMPv6TypeString(icmpType) fOut.write(outStr + "\n") print(outStr)
icmpCode = int(icmpBin[8:16],2) outStr = "Code : " + '{0:d}'.format(icmpCode) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
icmpCheckSum = int(icmpBin[16:32],2) outStr = "Checksum : " + '{0:04x}'.format(icmpCheckSum) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
icmpIdentifier = int(icmpBin[32:32+16],2) outStr = "Identifier : " + '{0:04x}'.format(icmpIdentifier) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
icmpSequence = int(icmpBin[32+16:32+32],2) outStr = "Sequence : " + '{0:d}'.format(icmpSequence) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
return 1
# Function to decode ICMPv6\Ping Reply ###################################### def decodePing6Reply(pktBytes,fOut) : pktLength = len(pktBytes) icmpBytes = pktBytes[0:pktLength] icmpInt = int.from_bytes(icmpBytes, 'big') icmpBin = '{0:0{1}b}'.format(icmpInt,pktLength*8)
outStr = "Ping Reply =========================================" fOut.write(outStr + "\n") print(outStr)
icmpType = int(icmpBin[0:8],2) outStr = "Type : " + '{0:d}'.format(icmpType) + "(Dec) : " + getICMPv6TypeString(icmpType) fOut.write(outStr + "\n") print(outStr)
icmpCode = int(icmpBin[8:16],2) outStr = "Code : " + '{0:d}'.format(icmpCode) + "(Dec)" fOut.write(outStr + "\n") print(outStr)
icmpCheckSum = int(icmpBin[16:32],2) outStr = "Checksum : " + '{0:04x}'.format(icmpCheckSum) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
icmpIdentifier = int(icmpBin[32:32+16],2) outStr = "Identifier : " + '{0:04x}'.format(icmpIdentifier) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
icmpSequence = int(icmpBin[32+16:32+32],2) outStr = "Sequence : " + '{0:d}'.format(icmpSequence) + "(HEX)" fOut.write(outStr + "\n") print(outStr)
return 1
# Start of Main Routine ==================================================== fHandleOut = open("IPv6_Out.txt","w")
#IPv6/ICMPv6/RS testStr1 = "60 00 00 00 00 08 3A FF FE 80 00 00 00 00 00 00 00 00 00 00 00 00 10 00 FF \ 02 00 00 00 00 00 00 00 00 00 00 00 00 00 02 85 00 6D 80 00 00 00 38 3A FF \ FE 80 00 00 00 00 00 00 02 00 00 FF FE 00 00 01 FE 80 00 00 00 00 00 00 00 \ 00 00 00 00 00 10 00 86 00 42 1F FF 00 07 08 00 00 00 00 00 00 00 00 01 01 \ 00 00 00 00 00 01 03 04 40 C0 00 27 8D 00 00 09 3A 80 00 00 00 00 20 01 04 \ 68 01 81 F1 00 00 00 00 00 00 00 00 00 6D 37 00 00 00 00"
#IPv6/ICMPv6/RA with 2 Options testStr2 = "6D 80 00 00 00 38 3A FF FE 80 00 00 00 00 00 00 02 00 00 FF FE 00 00 01 FE \ 80 00 00 00 00 00 00 00 00 00 00 00 00 10 00 86 00 42 1F FF 00 07 08 00 00 \ 00 00 00 00 00 00 01 01 00 00 00 00 00 01 03 04 40 C0 00 27 8D 00 00 09 3A \ 80 00 00 00 00 20 01 04 68 01 81 F1 00 00 00 00 00 00 00 00 00"
#IPv6/ICMPv6/RA with 3 Options testStr3 = "60 00 00 00 00 40 3A FF FE 80 00 00 00 00 00 00 D1 DE AE 75 2E 92 1C 33 FF \ 02 00 00 00 00 00 00 00 00 00 00 00 00 00 01 86 00 73 99 00 00 00 00 00 00 \ 00 00 00 00 00 00 01 01 90 E2 BA 2D C3 FE 05 01 00 00 00 00 05 DC 03 04 40 \ C0 00 27 8D 00 00 09 3A 80 00 00 00 00 20 01 04 68 01 81 F1 00 00 00 00 00 \ 00 00 00 00"
#IPv6/TCP testStr4 = "60 00 00 00 01 65 06 40 20 01 00 00 00 00 00 01 4C 16 9C 0F 49 86 9E 6D 20 \ 01 00 00 00 00 00 01 00 00 00 00 00 00 00 02 AF 4C 13 C4 63 CB D0 BC 2C 72 \ 30 79 80 18 00 D3 63 BF 00 00 01 01 08 0A 00 00 E9 15 00 01 CC 55"
#IPv6/ICMPv6/Ping Request testStr5 = "60 00 00 00 00 6C 3A 7F 20 01 04 68 01 81 F1 00 BC AA B2 4B C7 4C D7 63 20 \ 02 04 68 01 81 F1 00 00 00 00 00 00 00 00 01 80 00 89 37 00 01 AD 90 61 62 \ 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 \ 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 65 66 \ 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 65 66 67 68 \ 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 65 66 67 68"
#IPv6/ICMPv6/Ping Reply testStr6 = "60 00 00 00 00 6C 3A 80 20 02 04 68 01 81 F1 00 00 00 00 00 00 00 00 01 20 \ 01 04 68 01 81 F1 00 BC AA B2 4B C7 4C D7 63 81 00 88 37 00 01 AD 90 61 62 \ 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 \ 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 65 66 \ 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 65 66 67 68 \ 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 65 66 67 68"
#IPv6/UDP testStr7 = "60 00 00 00 02 A5 11 40 20 01 00 00 00 00 00 02 00 00 00 00 00 00 00 01 20 \ 01 00 00 00 00 00 02 00 00 00 00 00 00 00 02 13 C4 13 C4 02 A5 46 E5"
pktStr = testStr4 pktStr = pktStr.replace(" ","") pktStr = pktStr.replace("\n","") pktStrBytes = bytearray(binascii.a2b_hex(pktStr))
if((pktStrBytes[0] & 0xF0) == 0x60) : # Decode IPv6 Header payloadLength,nextHeader = decodeIPv6Header(pktStrBytes,fHandleOut)
if nextHeader == 6 : # Decode TCP Header if it is in the packet tcpByteAry = pktStrBytes[40:40+payloadLength] unusedBytes = decodeTcpHeader(tcpByteAry,fHandleOut) elif nextHeader == 17 : # Decode UDPHeader if it is in the packet udpByteAry = pktStrBytes[40:40+payloadLength] unusedBytes = decodeUdpHeader(udpByteAry,fHandleOut) elif nextHeader == 58 : # Decode ICMPv6 Header if it is in the packet icmpByteAry = pktStrBytes[40:40+payloadLength] if icmpByteAry[0] == 133 : # Decode Router Solicitation Packet if it is in the ICMPv6 Packet decodeRouterSolicitation(icmpByteAry,fHandleOut) elif icmpByteAry[0] == 134 : # Decode Router Advertisement Packet if it is in the ICMPv6 Packet decodeRouterAdvertisement(icmpByteAry,fHandleOut) elif icmpByteAry[0] == 128 : # Decode Ping Request Packet if it is in the ICMPv6 Packet decodePing6Request(icmpByteAry,fHandleOut) elif icmpByteAry[0] == 129 : # Decode Ping Reply Packet if it is in the ICMPv6 Packet decodePing6Reply(icmpByteAry,fHandleOut) else : print("No further decoding for Next Header")
fHandleOut.close()
Result > ---------------------------------------------------------
IPv6 Header ==================================================== Version : 6 Traffic Class : 00000000(Bin) FlowLabel : 00000000000000000000(Bin) payloadLen : 357(Dec) Next Header : 6(Dec) : TCP Hop Limit : 64(Dec) Source Address : 2001:0:0:1:4C16:9C0F:4986:9E6D Destination Address : 2001:0:0:1:0:0:0:2 TCP Header ========================================= Source Port : 44876(Dec) Destination Port : 5060(Dec) Sequence Number : 63CBD0BC(HEX) - 1674301628(Dec) Acknowledgement Number : 2C723079(HEX) - 745681017(Dec) Data Offset (Header Length) : 32(Bytes) Flags : 018(HEX) : 000000011000(BIN)----- 000. .... .... = Reserved ...0 .... .... = Nonce .... 0... .... = Congestion Window Reduced(CWR) .... .0.. .... = ECN-Echo .... ..0. .... = Urgent .... ...1 .... = Acknowlegment .... .... 1... = Push .... .... .0.. = Reset .... .... ..0. = Syn .... .... ...0 = Fin Window Size Value : 211(DEC) Checksum : 63BF(HEX) Urgent Pointer : 0000(HEX) TCP Option : 0101080A0000E9150001CC55(HEX)
|
||