簡體   English   中英

帶有自定義圖層的Scapy sr()

[英]Scapy sr() with custom layers

當使用sr()或srp()函數時 - Scapy如何知道收到的數據包是我發送的數據包的答案?

我編寫了一個模仿BACNet的自定義協議。 我可以將一個WHO_IS數據包發送到BACNet設備,並且該設備使用I_AM數據包進行應答,該數據包由於層綁定而被正確分解,但sr函數不會將其識別為答案。 如何讓Scapy接受這些數據包作為答案?

更新:這是我的圖層類的樣子。 我認為answers()方法看起來沒問題,但它仍然不起作用。 在實現answers()方法時,有什么我可能會誤解的嗎? 在我的理解中, self指的是層本身的類,而other是所討論的接收包。 因此,為了將有效負載傳遞到下一個更高層,我傳遞other.payload並使用下一個更高層類調用answers()方法。 這些層像Ether/IP/UDP/BVLC/NPDU/APDU一樣堆疊。

class BVLC(Packet):

    name = "BVLC"
    fields_desc = [
       # many fields
                   ]

    def post_build(self, pkt, pay):
        if self.length == None:                
            pkt = pkt[0:2] + struct.pack('!H', len(pay)+len(pkt)) + pkt[4:]  
        return pkt+pay

    def answers(self, other):
        if not isinstance(other,BVLC):
            return 0
        else:
            return NPDU.answers(other.payload)


class NPDU(Packet):

    name = "NPDU"
    fields_desc = [ 
        # again, many fields
                   ]

    def answers(self, other):
        if not isinstance(other,NPDU):
            return 0
        else:
            return APDU.answers(other.payload)

class APDU(Packet):

    name = "APDU"
    fields_desc = [
          # many fields and the only relevant field in this case
            ConditionalField(
                ByteEnumField(
                    "serviceChoice", None, APDU_Service_Unconfirmed.revDict()),
                    lambda pkt: pkt.pduType == APDU_Type.CONFIRMED_SERVICE_REQUEST or
                                pkt.pduType == APDU_Type.UNCONFIRMED_SERVICE_REQUEST), 
                   ]

    def answers(self, other):
        if not isinstance(other,APDU):
            return 0
        else:
            if self.serviceChoice == APDU_Service_Unconfirmed.WHO_IS and\
               other.serviceChoice == APDU_Service_Unconfirmed.I_AM:
                return 1
        return 0

Scapy sr只為每個發送的數據包調用recv_packet.answers(sent_packet) 因此,您必須為您的圖層實施def answers() ,請參閱:

def answers(self, other):
    """DEV: true if self is an answer from other"""
    if other.__class__ == self.__class__:
        return self.payload.answers(other.payload)
    return 0

這是原始TCP層的摘錄:

def answers(self, other):
    if not isinstance(other, TCP):
        return 0
    if conf.checkIPsrc:
        if not ((self.sport == other.dport) and
                (self.dport == other.sport)):
            return 0
    if (abs(other.seq-self.ack) > 2+len(other.payload)):
        return 0
    return 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM