1b5a79ce91bed545d956464f5a8003c6898616a45Phil# scapy.contrib.description = Label Distribution Protocol (LDP)
2b5a79ce91bed545d956464f5a8003c6898616a45Phil# scapy.contrib.status = loads
3b5a79ce91bed545d956464f5a8003c6898616a45Phil
4b5a79ce91bed545d956464f5a8003c6898616a45Phil# http://git.savannah.gnu.org/cgit/ldpscapy.git/snapshot/ldpscapy-5285b81d6e628043df2a83301b292f24a95f0ba1.tar.gz
5b5a79ce91bed545d956464f5a8003c6898616a45Phil
6b5a79ce91bed545d956464f5a8003c6898616a45Phil# This program is free software: you can redistribute it and/or modify
7b5a79ce91bed545d956464f5a8003c6898616a45Phil# it under the terms of the GNU General Public License as published by
8b5a79ce91bed545d956464f5a8003c6898616a45Phil# the Free Software Foundation, either version 3 of the License, or
9b5a79ce91bed545d956464f5a8003c6898616a45Phil# (at your option) any later version.
10b5a79ce91bed545d956464f5a8003c6898616a45Phil
11b5a79ce91bed545d956464f5a8003c6898616a45Phil# This program is distributed in the hope that it will be useful,
12b5a79ce91bed545d956464f5a8003c6898616a45Phil# but WITHOUT ANY WARRANTY; without even the implied warranty of
13b5a79ce91bed545d956464f5a8003c6898616a45Phil# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14b5a79ce91bed545d956464f5a8003c6898616a45Phil# GNU General Public License for more details.
15b5a79ce91bed545d956464f5a8003c6898616a45Phil
16b5a79ce91bed545d956464f5a8003c6898616a45Phil# You should have received a copy of the GNU General Public License
17b5a79ce91bed545d956464f5a8003c6898616a45Phil# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18b5a79ce91bed545d956464f5a8003c6898616a45Phil
19b5a79ce91bed545d956464f5a8003c6898616a45Phil# Copyright (C) 2010 Florian Duraffourg
20b5a79ce91bed545d956464f5a8003c6898616a45Phil
2122a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotterfrom __future__ import absolute_import
22b5a79ce91bed545d956464f5a8003c6898616a45Philimport struct
23b5a79ce91bed545d956464f5a8003c6898616a45Phil
24b5a79ce91bed545d956464f5a8003c6898616a45Philfrom scapy.packet import *
25b5a79ce91bed545d956464f5a8003c6898616a45Philfrom scapy.fields import *
26b5a79ce91bed545d956464f5a8003c6898616a45Philfrom scapy.ansmachine import *
27b5a79ce91bed545d956464f5a8003c6898616a45Philfrom scapy.layers.inet import UDP
28b5a79ce91bed545d956464f5a8003c6898616a45Philfrom scapy.layers.inet import TCP
29b5a79ce91bed545d956464f5a8003c6898616a45Philfrom scapy.base_classes import Net
3022a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotterfrom scapy.modules.six.moves import range
31b5a79ce91bed545d956464f5a8003c6898616a45Phil
32b5a79ce91bed545d956464f5a8003c6898616a45Phil
33b5a79ce91bed545d956464f5a8003c6898616a45Phil# Guess payload
34b5a79ce91bed545d956464f5a8003c6898616a45Phildef guess_payload(p):
35b5a79ce91bed545d956464f5a8003c6898616a45Phil    LDPTypes = {
36b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0001: LDPNotification,
37b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0100: LDPHello,
38b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0200: LDPInit,
39b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0201: LDPKeepAlive,
40b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0300: LDPAddress,
41b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0301: LDPAddressWM,
42b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0400: LDPLabelMM,
43b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0401: LDPLabelReqM,
44b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0404: LDPLabelARM,
45b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0402: LDPLabelWM,
46b5a79ce91bed545d956464f5a8003c6898616a45Phil        0x0403: LDPLabelRelM,
47b5a79ce91bed545d956464f5a8003c6898616a45Phil        }
48b5a79ce91bed545d956464f5a8003c6898616a45Phil    type = struct.unpack("!H",p[0:2])[0]
49b5a79ce91bed545d956464f5a8003c6898616a45Phil    type = type & 0x7fff
50b5a79ce91bed545d956464f5a8003c6898616a45Phil    if type == 0x0001 and struct.unpack("!H",p[2:4])[0] > 20:
51b5a79ce91bed545d956464f5a8003c6898616a45Phil        return LDP
52b5a79ce91bed545d956464f5a8003c6898616a45Phil    if type in LDPTypes:
53b5a79ce91bed545d956464f5a8003c6898616a45Phil        return LDPTypes[type]
54b5a79ce91bed545d956464f5a8003c6898616a45Phil    else:
557b3e970663abd72697e17b70aba9943ae0dad404Phil        return conf.raw_layer
56b5a79ce91bed545d956464f5a8003c6898616a45Phil
57b5a79ce91bed545d956464f5a8003c6898616a45Phil## Fields ##
58b5a79ce91bed545d956464f5a8003c6898616a45Phil
59b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.4.1. FEC TLV
60b5a79ce91bed545d956464f5a8003c6898616a45Phil
61b5a79ce91bed545d956464f5a8003c6898616a45Philclass FecTLVField(StrField):
62b5a79ce91bed545d956464f5a8003c6898616a45Phil    islist=1
63b5a79ce91bed545d956464f5a8003c6898616a45Phil    def m2i(self, pkt, x):
64b5a79ce91bed545d956464f5a8003c6898616a45Phil        nbr = struct.unpack("!H",x[2:4])[0]
65b5a79ce91bed545d956464f5a8003c6898616a45Phil        used = 0
66b5a79ce91bed545d956464f5a8003c6898616a45Phil        x=x[4:]
67b5a79ce91bed545d956464f5a8003c6898616a45Phil        list=[]
68b5a79ce91bed545d956464f5a8003c6898616a45Phil        while x:
69b5a79ce91bed545d956464f5a8003c6898616a45Phil            #if x[0] == 1:
70b5a79ce91bed545d956464f5a8003c6898616a45Phil            #   list.append('Wildcard')
71b5a79ce91bed545d956464f5a8003c6898616a45Phil            #else:
72b5a79ce91bed545d956464f5a8003c6898616a45Phil            #mask=ord(x[8*i+3])
73b5a79ce91bed545d956464f5a8003c6898616a45Phil            #add=inet_ntoa(x[8*i+4:8*i+8])
74b5a79ce91bed545d956464f5a8003c6898616a45Phil            mask=ord(x[3])
75b5a79ce91bed545d956464f5a8003c6898616a45Phil            nbroctets = mask / 8
76b5a79ce91bed545d956464f5a8003c6898616a45Phil            if mask % 8:
77b5a79ce91bed545d956464f5a8003c6898616a45Phil                nbroctets += 1
782a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter            add=inet_ntoa(x[4:4+nbroctets]+b"\x00"*(4-nbroctets))
79b5a79ce91bed545d956464f5a8003c6898616a45Phil            list.append( (add, mask) )
80b5a79ce91bed545d956464f5a8003c6898616a45Phil            used += 4 + nbroctets
81b5a79ce91bed545d956464f5a8003c6898616a45Phil            x=x[4+nbroctets:]
82b5a79ce91bed545d956464f5a8003c6898616a45Phil        return list
83b5a79ce91bed545d956464f5a8003c6898616a45Phil    def i2m(self, pkt, x):
84d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter        if isinstance(x, str):
85b5a79ce91bed545d956464f5a8003c6898616a45Phil            return x
862a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter        s = b"\x01\x00"
87b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = 0
88b5a79ce91bed545d956464f5a8003c6898616a45Phil        fec = ""
89b5a79ce91bed545d956464f5a8003c6898616a45Phil        for o in x:
902a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter            fec += b"\x02\x00\x01"
91b5a79ce91bed545d956464f5a8003c6898616a45Phil            # mask length
92b5a79ce91bed545d956464f5a8003c6898616a45Phil            fec += struct.pack("!B",o[1])
93b5a79ce91bed545d956464f5a8003c6898616a45Phil            # Prefix
94b5a79ce91bed545d956464f5a8003c6898616a45Phil            fec += inet_aton(o[0])
95b5a79ce91bed545d956464f5a8003c6898616a45Phil            l += 8
96b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!H",l)
97b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += fec
98b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s
99b5a79ce91bed545d956464f5a8003c6898616a45Phil    def size(self, s):
100b5a79ce91bed545d956464f5a8003c6898616a45Phil        """Get the size of this field"""
101b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = 4 + struct.unpack("!H",s[2:4])[0]
102b5a79ce91bed545d956464f5a8003c6898616a45Phil        return l
103b5a79ce91bed545d956464f5a8003c6898616a45Phil    def getfield(self, pkt, s):
104b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = self.size(s)
105b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s[l:],self.m2i(pkt, s[:l])
106b5a79ce91bed545d956464f5a8003c6898616a45Phil
107b5a79ce91bed545d956464f5a8003c6898616a45Phil
108b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.4.2.1. Generic Label TLV
109b5a79ce91bed545d956464f5a8003c6898616a45Phil
110b5a79ce91bed545d956464f5a8003c6898616a45Philclass LabelTLVField(StrField):
111b5a79ce91bed545d956464f5a8003c6898616a45Phil    def m2i(self, pkt, x):
112b5a79ce91bed545d956464f5a8003c6898616a45Phil        return struct.unpack("!I",x[4:8])[0]
113b5a79ce91bed545d956464f5a8003c6898616a45Phil    def i2m(self, pkt, x):
114d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter        if isinstance(x, str):
115b5a79ce91bed545d956464f5a8003c6898616a45Phil            return x
1162a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter        s = b"\x02\x00\x00\x04"
117b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!I",x)
118b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s
119b5a79ce91bed545d956464f5a8003c6898616a45Phil    def size(self, s):
120b5a79ce91bed545d956464f5a8003c6898616a45Phil        """Get the size of this field"""
121b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = 4 + struct.unpack("!H",s[2:4])[0]
122b5a79ce91bed545d956464f5a8003c6898616a45Phil        return l
123b5a79ce91bed545d956464f5a8003c6898616a45Phil    def getfield(self, pkt, s):
124b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = self.size(s)
125b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s[l:],self.m2i(pkt, s[:l])
126b5a79ce91bed545d956464f5a8003c6898616a45Phil
127b5a79ce91bed545d956464f5a8003c6898616a45Phil
128b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.4.3. Address List TLV
129b5a79ce91bed545d956464f5a8003c6898616a45Phil
130b5a79ce91bed545d956464f5a8003c6898616a45Philclass AddressTLVField(StrField):
131b5a79ce91bed545d956464f5a8003c6898616a45Phil    islist=1
132b5a79ce91bed545d956464f5a8003c6898616a45Phil    def m2i(self, pkt, x):
133b5a79ce91bed545d956464f5a8003c6898616a45Phil        nbr = struct.unpack("!H",x[2:4])[0] - 2
134b5a79ce91bed545d956464f5a8003c6898616a45Phil        nbr /= 4
135b5a79ce91bed545d956464f5a8003c6898616a45Phil        x=x[6:]
136b5a79ce91bed545d956464f5a8003c6898616a45Phil        list=[]
13722a55b62eb35e8611fe03b99e4ff4f257a97b5d1gpotter        for i in range(0, nbr):
138b5a79ce91bed545d956464f5a8003c6898616a45Phil            add = x[4*i:4*i+4]
139b5a79ce91bed545d956464f5a8003c6898616a45Phil            list.append(inet_ntoa(add))
140b5a79ce91bed545d956464f5a8003c6898616a45Phil        return list
141b5a79ce91bed545d956464f5a8003c6898616a45Phil    def i2m(self, pkt, x):
142d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter        if isinstance(x, str):
143b5a79ce91bed545d956464f5a8003c6898616a45Phil            return x
144b5a79ce91bed545d956464f5a8003c6898616a45Phil        l=2+len(x)*4
1452a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter        s = b"\x01\x01"+struct.pack("!H",l)+b"\x00\x01"
146b5a79ce91bed545d956464f5a8003c6898616a45Phil        for o in x:
147b5a79ce91bed545d956464f5a8003c6898616a45Phil            s += inet_aton(o)
148b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s
149b5a79ce91bed545d956464f5a8003c6898616a45Phil    def size(self, s):
150b5a79ce91bed545d956464f5a8003c6898616a45Phil        """Get the size of this field"""
151b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = 4 + struct.unpack("!H",s[2:4])[0]
152b5a79ce91bed545d956464f5a8003c6898616a45Phil        return l
153b5a79ce91bed545d956464f5a8003c6898616a45Phil    def getfield(self, pkt, s):
154b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = self.size(s)
155b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s[l:],self.m2i(pkt, s[:l])
156b5a79ce91bed545d956464f5a8003c6898616a45Phil
157b5a79ce91bed545d956464f5a8003c6898616a45Phil
158b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.4.6. Status TLV
159b5a79ce91bed545d956464f5a8003c6898616a45Phil
160b5a79ce91bed545d956464f5a8003c6898616a45Philclass StatusTLVField(StrField):
161b5a79ce91bed545d956464f5a8003c6898616a45Phil    islist=1
162b5a79ce91bed545d956464f5a8003c6898616a45Phil    def m2i(self, pkt, x):
163b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = []
164b5a79ce91bed545d956464f5a8003c6898616a45Phil        statuscode = struct.unpack("!I",x[4:8])[0]
165b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( (statuscode & 2**31) >> 31)
166b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( (statuscode & 2**30) >> 30)
167b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( statuscode & 0x3FFFFFFF )
168b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( struct.unpack("!I", x[8:12])[0] )
169b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( struct.unpack("!H", x[12:14])[0] )
170b5a79ce91bed545d956464f5a8003c6898616a45Phil        return l
171b5a79ce91bed545d956464f5a8003c6898616a45Phil    def i2m(self, pkt, x):
172d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter        if isinstance(x, str):
173b5a79ce91bed545d956464f5a8003c6898616a45Phil            return x
1742a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter        s = b"\x03\x00" + struct.pack("!H",10)
175b5a79ce91bed545d956464f5a8003c6898616a45Phil        statuscode = 0
176b5a79ce91bed545d956464f5a8003c6898616a45Phil        if x[0] != 0:
177b5a79ce91bed545d956464f5a8003c6898616a45Phil            statuscode += 2**31
178b5a79ce91bed545d956464f5a8003c6898616a45Phil        if x[1] != 0:
179b5a79ce91bed545d956464f5a8003c6898616a45Phil            statuscode += 2**30
180b5a79ce91bed545d956464f5a8003c6898616a45Phil        statuscode += x[2]
181b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!I",statuscode)
182b5a79ce91bed545d956464f5a8003c6898616a45Phil        if len(x) > 3:
183b5a79ce91bed545d956464f5a8003c6898616a45Phil            s += struct.pack("!I",x[3])
184b5a79ce91bed545d956464f5a8003c6898616a45Phil        else:
1852a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter            s += b"\x00\x00\x00\x00"
186b5a79ce91bed545d956464f5a8003c6898616a45Phil        if len(x) > 4:
187b5a79ce91bed545d956464f5a8003c6898616a45Phil            s += struct.pack("!H",x[4])
188b5a79ce91bed545d956464f5a8003c6898616a45Phil        else:
1892a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter            s += b"\x00\x00"
190b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s
191b5a79ce91bed545d956464f5a8003c6898616a45Phil    def getfield(self, pkt, s):
192b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = 14
193b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s[l:],self.m2i(pkt, s[:l])
194b5a79ce91bed545d956464f5a8003c6898616a45Phil
195b5a79ce91bed545d956464f5a8003c6898616a45Phil
196b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.2 Common Hello Parameters TLV
197b5a79ce91bed545d956464f5a8003c6898616a45Philclass CommonHelloTLVField(StrField):
198b5a79ce91bed545d956464f5a8003c6898616a45Phil    islist = 1
199b5a79ce91bed545d956464f5a8003c6898616a45Phil    def m2i(self, pkt, x):
200b5a79ce91bed545d956464f5a8003c6898616a45Phil        list = []
201b5a79ce91bed545d956464f5a8003c6898616a45Phil        v = struct.unpack("!H",x[4:6])[0]
202b5a79ce91bed545d956464f5a8003c6898616a45Phil        list.append(v)
203b5a79ce91bed545d956464f5a8003c6898616a45Phil        flags = struct.unpack("B",x[6])[0]
204b5a79ce91bed545d956464f5a8003c6898616a45Phil        v = ( flags & 0x80 ) >> 7
205b5a79ce91bed545d956464f5a8003c6898616a45Phil        list.append(v)
206b5a79ce91bed545d956464f5a8003c6898616a45Phil        v = ( flags & 0x40 ) >> 7
207b5a79ce91bed545d956464f5a8003c6898616a45Phil        list.append(v)
208b5a79ce91bed545d956464f5a8003c6898616a45Phil        return list
209b5a79ce91bed545d956464f5a8003c6898616a45Phil    def i2m(self, pkt, x):
210d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter        if isinstance(x, str):
211b5a79ce91bed545d956464f5a8003c6898616a45Phil            return x
2122a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter        s = b"\x04\x00\x00\x04"
213b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!H",x[0])
214b5a79ce91bed545d956464f5a8003c6898616a45Phil        byte = 0
215b5a79ce91bed545d956464f5a8003c6898616a45Phil        if x[1] == 1:
216b5a79ce91bed545d956464f5a8003c6898616a45Phil            byte += 0x80
217b5a79ce91bed545d956464f5a8003c6898616a45Phil        if x[2] == 1:
218b5a79ce91bed545d956464f5a8003c6898616a45Phil            byte += 0x40
219b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!B",byte)
2202a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter        s += b"\x00"
221b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s
222b5a79ce91bed545d956464f5a8003c6898616a45Phil    def getfield(self, pkt, s):
223b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = 8
224b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s[l:],self.m2i(pkt, s[:l])
225b5a79ce91bed545d956464f5a8003c6898616a45Phil
226b5a79ce91bed545d956464f5a8003c6898616a45Phil
227b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.3 Common Session Parameters TLV
228b5a79ce91bed545d956464f5a8003c6898616a45Philclass CommonSessionTLVField(StrField):
229b5a79ce91bed545d956464f5a8003c6898616a45Phil    islist = 1
230b5a79ce91bed545d956464f5a8003c6898616a45Phil    def m2i(self, pkt, x):
231ba60ebfb60f4faecaa904faeb04823b5d37d0479Rémy Léone        l = [struct.unpack("!H", x[6:8])[0]]
232b5a79ce91bed545d956464f5a8003c6898616a45Phil        octet = struct.unpack("B",x[8:9])[0]
233b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( (octet & 2**7 ) >> 7 )
234b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( (octet & 2**6 ) >> 6 )
235b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( struct.unpack("B",x[9:10])[0] )
236b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( struct.unpack("!H",x[10:12])[0] )
237b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( inet_ntoa(x[12:16]) )
238b5a79ce91bed545d956464f5a8003c6898616a45Phil        l.append( struct.unpack("!H",x[16:18])[0] )
239b5a79ce91bed545d956464f5a8003c6898616a45Phil        return l
240b5a79ce91bed545d956464f5a8003c6898616a45Phil    def i2m(self, pkt, x):
241d51edef8530fe1e944f13eb65ef863c2d7f04b1dgpotter        if isinstance(x, str):
242b5a79ce91bed545d956464f5a8003c6898616a45Phil            return x
2432a7ad0d13aaaa2a5358f82c67877856863a30d61gpotter        s = b"\x05\x00\x00\x0E\x00\x01"
244b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!H",x[0])
245b5a79ce91bed545d956464f5a8003c6898616a45Phil        octet = 0
246b5a79ce91bed545d956464f5a8003c6898616a45Phil        if x[1] != 0:
247b5a79ce91bed545d956464f5a8003c6898616a45Phil            octet += 2**7
248b5a79ce91bed545d956464f5a8003c6898616a45Phil        if x[2] != 0:
249b5a79ce91bed545d956464f5a8003c6898616a45Phil            octet += 2**6
250b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!B",octet)
251b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!B",x[3])
252b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!H",x[4])
253b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += inet_aton(x[5])
254b5a79ce91bed545d956464f5a8003c6898616a45Phil        s += struct.pack("!H",x[6])
255b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s
256b5a79ce91bed545d956464f5a8003c6898616a45Phil    def getfield(self, pkt, s):
257b5a79ce91bed545d956464f5a8003c6898616a45Phil        l = 18
258b5a79ce91bed545d956464f5a8003c6898616a45Phil        return s[l:],self.m2i(pkt, s[:l])
259b5a79ce91bed545d956464f5a8003c6898616a45Phil
260b5a79ce91bed545d956464f5a8003c6898616a45Phil
261b5a79ce91bed545d956464f5a8003c6898616a45Phil
262b5a79ce91bed545d956464f5a8003c6898616a45Phil## Messages ##
263b5a79ce91bed545d956464f5a8003c6898616a45Phil
264b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.1. Notification Message
265b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPNotification(Packet):
266b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPNotification"
267b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
268b5a79ce91bed545d956464f5a8003c6898616a45Phil                    BitField("type", 0x0001, 15),
269b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
270b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0) ,
271b5a79ce91bed545d956464f5a8003c6898616a45Phil                    StatusTLVField("status",(0,0,0,0,0)) ]
272b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
273b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
274b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
275b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
276b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
277b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
278b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
279b5a79ce91bed545d956464f5a8003c6898616a45Phil
280b5a79ce91bed545d956464f5a8003c6898616a45Phil
281b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.2. Hello Message
282b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPHello(Packet):
283b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPHello"
284b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
285b5a79ce91bed545d956464f5a8003c6898616a45Phil                    BitField("type", 0x0100, 15),
286b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
287b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0) ,
288b5a79ce91bed545d956464f5a8003c6898616a45Phil                    CommonHelloTLVField("params",[180,0,0]) ]
289b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
290b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
291b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
292b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
293b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
294b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
295b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
296b5a79ce91bed545d956464f5a8003c6898616a45Phil
297b5a79ce91bed545d956464f5a8003c6898616a45Phil
298b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.3. Initialization Message
299b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPInit(Packet):
300b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPInit"
301b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
302b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0200, 15),
303b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
304b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0),
305b5a79ce91bed545d956464f5a8003c6898616a45Phil                    CommonSessionTLVField("params",None)]
306b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
307b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
308b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
309b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
310b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
311b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
312b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
313b5a79ce91bed545d956464f5a8003c6898616a45Phil
314b5a79ce91bed545d956464f5a8003c6898616a45Phil
315b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.4. KeepAlive Message
316b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPKeepAlive(Packet):
317b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPKeepAlive"
318b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
319b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0201, 15),
320b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
321b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0)]
322b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
323b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
324b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
325b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
326b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
327b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
328b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
329b5a79ce91bed545d956464f5a8003c6898616a45Phil
330b5a79ce91bed545d956464f5a8003c6898616a45Phil
331b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.5. Address Message
332b5a79ce91bed545d956464f5a8003c6898616a45Phil
333b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPAddress(Packet):
334b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPAddress"
335b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
336b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0300, 15),
337b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
338b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0),
339b5a79ce91bed545d956464f5a8003c6898616a45Phil                    AddressTLVField("address",None) ]
340b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
341b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
342b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
343b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
344b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
345b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
346b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
347b5a79ce91bed545d956464f5a8003c6898616a45Phil
348b5a79ce91bed545d956464f5a8003c6898616a45Phil
349b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.6. Address Withdraw Message
350b5a79ce91bed545d956464f5a8003c6898616a45Phil
351b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPAddressWM(Packet):
352b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPAddressWM"
353b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
354b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0301, 15),
355b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
356b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0),
357b5a79ce91bed545d956464f5a8003c6898616a45Phil                    AddressTLVField("address",None) ]
358b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
359b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
360b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
361b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
362b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
363b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
364b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
365b5a79ce91bed545d956464f5a8003c6898616a45Phil
366b5a79ce91bed545d956464f5a8003c6898616a45Phil
367b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.7. Label Mapping Message
368b5a79ce91bed545d956464f5a8003c6898616a45Phil
369b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPLabelMM(Packet):
370b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPLabelMM"
371b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
372b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0400, 15),
373b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
374b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0),
375b5a79ce91bed545d956464f5a8003c6898616a45Phil                    FecTLVField("fec",None),
376b5a79ce91bed545d956464f5a8003c6898616a45Phil                    LabelTLVField("label",0)]
377b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
378b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
379b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
380b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
381b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
382b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
383b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
384b5a79ce91bed545d956464f5a8003c6898616a45Phil
385b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.8. Label Request Message
386b5a79ce91bed545d956464f5a8003c6898616a45Phil
387b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPLabelReqM(Packet):
388b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPLabelReqM"
389b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
390b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0401, 15),
391b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
392b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0),
393b5a79ce91bed545d956464f5a8003c6898616a45Phil                    FecTLVField("fec",None)]
394b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
395b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
396b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
397b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
398b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
399b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
400b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
401b5a79ce91bed545d956464f5a8003c6898616a45Phil
402b5a79ce91bed545d956464f5a8003c6898616a45Phil
403b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.9. Label Abort Request Message
404b5a79ce91bed545d956464f5a8003c6898616a45Phil
405b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPLabelARM(Packet):
406b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPLabelARM"
407b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
408b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0404, 15),
409b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
410b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0),
411b5a79ce91bed545d956464f5a8003c6898616a45Phil                    FecTLVField("fec",None),
412b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("labelRMid",0)]
413b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
414b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
415b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
416b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
417b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
418b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
419b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
420b5a79ce91bed545d956464f5a8003c6898616a45Phil
421b5a79ce91bed545d956464f5a8003c6898616a45Phil
422b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.10. Label Withdraw Message
423b5a79ce91bed545d956464f5a8003c6898616a45Phil
424b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPLabelWM(Packet):
425b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPLabelWM"
426b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
427b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0402, 15),
428b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
429b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0),
430b5a79ce91bed545d956464f5a8003c6898616a45Phil                    FecTLVField("fec",None),
431b5a79ce91bed545d956464f5a8003c6898616a45Phil                    LabelTLVField("label",0)]
432b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
433b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
434b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
435b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
436b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
437b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
438b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
439b5a79ce91bed545d956464f5a8003c6898616a45Phil
440b5a79ce91bed545d956464f5a8003c6898616a45Phil
441b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.5.11. Label Release Message
442b5a79ce91bed545d956464f5a8003c6898616a45Phil
443b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDPLabelRelM(Packet):
444b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDPLabelRelM"
445b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ BitField("u",0,1),
446b5a79ce91bed545d956464f5a8003c6898616a45Phil                    XBitField("type", 0x0403, 15),
447b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
448b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IntField("id", 0),
449b5a79ce91bed545d956464f5a8003c6898616a45Phil                    FecTLVField("fec",None),
450b5a79ce91bed545d956464f5a8003c6898616a45Phil                    LabelTLVField("label",0)]
451b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
452b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
453b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p) - 4
454b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
455b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
456b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
457b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
458b5a79ce91bed545d956464f5a8003c6898616a45Phil
459b5a79ce91bed545d956464f5a8003c6898616a45Phil
460b5a79ce91bed545d956464f5a8003c6898616a45Phil# 3.1. LDP PDUs
461b5a79ce91bed545d956464f5a8003c6898616a45Philclass LDP(Packet):
462b5a79ce91bed545d956464f5a8003c6898616a45Phil    name = "LDP"
463b5a79ce91bed545d956464f5a8003c6898616a45Phil    fields_desc = [ ShortField("version",1),
464b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("len", None),
465b5a79ce91bed545d956464f5a8003c6898616a45Phil                    IPField("id","127.0.0.1"),
466b5a79ce91bed545d956464f5a8003c6898616a45Phil                    ShortField("space",0) ]
467b5a79ce91bed545d956464f5a8003c6898616a45Phil    def post_build(self, p, pay):
468b5a79ce91bed545d956464f5a8003c6898616a45Phil        if self.len is None:
469b5a79ce91bed545d956464f5a8003c6898616a45Phil            l = len(p)+len(pay)-4
470b5a79ce91bed545d956464f5a8003c6898616a45Phil            p = p[:2]+struct.pack("!H", l)+p[4:]
471b5a79ce91bed545d956464f5a8003c6898616a45Phil        return p+pay
472b5a79ce91bed545d956464f5a8003c6898616a45Phil    def guess_payload_class(self, p):
473b5a79ce91bed545d956464f5a8003c6898616a45Phil        return guess_payload(p)
474b5a79ce91bed545d956464f5a8003c6898616a45Phil
475b5a79ce91bed545d956464f5a8003c6898616a45Philbind_layers( TCP, LDP, sport=646, dport=646 )
476b5a79ce91bed545d956464f5a8003c6898616a45Philbind_layers( UDP, LDP, sport=646, dport=646 )
477