Вопросы кодирования Python о побитовом сдвиге и логических операциях в анализаторе пакетов

import socket
import sys
import struct
import re


#get data
def receiveData(s):
 
 data=''
 try:
  data=s.recvfrom(65565)
 except timeout:
  data = ''
 except:
  print "An error occurred"
  sys.exc_info()
 return data[0]


#get Type Of Service - 8bits
def getTOS(data):

 precedence = {0:'Routine',1:'Priority', 2:'Immediate', 3:'Flash', 4:'Flash Override', 5:'CRITIC/ECP', 6:'Internetwork control', 7:'Network Control'}
 delay = {0:'Normal Delay', 1:'Low Delay'}
 throughput = {0:'Normal Throughput', 1:'High Throughput'}
 reliability = {0:'Normal Reliability', 1:'High Reliability'}
 monetary = {0:'Normal Cost', 1:'Minimize monetary cost'}
  
 D = data & 0x10
 D >>= 4
 T = data & 0x8
 T >>= 3
 R = data & 0x4
 R >>= 2
 M = data & 0x2
 M >>=1

 tabs = "\n\t\t\t"
 TOS = precedence [data >> 5]+ tabs + delay[D] + tabs + throughput[T] + tabs + reliability[R] + tabs + monetary[M]
 return TOS
 
def getFlags(data):
 
 flagR = {0:'Cleared to 0'}
 flagDF = {0:'Fragment if necessary', 1:'Do not Fragment'}
 flagMF = {0:'This is the last Fragment', 1:'More fragments to follow this fragment'}

 R = data & 0x8000
 R >>= 15
 DF = data & 0x4000
 DF >>= 14
 MF = data & 0x2000
 MF >>= 13

 tabs = '\n\t\t\t'
 flags = flagR[R] + tabs + flagDF[DF] + tabs + flagMF[MF]
 return flags

def getProtocol(protocolNr):
 
 protocolFile = open('/root/Desktop/protocol.txt', 'r')
 protocolData = protocolFile.read()
 protocol = re.findall(r'\n' + str(protocolNr) + ' (?:.)+\n', protocolData)
 if protocol:
  protocol = protocol[0]
  protocol = protocol.replace('\n', '')
  protocol = protocol.replace(str(protocolNr), '')
  protocol = protocol.lstrip()
  return protocol
 else:
  return "No such protocol found" 
 

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

data = receiveData(s)
unpackedData = struct.unpack('!BBHHHBBH4s4s', data[:20])

version_IHL = unpackedData[0]
version = version_IHL >> 4
IHL = version_IHL & 0xF
TOS = unpackedData[1]
totalLength = unpackedData[2]
ID = unpackedData[3]
flags = unpackedData[4]
fragmentOffset = unpackedData[4] & 0x1FFF
TTL = unpackedData[5] 
protocolNr = unpackedData[6]
checksum = unpackedData[7]
sourceAddress = socket.inet_ntoa(unpackedData[8])
destinationAddress = socket.inet_ntoa(unpackedData[9])

print " An IP packed with the size %i was captured :" %totalLength
print " Raw Data :" +data
print "\nParsed Data"
print " Version:\t\t" +str(version)
print " Header Length:\t\t" + str(IHL*4) + "bytes"
print " Type of Service:\t" + getTOS(TOS)
print " ID:\t\t\t" + str(hex(ID)) + " (" + str(ID) + ")"
print " Flags:\t\t\t" + getFlags(flags)
print " Fragment Offset:" + str(fragmentOffset)
print " TTL:\t\t\t" + str(TTL)
print " Protocol:\t\t\t" +getProtocol(protocolNr)
print " Checksum:\t\t\t" +str(checksum)
print " Source:\t\t\t" +sourceAddress
print " Destination:\t\t\t" +destinationAddress
print " Payload:\n" + data[20:]

Ниже я извлек некоторые разделы кода сверху и любезно потратил некоторое время, чтобы ответить на следующие вопросы.

(1)

D = data & 0x10
D >>= 4
T = data & 0x8
T >>= 3
R = data & 0x4
R >>= 2
M = data & 0x2
M >>=1

tabs = "\n\t\t\t"
TOS = precedence [data >> 5]+ ......

В приведенном выше разделе не могли бы вы объяснить, на каком основании D=data & 0x10 используется и смещается вправо 4 раза, а также почему приоритет смещается 5 раз вправо. Мой вопрос больше похож на то, почему 0x10 специально использовался для AND с данными и затем сдвигался вправо 4 раза, чтобы получить бит задержки. Я ищу разъяснения по всем другим битам, таким как T, R, M, в приведенном выше разделе, а также по битам флагов в разделе ниже.

