| 1 |
|
|---|
| 2 |
""" |
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
from scapy import * |
|---|
| 16 |
|
|---|
| 17 |
class GenericTlv(Packet): |
|---|
| 18 |
name = "Generic TLV" |
|---|
| 19 |
fields_desc = [ XShortField("type", 0x0001), |
|---|
| 20 |
FieldLenField("length", None, length_of=lambda pkt:pkt.value + 4), |
|---|
| 21 |
StrLenField("value", "", length_from=lambda pkt:pkt.length - 4) |
|---|
| 22 |
] |
|---|
| 23 |
|
|---|
| 24 |
def guess_payload_class(self, p): |
|---|
| 25 |
return Padding |
|---|
| 26 |
|
|---|
| 27 |
class RepeatedTlvListField(PacketListField): |
|---|
| 28 |
def __init__(self, name, default, cls): |
|---|
| 29 |
PacketField.__init__(self, name, default, cls) |
|---|
| 30 |
|
|---|
| 31 |
def getfield(self, pkt, s): |
|---|
| 32 |
lst = [] |
|---|
| 33 |
remain = s |
|---|
| 34 |
while len(remain) > 0: |
|---|
| 35 |
p = self.m2i(pkt,remain) |
|---|
| 36 |
if Padding in p: |
|---|
| 37 |
pad = p[Padding] |
|---|
| 38 |
remain = pad.load |
|---|
| 39 |
del(pad.underlayer.payload) |
|---|
| 40 |
else: |
|---|
| 41 |
remain = "" |
|---|
| 42 |
lst.append(p) |
|---|
| 43 |
return remain,lst |
|---|
| 44 |
|
|---|
| 45 |
def addfield(self, pkt, s, val): |
|---|
| 46 |
return s+reduce(str.__add__, map(str, val),"") |
|---|
| 47 |
|
|---|
| 48 |
_DTP_TLV_CLS = { |
|---|
| 49 |
0x0001 : "DTPDomain", |
|---|
| 50 |
0x0002 : "DTPStatus", |
|---|
| 51 |
0x0003 : "DTPType", |
|---|
| 52 |
0x0004 : "DTPNeighbor" |
|---|
| 53 |
} |
|---|
| 54 |
|
|---|
| 55 |
_DTP_TLV_NAME = { |
|---|
| 56 |
0x0001 : "Domain", |
|---|
| 57 |
0x0002 : "Status", |
|---|
| 58 |
0x0003 : "Type", |
|---|
| 59 |
0x0004 : "Neighbor" |
|---|
| 60 |
} |
|---|
| 61 |
|
|---|
| 62 |
class DTPDomain(Packet): |
|---|
| 63 |
name = "DTP Domain" |
|---|
| 64 |
fields_desc = [ XShortEnumField("type", 0x0001, _DTP_TLV_NAME), |
|---|
| 65 |
FieldLenField("length", None, "domain", adjust=lambda pkt,x:x + 4), |
|---|
| 66 |
StrLenField("domain", "", length_from=lambda pkt:pkt.length - 4) |
|---|
| 67 |
] |
|---|
| 68 |
|
|---|
| 69 |
def guess_payload_class(self, p): |
|---|
| 70 |
return Padding |
|---|
| 71 |
|
|---|
| 72 |
class DTPStatus(Packet): |
|---|
| 73 |
name = "DTP Status" |
|---|
| 74 |
fields_desc = [ XShortEnumField("type", 0x0002, _DTP_TLV_NAME), |
|---|
| 75 |
FieldLenField("length", None, "status", adjust=lambda pkt,x:x + 4), |
|---|
| 76 |
StrLenField("status", "", length_from=lambda pkt:pkt.length - 4) |
|---|
| 77 |
] |
|---|
| 78 |
|
|---|
| 79 |
def guess_payload_class(self, p): |
|---|
| 80 |
return Padding |
|---|
| 81 |
|
|---|
| 82 |
class DTPType(Packet): |
|---|
| 83 |
name = "DTP Type" |
|---|
| 84 |
fields_desc = [ XShortEnumField("type", 0x0003, _DTP_TLV_NAME), |
|---|
| 85 |
FieldLenField("length", None, "dtptype", adjust=lambda pkt,x:x + 4), |
|---|
| 86 |
StrLenField("dtptype", "", length_from=lambda pkt:pkt.length - 4) |
|---|
| 87 |
] |
|---|
| 88 |
|
|---|
| 89 |
def guess_payload_class(self, p): |
|---|
| 90 |
return Padding |
|---|
| 91 |
|
|---|
| 92 |
class DTPNeighbor(Packet): |
|---|
| 93 |
name = "DTP Neighbor" |
|---|
| 94 |
fields_desc = [ XShortEnumField("type", 0x0004, _DTP_TLV_NAME), |
|---|
| 95 |
FieldLenField("length", None, "neighbor", adjust=lambda pkt,x:x + 4), |
|---|
| 96 |
MACField("neighbor", None) |
|---|
| 97 |
] |
|---|
| 98 |
|
|---|
| 99 |
def guess_payload_class(self, p): |
|---|
| 100 |
return Padding |
|---|
| 101 |
|
|---|
| 102 |
def _DTPGuessPayloadClass(p, **kargs): |
|---|
| 103 |
cls = Raw |
|---|
| 104 |
if len(p) >= 2: |
|---|
| 105 |
t = struct.unpack("!H", p[:2])[0] |
|---|
| 106 |
|
|---|
| 107 |
clsname = _DTP_TLV_CLS.get(t, "GenericTlv") |
|---|
| 108 |
cls = globals()[clsname] |
|---|
| 109 |
return cls(p, **kargs) |
|---|
| 110 |
|
|---|
| 111 |
class DTP(Packet): |
|---|
| 112 |
name = "DTP" |
|---|
| 113 |
fields_desc = [ ByteField("ver", 1), |
|---|
| 114 |
RepeatedTlvListField("tlvlist", [], _DTPGuessPayloadClass) |
|---|
| 115 |
] |
|---|
| 116 |
|
|---|
| 117 |
bind_layers(SNAP, DTP, code=0x2004, OUI=0xc) |
|---|
| 118 |
|
|---|
| 119 |
|
|---|
| 120 |
def negotiate_trunk(iface=conf.iface, mymac=str(RandMAC())): |
|---|
| 121 |
print "Trying to negotiate a trunk on interface %s" % iface |
|---|
| 122 |
|
|---|
| 123 |
p = Dot3(src=mymac, dst="01:00:0c:cc:cc:cc")/LLC()/SNAP()/DTP(ver=1, tlvlist=[DTPDomain(length=13, type=1, domain="\x00\x00\x00\x00\x00\x00\x00\x00\x00"),DTPStatus(status="\x03", length=5, type=2),DTPType(length=5, type=3, dtptype="\xa5"),DTPNeighbor(length=10, type=4, neighbor=mymac)]) |
|---|
| 124 |
sendp(p) |
|---|
| 125 |
|
|---|
| 126 |
if __name__ == "__main__": |
|---|
| 127 |
interact(mydict=globals(), mybanner="DTP") |
|---|