xref: /aosp_15_r20/external/openthread/tests/scripts/thread-cert/test_ipv6.py (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*cfb92d14SAndroid Build Coastguard Worker#
3*cfb92d14SAndroid Build Coastguard Worker#  Copyright (c) 2016, The OpenThread Authors.
4*cfb92d14SAndroid Build Coastguard Worker#  All rights reserved.
5*cfb92d14SAndroid Build Coastguard Worker#
6*cfb92d14SAndroid Build Coastguard Worker#  Redistribution and use in source and binary forms, with or without
7*cfb92d14SAndroid Build Coastguard Worker#  modification, are permitted provided that the following conditions are met:
8*cfb92d14SAndroid Build Coastguard Worker#  1. Redistributions of source code must retain the above copyright
9*cfb92d14SAndroid Build Coastguard Worker#     notice, this list of conditions and the following disclaimer.
10*cfb92d14SAndroid Build Coastguard Worker#  2. Redistributions in binary form must reproduce the above copyright
11*cfb92d14SAndroid Build Coastguard Worker#     notice, this list of conditions and the following disclaimer in the
12*cfb92d14SAndroid Build Coastguard Worker#     documentation and/or other materials provided with the distribution.
13*cfb92d14SAndroid Build Coastguard Worker#  3. Neither the name of the copyright holder nor the
14*cfb92d14SAndroid Build Coastguard Worker#     names of its contributors may be used to endorse or promote products
15*cfb92d14SAndroid Build Coastguard Worker#     derived from this software without specific prior written permission.
16*cfb92d14SAndroid Build Coastguard Worker#
17*cfb92d14SAndroid Build Coastguard Worker#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18*cfb92d14SAndroid Build Coastguard Worker#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*cfb92d14SAndroid Build Coastguard Worker#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*cfb92d14SAndroid Build Coastguard Worker#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21*cfb92d14SAndroid Build Coastguard Worker#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*cfb92d14SAndroid Build Coastguard Worker#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*cfb92d14SAndroid Build Coastguard Worker#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*cfb92d14SAndroid Build Coastguard Worker#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*cfb92d14SAndroid Build Coastguard Worker#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*cfb92d14SAndroid Build Coastguard Worker#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*cfb92d14SAndroid Build Coastguard Worker#  POSSIBILITY OF SUCH DAMAGE.
28*cfb92d14SAndroid Build Coastguard Worker#
29*cfb92d14SAndroid Build Coastguard Worker
30*cfb92d14SAndroid Build Coastguard Workerimport io
31*cfb92d14SAndroid Build Coastguard Workerimport random
32*cfb92d14SAndroid Build Coastguard Workerimport string
33*cfb92d14SAndroid Build Coastguard Workerimport struct
34*cfb92d14SAndroid Build Coastguard Workerimport unittest
35*cfb92d14SAndroid Build Coastguard Worker
36*cfb92d14SAndroid Build Coastguard Workerfrom ipaddress import ip_address
37*cfb92d14SAndroid Build Coastguard Worker
38*cfb92d14SAndroid Build Coastguard Workerfrom ipv6 import (
39*cfb92d14SAndroid Build Coastguard Worker    ICMPv6Header,
40*cfb92d14SAndroid Build Coastguard Worker    UDPHeader,
41*cfb92d14SAndroid Build Coastguard Worker    IPv6Header,
42*cfb92d14SAndroid Build Coastguard Worker    IPv6PacketFactory,
43*cfb92d14SAndroid Build Coastguard Worker    UDPDatagram,
44*cfb92d14SAndroid Build Coastguard Worker    UDPDatagramFactory,
45*cfb92d14SAndroid Build Coastguard Worker    ICMPv6Factory,
46*cfb92d14SAndroid Build Coastguard Worker    HopByHopFactory,
47*cfb92d14SAndroid Build Coastguard Worker    MPLOptionFactory,
48*cfb92d14SAndroid Build Coastguard Worker    ICMPv6,
49*cfb92d14SAndroid Build Coastguard Worker    HopByHopOptionHeader,
50*cfb92d14SAndroid Build Coastguard Worker    HopByHopOption,
51*cfb92d14SAndroid Build Coastguard Worker    HopByHop,
52*cfb92d14SAndroid Build Coastguard Worker    MPLOption,
53*cfb92d14SAndroid Build Coastguard Worker    IPv6Packet,
54*cfb92d14SAndroid Build Coastguard Worker    ICMPv6EchoBody,
55*cfb92d14SAndroid Build Coastguard Worker    BytesPayload,
56*cfb92d14SAndroid Build Coastguard Worker    ICMPv6EchoBodyFactory,
57*cfb92d14SAndroid Build Coastguard Worker    UpperLayerProtocol,
58*cfb92d14SAndroid Build Coastguard Worker    UDPHeaderFactory,
59*cfb92d14SAndroid Build Coastguard Worker    HopByHopOptionsFactory,
60*cfb92d14SAndroid Build Coastguard Worker    ICMPv6DestinationUnreachableFactory,
61*cfb92d14SAndroid Build Coastguard Worker    BytesPayloadFactory,
62*cfb92d14SAndroid Build Coastguard Worker    ICMPv6DestinationUnreachable,
63*cfb92d14SAndroid Build Coastguard Worker    UdpBasedOnSrcDstPortsPayloadFactory,
64*cfb92d14SAndroid Build Coastguard Worker    FragmentHeader,
65*cfb92d14SAndroid Build Coastguard Worker)
66*cfb92d14SAndroid Build Coastguard Worker
67*cfb92d14SAndroid Build Coastguard Workerimport common
68*cfb92d14SAndroid Build Coastguard Worker
69*cfb92d14SAndroid Build Coastguard Worker
70*cfb92d14SAndroid Build Coastguard Workerclass HopByHopOptionBytesValue:
71*cfb92d14SAndroid Build Coastguard Worker    """ Test helper class """
72*cfb92d14SAndroid Build Coastguard Worker
73*cfb92d14SAndroid Build Coastguard Worker    _value = "value"
74*cfb92d14SAndroid Build Coastguard Worker
75*cfb92d14SAndroid Build Coastguard Worker    def __init__(self, _bytes):
76*cfb92d14SAndroid Build Coastguard Worker        self.bytes = _bytes
77*cfb92d14SAndroid Build Coastguard Worker
78*cfb92d14SAndroid Build Coastguard Worker    def to_bytes(self):
79*cfb92d14SAndroid Build Coastguard Worker        return self.bytes
80*cfb92d14SAndroid Build Coastguard Worker
81*cfb92d14SAndroid Build Coastguard Worker    def to_dict(self, d=None):
82*cfb92d14SAndroid Build Coastguard Worker        d = d if d is not None else dict()
83*cfb92d14SAndroid Build Coastguard Worker
84*cfb92d14SAndroid Build Coastguard Worker        d[self._value] = self.bytes
85*cfb92d14SAndroid Build Coastguard Worker        return d
86*cfb92d14SAndroid Build Coastguard Worker
87*cfb92d14SAndroid Build Coastguard Worker    def __len__(self):
88*cfb92d14SAndroid Build Coastguard Worker        return len(self.bytes)
89*cfb92d14SAndroid Build Coastguard Worker
90*cfb92d14SAndroid Build Coastguard Worker
91*cfb92d14SAndroid Build Coastguard Workerclass ICMPv6BytesBody:
92*cfb92d14SAndroid Build Coastguard Worker    """ Test helper class """
93*cfb92d14SAndroid Build Coastguard Worker
94*cfb92d14SAndroid Build Coastguard Worker    _icmp_body = "icmp_body"
95*cfb92d14SAndroid Build Coastguard Worker
96*cfb92d14SAndroid Build Coastguard Worker    def __init__(self, _bytes):
97*cfb92d14SAndroid Build Coastguard Worker        self.bytes = _bytes
98*cfb92d14SAndroid Build Coastguard Worker
99*cfb92d14SAndroid Build Coastguard Worker    def to_bytes(self):
100*cfb92d14SAndroid Build Coastguard Worker        return self.bytes
101*cfb92d14SAndroid Build Coastguard Worker
102*cfb92d14SAndroid Build Coastguard Worker    def to_dict(self, d=None):
103*cfb92d14SAndroid Build Coastguard Worker
104*cfb92d14SAndroid Build Coastguard Worker        d[self._icmp_body] = self.bytes
105*cfb92d14SAndroid Build Coastguard Worker        return d
106*cfb92d14SAndroid Build Coastguard Worker
107*cfb92d14SAndroid Build Coastguard Worker    def __len__(self):
108*cfb92d14SAndroid Build Coastguard Worker        return len(self.bytes)
109*cfb92d14SAndroid Build Coastguard Worker
110*cfb92d14SAndroid Build Coastguard Worker
111*cfb92d14SAndroid Build Coastguard Workerclass ICMPv6BytesBodyFactory:
112*cfb92d14SAndroid Build Coastguard Worker    """ Test helper class """
113*cfb92d14SAndroid Build Coastguard Worker
114*cfb92d14SAndroid Build Coastguard Worker    def parse(self, data, context):
115*cfb92d14SAndroid Build Coastguard Worker        return ICMPv6BytesBody(data.read())
116*cfb92d14SAndroid Build Coastguard Worker
117*cfb92d14SAndroid Build Coastguard Worker
118*cfb92d14SAndroid Build Coastguard Workerclass DummyHeader:
119*cfb92d14SAndroid Build Coastguard Worker
120*cfb92d14SAndroid Build Coastguard Worker    def __init__(self):
121*cfb92d14SAndroid Build Coastguard Worker        self.checksum = 0
122*cfb92d14SAndroid Build Coastguard Worker
123*cfb92d14SAndroid Build Coastguard Worker
124*cfb92d14SAndroid Build Coastguard Workerclass DummyUpperLayerProtocol(UpperLayerProtocol):
125*cfb92d14SAndroid Build Coastguard Worker
126*cfb92d14SAndroid Build Coastguard Worker    def __init__(self, header, data, _type):
127*cfb92d14SAndroid Build Coastguard Worker        super(DummyUpperLayerProtocol, self).__init__(header)
128*cfb92d14SAndroid Build Coastguard Worker        self._data = data
129*cfb92d14SAndroid Build Coastguard Worker        self._type = _type
130*cfb92d14SAndroid Build Coastguard Worker
131*cfb92d14SAndroid Build Coastguard Worker    @property
132*cfb92d14SAndroid Build Coastguard Worker    def type(self):
133*cfb92d14SAndroid Build Coastguard Worker        return self._type
134*cfb92d14SAndroid Build Coastguard Worker
135*cfb92d14SAndroid Build Coastguard Worker    def to_bytes(self):
136*cfb92d14SAndroid Build Coastguard Worker        return self._data
137*cfb92d14SAndroid Build Coastguard Worker
138*cfb92d14SAndroid Build Coastguard Worker    def __len__(self):
139*cfb92d14SAndroid Build Coastguard Worker        return len(self._data)
140*cfb92d14SAndroid Build Coastguard Worker
141*cfb92d14SAndroid Build Coastguard Worker
142*cfb92d14SAndroid Build Coastguard Workerdef any_uint(bits):
143*cfb92d14SAndroid Build Coastguard Worker    return random.randint(0, (1 << bits) - 1)
144*cfb92d14SAndroid Build Coastguard Worker
145*cfb92d14SAndroid Build Coastguard Worker
146*cfb92d14SAndroid Build Coastguard Workerdef any_type():
147*cfb92d14SAndroid Build Coastguard Worker    return any_uint(8)
148*cfb92d14SAndroid Build Coastguard Worker
149*cfb92d14SAndroid Build Coastguard Worker
150*cfb92d14SAndroid Build Coastguard Workerdef any_code():
151*cfb92d14SAndroid Build Coastguard Worker    return any_uint(8)
152*cfb92d14SAndroid Build Coastguard Worker
153*cfb92d14SAndroid Build Coastguard Worker
154*cfb92d14SAndroid Build Coastguard Workerdef any_checksum():
155*cfb92d14SAndroid Build Coastguard Worker    return any_uint(16)
156*cfb92d14SAndroid Build Coastguard Worker
157*cfb92d14SAndroid Build Coastguard Worker
158*cfb92d14SAndroid Build Coastguard Workerdef any_fragment_offset():
159*cfb92d14SAndroid Build Coastguard Worker    return any_uint(13)
160*cfb92d14SAndroid Build Coastguard Worker
161*cfb92d14SAndroid Build Coastguard Worker
162*cfb92d14SAndroid Build Coastguard Workerdef any_bool():
163*cfb92d14SAndroid Build Coastguard Worker    return (any_uint(1) == 1)
164*cfb92d14SAndroid Build Coastguard Worker
165*cfb92d14SAndroid Build Coastguard Worker
166*cfb92d14SAndroid Build Coastguard Workerdef any_fragment_identification():
167*cfb92d14SAndroid Build Coastguard Worker    return any_uint(32)
168*cfb92d14SAndroid Build Coastguard Worker
169*cfb92d14SAndroid Build Coastguard Worker
170*cfb92d14SAndroid Build Coastguard Workerdef any_icmp_payload(_type, code, checksum, body):
171*cfb92d14SAndroid Build Coastguard Worker    return bytearray([_type, code, (checksum >> 8) & 0xff, checksum & 0xff]) + body
172*cfb92d14SAndroid Build Coastguard Worker
173*cfb92d14SAndroid Build Coastguard Worker
174*cfb92d14SAndroid Build Coastguard Workerdef any_udp_payload(src_port, dst_port, payload, checksum):
175*cfb92d14SAndroid Build Coastguard Worker    payload_len = len(payload) + 8
176*cfb92d14SAndroid Build Coastguard Worker    return bytearray([(src_port >> 8) & 0xff, src_port & 0xff, (dst_port >> 8) & 0xff, dst_port & 0xff,
177*cfb92d14SAndroid Build Coastguard Worker                      (payload_len >> 8) & 0xff, payload_len & 0xff,
178*cfb92d14SAndroid Build Coastguard Worker                      (checksum >> 8) & 0xff, checksum & 0xff]) + payload
179*cfb92d14SAndroid Build Coastguard Worker
180*cfb92d14SAndroid Build Coastguard Worker
181*cfb92d14SAndroid Build Coastguard Workerdef any_hop_by_hop_payload(next_header, hdr_ext_len, payload):
182*cfb92d14SAndroid Build Coastguard Worker    return bytearray([next_header, hdr_ext_len]) + payload
183*cfb92d14SAndroid Build Coastguard Worker
184*cfb92d14SAndroid Build Coastguard Worker
185*cfb92d14SAndroid Build Coastguard Workerdef any_body():
186*cfb92d14SAndroid Build Coastguard Worker    length = any_uint(8)
187*cfb92d14SAndroid Build Coastguard Worker    body = "".join([random.choice(string.ascii_letters + string.digits + string.hexdigits) for _ in range(length)])
188*cfb92d14SAndroid Build Coastguard Worker    return bytearray(body.encode("utf-8"))
189*cfb92d14SAndroid Build Coastguard Worker
190*cfb92d14SAndroid Build Coastguard Worker
191*cfb92d14SAndroid Build Coastguard Workerdef any_payload():
192*cfb92d14SAndroid Build Coastguard Worker    length = any_uint(8)
193*cfb92d14SAndroid Build Coastguard Worker    payload = "".join([random.choice(string.printable) for _ in range(length)])
194*cfb92d14SAndroid Build Coastguard Worker    return bytearray(payload.encode("utf-8"))
195*cfb92d14SAndroid Build Coastguard Worker
196*cfb92d14SAndroid Build Coastguard Worker
197*cfb92d14SAndroid Build Coastguard Workerdef any_ip_address():
198*cfb92d14SAndroid Build Coastguard Worker    return bytearray([0xfe, 0x80]) + bytearray([0x00] * 6) + bytearray([random.getrandbits(8)] * 8)
199*cfb92d14SAndroid Build Coastguard Worker
200*cfb92d14SAndroid Build Coastguard Worker
201*cfb92d14SAndroid Build Coastguard Workerdef any_port():
202*cfb92d14SAndroid Build Coastguard Worker    return any_uint(16)
203*cfb92d14SAndroid Build Coastguard Worker
204*cfb92d14SAndroid Build Coastguard Worker
205*cfb92d14SAndroid Build Coastguard Workerdef any_mpl_opt_type():
206*cfb92d14SAndroid Build Coastguard Worker    return any_uint(8)
207*cfb92d14SAndroid Build Coastguard Worker
208*cfb92d14SAndroid Build Coastguard Worker
209*cfb92d14SAndroid Build Coastguard Workerdef any_mpl_opt_data_len():
210*cfb92d14SAndroid Build Coastguard Worker    return any_uint(8)
211*cfb92d14SAndroid Build Coastguard Worker
212*cfb92d14SAndroid Build Coastguard Worker
213*cfb92d14SAndroid Build Coastguard Workerdef any_mpl_S():
214*cfb92d14SAndroid Build Coastguard Worker    return any_uint(2)
215*cfb92d14SAndroid Build Coastguard Worker
216*cfb92d14SAndroid Build Coastguard Worker
217*cfb92d14SAndroid Build Coastguard Workerdef any_mpl_M():
218*cfb92d14SAndroid Build Coastguard Worker    return any_uint(1)
219*cfb92d14SAndroid Build Coastguard Worker
220*cfb92d14SAndroid Build Coastguard Worker
221*cfb92d14SAndroid Build Coastguard Workerdef any_mpl_V():
222*cfb92d14SAndroid Build Coastguard Worker    return any_uint(1)
223*cfb92d14SAndroid Build Coastguard Worker
224*cfb92d14SAndroid Build Coastguard Worker
225*cfb92d14SAndroid Build Coastguard Workerdef any_mpl_sequence():
226*cfb92d14SAndroid Build Coastguard Worker    return any_uint(8)
227*cfb92d14SAndroid Build Coastguard Worker
228*cfb92d14SAndroid Build Coastguard Worker
229*cfb92d14SAndroid Build Coastguard Workerdef any_mpl_seed_id(S):
230*cfb92d14SAndroid Build Coastguard Worker    length = MPLOption._seed_id_length[S]
231*cfb92d14SAndroid Build Coastguard Worker    seed_id = "".join([random.choice(string.ascii_letters + string.digits + string.hexdigits) for _ in range(length)])
232*cfb92d14SAndroid Build Coastguard Worker    return bytearray(seed_id.encode("utf-8"))
233*cfb92d14SAndroid Build Coastguard Worker
234*cfb92d14SAndroid Build Coastguard Worker
235*cfb92d14SAndroid Build Coastguard Workerdef any_next_header():
236*cfb92d14SAndroid Build Coastguard Worker    return any_uint(8)
237*cfb92d14SAndroid Build Coastguard Worker
238*cfb92d14SAndroid Build Coastguard Worker
239*cfb92d14SAndroid Build Coastguard Workerdef any_traffic_class():
240*cfb92d14SAndroid Build Coastguard Worker    return any_uint(8)
241*cfb92d14SAndroid Build Coastguard Worker
242*cfb92d14SAndroid Build Coastguard Worker
243*cfb92d14SAndroid Build Coastguard Workerdef any_flow_label():
244*cfb92d14SAndroid Build Coastguard Worker    return any_uint(20)
245*cfb92d14SAndroid Build Coastguard Worker
246*cfb92d14SAndroid Build Coastguard Worker
247*cfb92d14SAndroid Build Coastguard Workerdef any_hop_limit():
248*cfb92d14SAndroid Build Coastguard Worker    return any_uint(8)
249*cfb92d14SAndroid Build Coastguard Worker
250*cfb92d14SAndroid Build Coastguard Worker
251*cfb92d14SAndroid Build Coastguard Workerdef any_payload_length():
252*cfb92d14SAndroid Build Coastguard Worker    return any_uint(16)
253*cfb92d14SAndroid Build Coastguard Worker
254*cfb92d14SAndroid Build Coastguard Worker
255*cfb92d14SAndroid Build Coastguard Workerdef any_hdr_ext_len():
256*cfb92d14SAndroid Build Coastguard Worker    return any_uint(3)
257*cfb92d14SAndroid Build Coastguard Worker
258*cfb92d14SAndroid Build Coastguard Worker
259*cfb92d14SAndroid Build Coastguard Workerdef any_length():
260*cfb92d14SAndroid Build Coastguard Worker    return any_uint(4)
261*cfb92d14SAndroid Build Coastguard Worker
262*cfb92d14SAndroid Build Coastguard Worker
263*cfb92d14SAndroid Build Coastguard Workerdef any_str(length=8):
264*cfb92d14SAndroid Build Coastguard Worker    s = "".join(random.choice(string.printable) for _ in range(length))
265*cfb92d14SAndroid Build Coastguard Worker    return s.encode("utf-8")
266*cfb92d14SAndroid Build Coastguard Worker
267*cfb92d14SAndroid Build Coastguard Worker
268*cfb92d14SAndroid Build Coastguard Workerdef any_bytes(length=4):
269*cfb92d14SAndroid Build Coastguard Worker    return bytearray(any_str(length))
270*cfb92d14SAndroid Build Coastguard Worker
271*cfb92d14SAndroid Build Coastguard Worker
272*cfb92d14SAndroid Build Coastguard Workerdef any_dict(keys_count=4):
273*cfb92d14SAndroid Build Coastguard Worker    keys = [any_str() for _ in range(keys_count)]
274*cfb92d14SAndroid Build Coastguard Worker
275*cfb92d14SAndroid Build Coastguard Worker    d = {}
276*cfb92d14SAndroid Build Coastguard Worker    for key in keys:
277*cfb92d14SAndroid Build Coastguard Worker        d[key] = any_bytes()
278*cfb92d14SAndroid Build Coastguard Worker
279*cfb92d14SAndroid Build Coastguard Worker    return d
280*cfb92d14SAndroid Build Coastguard Worker
281*cfb92d14SAndroid Build Coastguard Worker
282*cfb92d14SAndroid Build Coastguard Workerdef any_mpl_option():
283*cfb92d14SAndroid Build Coastguard Worker    S = any_mpl_S()
284*cfb92d14SAndroid Build Coastguard Worker    M = any_mpl_M()
285*cfb92d14SAndroid Build Coastguard Worker    V = any_mpl_V()
286*cfb92d14SAndroid Build Coastguard Worker    sequence = any_mpl_sequence()
287*cfb92d14SAndroid Build Coastguard Worker    seed_id = any_mpl_seed_id(S)
288*cfb92d14SAndroid Build Coastguard Worker
289*cfb92d14SAndroid Build Coastguard Worker    return MPLOption(S, M, V, sequence, seed_id)
290*cfb92d14SAndroid Build Coastguard Worker
291*cfb92d14SAndroid Build Coastguard Worker
292*cfb92d14SAndroid Build Coastguard Workerdef any_hop_by_hop_bytes_option_header(length=4):
293*cfb92d14SAndroid Build Coastguard Worker    _type = any_type()
294*cfb92d14SAndroid Build Coastguard Worker
295*cfb92d14SAndroid Build Coastguard Worker    # 0 or 1 means padding, so type have to be higher than 1
296*cfb92d14SAndroid Build Coastguard Worker    while _type <= 1:
297*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
298*cfb92d14SAndroid Build Coastguard Worker
299*cfb92d14SAndroid Build Coastguard Worker    return HopByHopOptionHeader(_type, length)
300*cfb92d14SAndroid Build Coastguard Worker
301*cfb92d14SAndroid Build Coastguard Worker
302*cfb92d14SAndroid Build Coastguard Workerdef any_hop_by_hop_bytes_value(length=2):
303*cfb92d14SAndroid Build Coastguard Worker    return HopByHopOptionBytesValue(any_bytes(length))
304*cfb92d14SAndroid Build Coastguard Worker
305*cfb92d14SAndroid Build Coastguard Worker
306*cfb92d14SAndroid Build Coastguard Workerdef any_hop_by_hop_bytes_option():
307*cfb92d14SAndroid Build Coastguard Worker    length = any_length()
308*cfb92d14SAndroid Build Coastguard Worker    return HopByHopOption(any_hop_by_hop_bytes_option_header(length), any_hop_by_hop_bytes_value(length))
309*cfb92d14SAndroid Build Coastguard Worker
310*cfb92d14SAndroid Build Coastguard Worker
311*cfb92d14SAndroid Build Coastguard Workerdef any_hop_by_hop_mpl_option():
312*cfb92d14SAndroid Build Coastguard Worker    mpl_option = any_mpl_option()
313*cfb92d14SAndroid Build Coastguard Worker    return HopByHopOption(any_hop_by_hop_bytes_option_header(len(mpl_option)), mpl_option)
314*cfb92d14SAndroid Build Coastguard Worker
315*cfb92d14SAndroid Build Coastguard Worker
316*cfb92d14SAndroid Build Coastguard Workerdef any_identifier():
317*cfb92d14SAndroid Build Coastguard Worker    return any_uint(16)
318*cfb92d14SAndroid Build Coastguard Worker
319*cfb92d14SAndroid Build Coastguard Worker
320*cfb92d14SAndroid Build Coastguard Workerdef any_sequence_number():
321*cfb92d14SAndroid Build Coastguard Worker    return any_uint(16)
322*cfb92d14SAndroid Build Coastguard Worker
323*cfb92d14SAndroid Build Coastguard Worker
324*cfb92d14SAndroid Build Coastguard Workerdef any_data():
325*cfb92d14SAndroid Build Coastguard Worker    return any_bytes(random.randint(0, 32))
326*cfb92d14SAndroid Build Coastguard Worker
327*cfb92d14SAndroid Build Coastguard Worker
328*cfb92d14SAndroid Build Coastguard Workerdef any_upper_layer_payload(data, _type):
329*cfb92d14SAndroid Build Coastguard Worker    return DummyUpperLayerProtocol(DummyHeader(), data, _type)
330*cfb92d14SAndroid Build Coastguard Worker
331*cfb92d14SAndroid Build Coastguard Worker
332*cfb92d14SAndroid Build Coastguard Workerdef any_extension_headers():
333*cfb92d14SAndroid Build Coastguard Worker    return []
334*cfb92d14SAndroid Build Coastguard Worker
335*cfb92d14SAndroid Build Coastguard Worker
336*cfb92d14SAndroid Build Coastguard Workerdef any_message_info():
337*cfb92d14SAndroid Build Coastguard Worker    return common.MessageInfo()
338*cfb92d14SAndroid Build Coastguard Worker
339*cfb92d14SAndroid Build Coastguard Worker
340*cfb92d14SAndroid Build Coastguard Workerclass TestIPv6Header(unittest.TestCase):
341*cfb92d14SAndroid Build Coastguard Worker
342*cfb92d14SAndroid Build Coastguard Worker    def test_should_convert_IPv6_header_to_bytes_when_to_bytes_method_is_called(self):
343*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
344*cfb92d14SAndroid Build Coastguard Worker        traffic_class = any_traffic_class()
345*cfb92d14SAndroid Build Coastguard Worker        flow_label = any_flow_label()
346*cfb92d14SAndroid Build Coastguard Worker        payload_length = any_payload_length()
347*cfb92d14SAndroid Build Coastguard Worker        next_header = any_next_header()
348*cfb92d14SAndroid Build Coastguard Worker        hop_limit = any_hop_limit()
349*cfb92d14SAndroid Build Coastguard Worker        source_address = any_ip_address()
350*cfb92d14SAndroid Build Coastguard Worker        destination_address = any_ip_address()
351*cfb92d14SAndroid Build Coastguard Worker
352*cfb92d14SAndroid Build Coastguard Worker        ipv6_header = IPv6Header(source_address, destination_address, traffic_class, flow_label, hop_limit,
353*cfb92d14SAndroid Build Coastguard Worker                                 payload_length, next_header)
354*cfb92d14SAndroid Build Coastguard Worker
355*cfb92d14SAndroid Build Coastguard Worker        # WHEN
356*cfb92d14SAndroid Build Coastguard Worker        data = ipv6_header.to_bytes()
357*cfb92d14SAndroid Build Coastguard Worker
358*cfb92d14SAndroid Build Coastguard Worker        # THEN
359*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(6, data[0] >> 4)
360*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(traffic_class, ((data[0] << 8 | data[1]) >> 4) & 0xff)
361*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(flow_label, ((data[1] & 0x0F) << 16) | (data[2] << 8) | data[3])
362*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(payload_length, struct.unpack("!H", data[4:6])[0])
363*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(next_header, data[6])
364*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(hop_limit, data[7])
365*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(source_address, data[8:24])
366*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(destination_address, data[24:40])
367*cfb92d14SAndroid Build Coastguard Worker
368*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_IPv6Header_when_from_bytes_classmethod_is_called(self):
369*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
370*cfb92d14SAndroid Build Coastguard Worker        traffic_class = any_traffic_class()
371*cfb92d14SAndroid Build Coastguard Worker        flow_label = any_flow_label()
372*cfb92d14SAndroid Build Coastguard Worker        payload_length = any_payload_length()
373*cfb92d14SAndroid Build Coastguard Worker        next_header = any_next_header()
374*cfb92d14SAndroid Build Coastguard Worker        hop_limit = any_hop_limit()
375*cfb92d14SAndroid Build Coastguard Worker        source_address = any_ip_address()
376*cfb92d14SAndroid Build Coastguard Worker        destination_address = any_ip_address()
377*cfb92d14SAndroid Build Coastguard Worker
378*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([(6 << 4) | (traffic_class >> 4), (traffic_class & 0xF) << 4 | (flow_label >> 16) & 0xF,
379*cfb92d14SAndroid Build Coastguard Worker                          (flow_label >> 8) & 0xff, flow_label & 0xff, payload_length >> 8, payload_length & 0xff,
380*cfb92d14SAndroid Build Coastguard Worker                          next_header, hop_limit])
381*cfb92d14SAndroid Build Coastguard Worker        data += ip_address(bytes(source_address)).packed + ip_address(bytes(destination_address)).packed
382*cfb92d14SAndroid Build Coastguard Worker
383*cfb92d14SAndroid Build Coastguard Worker        # WHEN
384*cfb92d14SAndroid Build Coastguard Worker        ipv6_header = IPv6Header.from_bytes(io.BytesIO(data))
385*cfb92d14SAndroid Build Coastguard Worker
386*cfb92d14SAndroid Build Coastguard Worker        # THEN
387*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(6, ipv6_header.version)
388*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(traffic_class, ipv6_header.traffic_class)
389*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(flow_label, ipv6_header.flow_label)
390*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(payload_length, ipv6_header.payload_length)
391*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(next_header, ipv6_header.next_header)
392*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(hop_limit, ipv6_header.hop_limit)
393*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(source_address, ipv6_header.source_address.packed)
394*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(destination_address, ipv6_header.destination_address.packed)
395*cfb92d14SAndroid Build Coastguard Worker
396*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_proper_header_length_when_IPv6Packet_object_is_called_in_len(self):
397*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
398*cfb92d14SAndroid Build Coastguard Worker        ipv6_header = IPv6Header(any_traffic_class(), any_flow_label(), any_payload_length(), any_next_header(),
399*cfb92d14SAndroid Build Coastguard Worker                                 any_hop_limit(), any_ip_address(), any_ip_address())
400*cfb92d14SAndroid Build Coastguard Worker
401*cfb92d14SAndroid Build Coastguard Worker        # WHEN
402*cfb92d14SAndroid Build Coastguard Worker        ipv6_header_length = len(ipv6_header)
403*cfb92d14SAndroid Build Coastguard Worker
404*cfb92d14SAndroid Build Coastguard Worker        # THEN
405*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(40, ipv6_header_length)
406*cfb92d14SAndroid Build Coastguard Worker
407*cfb92d14SAndroid Build Coastguard Worker
408*cfb92d14SAndroid Build Coastguard Workerclass TestUDPHeader(unittest.TestCase):
409*cfb92d14SAndroid Build Coastguard Worker
410*cfb92d14SAndroid Build Coastguard Worker    def test_should_convert_UDP_header_to_bytes_when_to_bytes_method_is_called(self):
411*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
412*cfb92d14SAndroid Build Coastguard Worker        src_port = any_port()
413*cfb92d14SAndroid Build Coastguard Worker        dst_port = any_port()
414*cfb92d14SAndroid Build Coastguard Worker        payload_length = any_payload_length()
415*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
416*cfb92d14SAndroid Build Coastguard Worker
417*cfb92d14SAndroid Build Coastguard Worker        udp_header = UDPHeader(src_port, dst_port, payload_length, checksum)
418*cfb92d14SAndroid Build Coastguard Worker
419*cfb92d14SAndroid Build Coastguard Worker        # WHEN
420*cfb92d14SAndroid Build Coastguard Worker        data = udp_header.to_bytes()
421*cfb92d14SAndroid Build Coastguard Worker
422*cfb92d14SAndroid Build Coastguard Worker        # THEN
423*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(src_port, struct.unpack("!H", data[0:2])[0])
424*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(dst_port, struct.unpack("!H", data[2:4])[0])
425*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(payload_length, struct.unpack("!H", data[4:6])[0])
426*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(checksum, struct.unpack("!H", data[6:])[0])
427*cfb92d14SAndroid Build Coastguard Worker
428*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_UDPHeader_when_from_bytes_classmethod_is_called(self):
429*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
430*cfb92d14SAndroid Build Coastguard Worker        src_port = any_port()
431*cfb92d14SAndroid Build Coastguard Worker        dst_port = any_port()
432*cfb92d14SAndroid Build Coastguard Worker        payload_length = any_payload_length()
433*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
434*cfb92d14SAndroid Build Coastguard Worker
435*cfb92d14SAndroid Build Coastguard Worker        data = struct.pack("!H", src_port) + struct.pack("!H", dst_port) + \
436*cfb92d14SAndroid Build Coastguard Worker            struct.pack("!H", payload_length) + struct.pack("!H", checksum)
437*cfb92d14SAndroid Build Coastguard Worker
438*cfb92d14SAndroid Build Coastguard Worker        # WHEN
439*cfb92d14SAndroid Build Coastguard Worker        udp_header = UDPHeader.from_bytes(io.BytesIO(data))
440*cfb92d14SAndroid Build Coastguard Worker
441*cfb92d14SAndroid Build Coastguard Worker        # THEN
442*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(src_port, udp_header.src_port)
443*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(dst_port, udp_header.dst_port)
444*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(payload_length, udp_header.payload_length)
445*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(checksum, udp_header.checksum)
446*cfb92d14SAndroid Build Coastguard Worker
447*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_proper_header_length_when_UDPHeader_object_is_called_in_len(self):
448*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
449*cfb92d14SAndroid Build Coastguard Worker        udp_header = UDPHeader(any_port(), any_port(), any_payload_length(), any_checksum())
450*cfb92d14SAndroid Build Coastguard Worker
451*cfb92d14SAndroid Build Coastguard Worker        # WHEN
452*cfb92d14SAndroid Build Coastguard Worker        udp_header_length = len(udp_header)
453*cfb92d14SAndroid Build Coastguard Worker
454*cfb92d14SAndroid Build Coastguard Worker        # THEN
455*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(8, udp_header_length)
456*cfb92d14SAndroid Build Coastguard Worker
457*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_17_when_type_property_is_called(self):
458*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
459*cfb92d14SAndroid Build Coastguard Worker        udp_header = UDPHeader(any_port(), any_port(), any_payload_length(), any_checksum())
460*cfb92d14SAndroid Build Coastguard Worker
461*cfb92d14SAndroid Build Coastguard Worker        # THEN
462*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(17, udp_header.type)
463*cfb92d14SAndroid Build Coastguard Worker
464*cfb92d14SAndroid Build Coastguard Worker
465*cfb92d14SAndroid Build Coastguard Workerclass TestICMPv6Header(unittest.TestCase):
466*cfb92d14SAndroid Build Coastguard Worker
467*cfb92d14SAndroid Build Coastguard Worker    def test_should_convert_icmp_message_header_to_bytes_when_to_bytes_method_is_called(self):
468*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
469*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
470*cfb92d14SAndroid Build Coastguard Worker        code = any_code()
471*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
472*cfb92d14SAndroid Build Coastguard Worker
473*cfb92d14SAndroid Build Coastguard Worker        icmpv6_header = ICMPv6Header(_type, code, checksum)
474*cfb92d14SAndroid Build Coastguard Worker
475*cfb92d14SAndroid Build Coastguard Worker        # WHEN
476*cfb92d14SAndroid Build Coastguard Worker        data = icmpv6_header.to_bytes()
477*cfb92d14SAndroid Build Coastguard Worker
478*cfb92d14SAndroid Build Coastguard Worker        # THEN
479*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(_type, data[0])
480*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(code, data[1])
481*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(checksum, struct.unpack("!H", data[2:])[0])
482*cfb92d14SAndroid Build Coastguard Worker
483*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_ICMPv6Header_when_to_bytes_classmethod_is_called(self):
484*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
485*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
486*cfb92d14SAndroid Build Coastguard Worker        code = any_code()
487*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
488*cfb92d14SAndroid Build Coastguard Worker
489*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([_type, code]) + struct.pack("!H", checksum)
490*cfb92d14SAndroid Build Coastguard Worker
491*cfb92d14SAndroid Build Coastguard Worker        # WHEN
492*cfb92d14SAndroid Build Coastguard Worker        icmpv6_header = ICMPv6Header.from_bytes(io.BytesIO(data))
493*cfb92d14SAndroid Build Coastguard Worker
494*cfb92d14SAndroid Build Coastguard Worker        # THEN
495*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(_type, icmpv6_header.type)
496*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(code, icmpv6_header.code)
497*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(checksum, icmpv6_header.checksum)
498*cfb92d14SAndroid Build Coastguard Worker
499*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_proper_header_length_when_ICMPv6Header_object_is_called_in_len(self):
500*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
501*cfb92d14SAndroid Build Coastguard Worker        icmpv6_header = ICMPv6Header(any_type(), any_code(), any_checksum())
502*cfb92d14SAndroid Build Coastguard Worker
503*cfb92d14SAndroid Build Coastguard Worker        # WHEN
504*cfb92d14SAndroid Build Coastguard Worker        icmpv6_header_length = len(icmpv6_header)
505*cfb92d14SAndroid Build Coastguard Worker
506*cfb92d14SAndroid Build Coastguard Worker        # THEN
507*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(4, icmpv6_header_length)
508*cfb92d14SAndroid Build Coastguard Worker
509*cfb92d14SAndroid Build Coastguard Worker
510*cfb92d14SAndroid Build Coastguard Workerclass TestIPv6Packet(unittest.TestCase):
511*cfb92d14SAndroid Build Coastguard Worker
512*cfb92d14SAndroid Build Coastguard Worker    def test_should_build_IPv6Packet_with_ICMP_payload_from_well_know_values_when_to_bytes_method_is_called(self):
513*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
514*cfb92d14SAndroid Build Coastguard Worker
515*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet = IPv6Packet(
516*cfb92d14SAndroid Build Coastguard Worker            IPv6Header(source_address="fd00:1234:4555::ff:fe00:1800", destination_address="ff03::1"),
517*cfb92d14SAndroid Build Coastguard Worker            ICMPv6(
518*cfb92d14SAndroid Build Coastguard Worker                ICMPv6Header(128, 0),
519*cfb92d14SAndroid Build Coastguard Worker                ICMPv6EchoBody(
520*cfb92d14SAndroid Build Coastguard Worker                    0, 2,
521*cfb92d14SAndroid Build Coastguard Worker                    bytearray([
522*cfb92d14SAndroid Build Coastguard Worker                        0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
523*cfb92d14SAndroid Build Coastguard Worker                        0x41, 0x41
524*cfb92d14SAndroid Build Coastguard Worker                    ]))), [
525*cfb92d14SAndroid Build Coastguard Worker                        HopByHop(options=[
526*cfb92d14SAndroid Build Coastguard Worker                            HopByHopOption(HopByHopOptionHeader(
527*cfb92d14SAndroid Build Coastguard Worker                                _type=0x6d), MPLOption(S=1, M=0, V=0, sequence=2, seed_id=bytearray([0x00, 0x18])))
528*cfb92d14SAndroid Build Coastguard Worker                        ])
529*cfb92d14SAndroid Build Coastguard Worker                    ])
530*cfb92d14SAndroid Build Coastguard Worker
531*cfb92d14SAndroid Build Coastguard Worker        # WHEN
532*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet_bytes = ipv6_packet.to_bytes()
533*cfb92d14SAndroid Build Coastguard Worker
534*cfb92d14SAndroid Build Coastguard Worker        # THEN
535*cfb92d14SAndroid Build Coastguard Worker        expected_ipv6_packet_bytes = bytearray([
536*cfb92d14SAndroid Build Coastguard Worker            0x60, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40, 0xfd, 0x00, 0x12, 0x34, 0x45, 0x55, 0x00, 0x00, 0x00, 0x00,
537*cfb92d14SAndroid Build Coastguard Worker            0x00, 0xff, 0xfe, 0x00, 0x18, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18, 0x80, 0x00, 0x87, 0x12, 0x00, 0x00,
539*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
540*cfb92d14SAndroid Build Coastguard Worker            0x41, 0x41
541*cfb92d14SAndroid Build Coastguard Worker        ])
542*cfb92d14SAndroid Build Coastguard Worker
543*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_ipv6_packet_bytes, ipv6_packet_bytes)
544*cfb92d14SAndroid Build Coastguard Worker
545*cfb92d14SAndroid Build Coastguard Worker    def test_should_build_IPv6Packet_with_UDP_payload_from_well_know_values_when_to_bytes_method_is_called(self):
546*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
547*cfb92d14SAndroid Build Coastguard Worker        ipv6_header = IPv6Header(source_address="fe80::1", destination_address="ff02::2", hop_limit=255)
548*cfb92d14SAndroid Build Coastguard Worker
549*cfb92d14SAndroid Build Coastguard Worker        udp_dgram = UDPDatagram(
550*cfb92d14SAndroid Build Coastguard Worker            UDPHeader(src_port=19788, dst_port=19788),
551*cfb92d14SAndroid Build Coastguard Worker            BytesPayload(
552*cfb92d14SAndroid Build Coastguard Worker                bytearray([
553*cfb92d14SAndroid Build Coastguard Worker                    0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x01, 0x01, 0x0b, 0x03,
554*cfb92d14SAndroid Build Coastguard Worker                    0x04, 0xc6, 0x69, 0x73, 0x51, 0x0e, 0x01, 0x80, 0x12, 0x02, 0x00, 0x01, 0xde, 0xad, 0xbe, 0xef
555*cfb92d14SAndroid Build Coastguard Worker                ])))
556*cfb92d14SAndroid Build Coastguard Worker
557*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet = IPv6Packet(ipv6_header, udp_dgram)
558*cfb92d14SAndroid Build Coastguard Worker
559*cfb92d14SAndroid Build Coastguard Worker        # WHEN
560*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet_bytes = ipv6_packet.to_bytes()
561*cfb92d14SAndroid Build Coastguard Worker
562*cfb92d14SAndroid Build Coastguard Worker        # THEN
563*cfb92d14SAndroid Build Coastguard Worker        expected_ipv6_packet_bytes = bytearray([
564*cfb92d14SAndroid Build Coastguard Worker            0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x11, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x00, 0x00, 0x02, 0x4d, 0x4c, 0x4d, 0x4c, 0x00, 0x28, 0xe9, 0xf4, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00,
567*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x01, 0x01, 0x0b, 0x03, 0x04, 0xc6, 0x69, 0x73, 0x51, 0x0e, 0x01, 0x80,
568*cfb92d14SAndroid Build Coastguard Worker            0x12, 0x02, 0x00, 0x01, 0xde, 0xad, 0xbe, 0xef
569*cfb92d14SAndroid Build Coastguard Worker        ])
570*cfb92d14SAndroid Build Coastguard Worker
571*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_ipv6_packet_bytes, ipv6_packet_bytes)
572*cfb92d14SAndroid Build Coastguard Worker
573*cfb92d14SAndroid Build Coastguard Worker
574*cfb92d14SAndroid Build Coastguard Workerclass TestIPv6PacketFactory(unittest.TestCase):
575*cfb92d14SAndroid Build Coastguard Worker
576*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_IPv6Packet_with_MPL_and_ICMP_when_to_bytes_method_is_called(self):
577*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
578*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet_bytes = bytearray([
579*cfb92d14SAndroid Build Coastguard Worker            0x60, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40, 0xfd, 0x00, 0x12, 0x34, 0x45, 0x55, 0x00, 0x00, 0x00, 0x00,
580*cfb92d14SAndroid Build Coastguard Worker            0x00, 0xff, 0xfe, 0x00, 0x18, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x6d, 0x04, 0x40, 0x02, 0x00, 0x18, 0x80, 0x00, 0x87, 0x12, 0x00, 0x00,
582*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
583*cfb92d14SAndroid Build Coastguard Worker            0x41, 0x41
584*cfb92d14SAndroid Build Coastguard Worker        ])
585*cfb92d14SAndroid Build Coastguard Worker
586*cfb92d14SAndroid Build Coastguard Worker        ipv6_factory = IPv6PacketFactory(ehf={
587*cfb92d14SAndroid Build Coastguard Worker            0:
588*cfb92d14SAndroid Build Coastguard Worker                HopByHopFactory(hop_by_hop_options_factory=HopByHopOptionsFactory(
589*cfb92d14SAndroid Build Coastguard Worker                    options_factories={109: MPLOptionFactory()}))
590*cfb92d14SAndroid Build Coastguard Worker        },
591*cfb92d14SAndroid Build Coastguard Worker                                         ulpf={58: ICMPv6Factory(body_factories={128: ICMPv6EchoBodyFactory()})})
592*cfb92d14SAndroid Build Coastguard Worker
593*cfb92d14SAndroid Build Coastguard Worker        # WHEN
594*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet = ipv6_factory.parse(io.BytesIO(ipv6_packet_bytes), any_message_info())
595*cfb92d14SAndroid Build Coastguard Worker
596*cfb92d14SAndroid Build Coastguard Worker        # THEN
597*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual('fd00:1234:4555::ff:fe00:1800', ipv6_packet.ipv6_header.source_address.compressed)
598*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual('ff03::1', ipv6_packet.ipv6_header.destination_address.compressed)
599*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(64, ipv6_packet.ipv6_header.hop_limit)
600*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.ipv6_header.next_header)
601*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(34, ipv6_packet.ipv6_header.payload_length)
602*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.ipv6_header.flow_label)
603*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.ipv6_header.traffic_class)
604*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(6, ipv6_packet.ipv6_header.version)
605*cfb92d14SAndroid Build Coastguard Worker
606*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(1, ipv6_packet.extension_headers[0].options[0].value.S)
607*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.extension_headers[0].options[0].value.M)
608*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.extension_headers[0].options[0].value.V)
609*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(2, ipv6_packet.extension_headers[0].options[0].value.sequence)
610*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(bytearray([0x00, 0x18]), ipv6_packet.extension_headers[0].options[0].value.seed_id)
611*cfb92d14SAndroid Build Coastguard Worker
612*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(34578, ipv6_packet.upper_layer_protocol.header.checksum)
613*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(128, ipv6_packet.upper_layer_protocol.header.type)
614*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.upper_layer_protocol.header.code)
615*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.upper_layer_protocol.body.identifier)
616*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(2, ipv6_packet.upper_layer_protocol.body.sequence_number)
617*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(b'\x80\x00\xc7\xbf\x00\x00\x00\x01AAAAAAAAAA', ipv6_packet.upper_layer_protocol.body.data)
618*cfb92d14SAndroid Build Coastguard Worker
619*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_IPv6Packet_without_any_extension_header_with_ICMP_when_to_bytes_method_is_called(self):
620*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
621*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet_bytes = bytearray([
622*cfb92d14SAndroid Build Coastguard Worker            0x60, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x3A, 0x40, 0xfd, 0x00, 0x12, 0x34, 0x45, 0x55, 0x00, 0x00, 0x00, 0x00,
623*cfb92d14SAndroid Build Coastguard Worker            0x00, 0xff, 0xfe, 0x00, 0x18, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00,
625*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
626*cfb92d14SAndroid Build Coastguard Worker        ])
627*cfb92d14SAndroid Build Coastguard Worker
628*cfb92d14SAndroid Build Coastguard Worker        ipv6_factory = IPv6PacketFactory(ulpf={58: ICMPv6Factory(body_factories={128: ICMPv6EchoBodyFactory()})})
629*cfb92d14SAndroid Build Coastguard Worker
630*cfb92d14SAndroid Build Coastguard Worker        # WHEN
631*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet = ipv6_factory.parse(io.BytesIO(ipv6_packet_bytes), any_message_info())
632*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet._validate_checksum()
633*cfb92d14SAndroid Build Coastguard Worker
634*cfb92d14SAndroid Build Coastguard Worker        # THEN
635*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual('fd00:1234:4555::ff:fe00:1800', ipv6_packet.ipv6_header.source_address.compressed)
636*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual('ff03::1', ipv6_packet.ipv6_header.destination_address.compressed)
637*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(64, ipv6_packet.ipv6_header.hop_limit)
638*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(58, ipv6_packet.ipv6_header.next_header)
639*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(26, ipv6_packet.ipv6_header.payload_length)
640*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.ipv6_header.flow_label)
641*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.ipv6_header.traffic_class)
642*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(6, ipv6_packet.ipv6_header.version)
643*cfb92d14SAndroid Build Coastguard Worker
644*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(34578, ipv6_packet.upper_layer_protocol.header.checksum)
645*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(128, ipv6_packet.upper_layer_protocol.header.type)
646*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.upper_layer_protocol.header.code)
647*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, ipv6_packet.upper_layer_protocol.body.identifier)
648*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(2, ipv6_packet.upper_layer_protocol.body.sequence_number)
649*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(b'\x80\x00\xc7\xbf\x00\x00\x00\x01AAAAAAAAAA', ipv6_packet.upper_layer_protocol.body.data)
650*cfb92d14SAndroid Build Coastguard Worker
651*cfb92d14SAndroid Build Coastguard Worker    def test_should_set_message_info_field_when_to_bytes_method_is_called(self):
652*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
653*cfb92d14SAndroid Build Coastguard Worker        ipv6_packet_data = bytearray([
654*cfb92d14SAndroid Build Coastguard Worker            0x60, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x3A, 0x40, 0xfd, 0x00, 0x12, 0x34, 0x45, 0x55, 0x00, 0x00, 0x00, 0x00,
655*cfb92d14SAndroid Build Coastguard Worker            0x00, 0xff, 0xfe, 0x00, 0x18, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00,
657*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
658*cfb92d14SAndroid Build Coastguard Worker        ])
659*cfb92d14SAndroid Build Coastguard Worker
660*cfb92d14SAndroid Build Coastguard Worker        message_info = any_message_info()
661*cfb92d14SAndroid Build Coastguard Worker        message_info.source_ipv6 = "ff::"
662*cfb92d14SAndroid Build Coastguard Worker        message_info.destination_address = "ff::"
663*cfb92d14SAndroid Build Coastguard Worker
664*cfb92d14SAndroid Build Coastguard Worker        factory = IPv6PacketFactory(ulpf={58: ICMPv6Factory(body_factories={128: ICMPv6EchoBodyFactory()})})
665*cfb92d14SAndroid Build Coastguard Worker
666*cfb92d14SAndroid Build Coastguard Worker        # WHEN
667*cfb92d14SAndroid Build Coastguard Worker        factory.parse(io.BytesIO(ipv6_packet_data), message_info)
668*cfb92d14SAndroid Build Coastguard Worker
669*cfb92d14SAndroid Build Coastguard Worker        # THEN
670*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual("fd00:1234:4555::ff:fe00:1800", message_info.source_ipv6.compressed)
671*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual("ff03::1", message_info.destination_ipv6.compressed)
672*cfb92d14SAndroid Build Coastguard Worker
673*cfb92d14SAndroid Build Coastguard Worker
674*cfb92d14SAndroid Build Coastguard Workerclass TestUDPDatagram(unittest.TestCase):
675*cfb92d14SAndroid Build Coastguard Worker
676*cfb92d14SAndroid Build Coastguard Worker    def test_should_creates_bytes_from_UDPHeader_and_payload_when_to_bytes_method_is_called(self):
677*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
678*cfb92d14SAndroid Build Coastguard Worker        src_port = any_port()
679*cfb92d14SAndroid Build Coastguard Worker        dst_port = any_port()
680*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
681*cfb92d14SAndroid Build Coastguard Worker
682*cfb92d14SAndroid Build Coastguard Worker        payload = any_payload()
683*cfb92d14SAndroid Build Coastguard Worker        payload_length = len(payload) + 8  # UDP length consists of UDP header length and payload length
684*cfb92d14SAndroid Build Coastguard Worker
685*cfb92d14SAndroid Build Coastguard Worker        udp_header = UDPHeader(src_port, dst_port, payload_length, checksum)
686*cfb92d14SAndroid Build Coastguard Worker        udp_payload = BytesPayload(payload)
687*cfb92d14SAndroid Build Coastguard Worker        udp_dgram = UDPDatagram(udp_header, udp_payload)
688*cfb92d14SAndroid Build Coastguard Worker
689*cfb92d14SAndroid Build Coastguard Worker        # WHEN
690*cfb92d14SAndroid Build Coastguard Worker        udp_dgram_bytes = udp_dgram.to_bytes()
691*cfb92d14SAndroid Build Coastguard Worker
692*cfb92d14SAndroid Build Coastguard Worker        # THEN
693*cfb92d14SAndroid Build Coastguard Worker        expected_udp_dgram_bytes = struct.pack("!H", src_port) + struct.pack("!H", dst_port) + \
694*cfb92d14SAndroid Build Coastguard Worker            struct.pack("!H", payload_length) + struct.pack("!H", checksum) + payload
695*cfb92d14SAndroid Build Coastguard Worker
696*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_udp_dgram_bytes, udp_dgram_bytes)
697*cfb92d14SAndroid Build Coastguard Worker
698*cfb92d14SAndroid Build Coastguard Worker
699*cfb92d14SAndroid Build Coastguard Workerclass TestIPv6FragmentHeader(unittest.TestCase):
700*cfb92d14SAndroid Build Coastguard Worker
701*cfb92d14SAndroid Build Coastguard Worker    def test_shold_convert_IPv6_fragment_header_to_bytes_when_to_bytes_method_is_called(self):
702*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
703*cfb92d14SAndroid Build Coastguard Worker        type = any_type()
704*cfb92d14SAndroid Build Coastguard Worker        offset = any_fragment_offset()
705*cfb92d14SAndroid Build Coastguard Worker        more_flag = any_bool()
706*cfb92d14SAndroid Build Coastguard Worker        identification = any_fragment_identification()
707*cfb92d14SAndroid Build Coastguard Worker
708*cfb92d14SAndroid Build Coastguard Worker        ipv6_fragment_header = FragmentHeader(type, offset, more_flag, identification)
709*cfb92d14SAndroid Build Coastguard Worker
710*cfb92d14SAndroid Build Coastguard Worker        # WHEN
711*cfb92d14SAndroid Build Coastguard Worker        actual = ipv6_fragment_header.to_bytes()
712*cfb92d14SAndroid Build Coastguard Worker
713*cfb92d14SAndroid Build Coastguard Worker        # THEN
714*cfb92d14SAndroid Build Coastguard Worker        expected = bytearray([type, 0x00, offset >> 5, ((offset << 3) & 0xff) | more_flag])\
715*cfb92d14SAndroid Build Coastguard Worker            + struct.pack("!I", identification)
716*cfb92d14SAndroid Build Coastguard Worker
717*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected, actual)
718*cfb92d14SAndroid Build Coastguard Worker
719*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_FragmentHeader_when_from_bytes_classmethod_is_called(self):
720*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
721*cfb92d14SAndroid Build Coastguard Worker        type = any_type()
722*cfb92d14SAndroid Build Coastguard Worker        offset = any_fragment_offset()
723*cfb92d14SAndroid Build Coastguard Worker        more_flag = any_bool()
724*cfb92d14SAndroid Build Coastguard Worker        identification = any_fragment_identification()
725*cfb92d14SAndroid Build Coastguard Worker
726*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([type, 0x00, offset >> 5, ((offset << 3) & 0xff) | more_flag])\
727*cfb92d14SAndroid Build Coastguard Worker            + struct.pack("!I", identification)
728*cfb92d14SAndroid Build Coastguard Worker
729*cfb92d14SAndroid Build Coastguard Worker        # WHEN
730*cfb92d14SAndroid Build Coastguard Worker        ipv6_fragment_header = FragmentHeader.from_bytes(io.BytesIO(data))
731*cfb92d14SAndroid Build Coastguard Worker
732*cfb92d14SAndroid Build Coastguard Worker        # THEN
733*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(type, ipv6_fragment_header.next_header)
734*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(offset, ipv6_fragment_header.offset)
735*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(more_flag, ipv6_fragment_header.more_flag)
736*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(identification, ipv6_fragment_header.identification)
737*cfb92d14SAndroid Build Coastguard Worker
738*cfb92d14SAndroid Build Coastguard Worker
739*cfb92d14SAndroid Build Coastguard Workerclass TestICMPv6(unittest.TestCase):
740*cfb92d14SAndroid Build Coastguard Worker
741*cfb92d14SAndroid Build Coastguard Worker    def test_should_creates_bytes_from_ICMPv6Header_and_body_when_to_bytes_method_is_called(self):
742*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
743*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
744*cfb92d14SAndroid Build Coastguard Worker        code = any_code()
745*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
746*cfb92d14SAndroid Build Coastguard Worker        body = any_body()
747*cfb92d14SAndroid Build Coastguard Worker
748*cfb92d14SAndroid Build Coastguard Worker        icmpv6_header = ICMPv6Header(_type, code, checksum)
749*cfb92d14SAndroid Build Coastguard Worker        icmpv6_body = ICMPv6BytesBody(body)
750*cfb92d14SAndroid Build Coastguard Worker        icmpv6_msg = ICMPv6(icmpv6_header, icmpv6_body)
751*cfb92d14SAndroid Build Coastguard Worker
752*cfb92d14SAndroid Build Coastguard Worker        # WHEN
753*cfb92d14SAndroid Build Coastguard Worker        actual = icmpv6_msg.to_bytes()
754*cfb92d14SAndroid Build Coastguard Worker
755*cfb92d14SAndroid Build Coastguard Worker        # THEN
756*cfb92d14SAndroid Build Coastguard Worker        expected = bytearray([_type, code]) + struct.pack("!H", checksum) + body
757*cfb92d14SAndroid Build Coastguard Worker
758*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected, actual)
759*cfb92d14SAndroid Build Coastguard Worker
760*cfb92d14SAndroid Build Coastguard Worker
761*cfb92d14SAndroid Build Coastguard Workerclass TestHopByHop(unittest.TestCase):
762*cfb92d14SAndroid Build Coastguard Worker
763*cfb92d14SAndroid Build Coastguard Worker    def _calculate_hdr_ext_len(self, payload_len):
764*cfb92d14SAndroid Build Coastguard Worker        count = payload_len // 8
765*cfb92d14SAndroid Build Coastguard Worker        rest = payload_len % 8
766*cfb92d14SAndroid Build Coastguard Worker
767*cfb92d14SAndroid Build Coastguard Worker        if rest != 0:
768*cfb92d14SAndroid Build Coastguard Worker            count += 1
769*cfb92d14SAndroid Build Coastguard Worker
770*cfb92d14SAndroid Build Coastguard Worker        if count == 0 and rest == 0:
771*cfb92d14SAndroid Build Coastguard Worker            return count
772*cfb92d14SAndroid Build Coastguard Worker
773*cfb92d14SAndroid Build Coastguard Worker        return count - 1
774*cfb92d14SAndroid Build Coastguard Worker
775*cfb92d14SAndroid Build Coastguard Worker    def _calculate_required_padding(self, content_length):
776*cfb92d14SAndroid Build Coastguard Worker        excess_bytes = content_length & 0x7
777*cfb92d14SAndroid Build Coastguard Worker
778*cfb92d14SAndroid Build Coastguard Worker        if excess_bytes > 0:
779*cfb92d14SAndroid Build Coastguard Worker            return 8 - excess_bytes
780*cfb92d14SAndroid Build Coastguard Worker
781*cfb92d14SAndroid Build Coastguard Worker        return 0
782*cfb92d14SAndroid Build Coastguard Worker
783*cfb92d14SAndroid Build Coastguard Worker    def create_padding(self, padding_length):
784*cfb92d14SAndroid Build Coastguard Worker        if padding_length == 1:
785*cfb92d14SAndroid Build Coastguard Worker            return bytearray([0x00])
786*cfb92d14SAndroid Build Coastguard Worker        elif padding_length > 1:
787*cfb92d14SAndroid Build Coastguard Worker            padding_length -= 2
788*cfb92d14SAndroid Build Coastguard Worker            return bytearray([0x01, padding_length]) + bytearray([0x00 for _ in range(padding_length)])
789*cfb92d14SAndroid Build Coastguard Worker        else:
790*cfb92d14SAndroid Build Coastguard Worker            return bytearray()
791*cfb92d14SAndroid Build Coastguard Worker
792*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_bytes_from_HopByHop_when_to_bytes_method_is_called(self):
793*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
794*cfb92d14SAndroid Build Coastguard Worker        next_header = any_next_header()
795*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_option = any_hop_by_hop_bytes_option()
796*cfb92d14SAndroid Build Coastguard Worker        hdr_ext_len = self._calculate_hdr_ext_len(2 + len(hop_by_hop_option))
797*cfb92d14SAndroid Build Coastguard Worker
798*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop = HopByHop(next_header, [hop_by_hop_option])
799*cfb92d14SAndroid Build Coastguard Worker
800*cfb92d14SAndroid Build Coastguard Worker        # WHEN
801*cfb92d14SAndroid Build Coastguard Worker        data = hop_by_hop.to_bytes()
802*cfb92d14SAndroid Build Coastguard Worker
803*cfb92d14SAndroid Build Coastguard Worker        # THEN
804*cfb92d14SAndroid Build Coastguard Worker        expected_data = bytearray([next_header, hdr_ext_len]) + hop_by_hop_option.to_bytes()
805*cfb92d14SAndroid Build Coastguard Worker        padding_length = self._calculate_required_padding(len(expected_data))
806*cfb92d14SAndroid Build Coastguard Worker        expected_data += self.create_padding(padding_length)
807*cfb92d14SAndroid Build Coastguard Worker
808*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_data, data)
809*cfb92d14SAndroid Build Coastguard Worker
810*cfb92d14SAndroid Build Coastguard Worker
811*cfb92d14SAndroid Build Coastguard Workerclass TestMPLOption(unittest.TestCase):
812*cfb92d14SAndroid Build Coastguard Worker
813*cfb92d14SAndroid Build Coastguard Worker    def test_should_convert_MPLOption_to_bytes_when_to_bytes_method_is_called(self):
814*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
815*cfb92d14SAndroid Build Coastguard Worker        S = any_mpl_S()
816*cfb92d14SAndroid Build Coastguard Worker        M = any_mpl_M()
817*cfb92d14SAndroid Build Coastguard Worker        V = any_mpl_V()
818*cfb92d14SAndroid Build Coastguard Worker        sequence = any_mpl_sequence()
819*cfb92d14SAndroid Build Coastguard Worker        seed_id = any_mpl_seed_id(S)
820*cfb92d14SAndroid Build Coastguard Worker
821*cfb92d14SAndroid Build Coastguard Worker        mpl_option = MPLOption(S, M, V, sequence, seed_id)
822*cfb92d14SAndroid Build Coastguard Worker
823*cfb92d14SAndroid Build Coastguard Worker        # WHEN
824*cfb92d14SAndroid Build Coastguard Worker        data = mpl_option.to_bytes()
825*cfb92d14SAndroid Build Coastguard Worker
826*cfb92d14SAndroid Build Coastguard Worker        # THEN
827*cfb92d14SAndroid Build Coastguard Worker        expected_data = bytearray([(S << 6) | (M << 5) | (V << 4), sequence]) + seed_id
828*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_data, data)
829*cfb92d14SAndroid Build Coastguard Worker
830*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_MPLOption_when_to_bytes_method_is_called_with_data(self):
831*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
832*cfb92d14SAndroid Build Coastguard Worker        S = any_mpl_S()
833*cfb92d14SAndroid Build Coastguard Worker        M = any_mpl_M()
834*cfb92d14SAndroid Build Coastguard Worker        V = any_mpl_V()
835*cfb92d14SAndroid Build Coastguard Worker        sequence = any_mpl_sequence()
836*cfb92d14SAndroid Build Coastguard Worker        seed_id = any_mpl_seed_id(S)
837*cfb92d14SAndroid Build Coastguard Worker
838*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([(S << 6) | (M << 5) | (V << 4), sequence]) + seed_id
839*cfb92d14SAndroid Build Coastguard Worker
840*cfb92d14SAndroid Build Coastguard Worker        # WHEN
841*cfb92d14SAndroid Build Coastguard Worker        mpl_option = MPLOption.from_bytes(io.BytesIO(data))
842*cfb92d14SAndroid Build Coastguard Worker
843*cfb92d14SAndroid Build Coastguard Worker        # THEN
844*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(S, mpl_option.S)
845*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(M, mpl_option.M)
846*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(V, mpl_option.V)
847*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(sequence, mpl_option.sequence)
848*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(seed_id, mpl_option.seed_id)
849*cfb92d14SAndroid Build Coastguard Worker
850*cfb92d14SAndroid Build Coastguard Worker    def test_check_if_mpl_seed_id_length_values_was_not_changed(self):
851*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(0, MPLOption._seed_id_length[0])
852*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(2, MPLOption._seed_id_length[1])
853*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(8, MPLOption._seed_id_length[2])
854*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(16, MPLOption._seed_id_length[3])
855*cfb92d14SAndroid Build Coastguard Worker
856*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_proper_length_when_len_is_called_with_mpl_option_object(self):
857*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
858*cfb92d14SAndroid Build Coastguard Worker        S = any_mpl_S()
859*cfb92d14SAndroid Build Coastguard Worker        M = any_mpl_M()
860*cfb92d14SAndroid Build Coastguard Worker        V = any_mpl_V()
861*cfb92d14SAndroid Build Coastguard Worker        sequence = any_mpl_sequence()
862*cfb92d14SAndroid Build Coastguard Worker        seed_id = any_mpl_seed_id(S)
863*cfb92d14SAndroid Build Coastguard Worker
864*cfb92d14SAndroid Build Coastguard Worker        mpl_option = MPLOption(S, M, V, sequence, seed_id)
865*cfb92d14SAndroid Build Coastguard Worker
866*cfb92d14SAndroid Build Coastguard Worker        # WHEN
867*cfb92d14SAndroid Build Coastguard Worker        mpl_option_length = len(mpl_option)
868*cfb92d14SAndroid Build Coastguard Worker
869*cfb92d14SAndroid Build Coastguard Worker        # THEN
870*cfb92d14SAndroid Build Coastguard Worker        SMV_and_sequence_length = 2
871*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(SMV_and_sequence_length + len(seed_id), mpl_option_length)
872*cfb92d14SAndroid Build Coastguard Worker
873*cfb92d14SAndroid Build Coastguard Worker
874*cfb92d14SAndroid Build Coastguard Workerclass TestclassHopByHopOption(unittest.TestCase):
875*cfb92d14SAndroid Build Coastguard Worker
876*cfb92d14SAndroid Build Coastguard Worker    def test_should_convert_HopByHopOption_to_bytes_when_to_bytes_method_is_called(self):
877*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
878*cfb92d14SAndroid Build Coastguard Worker        length = any_length()
879*cfb92d14SAndroid Build Coastguard Worker        header = any_hop_by_hop_bytes_option_header(length)
880*cfb92d14SAndroid Build Coastguard Worker        value = any_hop_by_hop_bytes_value(length)
881*cfb92d14SAndroid Build Coastguard Worker
882*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_option = HopByHopOption(header, value)
883*cfb92d14SAndroid Build Coastguard Worker
884*cfb92d14SAndroid Build Coastguard Worker        # WHEN
885*cfb92d14SAndroid Build Coastguard Worker        data = hop_by_hop_option.to_bytes()
886*cfb92d14SAndroid Build Coastguard Worker
887*cfb92d14SAndroid Build Coastguard Worker        # THEN
888*cfb92d14SAndroid Build Coastguard Worker        expected_data = header.to_bytes() + value.to_bytes()
889*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_data, data)
890*cfb92d14SAndroid Build Coastguard Worker
891*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_length_of_HopByHopOption_when_len_is_called_with_hop_by_hop_option_object(self):
892*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
893*cfb92d14SAndroid Build Coastguard Worker        length = any_length()
894*cfb92d14SAndroid Build Coastguard Worker        header = any_hop_by_hop_bytes_option_header(length)
895*cfb92d14SAndroid Build Coastguard Worker        value = any_hop_by_hop_bytes_value(length)
896*cfb92d14SAndroid Build Coastguard Worker
897*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_option = HopByHopOption(header, value)
898*cfb92d14SAndroid Build Coastguard Worker
899*cfb92d14SAndroid Build Coastguard Worker        # WHEN
900*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_option_length = len(hop_by_hop_option)
901*cfb92d14SAndroid Build Coastguard Worker
902*cfb92d14SAndroid Build Coastguard Worker        # THEN
903*cfb92d14SAndroid Build Coastguard Worker        header_length = 2
904*cfb92d14SAndroid Build Coastguard Worker        expected_hop_by_hop_option_length = header_length + length
905*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_hop_by_hop_option_length, hop_by_hop_option_length)
906*cfb92d14SAndroid Build Coastguard Worker
907*cfb92d14SAndroid Build Coastguard Worker
908*cfb92d14SAndroid Build Coastguard Workerclass TestHopByHopOptionHeader(unittest.TestCase):
909*cfb92d14SAndroid Build Coastguard Worker
910*cfb92d14SAndroid Build Coastguard Worker    def test_should_convert_HopByHopOptionHeader_to_bytes_when_to_bytes_method_is_called(self):
911*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
912*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
913*cfb92d14SAndroid Build Coastguard Worker        length = any_length()
914*cfb92d14SAndroid Build Coastguard Worker
915*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_option_header = HopByHopOptionHeader(_type, length)
916*cfb92d14SAndroid Build Coastguard Worker
917*cfb92d14SAndroid Build Coastguard Worker        # WHEN
918*cfb92d14SAndroid Build Coastguard Worker        data = hop_by_hop_option_header.to_bytes()
919*cfb92d14SAndroid Build Coastguard Worker
920*cfb92d14SAndroid Build Coastguard Worker        # THEN
921*cfb92d14SAndroid Build Coastguard Worker        expected_data = bytearray([_type, length])
922*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_data, data)
923*cfb92d14SAndroid Build Coastguard Worker
924*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_HopByHopOptionHeader_when_to_bytes_method_is_called_with_data(self):
925*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
926*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
927*cfb92d14SAndroid Build Coastguard Worker        length = any_length()
928*cfb92d14SAndroid Build Coastguard Worker
929*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([_type, length])
930*cfb92d14SAndroid Build Coastguard Worker
931*cfb92d14SAndroid Build Coastguard Worker        # WHEN
932*cfb92d14SAndroid Build Coastguard Worker        option_header = HopByHopOptionHeader.from_bytes(io.BytesIO(data))
933*cfb92d14SAndroid Build Coastguard Worker
934*cfb92d14SAndroid Build Coastguard Worker        # THEN
935*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(_type, option_header.type)
936*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(length, option_header.length)
937*cfb92d14SAndroid Build Coastguard Worker
938*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_proper_length_when_len_is_called_with_HopByHopOptionHeader_object(self):
939*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
940*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
941*cfb92d14SAndroid Build Coastguard Worker        length = any_length()
942*cfb92d14SAndroid Build Coastguard Worker
943*cfb92d14SAndroid Build Coastguard Worker        option_header = HopByHopOptionHeader(_type, length)
944*cfb92d14SAndroid Build Coastguard Worker
945*cfb92d14SAndroid Build Coastguard Worker        # WHEN
946*cfb92d14SAndroid Build Coastguard Worker        option_header_length = len(option_header)
947*cfb92d14SAndroid Build Coastguard Worker
948*cfb92d14SAndroid Build Coastguard Worker        # THEN
949*cfb92d14SAndroid Build Coastguard Worker        expected_option_header_length = 2
950*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_option_header_length, option_header_length)
951*cfb92d14SAndroid Build Coastguard Worker
952*cfb92d14SAndroid Build Coastguard Worker
953*cfb92d14SAndroid Build Coastguard Workerclass TestHopByHopFactory(unittest.TestCase):
954*cfb92d14SAndroid Build Coastguard Worker
955*cfb92d14SAndroid Build Coastguard Worker    def _calculate_hdr_ext_len(self, payload_length):
956*cfb92d14SAndroid Build Coastguard Worker        count = payload_length >> 3
957*cfb92d14SAndroid Build Coastguard Worker
958*cfb92d14SAndroid Build Coastguard Worker        if (payload_length & 0x7) == 0 and count > 0:
959*cfb92d14SAndroid Build Coastguard Worker            return count - 1
960*cfb92d14SAndroid Build Coastguard Worker
961*cfb92d14SAndroid Build Coastguard Worker        return count
962*cfb92d14SAndroid Build Coastguard Worker
963*cfb92d14SAndroid Build Coastguard Worker    def padding(self, content_length):
964*cfb92d14SAndroid Build Coastguard Worker        excess_bytes = content_length & 0x7
965*cfb92d14SAndroid Build Coastguard Worker
966*cfb92d14SAndroid Build Coastguard Worker        if excess_bytes > 0:
967*cfb92d14SAndroid Build Coastguard Worker            padding_length = 8 - excess_bytes
968*cfb92d14SAndroid Build Coastguard Worker
969*cfb92d14SAndroid Build Coastguard Worker            if padding_length == 1:
970*cfb92d14SAndroid Build Coastguard Worker                return bytearray([0x00])
971*cfb92d14SAndroid Build Coastguard Worker            elif padding_length > 1:
972*cfb92d14SAndroid Build Coastguard Worker                padding_length -= 2
973*cfb92d14SAndroid Build Coastguard Worker                return bytearray([0x01, padding_length]) + bytearray([0x00 for _ in range(padding_length)])
974*cfb92d14SAndroid Build Coastguard Worker
975*cfb92d14SAndroid Build Coastguard Worker        return bytearray()
976*cfb92d14SAndroid Build Coastguard Worker
977*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_HopByHop_object_instance_when_to_bytes_method_is_called_with_data(self):
978*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
979*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_option = any_hop_by_hop_mpl_option()
980*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_option_type = hop_by_hop_option.header.type
981*cfb92d14SAndroid Build Coastguard Worker
982*cfb92d14SAndroid Build Coastguard Worker        next_header = any_next_header()
983*cfb92d14SAndroid Build Coastguard Worker        hdr_ext_len = self._calculate_hdr_ext_len(2 + len(hop_by_hop_option))
984*cfb92d14SAndroid Build Coastguard Worker
985*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_factory = HopByHopFactory(hop_by_hop_options_factory=HopByHopOptionsFactory(
986*cfb92d14SAndroid Build Coastguard Worker            options_factories={hop_by_hop_option_type: MPLOptionFactory()}))
987*cfb92d14SAndroid Build Coastguard Worker
988*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([next_header, hdr_ext_len]) + hop_by_hop_option.to_bytes()
989*cfb92d14SAndroid Build Coastguard Worker        data += self.padding(len(data))
990*cfb92d14SAndroid Build Coastguard Worker
991*cfb92d14SAndroid Build Coastguard Worker        # WHEN
992*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop = hop_by_hop_factory.parse(io.BytesIO(data), any_message_info())
993*cfb92d14SAndroid Build Coastguard Worker
994*cfb92d14SAndroid Build Coastguard Worker        # THEN
995*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(hop_by_hop_option.value.S, hop_by_hop.options[0].value.S)
996*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(hop_by_hop_option.value.V, hop_by_hop.options[0].value.V)
997*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(hop_by_hop_option.value.M, hop_by_hop.options[0].value.M)
998*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(hop_by_hop_option.value.sequence, hop_by_hop.options[0].value.sequence)
999*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(hop_by_hop_option.value.seed_id, hop_by_hop.options[0].value.seed_id)
1000*cfb92d14SAndroid Build Coastguard Worker
1001*cfb92d14SAndroid Build Coastguard Worker    def test_should_raise_RuntimeError_when_no_option_factory_is_set_and_parse_method_is_called(self):
1002*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1003*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_option = any_hop_by_hop_mpl_option()
1004*cfb92d14SAndroid Build Coastguard Worker
1005*cfb92d14SAndroid Build Coastguard Worker        next_header = any_next_header()
1006*cfb92d14SAndroid Build Coastguard Worker        hdr_ext_len = self._calculate_hdr_ext_len(2 + len(hop_by_hop_option))
1007*cfb92d14SAndroid Build Coastguard Worker
1008*cfb92d14SAndroid Build Coastguard Worker        hop_by_hop_factory = HopByHopFactory(hop_by_hop_options_factory=HopByHopOptionsFactory())
1009*cfb92d14SAndroid Build Coastguard Worker
1010*cfb92d14SAndroid Build Coastguard Worker        data = bytes([next_header, hdr_ext_len]) + hop_by_hop_option.to_bytes()
1011*cfb92d14SAndroid Build Coastguard Worker        data += self.padding(len(data))
1012*cfb92d14SAndroid Build Coastguard Worker
1013*cfb92d14SAndroid Build Coastguard Worker        # THEN
1014*cfb92d14SAndroid Build Coastguard Worker        self.assertRaises(RuntimeError, hop_by_hop_factory.parse, io.BytesIO(data), any_message_info())
1015*cfb92d14SAndroid Build Coastguard Worker
1016*cfb92d14SAndroid Build Coastguard Worker
1017*cfb92d14SAndroid Build Coastguard Workerclass TestMPLOptionFactory(unittest.TestCase):
1018*cfb92d14SAndroid Build Coastguard Worker
1019*cfb92d14SAndroid Build Coastguard Worker    def test_should_produce_MPLOption_from_bytes_when_to_bytes_method_is_called_with_data(self):
1020*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1021*cfb92d14SAndroid Build Coastguard Worker        S = any_mpl_S()
1022*cfb92d14SAndroid Build Coastguard Worker        M = any_mpl_M()
1023*cfb92d14SAndroid Build Coastguard Worker        V = any_mpl_V()
1024*cfb92d14SAndroid Build Coastguard Worker        sequence = any_mpl_sequence()
1025*cfb92d14SAndroid Build Coastguard Worker        seed_id = any_mpl_seed_id(S)
1026*cfb92d14SAndroid Build Coastguard Worker
1027*cfb92d14SAndroid Build Coastguard Worker        SMV = (S << 6) | (M << 5) | (V << 4)
1028*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([SMV, sequence]) + seed_id
1029*cfb92d14SAndroid Build Coastguard Worker
1030*cfb92d14SAndroid Build Coastguard Worker        factory = MPLOptionFactory()
1031*cfb92d14SAndroid Build Coastguard Worker
1032*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1033*cfb92d14SAndroid Build Coastguard Worker        mpl_opt = factory.parse(io.BytesIO(data), any_message_info())
1034*cfb92d14SAndroid Build Coastguard Worker
1035*cfb92d14SAndroid Build Coastguard Worker        # THEN
1036*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(mpl_opt.S, S)
1037*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(mpl_opt.M, M)
1038*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(mpl_opt.V, V)
1039*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(mpl_opt.sequence, sequence)
1040*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(mpl_opt.seed_id, seed_id)
1041*cfb92d14SAndroid Build Coastguard Worker
1042*cfb92d14SAndroid Build Coastguard Worker
1043*cfb92d14SAndroid Build Coastguard Workerclass TestUdpBasedOnSrcDstPortsPayloadFactory(unittest.TestCase):
1044*cfb92d14SAndroid Build Coastguard Worker
1045*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_payload_from_data_when_src_port_factory_is_defined_and_parse_method_is_called(self):
1046*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1047*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1048*cfb92d14SAndroid Build Coastguard Worker
1049*cfb92d14SAndroid Build Coastguard Worker        message_info = common.MessageInfo()
1050*cfb92d14SAndroid Build Coastguard Worker        message_info.src_port = any_port()
1051*cfb92d14SAndroid Build Coastguard Worker        message_info.dst_port = any_port()
1052*cfb92d14SAndroid Build Coastguard Worker
1053*cfb92d14SAndroid Build Coastguard Worker        factory = UdpBasedOnSrcDstPortsPayloadFactory(
1054*cfb92d14SAndroid Build Coastguard Worker            src_dst_port_based_payload_factories={message_info.src_port: BytesPayloadFactory()})
1055*cfb92d14SAndroid Build Coastguard Worker
1056*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1057*cfb92d14SAndroid Build Coastguard Worker        actual_data = factory.parse(io.BytesIO(data), message_info)
1058*cfb92d14SAndroid Build Coastguard Worker
1059*cfb92d14SAndroid Build Coastguard Worker        # THEN
1060*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(data, actual_data.data)
1061*cfb92d14SAndroid Build Coastguard Worker
1062*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_payload_from_data_when_dst_port_factory_is_defined_and_parse_method_is_called(self):
1063*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1064*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1065*cfb92d14SAndroid Build Coastguard Worker
1066*cfb92d14SAndroid Build Coastguard Worker        message_info = common.MessageInfo()
1067*cfb92d14SAndroid Build Coastguard Worker        message_info.src_port = any_port()
1068*cfb92d14SAndroid Build Coastguard Worker        message_info.dst_port = any_port()
1069*cfb92d14SAndroid Build Coastguard Worker
1070*cfb92d14SAndroid Build Coastguard Worker        factory = UdpBasedOnSrcDstPortsPayloadFactory(
1071*cfb92d14SAndroid Build Coastguard Worker            src_dst_port_based_payload_factories={message_info.dst_port: BytesPayloadFactory()})
1072*cfb92d14SAndroid Build Coastguard Worker
1073*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1074*cfb92d14SAndroid Build Coastguard Worker        actual_data = factory.parse(io.BytesIO(data), message_info)
1075*cfb92d14SAndroid Build Coastguard Worker
1076*cfb92d14SAndroid Build Coastguard Worker        # THEN
1077*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(data, actual_data.data)
1078*cfb92d14SAndroid Build Coastguard Worker
1079*cfb92d14SAndroid Build Coastguard Worker    def test_should_raise_RuntimeError_when_parse_method_is_called_but_required_factory_is_not_defined(self):
1080*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1081*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1082*cfb92d14SAndroid Build Coastguard Worker
1083*cfb92d14SAndroid Build Coastguard Worker        message_info = common.MessageInfo()
1084*cfb92d14SAndroid Build Coastguard Worker        message_info.src_port = any_port()
1085*cfb92d14SAndroid Build Coastguard Worker        message_info.dst_port = any_port()
1086*cfb92d14SAndroid Build Coastguard Worker
1087*cfb92d14SAndroid Build Coastguard Worker        factory = UdpBasedOnSrcDstPortsPayloadFactory(src_dst_port_based_payload_factories={})
1088*cfb92d14SAndroid Build Coastguard Worker
1089*cfb92d14SAndroid Build Coastguard Worker        # THEN
1090*cfb92d14SAndroid Build Coastguard Worker        self.assertRaises(RuntimeError, factory.parse, io.BytesIO(data), message_info)
1091*cfb92d14SAndroid Build Coastguard Worker
1092*cfb92d14SAndroid Build Coastguard Worker
1093*cfb92d14SAndroid Build Coastguard Workerclass TestUDPDatagramFactory(unittest.TestCase):
1094*cfb92d14SAndroid Build Coastguard Worker
1095*cfb92d14SAndroid Build Coastguard Worker    def test_should_produce_UDPDatagram_from_bytes_when_to_bytes_method_is_called_with_data(self):
1096*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1097*cfb92d14SAndroid Build Coastguard Worker        src_port = any_port()
1098*cfb92d14SAndroid Build Coastguard Worker        dst_port = any_port()
1099*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
1100*cfb92d14SAndroid Build Coastguard Worker
1101*cfb92d14SAndroid Build Coastguard Worker        payload = any_payload()
1102*cfb92d14SAndroid Build Coastguard Worker        payload_length = len(payload) + len(UDPHeader(0, 0))
1103*cfb92d14SAndroid Build Coastguard Worker
1104*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([(src_port >> 8), (src_port & 0xff), (dst_port >> 8),
1105*cfb92d14SAndroid Build Coastguard Worker                          (dst_port & 0xff), (payload_length >> 8), (payload_length & 0xff), (checksum >> 8),
1106*cfb92d14SAndroid Build Coastguard Worker                          (checksum & 0xff)]) + payload
1107*cfb92d14SAndroid Build Coastguard Worker
1108*cfb92d14SAndroid Build Coastguard Worker        factory = UDPDatagramFactory(UDPHeaderFactory(), BytesPayloadFactory())
1109*cfb92d14SAndroid Build Coastguard Worker
1110*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1111*cfb92d14SAndroid Build Coastguard Worker        udp_dgram = factory.parse(io.BytesIO(data), any_message_info())
1112*cfb92d14SAndroid Build Coastguard Worker
1113*cfb92d14SAndroid Build Coastguard Worker        # THEN
1114*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(udp_dgram.header.src_port, src_port)
1115*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(udp_dgram.header.dst_port, dst_port)
1116*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(udp_dgram.header.payload_length, payload_length)
1117*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(udp_dgram.header.checksum, checksum)
1118*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(udp_dgram.payload.data, payload)
1119*cfb92d14SAndroid Build Coastguard Worker
1120*cfb92d14SAndroid Build Coastguard Worker    def test_should_set_src_and_dst_port_in_message_info_when_parse_method_is_called(self):
1121*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1122*cfb92d14SAndroid Build Coastguard Worker        message_info = any_message_info()
1123*cfb92d14SAndroid Build Coastguard Worker
1124*cfb92d14SAndroid Build Coastguard Worker        src_port = any_port()
1125*cfb92d14SAndroid Build Coastguard Worker        dst_port = any_port()
1126*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
1127*cfb92d14SAndroid Build Coastguard Worker
1128*cfb92d14SAndroid Build Coastguard Worker        payload = any_payload()
1129*cfb92d14SAndroid Build Coastguard Worker        payload_length = len(payload) + len(UDPHeader(0, 0))
1130*cfb92d14SAndroid Build Coastguard Worker
1131*cfb92d14SAndroid Build Coastguard Worker        data = (bytearray([
1132*cfb92d14SAndroid Build Coastguard Worker            (src_port >> 8),
1133*cfb92d14SAndroid Build Coastguard Worker            (src_port & 0xff),
1134*cfb92d14SAndroid Build Coastguard Worker            (dst_port >> 8),
1135*cfb92d14SAndroid Build Coastguard Worker            (dst_port & 0xff),
1136*cfb92d14SAndroid Build Coastguard Worker            (payload_length >> 8),
1137*cfb92d14SAndroid Build Coastguard Worker            (payload_length & 0xff),
1138*cfb92d14SAndroid Build Coastguard Worker            (checksum >> 8),
1139*cfb92d14SAndroid Build Coastguard Worker            (checksum & 0xff),
1140*cfb92d14SAndroid Build Coastguard Worker        ]) + payload)
1141*cfb92d14SAndroid Build Coastguard Worker
1142*cfb92d14SAndroid Build Coastguard Worker        factory = UDPDatagramFactory(UDPHeaderFactory(), BytesPayloadFactory())
1143*cfb92d14SAndroid Build Coastguard Worker
1144*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1145*cfb92d14SAndroid Build Coastguard Worker        factory.parse(io.BytesIO(data), message_info)
1146*cfb92d14SAndroid Build Coastguard Worker
1147*cfb92d14SAndroid Build Coastguard Worker        # THEN
1148*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(src_port, message_info.src_port)
1149*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(dst_port, message_info.dst_port)
1150*cfb92d14SAndroid Build Coastguard Worker
1151*cfb92d14SAndroid Build Coastguard Worker
1152*cfb92d14SAndroid Build Coastguard Workerclass TestICMPv6Factory(unittest.TestCase):
1153*cfb92d14SAndroid Build Coastguard Worker
1154*cfb92d14SAndroid Build Coastguard Worker    def test_should_produce_ICMPv6_from_bytes_when_to_bytes_method_is_called_with_data(self):
1155*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1156*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
1157*cfb92d14SAndroid Build Coastguard Worker        code = any_code()
1158*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
1159*cfb92d14SAndroid Build Coastguard Worker        body = any_body()
1160*cfb92d14SAndroid Build Coastguard Worker
1161*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([_type, code, (checksum >> 8), (checksum & 0xff)]) + body
1162*cfb92d14SAndroid Build Coastguard Worker
1163*cfb92d14SAndroid Build Coastguard Worker        factory = ICMPv6Factory(body_factories={_type: ICMPv6BytesBodyFactory()})
1164*cfb92d14SAndroid Build Coastguard Worker
1165*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1166*cfb92d14SAndroid Build Coastguard Worker        icmpv6_msg = factory.parse(io.BytesIO(data), any_message_info())
1167*cfb92d14SAndroid Build Coastguard Worker
1168*cfb92d14SAndroid Build Coastguard Worker        # THEN
1169*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(icmpv6_msg.header.type, _type)
1170*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(icmpv6_msg.header.code, code)
1171*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(icmpv6_msg.header.checksum, checksum)
1172*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(icmpv6_msg.body.bytes, body)
1173*cfb92d14SAndroid Build Coastguard Worker
1174*cfb92d14SAndroid Build Coastguard Worker    def test_should_raise_RuntimeError_when_method_parse_is_called_but_body_factory_is_not_present(self):
1175*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1176*cfb92d14SAndroid Build Coastguard Worker        _type = any_type()
1177*cfb92d14SAndroid Build Coastguard Worker        code = any_code()
1178*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
1179*cfb92d14SAndroid Build Coastguard Worker        body = any_body()
1180*cfb92d14SAndroid Build Coastguard Worker
1181*cfb92d14SAndroid Build Coastguard Worker        data = bytes([_type, code, (checksum >> 8), (checksum & 0xff)]) + body
1182*cfb92d14SAndroid Build Coastguard Worker
1183*cfb92d14SAndroid Build Coastguard Worker        factory = ICMPv6Factory()
1184*cfb92d14SAndroid Build Coastguard Worker
1185*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1186*cfb92d14SAndroid Build Coastguard Worker        self.assertRaises(RuntimeError, factory.parse, io.BytesIO(data), any_message_info())
1187*cfb92d14SAndroid Build Coastguard Worker
1188*cfb92d14SAndroid Build Coastguard Worker
1189*cfb92d14SAndroid Build Coastguard Workerclass TestBytesPayload(unittest.TestCase):
1190*cfb92d14SAndroid Build Coastguard Worker
1191*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_BytesPayload_when_from_bytes_class_method_is_called(self):
1192*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1193*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1194*cfb92d14SAndroid Build Coastguard Worker
1195*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1196*cfb92d14SAndroid Build Coastguard Worker        actual = BytesPayload.from_bytes(data)
1197*cfb92d14SAndroid Build Coastguard Worker
1198*cfb92d14SAndroid Build Coastguard Worker        # THEN
1199*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(data, actual.data)
1200*cfb92d14SAndroid Build Coastguard Worker
1201*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_exactly_the_same_data_as_passed_to_constructor_when_to_bytes_method_is_called(self):
1202*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1203*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1204*cfb92d14SAndroid Build Coastguard Worker        payload = BytesPayload(data)
1205*cfb92d14SAndroid Build Coastguard Worker
1206*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1207*cfb92d14SAndroid Build Coastguard Worker        actual = payload.to_bytes()
1208*cfb92d14SAndroid Build Coastguard Worker
1209*cfb92d14SAndroid Build Coastguard Worker        # THEN
1210*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(data, actual)
1211*cfb92d14SAndroid Build Coastguard Worker
1212*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_the_same_len_as_data_passed_to_constructor_when_len_is_called_on_BytesPayload_object(self):
1213*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1214*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1215*cfb92d14SAndroid Build Coastguard Worker        payload = BytesPayload(data)
1216*cfb92d14SAndroid Build Coastguard Worker
1217*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1218*cfb92d14SAndroid Build Coastguard Worker        actual = len(payload)
1219*cfb92d14SAndroid Build Coastguard Worker
1220*cfb92d14SAndroid Build Coastguard Worker        # THEN
1221*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(len(data), actual)
1222*cfb92d14SAndroid Build Coastguard Worker
1223*cfb92d14SAndroid Build Coastguard Worker
1224*cfb92d14SAndroid Build Coastguard Workerclass TestICMPv6EchoBody(unittest.TestCase):
1225*cfb92d14SAndroid Build Coastguard Worker
1226*cfb92d14SAndroid Build Coastguard Worker    def test_convert_ICMPv6_echo_body_to_data_when_to_bytes_method_is_called(self):
1227*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1228*cfb92d14SAndroid Build Coastguard Worker        identifier = any_identifier()
1229*cfb92d14SAndroid Build Coastguard Worker        sequence_number = any_sequence_number()
1230*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1231*cfb92d14SAndroid Build Coastguard Worker
1232*cfb92d14SAndroid Build Coastguard Worker        body = ICMPv6EchoBody(identifier, sequence_number, data)
1233*cfb92d14SAndroid Build Coastguard Worker
1234*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1235*cfb92d14SAndroid Build Coastguard Worker        actual = body.to_bytes()
1236*cfb92d14SAndroid Build Coastguard Worker
1237*cfb92d14SAndroid Build Coastguard Worker        # THEN
1238*cfb92d14SAndroid Build Coastguard Worker        expected = bytearray([identifier >> 8, identifier & 0xff, sequence_number >> 8, sequence_number & 0xff]) + data
1239*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected, actual)
1240*cfb92d14SAndroid Build Coastguard Worker
1241*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_ICMPv6EchoBody_from_data_when_from_bytes_classmethod_is_called(self):
1242*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1243*cfb92d14SAndroid Build Coastguard Worker        identifier = any_identifier()
1244*cfb92d14SAndroid Build Coastguard Worker        sequence_number = any_sequence_number()
1245*cfb92d14SAndroid Build Coastguard Worker        body_data = any_data()
1246*cfb92d14SAndroid Build Coastguard Worker
1247*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([(identifier >> 8), (identifier & 0xff), (sequence_number >> 8), (sequence_number & 0xff)])
1248*cfb92d14SAndroid Build Coastguard Worker        data += body_data
1249*cfb92d14SAndroid Build Coastguard Worker
1250*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1251*cfb92d14SAndroid Build Coastguard Worker        actual = ICMPv6EchoBody.from_bytes(io.BytesIO(data))
1252*cfb92d14SAndroid Build Coastguard Worker
1253*cfb92d14SAndroid Build Coastguard Worker        # THEN
1254*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(identifier, actual.identifier)
1255*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(sequence_number, actual.sequence_number)
1256*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(body_data, actual.data)
1257*cfb92d14SAndroid Build Coastguard Worker
1258*cfb92d14SAndroid Build Coastguard Worker    def test_should_build_ICMPv6EchoBody_from_well_know_values_when_to_bytes_method_is_called(self):
1259*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1260*cfb92d14SAndroid Build Coastguard Worker        body = ICMPv6EchoBody(
1261*cfb92d14SAndroid Build Coastguard Worker            0, 2,
1262*cfb92d14SAndroid Build Coastguard Worker            bytearray([
1263*cfb92d14SAndroid Build Coastguard Worker                0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1264*cfb92d14SAndroid Build Coastguard Worker                0x41
1265*cfb92d14SAndroid Build Coastguard Worker            ]))
1266*cfb92d14SAndroid Build Coastguard Worker
1267*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1268*cfb92d14SAndroid Build Coastguard Worker        actual = body.to_bytes()
1269*cfb92d14SAndroid Build Coastguard Worker
1270*cfb92d14SAndroid Build Coastguard Worker        # THEN
1271*cfb92d14SAndroid Build Coastguard Worker        expected = bytearray([
1272*cfb92d14SAndroid Build Coastguard Worker            0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0xc7, 0xbf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1273*cfb92d14SAndroid Build Coastguard Worker            0x41, 0x41, 0x41, 0x41
1274*cfb92d14SAndroid Build Coastguard Worker        ])
1275*cfb92d14SAndroid Build Coastguard Worker
1276*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected, actual)
1277*cfb92d14SAndroid Build Coastguard Worker
1278*cfb92d14SAndroid Build Coastguard Worker
1279*cfb92d14SAndroid Build Coastguard Workerclass TestICMPv6EchoBodyFactory(unittest.TestCase):
1280*cfb92d14SAndroid Build Coastguard Worker
1281*cfb92d14SAndroid Build Coastguard Worker    def test_should_build_ICMPv6EchoBody_when_to_bytes_method_is_called(self):
1282*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1283*cfb92d14SAndroid Build Coastguard Worker        identifier = any_identifier()
1284*cfb92d14SAndroid Build Coastguard Worker        sequence_number = any_sequence_number()
1285*cfb92d14SAndroid Build Coastguard Worker        body_data = any_data()
1286*cfb92d14SAndroid Build Coastguard Worker
1287*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([(identifier >> 8) & 0xff, identifier & 0xff,
1288*cfb92d14SAndroid Build Coastguard Worker                          (sequence_number >> 8) & 0xff, sequence_number & 0xff]) + body_data
1289*cfb92d14SAndroid Build Coastguard Worker
1290*cfb92d14SAndroid Build Coastguard Worker        factory = ICMPv6EchoBodyFactory()
1291*cfb92d14SAndroid Build Coastguard Worker
1292*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1293*cfb92d14SAndroid Build Coastguard Worker        actual = factory.parse(io.BytesIO(data), any_message_info())
1294*cfb92d14SAndroid Build Coastguard Worker
1295*cfb92d14SAndroid Build Coastguard Worker        # THEN
1296*cfb92d14SAndroid Build Coastguard Worker        self.assertTrue(isinstance(actual, ICMPv6EchoBody))
1297*cfb92d14SAndroid Build Coastguard Worker
1298*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(identifier, actual.identifier)
1299*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(sequence_number, actual.sequence_number)
1300*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(body_data, actual.data)
1301*cfb92d14SAndroid Build Coastguard Worker
1302*cfb92d14SAndroid Build Coastguard Worker
1303*cfb92d14SAndroid Build Coastguard Workerclass TestICMPv6DestinationUnreachable(unittest.TestCase):
1304*cfb92d14SAndroid Build Coastguard Worker
1305*cfb92d14SAndroid Build Coastguard Worker    def test_should_convert_ICMPv6DestinationUnreachable_to_bytearray_when_to_bytes_method_is_called(self):
1306*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1307*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1308*cfb92d14SAndroid Build Coastguard Worker
1309*cfb92d14SAndroid Build Coastguard Worker        icmpv6_dest_unreachable = ICMPv6DestinationUnreachable(data)
1310*cfb92d14SAndroid Build Coastguard Worker
1311*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1312*cfb92d14SAndroid Build Coastguard Worker        actual_data = icmpv6_dest_unreachable.to_bytes()
1313*cfb92d14SAndroid Build Coastguard Worker
1314*cfb92d14SAndroid Build Coastguard Worker        # THEN
1315*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(bytearray([0x00, 0x00, 0x00, 0x00]) + data, actual_data)
1316*cfb92d14SAndroid Build Coastguard Worker
1317*cfb92d14SAndroid Build Coastguard Worker    def test_should_convert_bytearray_to_ICMPv6DestinationUnreachable_when_from_bytes_method_is_called(self):
1318*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1319*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1320*cfb92d14SAndroid Build Coastguard Worker
1321*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1322*cfb92d14SAndroid Build Coastguard Worker        icmpv6_dest_unreachable = ICMPv6DestinationUnreachable.from_bytes(
1323*cfb92d14SAndroid Build Coastguard Worker            io.BytesIO(bytearray([0x00, 0x00, 0x00, 0x00]) + data))
1324*cfb92d14SAndroid Build Coastguard Worker
1325*cfb92d14SAndroid Build Coastguard Worker        # THEN
1326*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(data, icmpv6_dest_unreachable.data)
1327*cfb92d14SAndroid Build Coastguard Worker
1328*cfb92d14SAndroid Build Coastguard Worker    def test_should_raise_RuntimeError_when_from_bytes_method_is_called(self):
1329*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1330*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
1331*cfb92d14SAndroid Build Coastguard Worker
1332*cfb92d14SAndroid Build Coastguard Worker        unused = random.randint(1, 1 << 32)
1333*cfb92d14SAndroid Build Coastguard Worker
1334*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1335*cfb92d14SAndroid Build Coastguard Worker        self.assertRaises(RuntimeError, ICMPv6DestinationUnreachable.from_bytes,
1336*cfb92d14SAndroid Build Coastguard Worker                          io.BytesIO(bytearray(struct.pack(">I", unused)) + data))
1337*cfb92d14SAndroid Build Coastguard Worker
1338*cfb92d14SAndroid Build Coastguard Worker
1339*cfb92d14SAndroid Build Coastguard Workerclass TestICMPv6DestinationUnreachableFactory(unittest.TestCase):
1340*cfb92d14SAndroid Build Coastguard Worker
1341*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_ICMPv6DestinationUnreachable_when_parse_method_is_called(self):
1342*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1343*cfb92d14SAndroid Build Coastguard Worker        icmp_data = any_data()
1344*cfb92d14SAndroid Build Coastguard Worker
1345*cfb92d14SAndroid Build Coastguard Worker        factory = ICMPv6DestinationUnreachableFactory()
1346*cfb92d14SAndroid Build Coastguard Worker
1347*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([0x00, 0x00, 0x00, 0x00]) + icmp_data
1348*cfb92d14SAndroid Build Coastguard Worker
1349*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1350*cfb92d14SAndroid Build Coastguard Worker        icmpv6_dest_unreachable = factory.parse(io.BytesIO(data), any_message_info())
1351*cfb92d14SAndroid Build Coastguard Worker
1352*cfb92d14SAndroid Build Coastguard Worker        # THEN
1353*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(icmp_data, icmpv6_dest_unreachable.data)
1354*cfb92d14SAndroid Build Coastguard Worker
1355*cfb92d14SAndroid Build Coastguard Worker
1356*cfb92d14SAndroid Build Coastguard Workerclass TestUDPHeaderFactory(unittest.TestCase):
1357*cfb92d14SAndroid Build Coastguard Worker
1358*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_UDPHeader_when_to_bytes_method_is_called(self):
1359*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1360*cfb92d14SAndroid Build Coastguard Worker        factory = UDPHeaderFactory()
1361*cfb92d14SAndroid Build Coastguard Worker
1362*cfb92d14SAndroid Build Coastguard Worker        src_port = any_port()
1363*cfb92d14SAndroid Build Coastguard Worker        dst_port = any_port()
1364*cfb92d14SAndroid Build Coastguard Worker        payload_length = any_payload_length()
1365*cfb92d14SAndroid Build Coastguard Worker        checksum = any_checksum()
1366*cfb92d14SAndroid Build Coastguard Worker
1367*cfb92d14SAndroid Build Coastguard Worker        data = struct.pack("!H", src_port) + struct.pack("!H", dst_port) + \
1368*cfb92d14SAndroid Build Coastguard Worker            struct.pack("!H", payload_length) + struct.pack("!H", checksum)
1369*cfb92d14SAndroid Build Coastguard Worker
1370*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1371*cfb92d14SAndroid Build Coastguard Worker        udp_header = factory.parse(io.BytesIO(data), any_message_info())
1372*cfb92d14SAndroid Build Coastguard Worker
1373*cfb92d14SAndroid Build Coastguard Worker        # THEN
1374*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(src_port, udp_header.src_port)
1375*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(dst_port, udp_header.dst_port)
1376*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(payload_length, udp_header.payload_length)
1377*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(checksum, udp_header.checksum)
1378*cfb92d14SAndroid Build Coastguard Worker
1379*cfb92d14SAndroid Build Coastguard Worker
1380*cfb92d14SAndroid Build Coastguard Workerclass TestHopByHopOptionsFactory(unittest.TestCase):
1381*cfb92d14SAndroid Build Coastguard Worker
1382*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_option_from_bytearray_when_to_bytes_method_is_called(self):
1383*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
1384*cfb92d14SAndroid Build Coastguard Worker
1385*cfb92d14SAndroid Build Coastguard Worker        class DummyOptionFactory:
1386*cfb92d14SAndroid Build Coastguard Worker
1387*cfb92d14SAndroid Build Coastguard Worker            def parse(self, data, message_info):
1388*cfb92d14SAndroid Build Coastguard Worker                return data.read()
1389*cfb92d14SAndroid Build Coastguard Worker
1390*cfb92d14SAndroid Build Coastguard Worker        factory = HopByHopOptionsFactory(options_factories={2: DummyOptionFactory()})
1391*cfb92d14SAndroid Build Coastguard Worker
1392*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([0x02, 0x03, 0x11, 0x22, 0x33, 0x01, 0x00])
1393*cfb92d14SAndroid Build Coastguard Worker
1394*cfb92d14SAndroid Build Coastguard Worker        # WHEN
1395*cfb92d14SAndroid Build Coastguard Worker        actual_options = factory.parse(io.BytesIO(data), any_message_info())
1396*cfb92d14SAndroid Build Coastguard Worker
1397*cfb92d14SAndroid Build Coastguard Worker        # THEN
1398*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(1, len(actual_options))
1399*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(2, actual_options[0].header.type)
1400*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(3, actual_options[0].header.length)
1401*cfb92d14SAndroid Build Coastguard Worker
1402*cfb92d14SAndroid Build Coastguard Worker
1403*cfb92d14SAndroid Build Coastguard Workerif __name__ == "__main__":
1404*cfb92d14SAndroid Build Coastguard Worker    unittest.main()
1405