2 * Copyright (c) 2013 Contextream, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.lispflowmapping.southbound.lisp;
11 import static junit.framework.Assert.assertEquals;
12 import static junit.framework.Assert.assertFalse;
13 import static junit.framework.Assert.assertTrue;
15 import java.net.DatagramPacket;
16 import java.util.Arrays;
17 import java.util.List;
19 import junitx.framework.ArrayAssert;
20 import junitx.framework.Assert;
22 import org.jmock.api.Invocation;
23 import org.junit.Before;
24 import org.junit.Ignore;
25 import org.junit.Test;
26 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolver;
27 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServer;
28 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
29 import org.opendaylight.lispflowmapping.southbound.serializer.LispMessage;
30 import org.opendaylight.lispflowmapping.southbound.serializer.LispMessageEnum;
31 import org.opendaylight.lispflowmapping.southbound.util.ByteUtil;
32 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
33 import org.opendaylight.lispflowmapping.type.AddressFamilyNumberEnum;
34 import org.opendaylight.lispflowmapping.type.lisp.EidRecord;
35 import org.opendaylight.lispflowmapping.type.lisp.EidToLocatorRecord;
36 import org.opendaylight.lispflowmapping.type.lisp.LocatorRecord;
37 import org.opendaylight.lispflowmapping.type.lisp.MapNotify;
38 import org.opendaylight.lispflowmapping.type.lisp.MapRegister;
39 import org.opendaylight.lispflowmapping.type.lisp.MapReply;
40 import org.opendaylight.lispflowmapping.type.lisp.MapRequest;
41 import org.opendaylight.lispflowmapping.type.lisp.address.LispAddress;
42 import org.opendaylight.lispflowmapping.type.lisp.address.LispIpv4Address;
43 import org.opendaylight.lispflowmapping.type.lisp.address.LispIpv6Address;
45 public class LispSouthboundServiceTest extends BaseTestCase {
47 private LispSouthboundService testedLispService;
48 private IMapResolver mapResolver;
49 private IMapServer mapServer;
50 private byte[] mapRequestPacket;
51 private byte[] mapRegisterPacket;
52 private ValueSaverAction<MapRegister> mapRegisterSaver;
53 private ValueSaverAction<MapRequest> mapRequestSaver;
54 private MapNotify mapNotify;
55 private MapReply mapReply;
56 private EidToLocatorRecord eidToLocator;
58 private interface MapReplyIpv4SingleLocatorPos {
61 int LOCATOR_COUNT = 16;
62 int EID_MASK_LEN = 17;
66 int LOCATOR_RBIT = 33;
70 private interface MapReplyIpv4SecondLocatorPos {
71 int FIRST_LOCATOR_IPV4_LENGTH = 12;
72 int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
73 int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
74 int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
79 public void before() throws Exception {
81 mapResolver = context.mock(IMapResolver.class);
82 mapServer = context.mock(IMapServer.class);
83 testedLispService = new LispSouthboundService(mapResolver, mapServer);
85 mapRegisterSaver = new ValueSaverAction<MapRegister>();
86 mapRequestSaver = new ValueSaverAction<MapRequest>();
87 // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
88 // LISP(Type = 8 - Encapsulated)
89 // IP: 192.168.136.10 -> 1.2.3.4
91 // LISP(Type = 1 Map-Request
95 // Source EID not present
96 // Nonce: 0x3d8d2acd39c8d608
97 // ITR-RLOC AFI=1 Address=192.168.136.10
98 // Record 1: 1.2.3.4/32
99 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
100 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
101 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
102 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
103 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
104 + "0050 2a cd 39 c8 d6 08 00 00 00 01 c0 a8 88 0a 00 20 " //
105 + "0060 00 01 01 02 03 04"));
106 mapReply = new MapReply();
107 eidToLocator = new EidToLocatorRecord();
108 eidToLocator.setPrefix(new LispIpv4Address(0));
109 mapReply.addEidToLocator(eidToLocator);
111 // IP: 192.168.136.10 -> 128.223.156.35
112 // UDP: 49289 -> 4342
113 // LISP(Type = 3 Map-Register, P=1, M=1
117 // AuthDataLength: 20 Data:
118 // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
119 // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
121 // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
122 // Priority/Weight: 1/100, Multicast Priority/Weight:
126 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
127 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
128 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
129 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
130 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
131 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
132 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
133 mapNotify = new MapNotify();
138 public void todos() throws Exception {
140 // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
141 // TODO: Non-Encapsulated packets
144 @Test(expected = LispMalformedPacketException.class)
145 public void mapRegister__IllegalPacket() throws Exception {
146 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
147 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 " //
148 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "));
150 handlePacket(mapRegisterPacket);
153 @Test(expected = LispMalformedPacketException.class)
154 public void mapRequest__IllegalPacket() throws Exception {
155 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
156 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
157 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
158 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 " //
159 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "));
160 handlePacket(mapRequestPacket);
163 @Test(expected = LispMalformedPacketException.class)
164 public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
165 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
166 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 " //
167 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "));
168 handlePacket(mapRequestPacket);
172 public void mapRegister__TwoRlocs() throws Exception {
174 // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
175 // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
176 // Priority/Weight: 255/0
177 // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
178 // Multicast Priority/Weight: 255/0
179 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
180 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 " //
181 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 " //
182 + "0030 00 00 00 00 00 00 00 01 00 14 f8 3c d8 9d 92 8b " //
183 + "0040 67 20 2c 63 82 63 c5 38 7b 74 b8 70 01 dd 00 00 " //
184 + "0050 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 " //
185 + "0060 ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 " //
186 + "0070 00 01 c0 a8 88 33"));
188 oneOf(mapServer).handleMapRegister(with(mapRegisterSaver));
191 handlePacket(mapRegisterPacket);
193 List<EidToLocatorRecord> eidRecords = mapRegisterSaver.lastValue.getEidToLocatorRecords();
194 assertEquals(1, eidRecords.size());
195 EidToLocatorRecord eidRecord = eidRecords.get(0);
196 assertEquals(2, eidRecord.getLocators().size());
197 assertEquals(new LispIpv4Address("10.1.0.110"), eidRecord.getLocators().get(0).getLocator());
198 assertEquals(new LispIpv4Address("192.168.136.51"), eidRecord.getLocators().get(1).getLocator());
202 public void mapRegister__Ipv6Rloc() throws Exception {
203 // P bit (Proxy-Map-Reply): Set
204 // M bit (Want-Map-Notify): Set
209 // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
210 // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
212 // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
213 // Priority/Weight: 255/0
215 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
216 + "0010 00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 " //
217 + "0020 01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 " //
218 + "0030 00 00 00 00 00 00 00 01 00 14 5b c4 d4 4a 57 e2 " //
219 + "0040 a5 5d 57 7a 6f 89 77 9c 00 4f 5d a7 13 fb 00 00 " //
220 + "0050 00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff " //
221 + "0060 01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 " //
222 + "0070 00 01 0a 00 3a 9c"));
224 oneOf(mapServer).handleMapRegister(with(mapRegisterSaver));
227 handlePacket(mapRegisterPacket);
228 byte[] expectedIpv6Address = new byte[] { 0x26, 0x10, 0x00, (byte) 0xd0, (byte) 0xff, (byte) 0xff, 0x01, (byte) 0x92, 0x00, 0x00, 0x00, 0x00,
229 0x00, 0x00, 0x00, 0x01 };
231 EidToLocatorRecord eidToLocatorRecord = mapRegisterSaver.lastValue.getEidToLocatorRecords().get(0);
232 assertEquals(new LispIpv6Address(expectedIpv6Address), eidToLocatorRecord.getPrefix());
233 assertEquals(AddressFamilyNumberEnum.IP6, eidToLocatorRecord.getPrefix().getAfi());
235 assertEquals(new LispIpv4Address(0x0A003A9C), eidToLocatorRecord.getLocators().get(0).getLocator());
239 public void mapRegister__VerifyBasicFields() throws Exception {
240 oneOf(mapServer).handleMapRegister(with(mapRegisterSaver));
242 handlePacket(mapRegisterPacket);
244 EidToLocatorRecord eidToLocator = mapRegisterSaver.lastValue.getEidToLocatorRecords().get(0);
245 assertEquals(new LispIpv4Address(0x9910FE01), eidToLocator.getPrefix());
247 assertEquals(1, eidToLocator.getLocators().size());
248 assertEquals(new LispIpv4Address(0xC0A8880A), eidToLocator.getLocators().get(0).getLocator());
252 public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
253 allowing(mapServer).handleMapRegister(with(mapRegisterSaver));
256 assertNull(handlePacket(mapRegisterPacket));
260 public void mapRegister__NonSetMBit() throws Exception {
261 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
262 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df " //
263 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
264 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
265 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 " //
266 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
267 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
268 stubMapRegister(true);
270 handlePacket(registerWithNonSetMBit);
272 assertFalse(mapRegisterSaver.lastValue.isWantMapNotify());
276 public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
277 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
278 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
279 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
280 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
281 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
282 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
283 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
284 stubMapRegister(true);
286 handlePacket(registerWithNonSetMBit);
287 assertFalse(mapRegisterSaver.lastValue.isWantMapNotify());
291 public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
292 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
293 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
294 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
295 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
296 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
297 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
298 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
299 stubMapRegister(true);
301 handlePacket(registerWithNonSetMBit);
302 assertTrue(mapRegisterSaver.lastValue.isWantMapNotify());
306 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
307 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
308 extraDataPacket[mapRegisterPacket.length] = 0x9;
309 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
310 stubMapRegister(true);
312 DatagramPacket dp = new DatagramPacket(extraDataPacket, extraDataPacket.length);
313 dp.setLength(mapRegisterPacket.length);
314 byte[] notifyResult = testedLispService.handlePacket(dp).getData();
316 assertEquals(mapRegisterPacket.length, notifyResult.length);
321 public void mapNotify__VerifyBasicFields() throws Exception {
322 byte registerType = mapRegisterPacket[0];
323 assertEquals(LispMessageEnum.MapRegister.getValue(), registerType >> 4);
325 stubMapRegister(true);
327 byte[] result = handlePacketAsByteArray(mapRegisterPacket);
329 assertEquals(mapRegisterPacket.length, result.length);
331 byte expectedType = (byte) (LispMessageEnum.MapNotify.getValue() << 4);
332 assertHexEquals(expectedType, result[0]);
333 assertHexEquals((byte) 0x00, result[1]);
334 assertHexEquals((byte) 0x00, result[2]);
336 byte[] registerWithoutType = Arrays.copyOfRange(mapRegisterPacket, 3, mapRegisterPacket.length);
337 byte[] notifyWithoutType = Arrays.copyOfRange(result, 3, result.length);
338 ArrayAssert.assertEquals(registerWithoutType, notifyWithoutType);
342 public void mapNotify__VerifyPort() throws Exception {
343 stubMapRegister(true);
345 DatagramPacket notifyPacket = handlePacket(mapRegisterPacket);
346 assertEquals(LispMessage.PORT_NUM, notifyPacket.getPort());
350 public void mapRequest__VerifyBasicFields() throws Exception {
351 oneOf(mapResolver).handleMapRequest(with(mapRequestSaver));
354 handlePacketAsByteArray(mapRequestPacket);
355 List<EidRecord> eids = mapRequestSaver.lastValue.getEids();
356 assertEquals(1, eids.size());
357 LispAddress lispAddress = eids.get(0).getPrefix();
358 assertTrue(lispAddress instanceof LispIpv4Address);
359 assertEquals(asInet(0x01020304), ((LispIpv4Address) lispAddress).getAddress());
360 assertEquals((byte) 0x20, eids.get(0).getMaskLength());
361 assertEquals(0x3d8d2acd39c8d608L, mapRequestSaver.lastValue.getNonce());
362 assertEquals(AddressFamilyNumberEnum.RESERVED, mapRequestSaver.lastValue.getSourceEid().getAfi());
366 public void mapRequest__Ipv6Eid() throws Exception {
367 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
368 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
369 // (2610:d0:ffff:192::2)
372 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
373 // ITR-RLOC 1: 10.0.58.156
374 // Record 1: 2610:d0:ffff:192::2/128
375 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
376 // Authoritative, No-Action
378 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
379 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
380 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
381 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
382 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
383 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
384 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
385 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
386 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
387 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 " //
388 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 " //
389 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
391 allowing(mapResolver).handleMapRequest(with(mapRequestSaver));
394 handlePacketAsByteArray(mapRequestPacket);
395 assertEquals(new LispIpv6Address("2610:d0:ffff:192::1"), mapRequestSaver.lastValue.getSourceEid());
396 assertEquals(new LispIpv6Address("2610:d0:ffff:192::2"), mapRequestSaver.lastValue.getEids().get(0).getPrefix());
400 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
401 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
402 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
403 // (2610:d0:ffff:192::2)
404 // encapsulated UDP source port: 4342
406 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
407 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
408 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
409 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
410 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
411 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
412 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
413 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
414 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
415 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 " //
416 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 " //
417 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
419 allowing(mapResolver).handleMapRequest(with(mapRequestSaver));
422 DatagramPacket replyPacket = handlePacket(mapRequestPacket);
423 assertEquals(4342, replyPacket.getPort());
427 public void mapRequest__WithSourceEid() throws Exception {
428 // encapsulated LISP packet
429 // Source EID = 153.16.254.1
431 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 " //
432 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
433 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
434 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
435 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 14 00 00 01 ba f9 "
436 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
437 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
438 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 " //
439 + "0080 00 01 0a 00 01 26"));
441 allowing(mapResolver).handleMapRequest(with(mapRequestSaver));
444 handlePacketAsByteArray(mapRequestPacket);
445 Assert.assertNotEquals(AddressFamilyNumberEnum.RESERVED, mapRequestSaver.lastValue.getSourceEid().getAfi());
450 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
451 eidToLocator.setMaskLength((byte) 0x20)//
452 .setPrefix(new LispIpv4Address(0x0a0014c8));
453 mapReply.setNonce(0x3d8d2acd39c8d608L);
457 byte[] result = handlePacketAsByteArray(mapRequestPacket);
459 assertEquals(28, result.length);
461 byte expectedLispMessageType = 2;
462 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
463 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
465 byte expectedRecordCount = (byte) 1;
466 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
468 assertEquals(eidToLocator.getMaskLength(), result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
469 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
470 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
474 public void mapReply__VerifyBasicIPv6() throws Exception {
475 eidToLocator.setMaskLength((byte) 0x80)//
476 .setPrefix(new LispIpv6Address("::1"));
480 byte[] result = handlePacketAsByteArray(mapRequestPacket);
482 assertEquals(40, result.length);
484 byte expectedRecordCount = (byte) 1;
485 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
487 assertEquals(eidToLocator.getMaskLength(), result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
488 assertEquals(AddressFamilyNumberEnum.IP6.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
489 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
491 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
495 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
496 eidToLocator.setPrefix(new LispIpv6Address("::1"));
497 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv6Address("::2")));
501 byte[] result = handlePacketAsByteArray(mapRequestPacket);
503 assertEquals(64, result.length);
505 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
506 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
508 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
509 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
513 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
516 assertEquals(56756, handlePacket(mapRequestPacket).getPort());
520 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
521 eidToLocator.setMaskLength((byte) 0x20)//
522 .setPrefix(new LispIpv4Address(0x0a0014c8));
523 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv4Address(0x04030201)).setRouted(false));
526 byte[] result = handlePacketAsByteArray(mapRequestPacket);
527 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
531 public void mapReply__WithSingleLocator() throws Exception {
532 eidToLocator.setMaskLength((byte) 0x20)//
533 .setPrefix(new LispIpv4Address(0x0a0014c8));
534 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv4Address(0x04030201)).setRouted(true));
537 byte[] result = handlePacketAsByteArray(mapRequestPacket);
538 assertEquals(40, result.length);
540 byte expectedLocCount = 1;
541 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
543 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
545 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
546 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
550 public void mapReply__WithMultipleLocator() throws Exception {
551 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv4Address(0x04030201)).setRouted(true));
552 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv6Address("::1")).setRouted(true));
555 byte[] result = handlePacketAsByteArray(mapRequestPacket);
556 assertEquals(64, result.length);
558 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
560 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
561 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
562 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
564 assertEquals(AddressFamilyNumberEnum.IP6.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
566 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
567 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
568 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
570 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
574 public void handleUnknownLispMessage() throws Exception {
575 // IP: 192.168.136.10 -> 128.223.156.35
576 // UDP: 49289 -> 4342
577 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
579 byte[] unknownTypePacket = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
580 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
581 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
582 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
583 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
584 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
585 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
586 assertNull(handlePacket(unknownTypePacket));
590 public void mapRequest__MultipleItrRlocs() throws Exception {
591 // this is what LISPmob sends when configured multiple RLOCs for single
593 // ITR-RLOC 1: 10.1.0.111
594 // ITR-RLOC 2: 192.168.136.51
596 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
597 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 " //
598 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 " //
599 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 " //
600 + "0040 08 08 10 f6 10 f6 00 56 63 14 14 00 01 01 79 67 " //
601 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 " //
602 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 " //
603 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 " //
604 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 " //
605 + "0090 00 05 00 01 c0 a8 88 33"));
607 allowing(mapResolver).handleMapRequest(with(mapRequestSaver));
610 handlePacketAsByteArray(mapRequestPacket);
612 // assertEquals(2, mapRequestSaver.lastValue.getItrRlocs().size());
613 // assertEquals(new LispIpv4Address("10.1.0.111"),
614 // mapRequestSaver.lastValue.getItrRlocs().get(0));
615 // assertEquals(new LispIpv4Address("192.168.136.51"),
616 // mapRequestSaver.lastValue.getItrRlocs().get(1));
619 private void stubMapRegister(final boolean setNotifyFromRegister) {
620 allowing(mapServer).handleMapRegister(with(mapRegisterSaver));
621 will(new SimpleAction() {
624 public Object invoke(Invocation invocation) throws Throwable {
625 if (setNotifyFromRegister) {
626 mapNotify.setFromMapRegister(mapRegisterSaver.lastValue);
633 private void stubHandleRequest() {
634 allowing(mapResolver).handleMapRequest(wany(MapRequest.class));
638 private byte[] handlePacketAsByteArray(byte[] inPacket) {
639 return handlePacket(inPacket).getData();
642 private DatagramPacket handlePacket(byte[] inPacket) {
643 return testedLispService.handlePacket(new DatagramPacket(inPacket, inPacket.length));
646 private byte[] extractWSUdpByteArray(String wiresharkHex) {
647 final int HEADER_LEN = 42;
648 byte[] res = new byte[1000];
649 String[] split = wiresharkHex.split(" ");
651 for (String cur : split) {
653 if (cur.length() == 2) {
655 if (counter > HEADER_LEN) {
656 res[counter - HEADER_LEN - 1] = (byte) Integer.parseInt(cur, 16);
661 return Arrays.copyOf(res, counter - HEADER_LEN);