Olsr支持scapy

时间:2013-12-28 15:35:07

标签: python-2.6 scapy

我是网络安全的学生,我正在尝试使用Scapy的OLSR支持,但当然这个版本已经过时,所以我正在尝试修复但是在Python上成为新手我希望你能帮助我

目标是创建OLSR数据包以充当网络节点。

以下是我在做了一些改动之后从Scapy得到的代码你相信我必须做的工作是post_build方法。

#!/usr/bin/env python

#############################################################################
##                                                                         ##
## olsr.py --- OLSR protocol support for Scapy                             ##
##                                                                         ##
## Copyright (C) 2005  EADS/CRC security team <dcrstic.ccr(at)eads.net>    ##
##                     Arnaud Ebalard         <arnaud.ebalard@eads.net>    ##    
##                                                                         ##
## This program is free software; you can redistribute it and/or modify it ##
## under the terms of the GNU General Public License version 2 as          ##
## published by the Free Software Foundation; version 2.                   ##
##                                                                         ##
## This program is distributed in the hope that it will be useful, but     ##
## WITHOUT ANY WARRANTY; without even the implied warranty of              ##
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ##
## General Public License for more details.                                ##
##                                                                         ##
#############################################################################

#
# $Log: olsr.py,v $
# Revision 1.15  2006/02/08 13:22:52  ebalard
# Suppressed old comments.
#
# Revision 1.14  2006/02/08 13:14:51  ebalard
# Final Version. Evverything is up and running in v4/v6. Let's wait for bugs.
#
# Revision 1.13  2006/02/06 19:16:59  ebalard
# NetListField is now up and running, allowing user to pass hna list in
# many different ways.
#
# Revision 1.12  2006/02/06 15:41:35  ebalard
# _OLSROrigAddrField() is now ready.
#
# Revision 1.11  2006/02/03 15:19:29  ebalard
# In fact, _OLSROrigAddrField() is buggy due to _underlayer and Scapy
# internal games. bug correction is in progress.
#
# Revision 1.10  2006/02/03 12:14:41  ebalard
# _OLSROrigAddrField now supports v4 and v6 addresses depending on network
# protocols used. Simple tests performed. Require some more.
#
# Revision 1.9  2006/01/27 16:05:18  ebalard
# conf.olsr_IPv6available is now set if scapy6 has been loaded (else its
# value is 0).
#
# Revision 1.8  2006/01/27 15:11:16  ebalard
# Bug in _OLSRTimeField corrected.
# Added scapy6 loading if available (will be used for IPv6 version).
#
# Revision 1.7  2006/01/27 12:57:23  ebalard
# post_dissect() method is _now_ really ok.
#
# Revision 1.6  2006/01/27 10:04:00  ebalard
# Bug in do_dissect() corrected.
#
# Revision 1.5  2006/01/27 08:53:37  ebalard
# NetListField is now working fine.
#
# Revision 1.4  2006/01/26 18:41:29  ebalard
# Almost Everything is there. Need polish, debug, more tests and solving
# problems referenced in TODO marks.
#
# Revision 1.3  2006/01/25 18:30:51  ebalard
# Banner typo corrected.
#
# Revision 1.2  2006/01/25 18:29:14  ebalard
# All main classes are defined.
#
# Revision 1.1.1.1  2006/01/25 09:41:53  ebalard
# Creation of scapy-olsr repository.




# TODO List :
# - create overloaded_fields for classes that need them. For example
#   in order to set destination IP adresses (v4 and also v6)
# - Deal with the sequence number fields that should be incremented
#   automatically (sn, msgsn, ansn)
# - Everytime there is an originator address, we should use by default
#   the address provided by conf.iface. See if we can directly use
#   and IPSourceField.
# - Same for TC messages with addresses available on the system, other
#   than that of conf.iface ? 
# - See if 'anma' field in TC message needs a different default value to
#   basically include at least 1 IP
# - At the end of the file is an awful hack : we give UDP source port
#   a value different from 53 because Scapy would dissect such a packet
#   as DNS traffic. Let call that an unwanted feature of scapy ;-)
# - see with Phil to make this field available in Scapy. It has
#   disappeared somewhere in some version.
# - See "IPv6 for OLSR" to make it generic (v4/v6) and deal with v6
#   traffic if Scapy IPv6 extensions are available.

# Basic cases :
#
#  IP()/UDP()/OLSR()/OLSR_MID()
#  IP()/UDP()/OLSR()/OLSR_HELLO()/OLSR_HELLO_LinkMessage()/OLSR_HELLO_LinkMessage()/OLSR_HELLO_LinkMessage 
#  IP()/UDP()/OLSR()/OLSR_TC()
#  IP()/UDP()/OLSR()/OLSR_HNA()


import math

try:
    # Try to get IPv6 support
    from scapy6.all import *
    conf.olsr_IPv6available=1
except:
    from scapy.all import *
    conf.olsr_IPv6available=0

# Emission interval constants : section 18.2 of RFC 3626
# Most of them are unused in Scapy, at the moment
conf.olsr_HELLO_INTERVAL=2
conf.olsr_REFRESH_INTERVAL=2
conf.olsr_TC_INTERVAL=5
conf.olsr_MID_INTERVAL=conf.olsr_TC_INTERVAL
conf.olsr_HNA_INTERVAL=conf.olsr_TC_INTERVAL

# Holding time constants : section 18.3 of RFC 3626
# Most of them are unused in Scapy, at the moment
conf.olsr_NEIGHB_HOLD_TIME=3*conf.olsr_REFRESH_INTERVAL
conf.olsr_TOP_HOLD_TIME=3*conf.olsr_TC_INTERVAL
conf.olsr_DUP_HOLD_TIME=30
conf.olsr_MID_HOLD_TIME=3*conf.olsr_MID_INTERVAL
conf.olsr_HNA_HOLD_TIME=3*conf.olsr_HNA_INTERVAL

# The proposed value of constant C in sect. 18.1 of RFC 3626 is 1/16
conf.olsr_C = 1.0/16

# Referenced in Section 18.4 of RFC 3626
olsr_types = { 1: "OLSR HELLO Message",
               2: "OLSR TC Message",
               3: "OLSR MID Message",
               4: "OLSR HNA Message"  }

# Provides a mapping between previous types and associated Scapy
# classes  
olsr_cls = { 1: "OLSR_HELLO",
             2: "OLSR_TC",
             3: "OLSR_MID",
             4: "OLSR_HNA" }

# Referenced in Section 18.5 of RFC 3626. Used by _OLSRLinkField
olsr_link_types = { 0: "UNSPEC_LINK",
                    1: "ASYM_LINK",
                    2: "SYM_LINK",
                    3: "LOST_LINK" }

# Referenced in Section 18.6 of RFC 3626. Used by _OLSRLinkField
olsr_neighbor_types = { 0: "NOT_NEIGH",
                        1: "SYM_NEIGH",
                        2: "MPR_NEIGH",
                        3: "Unknown (not defined by RFC 3626)" }

# Referenced in Section 18.7 of RFC 3626
olsr_link_hysteresis = { 0.8: "HYST_THRESHOLD_HIGH",
                         0.3: "HYST_THRESHOLD_LOW",
                         0.5: "HYST_SCALING" }

# Referenced in Section 18.8 of RFC 3626
olsr_willingness = { 0: "WILL_NEVER",
                     1: "WILL_LOW",
                     3: "WILL_DEFAULT",
                     6: "WILL_HIGH",
                     7: "WILL_ALWAYS"}


# This class provides OLSR Message classes (TC, MID, HNA, but not HELLO)
# with a guess_payload_class() method that performs early guessing of
# following message type and returns associated class that should be
# used for dissection. 
class _OLSRDefaultPayload(Packet):
    name = "Provides OLSR Message classes with default_payload_class() method"
    fields_desc = []
    def default_payload_class(self, p):
        # OLSR Message classes are at least 12 bytes long
        if len(p) >= 12:
            return globals().get(olsr_cls.get(ord(p[0]),"Raw"), "Raw")
        return Raw

# Main OLSR header, used to provide length and serial for specific
# stacked messages (HELLO, TC, MID and HNA)

class OLSR(_OLSRDefaultPayload):
    name = "OLSR Header"
    fields_desc = [ ShortField("len", None),
                    ShortField("sn", 0) ]
    def post_build(self, pkt, p):
        # Packet Length Computation
        if self.len is None:
            l = len(p)
            pkt = struct.pack("!H", l) + pkt[2:]
        #pkt = pkt[:1] + hex(l)[2:]+ pkt[2:]
        return pkt+p


class IPListField(StrLenField):
    islist = 1

    def getfield(self, pkt, s):

        # grab announced length
        l = getattr(pkt, self.fld)  
        f = pkt.get_field(self.fld)
        if isinstance(f, FieldLenField):
            l += f.shift

        # Are we carried by IPv4 or IPv6 ? -> set self.af and self.addrlen
        under = pkt.underlayer
        while under is not None:
            if conf.olsr_IPv6available and isinstance(under, IPv6):
                self.af =socket.AF_INET6
                self.addrlen = 16
                break
            elif isinstance(under, IP):
                self.af = socket.AF_INET
                self.addrlen = 4
                break
            under = under.underlayer

        if under is None:
            warning("No IP or IPv6 underlayer to select OLSR carried")
            warning("address type. Using IPv6 as fallback.")            

        return s[l:], self.m2i(pkt,s[:l])

    def addfield(self, pkt, s, val):
        return s+self.i2m(pkt,val)

    def any2i(self, pkt, x): 
        if type(x) is list:
            return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
        else:
            r = []
            r.append(self.any2i_one(pkt,x))
            return r

    def any2i_one(self, pkt, x):
        if x is None or x is "":
            return None

        if x.count(':') > 0: # IPv6
            self.af =socket.AF_INET6
            self.addrlen = 16
            return x
        else:                # IPv4
            self.af =socket.AF_INET
            self.addrlen = 4                
            return x


    def m2i(self, pkt, x):
        r = []
        l = self.addrlen # has been set by getfield (I hope so)
        while len(x) >= l:
            r.append(socket.inet_ntop(self.af, x[:l]))
            x = x[l:]
        return r

    def i2m(self, pkt, x):
        s = ""
        if len(x) > 0:
            for ip in x:
                s += socket.inet_pton(self.af, ip)
            return s
        return ""

    def i2repr(self, pkt, x):      
        s = []
    if x == None:
        return "[]"
    for y in x:
        s.append('%s' % y)
        return "[ %s ]" % (", ".join(s))


# This OLSR Time field is used for VTime and HTime (respectively in
# Message headers and Hello messages). Decription is provided in
# section 18.3 of RFC 3626. Defaut value of C is the one found in
# conf.olsr_C (default to 1/16).
#
# TODO : check if 'from scratch' formulas give same results as that
# provided in section 18.3 of RFC  3626
class _OLSRTimeField(ByteField):
    def m2i(self, pkt, x):
        a = ((int(x)>>4) & 0x0f)
        b = int(x) & 0x0f
        C = conf.olsr_C
        return C*(1+float(a)/16)*(2**b)

    def i2m(self, pkt, x):
        C = conf.olsr_C
        tmp = float(x)/C
        # base arg is available from python 2.3
        b = int(math.log(tmp, 2)) 
        a = int((float(tmp)/(2**b) - 1)*16)
        # TODO : perform some tests on computed value.
        return a*16+b 

    def i2repr(self, pkt, x):
        x=int(x)
        a = ((x>>4) & 0x0f)
        b = x & 0x0f
        C = conf.olsr_C
        return "%d sec (with C=%.4f, a is %d and b is %d)" % (x, C, a, b)



# Hack :to avoid errors in following class when IPv6 extensions are not
#       available. 
if not conf.olsr_IPv6available:
    class IP6Field: pass

# How do we know the AF for input parameters :
# - in getfield() : we access underlayer till we find an IP or IPv6 layer.
# - in h2i() : we try to find ':' in input parameter to see if it's an IPv6 @.
class _OLSROrigAddrField(IPField, IP6Field):

    # In getfield(), we will get AF based on kind of IP layer carrying 
    # the packet
    def getfield(self, pkt, s):
        under = pkt.underlayer
        while under is not None:
            if conf.olsr_IPv6available and isinstance(under, IPv6):
                self.sz = 16
                self.fmt = "16s"
                break
            elif isinstance(under, IP):
                self.sz = 4
                self.fmt = "4s"
                break
            under = under.underlayer

        if under is None:
            warning("No IP or IPv6 underlayer to select OLSR carried address type. Using IPv6 as fallback.")            

        return s[self.sz:], self.m2i(pkt,s[:self.sz])

    def addfield(self, pkt, s, val):
        return s+self.i2m(pkt,val)            

    # In h2i(), the only way to get AF is by parsing given address string
    # looking for ':'
    def h2i(self, pkt, x):
        if (conf.olsr_IPv6available and
            ((type(x) is str and  x.count(':') > 0)
             or (type(x) is list and len(x) > 0 and x[0].count(':') > 0))):
            self.fmt="16s"
            self.sz=16
            return IP6Field.h2i(self, pkt, x)
        else:
            self.fmt="4s"
            self.sz=4
            return IPField.h2i(self, pkt, x)

    def m2i(self, pkt, x):
        if conf.olsr_IPv6available and self.sz == 16:
            return IP6Field.m2i(self, pkt, x)
        else:
            return IPField.m2i(self, pkt, x)

    def i2m(self, pkt, x):
        # Deal with default value if user does not provide one
        if x is None:
            if conf.iface is not None:
                if conf.olsr_IPv6available:
                    warning("No address provided. IPv6 extensions being available, IPv6 global address")
                    warning("of %s interface will be used." % conf.iface)
                    x=get_if_addr6(conf.iface)
                    self.sz=16
                    self.fmt="16s"
                    if x is None:
                        warning("%s has no IPv6 address. Using :: as fallback." % conf.iface)
                        x="::"
                else:
                    warning("No address provided. IPv4 address of %s interface will be used." % conf.iface)
                    x=get_if_addr(conf.iface)
                    self.sz=4
                    self.fmt="4s"
                    if x is None:
                        warning("%s has no IPv4 address. Using 0.0.0.0 as fallback." % conf.iface)
                        x="0.0.0.0"

        # Call IPv4/v6 specific method
        if self.sz == 16: # implies conf.IPv6available
            return IP6Field.i2m(self, pkt, x)
        else:
            return IPField.i2m(self, pkt, x)

#### OLSR MID Message class : section 5.1 of RFC 3626
class OLSR_MID(_OLSRDefaultPayload, Packet):
    name = "OLSR MID Message"
    fields_desc = [ ByteEnumField("type", 3, olsr_types ),
                    _OLSRTimeField("vtime", conf.olsr_MID_HOLD_TIME ),
                    FieldLenField("msgsize", None , "interfaces", "!H", adjust=lambda pkt,x:x-12),
                    _OLSROrigAddrField("oaddr", None),
                    ByteField("ttl", 255), # RFC 3626 sect 5.1
                    ByteField("hopcount", 0 ),
                    ShortField("msgsn", 0),
                    IPListField("interfaces", [], "msgsize") ]


# This class performs specific processing for "Link Code" fields found
# in Hello Link Messages. Described in section 6.1.1 of RFC 3626.
class _OLSRLinkField(ByteField):
    def any2i(self, pkt, x):
        return x

    def i2repr(self, pkt, x):
        # RFC 3626 only specifies processing of Link Codes < 16
        if x < 16:
            ntype= olsr_neighbor_types[(x & 0x0c)>>2]
            ltype= olsr_link_types[(x & 0x03)]
            res = "%d  (Neighbor type:%s, Link type:%s)" % (x, ntype, ltype)
        else:
            res = "%d  (not < 16, i.e. not RFC 3626 compliant)" % x
        return res

    #TODO : what about writing any2i ?

# This messages are intended to be stacked behind OLSR_HELLO messages
class OLSR_HELLO_LinkMessage(Packet):
    name = "OLSR HELLO - Link Message"
    fields_desc = [ _OLSRLinkField("linkcode", 0x06), # SYM_NEIGH and SYM_LINK
                    ByteField("res", 0),
                    FieldLenField("size", None, "neighint", "!H", adjust=lambda pkt,x:x-4),
                    IPListField("neighint", [], "size") ]

    # TODO : find a better wayt to have same level of indentation for
    #        link message packet
    def show(self, indent=3, lvl=0):
        ct = conf.color_theme
        print "%s %s %s" % (ct.punct("###["),
                            ct.layer_name(self.name),
                            ct.punct("]###"))
        for f in self.fields_desc:
            if isinstance(f, Emph):
                ncol = ct.emph_field_name
                vcol = ct.emph_field_value
            else:
                ncol = ct.field_name
                vcol = ct.field_value
            print "  %s%-10s%s %s" % (" "*indent*lvl,
                                      ncol(f.name),
                                      ct.punct("="),
                                      vcol(f.i2repr(self,self.__getattr__(f))))
        dec = 1
        if isinstance(self.payload, OLSR_HELLO_LinkMessage):
            dec = 0
        self.payload.display(indent=indent,lvl=lvl+dec)


# OLSR Hello Header : on this packet, multiple OLSR Link Messages can
# be stacked. 
class OLSR_HELLO(Packet):
    name = "OLSR HELLO Message"
    fields_desc = [ ByteEnumField("type", 1, olsr_types),
                    ByteField("vtime", conf.olsr_NEIGHB_HOLD_TIME), 
                    ShortField("msgsize", None),
                    _OLSROrigAddrField("oaddr", None),
                    ByteField("ttl", 1), #RFC 3626 sect 6.1
                    ByteField("hopcount", 0 ),
                    ShortField("msgsn", 0),
                    XShortField("res", 0),
                    _OLSRTimeField("htime", conf.olsr_HELLO_INTERVAL),
                    ByteEnumField("willingness", 3, olsr_willingness) ]

    def do_dissect(self, s):
        # Dissecting fields of OLSR_HELLO packet
        flist = self.fields_desc[:]
        flist.reverse()
        while s and flist:
            f = flist.pop()
            s,fval = f.getfield(self, s)
            self.fields[f] = fval

        # post_dissect() call has been removed. Make no sense here.
        # extract_padding() call has been removed. Make no sense here.

        # l will be the length of following link messages train (beginning)
        # what follows beginning (end) is another OLSR message
        l = self.msgsize - 16
        print hexdump(s[:1])
        print hexdump(s[1:])
        beginning,end = s[:1], s[1:]
        self.do_dissect_payload(beginning)

        # beginning has been dissected has a chain of Link messages.
        # Let's gain the end of that train
        while isinstance(self.payload, OLSR_HELLO_LinkMessage):
            self = self.payload

        # If end can be parsed  has an OLSR Message Header, let's find
        # its type, instantiate it and add the result to our packet
        if len(end) >= 12:
            cls = globals().get(olsr_cls.get(ord(end[0]),"Raw"), "Raw")
            self.add_payload(cls(end))


    def post_build(self, pkt, p):
        # compute length till payload is end of Link Message classes
        if self.msgsize is None:
            while isinstance(self.payload, OLSR_HELLO_LinkMessage):
                self = self.payload
            self=self.payload
            l = len(pkt)
            if self is not None:
                l -= len(str(self))
            pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:]
    return pkt+p


# Defined in section 9.1
class OLSR_TC(_OLSRDefaultPayload):
    name = "OLSR Topology Control (TC) Message"
    fields_desc = [ ByteEnumField("type", 2, olsr_types),
                    ByteField("vtime", conf.olsr_TOP_HOLD_TIME),
                    FieldLenField("msgsize", None, "anma", "!H", adjust=lambda pkt,x:x-16),
                    _OLSROrigAddrField("oaddr", None),
                    ByteField("ttl", 255), # RFC 3626 Sect 9.1
                    ByteField("hopcount", 0 ),
                    ShortField("msgsn", 0),
                    XShortField("ansn", 0),
                    XShortField("res", 0),
                    IPListField("anma", [], "msgsize") ]


# Internal representation of the NetListField is a list of tuple (net, mask).
# - net is in printable representation (output of inet_ntop)
# - mask is in printable representation (output of inet_ntop)
# Supports v4 and v6. See IPListField comment.
class NetListField(StrLenField):
    islist = 1

    def i2repr(self, pkt, x): # v4/v6 independent
        s = []
        if x is None:
            return "[]"
        for y in x:
            net, mask = y
            s.append('(%s, %s)' % (net, mask))
        return "[ %s ]" % (", ".join(s))

    def getfield(self, pkt, s):

        # grab announced length
        l = getattr(pkt, self.fld)  
        f = pkt.get_field(self.fld)
        if isinstance(f, FieldLenField):
            l += f.shift

        # Are we carried by IPv4 or IPv6 ? -> set self.af and self.addrlen
        under = pkt.underlayer
        while under is not None:
            if conf.olsr_IPv6available and isinstance(under, IPv6):
                self.af =socket.AF_INET6
                self.addrlen = 16
                break
            elif isinstance(under, IP):
                self.af = socket.AF_INET
                self.addrlen = 4
                break
            under = under.underlayer

        if under is None:
            warning("No IP or IPv6 underlayer to select OLSR carried")
            warning("address type. Using IPv6 as fallback.")            

        return s[l:], self.m2i(pkt,s[:l])

    def addfield(self, pkt, s, val):
        return s+self.i2m(pkt,val)

    def any2i(self, pkt, x): 
        if type(x) is list:
            return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
        else:
            r = []
            r.append(self.any2i_one(pkt,x))
            return r

    # TODO : reread this function and search the bugs
    def any2i_one(self, pkt, x):
        if x is None or x is "":
            return None

        if type(x) is str: # v4/v6 host/net (2001::/64 or 172.16.0.0/24)

            if x.count(':') > 0: # IPv6
                self.af =socket.AF_INET6
                self.addrlen = 16

                res=x.split("/")
                l = len(res)
                if l == 1: # host case. Prefix will be 128
                    return self.any2i_one("%s/%d", (res[0],128))
                elif l == 2: # net case (most common case)
                    return (res[0], socket.inet_ntop(socket.AF_INET6, in6_cidr2mask(int(res[1]))))
                else: # error
                    warning( "give me something better" )
                    return None

            else:          # v4 net or host : "172.16.0.0/24"
                self.af =socket.AF_INET
                self.addrlen = 4                

                res=x.split("/")
                l = len(res)
                if l == 1: # host case. Prefix will be 32
                    return (res[0], ltoa(itom(32)))
                elif l == 2: # net case (most common case)
                    return (res[0], ltoa(itom(int(res[1]))))
                else: # error
                    warning( "give me something better" )
                    return None

        elif type(x) is tuple: # for thos loving tuples
            if type(x[1]) is int:
                return self.any2i_one(pkt, "%s/%d" % (x[0], x[1]))
            else:
                # tuple (Net, Mask) to be able to send corrupted values.
                # Valid values are : ("2001::1", "ff:ff::"), ("172.16.0.0", "255.255.0.0")
                return x
        # Third case : error
        else:
            return None

    def m2i(self, pkt, x):
        r = []
        l = self.addrlen
        while len(x) >= 8:
            r.append((socket.inet_ntop(self.af, x[:l]),
                      socket.inet_ntop(self.af, x[l:2*l])))
            x = x[2*l:]
        return r

    def i2m(self, pkt, x):
        s = ""
        if len(x) > 0:
            for net in x:
                s += socket.inet_pton(self.af, net[0]) + socket.inet_pton(self.af, net[1])
            return s
        return ""



# Host and Network Association Message. Sect 12 of RFC 3626
# 
# "In order to provide this capability of injecting external routing
# information into an OLSR MANET, a node with such non-MANET
# interfaces periodically issues a Host and Netwrok Association (HNA)
# message, containing sufficient information for the recipients to
# construct an appropriate routing table"
#
# TODO :
# - set Vtime and ttl
class OLSR_HNA(_OLSRDefaultPayload):
    name = "OLSR Host and Network Association Message"
    fields_desc = [ ByteEnumField("type", 4, olsr_types),
                    ByteField("vtime", conf.olsr_HNA_HOLD_TIME),
                    FieldLenField("msgsize", None, "anma", "!H", adjust=lambda pkt,x:x-16),
                    _OLSROrigAddrField("oaddr", None),
                    ByteField("ttl", 255), # RFC 3626 Sect. 12.1
                    ByteField("hopcount", 0 ),
                    ShortField("msgsn", 0),
                    NetListField("hna", [], "msgsize") ]

bind_layers(                    UDP, OLSR                  , { "sport":54, "dport":698 } )
bind_layers(             OLSR_HELLO, OLSR_HELLO_LinkMessage, { })
bind_layers( OLSR_HELLO_LinkMessage, OLSR_HELLO_LinkMessage, { } )



interact(mydict=globals(),mybanner="OLSR add-ons $Revision: 1.15 $ 0.1")

规格:CentOS上的Python 2.6和Scapy 2.2.0。

修改:要为我的问题添加一些细节,希望得到答案,

当我使用 -

在Scapy上创建数据包时
p = IP(tos=0xc0, id=0, flags=0x02, 
    dst='10.0.0.255')/UDP()/OLSR()/OLSR_HELLO(oaddr='10.0.0.1', 
    willingness=0)/OLSR_HELLO_LinkMessage()

已成功创建。问题是,当我发送它并通过Wireshark捕获它时,数据包的大小不符合协议要求,这并不意味着数据包格式错误,这意味着如果我尝试将其发送到守护程序,如OLSRD,它被拒绝了。

现在提供更多详细信息,当我执行p.show2()时,我可以看到UDP的长度是32,但是当我尝试通过Wireshark从OLSRD捕获数据包时,我看到UDP长度是28。

当然,在OLSRD和Scapy Packets的比较中,OLSR层是相同的,但是数据包的总长度是不同的。

如果您需要更多详细信息,请与我们联系。

PS:因为我是学生并不意味着我想要准备好代码,我正在努力理解并解决我的问题。提前谢谢。

0 个答案:

没有答案