1 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
18 Logical Link Control(LLC, IEEE 802.2) parser/serializer
19 http://standards.ieee.org/getieee802/download/802.2-1998.pdf
24 +-----------------+--------------+
25 | DSAP address | 8 bits |
26 +-----------------+--------------+
27 | SSAP address | 8 bits |
28 +-----------------+--------------+
29 | Control | 8 or 16 bits |
30 +-----------------+--------------+
36 +-----+---+---+---+---+---+---+---+
37 | I/G | D | D | D | D | D | D | D |
38 +-----+---+---+---+---+---+---+---+
39 I/G bit = 0 : Individual DSAP
40 I/G bit = 1 : Group DSA
46 +-----+---+---+---+---+---+---+---+
47 | C/R | S | S | S | S | S | S | S |
48 +-----+---+---+---+---+---+---+---+
50 C/R bit = 1 : Response
60 1 2 3 4 5 6 7 8 9 10-16
61 +---+---+---+---+---+---+---+---+-----+------+
62 | 0 | N(S) | P/F | N(R) |
63 +---+---+---+---+---+---+---+---+-----+------+
69 1 2 3 4 5 6 7 8 9 10-16
70 +---+---+---+---+---+---+---+---+-----+------+
71 | 1 0 | S S | 0 0 0 0 | P/F | N(R) |
72 +---+---+---+---+---+---+---+---+-----+------+
79 +---+---+----+---+-----+---+----+---+
80 | 1 1 | M1 M1 | P/F | M2 M2 M2 |
81 +---+---+----+---+-----+---+----+---+
83 N(S) : sender send sequence number (Bit 2=lower-order-bit)
84 N(R) : sender receive sequence number (Bit 10=lower-order-bit)
85 S : supervisory function bit
86 M1/M2: modifier function bit
87 P/F : poll bit - command LLC PDUs
88 final bit - response LLC PDUs
94 from . import packet_base
95 from ryu.lib import stringify
101 class llc(packet_base.PacketBase):
102 """LLC(IEEE 802.2) header encoder/decoder class.
104 An instance has the following attributes at least.
105 Most of them are same to the on-wire counterparts but in host byte
107 __init__ takes the corresponding args in this order.
109 .. tabularcolumns:: |l|L|
111 =============== ===============================================
112 Attribute Description
113 =============== ===============================================
114 dsap_addr Destination service access point address field \
115 includes I/G bit at least significant bit.
116 ssap_addr Source service access point address field \
117 includes C/R bit at least significant bit.
118 control Control field \
119 [16 bits for formats that include sequence \
120 numbering, and 8 bits for formats that do not]. \
121 Either ryu.lib.packet.llc.ControlFormatI or \
122 ryu.lib.packet.llc.ControlFormatS or \
123 ryu.lib.packet.llc.ControlFormatU object.
124 =============== ===============================================
128 _PACK_LEN = struct.calcsize(_PACK_STR)
130 _CTR_PACK_STR = '!2xB'
135 def register_control_type(register_cls):
136 llc._CTR_TYPES[register_cls.TYPE] = register_cls
139 def __init__(self, dsap_addr, ssap_addr, control):
140 super(llc, self).__init__()
142 assert getattr(control, 'TYPE', None) in self._CTR_TYPES
144 self.dsap_addr = dsap_addr
145 self.ssap_addr = ssap_addr
146 self.control = control
149 def parser(cls, buf):
150 assert len(buf) >= cls._PACK_LEN
151 (dsap_addr, ssap_addr) = struct.unpack_from(cls._PACK_STR, buf)
153 (control,) = struct.unpack_from(cls._CTR_PACK_STR, buf)
154 ctrl = cls._get_control(control)
155 control, information = ctrl.parser(buf[cls._PACK_LEN:])
157 return (cls(dsap_addr, ssap_addr, control),
158 cls.get_packet_type(dsap_addr), information)
160 def serialize(self, payload, prev):
161 addr = struct.pack(self._PACK_STR, self.dsap_addr, self.ssap_addr)
162 control = self.control.serialize()
163 return addr + control
166 def _get_control(cls, buf):
167 key = buf & 0b1 if buf & 0b1 == ControlFormatI.TYPE else buf & 0b11
168 return cls._CTR_TYPES[key]
171 @llc.register_control_type
172 class ControlFormatI(stringify.StringifyMixin):
173 """LLC sub encoder/decoder class for control I-format field.
175 An instance has the following attributes at least.
176 Most of them are same to the on-wire counterparts but in host byte
178 __init__ takes the corresponding args in this order.
180 ======================== ===============================
181 Attribute Description
182 ======================== ===============================
183 send_sequence_number sender send sequence number
184 pf_bit poll/final bit
185 receive_sequence_number sender receive sequence number
186 ======================== ===============================
190 _PACK_LEN = struct.calcsize(_PACK_STR)
192 def __init__(self, send_sequence_number=0, pf_bit=0,
193 receive_sequence_number=0):
194 super(ControlFormatI, self).__init__()
195 self.send_sequence_number = send_sequence_number
197 self.receive_sequence_number = receive_sequence_number
200 def parser(cls, buf):
201 assert len(buf) >= cls._PACK_LEN
202 (control,) = struct.unpack_from(cls._PACK_STR, buf)
203 assert (control >> 8) & 0b1 == cls.TYPE
205 send_sequence_number = (control >> 9) & 0b1111111
206 pf_bit = (control >> 8) & 0b1
207 receive_sequence_number = (control >> 1) & 0b1111111
209 return cls(send_sequence_number, pf_bit,
210 receive_sequence_number), buf[cls._PACK_LEN:]
213 control = (self.send_sequence_number << 9 |
215 self.receive_sequence_number << 1 |
217 return struct.pack(self._PACK_STR, control)
220 @llc.register_control_type
221 class ControlFormatS(stringify.StringifyMixin):
222 """LLC sub encoder/decoder class for control S-format field.
224 An instance has the following attributes at least.
225 Most of them are same to the on-wire counterparts but in host byte
227 __init__ takes the corresponding args in this order.
229 ======================== ===============================
230 Attribute Description
231 ======================== ===============================
232 supervisory_function supervisory function bit
233 pf_bit poll/final bit
234 receive_sequence_number sender receive sequence number
235 ======================== ===============================
240 _PACK_LEN = struct.calcsize(_PACK_STR)
242 def __init__(self, supervisory_function=0, pf_bit=0,
243 receive_sequence_number=0):
244 super(ControlFormatS, self).__init__()
245 self.supervisory_function = supervisory_function
247 self.receive_sequence_number = receive_sequence_number
250 def parser(cls, buf):
251 assert len(buf) >= cls._PACK_LEN
252 (control,) = struct.unpack_from(cls._PACK_STR, buf)
254 assert (control >> 8) & 0b11 == cls.TYPE
256 supervisory_function = (control >> 10) & 0b11
257 pf_bit = (control >> 8) & 0b1
258 receive_sequence_number = (control >> 1) & 0b1111111
260 return cls(supervisory_function, pf_bit,
261 receive_sequence_number), buf[cls._PACK_LEN:]
264 control = (self.supervisory_function << 10 |
266 self.receive_sequence_number << 1 |
268 return struct.pack(self._PACK_STR, control)
271 @llc.register_control_type
272 class ControlFormatU(stringify.StringifyMixin):
273 """LLC sub encoder/decoder class for control U-format field.
275 An instance has the following attributes at least.
276 Most of them are same to the on-wire counterparts but in host byte
278 __init__ takes the corresponding args in this order.
280 ======================== ===============================
281 Attribute Description
282 ======================== ===============================
283 modifier_function1 modifier function bit
284 pf_bit poll/final bit
285 modifier_function2 modifier function bit
286 ======================== ===============================
291 _PACK_LEN = struct.calcsize(_PACK_STR)
293 def __init__(self, modifier_function1=0, pf_bit=0, modifier_function2=0):
294 super(ControlFormatU, self).__init__()
295 self.modifier_function1 = modifier_function1
297 self.modifier_function2 = modifier_function2
300 def parser(cls, buf):
301 assert len(buf) >= cls._PACK_LEN
302 (control,) = struct.unpack_from(cls._PACK_STR, buf)
304 assert control & 0b11 == cls.TYPE
306 modifier_function1 = (control >> 2) & 0b11
307 pf_bit = (control >> 4) & 0b1
308 modifier_function2 = (control >> 5) & 0b111
310 return cls(modifier_function1, pf_bit,
311 modifier_function2), buf[cls._PACK_LEN:]
314 control = (self.modifier_function2 << 5 |
316 self.modifier_function1 << 2 |
318 return struct.pack(self._PACK_STR, control)
321 llc.register_packet_type(bpdu.bpdu, SAP_BPDU)
322 llc.set_classes(llc._CTR_TYPES)