(2)

R = data & 0x8000
R >>= 15
DF = data & 0x4000
DF >>= 14
MF = data & 0x2000
MF >>= 13

В вышеприведенном сегменте, пожалуйста, объясните, на каком основании используется R = data & 0x8000 и сдвиньте его 15 раз вправо

(3)

fragmentOffset = unpackedData[4] & 0x1FFF

В приведенной выше строке кода, почему именно 0x1FFF был использован для AND с unpackedData[4]

Кредиты на исходный код достаются Ана Балика https://www.youtube.com/watch?v=ghokDuCDcMY

1 ответ

import socket
import sys
import struct
import re

def receiveData(s):
    data =''
    try:
        data , addr =s.recvfrom(655365)
    except timout:
        data =''
    except:
        print "An error hapend"
        sys.exc_info()
    return data

#get Type Of Service - 8bits
def getTOS(data):

 precedence = {0:'Routine',1:'Priority', 2:'Immediate', 3:'Flash', 4:'Flash Override', 5:'CRITIC/ECP', 6:'Internetwork control', 7:'Network Control'}
 delay = {0:'Normal Delay', 1:'Low Delay'}
 throughput = {0:'Normal Throughput', 1:'High Throughput'}
 reliability = {0:'Normal Reliability', 1:'High Reliability'}
 monetary = {0:'Normal Cost', 1:'Minimize monetary cost'}
  
 D = data & 0x10
 D >>= 4
 T = data & 0x8
 T >>= 3
 R = data & 0x4
 R >>= 2
 M = data & 0x2
 M >>=1

 tabs = "\n\t\t\t"
 TOS = precedence [data >> 5]+ tabs + delay[D] + tabs + throughput[T] + tabs + reliability[R] + tabs + monetary[M]
 return TOS
 
def getFlags(data):
 
 flagR = {0:'Cleared to 0'}
 flagDF = {0:'Fragment if necessary', 1:'Do not Fragment'}
 flagMF = {0:'This is the last Fragment', 1:'More fragments to follow this fragment'}

 R = data & 0x8000
 R >>= 15
 DF = data & 0x4000
 DF >>= 14
 MF = data & 0x2000
 MF >>= 13

 tabs = '\n\t\t\t'
 flags = flagR[R] + tabs + flagDF[DF] + tabs + flagMF[MF]
 return flags

def getProtocol(protocolNr):
 
 protocolFile = open('protocol.txt', 'r')
 protocolData = protocolFile.read()
 protocol = re.findall(r'\n' + str(protocolNr) + ' (?:.)+\n', protocolData)
 if protocol:
  protocol = protocol[0]
  protocol = protocol.replace('\n', '')
  protocol = protocol.replace(str(protocolNr), '')
  protocol = protocol.lstrip()
  return protocol
 else:
  return "No such protocol found" 

def showdata(unpackedData):
    version_IHL = unpackedData[0]
    version = version_IHL >> 4
    IHL = version_IHL & 0xF
    TOS = unpackedData[1]
    totalLength = unpackedData[2]
    ID = unpackedData[3]
    flags = unpackedData[4]
    fragmentOffset = unpackedData[4] & 0x1FFF
    TTL = unpackedData[5] 
    protocolNr = unpackedData[6]
    checksum = unpackedData[7]
    sourceAddress = socket.inet_ntoa(unpackedData[8])
    destinationAddress = socket.inet_ntoa(unpackedData[9])

    print " An IP packed with the size %i was captured :" %totalLength
    print " Raw Data :" +data
    print "\nParsed Data"
    print " Version:\t\t" +str(version)
    print " Header Length:\t\t" + str(IHL*4) + "bytes"
    print " Type of Service:\t" + getTOS(TOS)
    print " ID:\t\t\t" + str(hex(ID)) + " (" + str(ID) + ")"
    print " Flags:\t\t\t" + getFlags(flags)
    print " Fragment Offset:" + str(fragmentOffset)
    print " TTL:\t\t\t" + str(TTL)
    print " Protocol:\t\t\t" +getProtocol(protocolNr)
    print " Checksum:\t\t\t" +str(checksum)
    print " Source:\t\t\t" +sourceAddress
    print " Destination:\t\t\t" +destinationAddress
    print " Payload:\n" + data[20:]




        
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())

# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))

# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

for i in range(100):
    # receive a package
    #print s.recvfrom(65565)
    data=receiveData(s)
    datastr = str(data)
    if len(datastr) >19 :
        unpackedData = struct.unpack('!BBHHHBBH4s4s',datastr[:20])
        #print unpackedData
        showdata(unpackedData)
    else:
        print data

# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

import socket
import sys
import struct
import re

def receiveData(s):
    data =''
    try:
        data , addr =s.recvfrom(655365)
    except timout:
        data =''
    except:
        print "An error hapend"
        sys.exc_info()
    return data

#get Type Of Service - 8bits
def getTOS(data):

 precedence = {0:'Routine',1:'Priority', 2:'Immediate', 3:'Flash', 4:'Flash Override', 5:'CRITIC/ECP', 6:'Internetwork control', 7:'Network Control'}
 delay = {0:'Normal Delay', 1:'Low Delay'}
 throughput = {0:'Normal Throughput', 1:'High Throughput'}
 reliability = {0:'Normal Reliability', 1:'High Reliability'}
 monetary = {0:'Normal Cost', 1:'Minimize monetary cost'}
  
 D = data & 0x10
 D >>= 4
 T = data & 0x8
 T >>= 3
 R = data & 0x4
 R >>= 2
 M = data & 0x2
 M >>=1

 tabs = "\n\t\t\t"
 TOS = precedence [data >> 5]+ tabs + delay[D] + tabs + throughput[T] + tabs + reliability[R] + tabs + monetary[M]
 return TOS
 
def getFlags(data):
 
 flagR = {0:'Cleared to 0'}
 flagDF = {0:'Fragment if necessary', 1:'Do not Fragment'}
 flagMF = {0:'This is the last Fragment', 1:'More fragments to follow this fragment'}

 R = data & 0x8000
 R >>= 15
 DF = data & 0x4000
 DF >>= 14
 MF = data & 0x2000
 MF >>= 13

 tabs = '\n\t\t\t'
 flags = flagR[R] + tabs + flagDF[DF] + tabs + flagMF[MF]
 return flags

def getProtocol(protocolNr):
 
 protocolFile = open('protocol.txt', 'r')
 protocolData = protocolFile.read()
 protocol = re.findall(r'\n' + str(protocolNr) + ' (?:.)+\n', protocolData)
 if protocol:
  protocol = protocol[0]
  protocol = protocol.replace('\n', '')
  protocol = protocol.replace(str(protocolNr), '')
  protocol = protocol.lstrip()
  return protocol
 else:
  return "No such protocol found" 

def showdata(unpackedData):
    version_IHL = unpackedData[0]
    version = version_IHL >> 4
    IHL = version_IHL & 0xF
    TOS = unpackedData[1]
    totalLength = unpackedData[2]
    ID = unpackedData[3]
    flags = unpackedData[4]
    fragmentOffset = unpackedData[4] & 0x1FFF
    TTL = unpackedData[5] 
    protocolNr = unpackedData[6]
    checksum = unpackedData[7]
    sourceAddress = socket.inet_ntoa(unpackedData[8])
    destinationAddress = socket.inet_ntoa(unpackedData[9])

    print " An IP packed with the size %i was captured :" %totalLength
    print " Raw Data :" +data
    print "\nParsed Data"
    print " Version:\t\t" +str(version)
    print " Header Length:\t\t" + str(IHL*4) + "bytes"
    print " Type of Service:\t" + getTOS(TOS)
    print " ID:\t\t\t" + str(hex(ID)) + " (" + str(ID) + ")"
    print " Flags:\t\t\t" + getFlags(flags)
    print " Fragment Offset:" + str(fragmentOffset)
    print " TTL:\t\t\t" + str(TTL)
    print " Protocol:\t\t\t" +getProtocol(protocolNr)
    print " Checksum:\t\t\t" +str(checksum)
    print " Source:\t\t\t" +sourceAddress
    print " Destination:\t\t\t" +destinationAddress
    print " Payload:\n" + data[20:]




        
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())

# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))

# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

for i in range(100):
    # receive a package
    #print s.recvfrom(65565)
    data=receiveData(s)
    datastr = str(data)
    if len(datastr) >19 :
        unpackedData = struct.unpack('!BBHHHBBH4s4s',datastr[:20])
        #print unpackedData
        showdata(unpackedData)
    else:
        print data

# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

Другие вопросы по тегам