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