struct.unpack改变程序并扭曲输出?

时间:2016-01-14 11:54:59

标签: python struct scapy

我已经为scapy写了一个函数,它有助于解析数据包。该函数接收原始数据包并返回解析所包含数据所需的类。该函数应该工作,但它以某种方式返回错误的类。现在我测试了一些东西我刚添加了一行

struct.unpack("!B", packet)

在函数的开头,实际上什么也没做,但是 - 这对我来说很奇怪 - 不知何故,这使得函数做了它应该做的事情。怎么会这样?我已经多次测试了它。如果没有这一行在函数的开头它就不能正常工作,但是,这条线的行为应该像它应该的那样,虽然输出看起来有点扭曲,我也不知道为什么。

用线输出。它被扭曲了,有些线条在错误的位置,有些甚至是重复的。

###[ Ethernet ]###
  src       = 00:30:de:09:c7:76
  dst       = ff:ff:ff:ff:ff:ff
  type      = 0x800
  src       = 00:30:de:09:c7:83
###[ IP ]###
  type      = 0x800     version   = 4L

     ihl       = 5L
###[ IP ]###
     tos       = 0x0
     version   = 4L
     len       = 52
     ihl       = 5L
     id        = 312
     tos       = 0x0     flags     = DF

     frag      = 0L
     len       = 52
     ttl       = 64
     id        = 91
     proto     = udp
     flags     = DF
     frag      = 0L
     ttl       = 64
     proto     = udp
     chksum    = 0xb52d
     chksum    = 0xb60b
     src       = 192.168.1.4
     src       = 192.168.1.3
     dst       = 192.168.1.255     dst       = 192.168.1.255

     \options   \
     \options   \
###[ UDP ]###
###[ UDP ]###        sport     = 47808

        dport     = 47808
        sport     = 47808
        len       = 32
        dport     = 47808
        chksum    = 0x6cec
        len       = 32
###[ BVLC ]###
        chksum    = 0x79eb
           type      = 0x81
###[ BVLC ]###
           function  = ORIGINAL_BROADCAST_NPDU
           type      = 0x81
           length    = 24
           function  = ORIGINAL_BROADCAST_NPDU###[ NPDU ]###

              version   = 1
           length    = 24
              control   = 32L
###[ NPDU ]###
              dnet      = 65535
              version   = 1
              dlen      = 0              control   = 32L

              hopCount  = 255
              dnet      = 65535
###[ APDU ]###
              dlen      = 0
                 pduType   = UNCONFIRMED_SERVICE_REQUEST
              hopCount  = 255
                 reserved  = None
###[ APDU ]###
                 serviceChoice= I_AM
                 pduType   = UNCONFIRMED_SERVICE_REQUEST
                 \tagsField \
                 reserved  = None
                  |###[ Raw ]###
                 serviceChoice= I_AM
                  |  load      = '\xc4\x02\t\xc7\x83"\x01\xe0\x91\x00!\xde'
                 \tagsField \
                  |###[ Raw ]###
                  |  load      = '\xc4\x02\t\xc7v"\x01\xe0\x91\x00!\xde'

如果没有该行,输出看起来像这样,但数据实际上是错误的。 Raw层实际上应该是一个APDU层。

###[ Ethernet ]###
  dst       = ff:ff:ff:ff:ff:ff
  src       = 00:30:de:09:c7:83
  type      = 0x800
###[ IP ]###
     version   = 4L
     ihl       = 5L
     tos       = 0x0
     len       = 52
     id        = 105
     flags     = DF
     frag      = 0L
     ttl       = 64
     proto     = udp
     chksum    = 0xb5fd
     src       = 192.168.1.3
     dst       = 192.168.1.255
     \options   \
###[ UDP ]###
        sport     = 47808
        dport     = 47808
        len       = 32
        chksum    = 0x6cec
###[ BVLC ]###
           type      = 0x81
           function  = ORIGINAL_BROADCAST_NPDU
           length    = 24
###[ NPDU ]###
              version   = 1
              control   = 32L
              dnet      = 65535
              dlen      = 0
              hopCount  = 255
###[ Raw ]###
                 load      = '\x10\x00\xc4\x02\t\xc7\x83"\x01\xe0\x91\x00!\xde'

该功能如下所示

def guessBACnetTagClass(packet, **kargs):

    """ Returns the correct BACnetTag Class needed to dissect
        the current tag

        @type    packet:    binary string
        @param   packet:    the current packet

        @type    cls:       class
        @return  cls:       the correct class for dissection
    """

    struct.unpack("!B", packet) # <------ with this line it works

    # Convert main tag Byte to binary format
    tagByteBinary = "{0:08b}".format(int(struct.unpack("!B", packet[0])[0]))

    # Extract information from main tag Byte
    tagNumber = int(tagByteBinary[0:4], 2)
    tagClass = BACnetTagClass.revDict()[int(tagByteBinary[4:5], 2)]
    lengthValueType = int(tagByteBinary[5:8], 2)

    # Tag is Application Tag
    if tagClass == BACnetTagClass.APPLICATION:
        clsName = BACnetApplicationTagClasses[tagNumber]
        cls = globals()[clsName]
        print cls
        return cls(packet, **kargs)

    # Tag is Context Specific Tag
    if tagClass == BACnetTagClass.CONTEXT_SPECIFIC:
        if lengthValueType == BACnetConstructedLVT.OPENING_TAG:
            cls = BACnetTag_Opening
        if lengthValueType == BACnetConstructedLVT.CLOSING_TAG:
            cls = BACnetTag_Closing

        # Check if a class was selected
        if cls is not None:
            print cls
            return cls(packet, **kargs)

这有什么意义吗?如何执行这一功能改变输出这么多?

0 个答案:

没有答案