summaryrefslogtreecommitdiffstats
path: root/scripts/external_libs/scapy-2.3.1/python3/scapy/contrib/dtp.py
blob: 1907300bae137170b04d32030bd89f40c994b1b3 (plain)
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")
n> } serialize_main_header_t; always_inline void serialize_error (serialize_main_header_t * m, clib_error_t * error) { clib_longjmp (&m->error_longjmp, pointer_to_uword (error)); } #define serialize_error_return(m,args...) \ serialize_error (&(m)->header, clib_error_return (0, args)) void *serialize_read_write_not_inline (serialize_main_header_t * m, serialize_stream_t * s, uword n_bytes, uword flags); #define SERIALIZE_FLAG_IS_READ (1 << 0) #define SERIALIZE_FLAG_IS_WRITE (1 << 1) always_inline void * serialize_stream_read_write (serialize_main_header_t * header, serialize_stream_t * s, uword n_bytes, uword flags) { uword i, j, l; l = vec_len (s->overflow_buffer); i = s->current_buffer_index; j = i + n_bytes; s->current_buffer_index = j; if (l == 0 && j <= s->n_buffer_bytes) { return s->buffer + i; } else { s->current_buffer_index = i; return serialize_read_write_not_inline (header, s, n_bytes, flags); } } typedef struct { serialize_main_header_t header; serialize_stream_t stream; } serialize_main_t; always_inline void serialize_set_end_of_stream (serialize_main_t * m) { serialize_stream_set_end_of_stream (&m->stream); } always_inline uword serialize_is_end_of_stream (serialize_main_t * m) { return serialize_stream_is_end_of_stream (&m->stream); } typedef struct { serialize_main_header_t header; serialize_stream_t *streams; } serialize_multiple_main_t; typedef void (serialize_function_t) (serialize_main_t * m, va_list * va); always_inline void * unserialize_get (serialize_main_t * m, uword n_bytes) { return serialize_stream_read_write (&m->header, &m->stream, n_bytes, SERIALIZE_FLAG_IS_READ); } always_inline void * serialize_get (serialize_main_t * m, uword n_bytes) { return serialize_stream_read_write (&m->header, &m->stream, n_bytes, SERIALIZE_FLAG_IS_WRITE); } always_inline void serialize_integer (serialize_main_t * m, u64 x, u32 n_bytes) { u8 *p = serialize_get (m, n_bytes); if (n_bytes == 1) p[0] = x; else if (n_bytes == 2) clib_mem_unaligned (p, u16) = clib_host_to_net_u16 (x); else if (n_bytes == 4) clib_mem_unaligned (p, u32) = clib_host_to_net_u32 (x); else if (n_bytes == 8) clib_mem_unaligned (p, u64) = clib_host_to_net_u64 (x); else ASSERT (0); } always_inline void unserialize_integer (serialize_main_t * m, void *x, u32 n_bytes) { u8 *p = unserialize_get (m, n_bytes); if (n_bytes == 1) *(u8 *) x = p[0]; else if (n_bytes == 2) *(u16 *) x = clib_net_to_host_unaligned_mem_u16 ((u16 *) p); else if (n_bytes == 4) *(u32 *) x = clib_net_to_host_unaligned_mem_u32 ((u32 *) p); else if (n_bytes == 8) *(u64 *) x = clib_net_to_host_unaligned_mem_u64 ((u64 *) p); else ASSERT (0); } /* As above but tries to be more compact. */ always_inline void serialize_likely_small_unsigned_integer (serialize_main_t * m, u64 x) { u64 r = x; u8 *p; /* Low bit set means it fits into 1 byte. */ if (r < (1 << 7)) { p = serialize_get (m, 1); p[0] = 1 + 2 * r; return; } /* Low 2 bits 1 0 means it fits into 2 bytes. */ r -= (1 << 7); if (r < (1 << 14)) { p = serialize_get (m, 2); clib_mem_unaligned (p, u16) = clib_host_to_little_u16 (4 * r + 2); return; } r -= (1 << 14); if (r < (1 << 29)) { p = serialize_get (m, 4); clib_mem_unaligned (p, u32) = clib_host_to_little_u32 (8 * r + 4); return; } p = serialize_get (m, 9); p[0] = 0; /* Only low 3 bits are used. */ clib_mem_unaligned (p + 1, u64) = clib_host_to_little_u64 (x); } always_inline u64 unserialize_likely_small_unsigned_integer (serialize_main_t * m) { u8 *p = unserialize_get (m, 1); u64 r; u32 y = p[0]; if (y & 1) return y / 2; r = 1 << 7; if (y & 2) { p = unserialize_get (m, 1); r += (y / 4) + (p[0] << 6); return r; } r += 1 << 14; if (y & 4) { p = unserialize_get (m, 3); r += ((y / 8) + (p[0] << (5 + 8 * 0)) + (p[1] << (5 + 8 * 1)) + (p[2] << (5 + 8 * 2))); return r; } p = unserialize_get (m, 8); r = clib_mem_unaligned (p, u64); r = clib_little_to_host_u64 (r); return r; } always_inline void serialize_likely_small_signed_integer (serialize_main_t * m, i64 s) { u64 u = s < 0 ? -(2 * s + 1) : 2 * s; serialize_likely_small_unsigned_integer (m, u); } always_inline i64 unserialize_likely_small_signed_integer (serialize_main_t * m) { u64 u = unserialize_likely_small_unsigned_integer (m); i64 s = u / 2; return (u & 1) ? -s : s; } void serialize_multiple_1 (serialize_main_t * m, void *data, uword data_stride, uword n_data); void serialize_multiple_2 (serialize_main_t * m, void *data, uword data_stride, uword n_data); void serialize_multiple_4 (serialize_main_t * m, void *data, uword data_stride, uword n_data); void unserialize_multiple_1 (serialize_main_t * m, void *data, uword data_stride, uword n_data); void unserialize_multiple_2 (serialize_main_t * m, void *data, uword data_stride, uword n_data); void unserialize_multiple_4 (serialize_main_t * m, void *data, uword data_stride, uword n_data); always_inline void serialize_multiple (serialize_main_t * m, void *data, uword n_data_bytes, uword data_stride, uword n_data) { if (n_data_bytes == 1) serialize_multiple_1 (m, data, data_stride, n_data); else if (n_data_bytes == 2) serialize_multiple_2 (m, data, data_stride, n_data); else if (n_data_bytes == 4) serialize_multiple_4 (m, data, data_stride, n_data); else ASSERT (0); } always_inline void unserialize_multiple (serialize_main_t * m, void *data, uword n_data_bytes, uword data_stride, uword n_data) { if (n_data_bytes == 1) unserialize_multiple_1 (m, data, data_stride, n_data); else if (n_data_bytes == 2) unserialize_multiple_2 (m, data, data_stride, n_data); else if (n_data_bytes == 4) unserialize_multiple_4 (m, data, data_stride, n_data); else ASSERT (0); } /* Basic types. */ serialize_function_t serialize_64, unserialize_64; serialize_function_t serialize_32, unserialize_32; serialize_function_t serialize_16, unserialize_16; serialize_function_t serialize_8, unserialize_8; serialize_function_t serialize_f64, unserialize_f64; serialize_function_t serialize_f32, unserialize_f32; /* Basic vector types. */ serialize_function_t serialize_vec_8, unserialize_vec_8; serialize_function_t serialize_vec_16, unserialize_vec_16; serialize_function_t serialize_vec_32, unserialize_vec_32; serialize_function_t serialize_vec_64, unserialize_vec_64; /* Serialize generic vectors. */ serialize_function_t serialize_vector, unserialize_vector, unserialize_aligned_vector; #define vec_serialize(m,v,f) \ serialize ((m), serialize_vector, (v), sizeof ((v)[0]), (f)) #define vec_unserialize(m,v,f) \ unserialize ((m), unserialize_vector, (v), sizeof ((*(v))[0]), (f)) #define vec_unserialize_aligned(m,v,f) \ unserialize ((m), unserialize_aligned_vector, (v), sizeof ((*(v))[0]), (f)) /* Serialize pools. */ serialize_function_t serialize_pool, unserialize_pool, unserialize_aligned_pool; #define pool_serialize(m,v,f) \ serialize ((m), serialize_pool, (v), sizeof ((v)[0]), (f)) #define pool_unserialize(m,v,f) \ unserialize ((m), unserialize_pool, (v), sizeof ((*(v))[0]), (f)) #define pool_unserialize_aligned(m,v,a,f) \ unserialize ((m), unserialize_aligned_pool, (v), sizeof ((*(v))[0]), (a), (f)) /* Serialize heaps. */ serialize_function_t serialize_heap, unserialize_heap; void serialize_bitmap (serialize_main_t * m, uword * b); uword *unserialize_bitmap (serialize_main_t * m); void serialize_cstring (serialize_main_t * m, char *string); void unserialize_cstring (serialize_main_t * m, char **string); void serialize_close (serialize_main_t * m); void unserialize_close (serialize_main_t * m); void serialize_open_data (serialize_main_t * m, u8 * data, uword n_data_bytes); void unserialize_open_data (serialize_main_t * m, u8 * data, uword n_data_bytes); /* Starts serialization with expanding vector as buffer. */ void serialize_open_vector (serialize_main_t * m, u8 * vector); /* Serialization is done: returns vector buffer to caller. */ void *serialize_close_vector (serialize_main_t * m); void unserialize_open_vector (serialize_main_t * m, u8 * vector); #ifdef CLIB_UNIX clib_error_t *serialize_open_clib_file (serialize_main_t * m, char *file); clib_error_t *unserialize_open_clib_file (serialize_main_t * m, char *file); void serialize_open_clib_file_descriptor (serialize_main_t * m, int fd); void unserialize_open_clib_file_descriptor (serialize_main_t * m, int fd); #endif /* CLIB_UNIX */ /* Main routines. */ clib_error_t *serialize (serialize_main_t * m, ...); clib_error_t *unserialize (serialize_main_t * m, ...); clib_error_t *va_serialize (serialize_main_t * m, va_list * va); void serialize_magic (serialize_main_t * m, void *magic, u32 magic_bytes); void unserialize_check_magic (serialize_main_t * m, void *magic, u32 magic_bytes); #endif /* included_clib_serialize_h */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */