blob: 23683c4ca95a1e24614030e990d889179d37da21 [file] [log] [blame]
#!/usr/bin/env python
# This file is part of Scapy
# Scapy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# any later version.
#
# Scapy 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.
#
# You should have received a copy of the GNU General Public License
# along with Scapy. If not, see <http://www.gnu.org/licenses/>.
# 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 __future__ import absolute_import
from __future__ import print_function
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 + ''.join(str(v) for v in 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", b"\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", b"\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", b"\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")