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.nio.ByteBuffer;
17 import java.util.Arrays;
18 import java.util.List;
20 import junitx.framework.ArrayAssert;
21 import junitx.framework.Assert;
23 import org.apache.commons.lang3.ArrayUtils;
24 import org.jmock.api.Invocation;
25 import org.junit.Before;
26 import org.junit.Ignore;
27 import org.junit.Test;
28 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
29 import org.opendaylight.lispflowmapping.implementation.serializer.LispMessage;
30 import org.opendaylight.lispflowmapping.implementation.serializer.LispMessageEnum;
31 import org.opendaylight.lispflowmapping.implementation.serializer.MapNotifySerializer;
32 import org.opendaylight.lispflowmapping.implementation.serializer.MapReplySerializer;
33 import org.opendaylight.lispflowmapping.implementation.util.ByteUtil;
34 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolver;
35 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServer;
36 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
37 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
38 import org.opendaylight.lispflowmapping.type.AddressFamilyNumberEnum;
39 import org.opendaylight.lispflowmapping.type.lisp.EidRecord;
40 import org.opendaylight.lispflowmapping.type.lisp.EidToLocatorRecord;
41 import org.opendaylight.lispflowmapping.type.lisp.LocatorRecord;
42 import org.opendaylight.lispflowmapping.type.lisp.MapNotify;
43 import org.opendaylight.lispflowmapping.type.lisp.MapRegister;
44 import org.opendaylight.lispflowmapping.type.lisp.MapReply;
45 import org.opendaylight.lispflowmapping.type.lisp.MapRequest;
46 import org.opendaylight.lispflowmapping.type.lisp.address.LispAddress;
47 import org.opendaylight.lispflowmapping.type.lisp.address.LispIpv4Address;
48 import org.opendaylight.lispflowmapping.type.lisp.address.LispIpv6Address;
49 import org.opendaylight.lispflowmapping.type.sbplugin.LispNotification;
50 import org.opendaylight.lispflowmapping.type.sbplugin.MapRegisterNotification;
51 import org.opendaylight.lispflowmapping.type.sbplugin.MapRequestNotification;
53 public class LispSouthboundServiceTest extends BaseTestCase {
55 private LispSouthboundService testedLispService;
56 private IMapResolver mapResolver;
57 private IMapServer mapServer;
58 private NotificationProviderService nps;
59 private byte[] mapRequestPacket;
60 private byte[] mapRegisterPacket;
61 private ValueSaverAction<LispNotification> lispNotificationSaver;
62 //private ValueSaverAction<MapRegister> mapRegisterSaver;
63 //private ValueSaverAction<MapRequest> mapRequestSaver;
64 private MapNotify mapNotify;
65 private MapReply mapReply;
66 private EidToLocatorRecord eidToLocator;
68 private interface MapReplyIpv4SingleLocatorPos {
71 int LOCATOR_COUNT = 16;
72 int EID_MASK_LEN = 17;
76 int LOCATOR_RBIT = 33;
80 private interface MapReplyIpv4SecondLocatorPos {
81 int FIRST_LOCATOR_IPV4_LENGTH = 12;
82 int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
83 int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
84 int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
89 public void before() throws Exception {
91 //mapResolver = context.mock(IMapResolver.class);
92 //mapServer = context.mock(IMapServer.class);
93 testedLispService = new LispSouthboundService();
94 nps = context.mock(NotificationProviderService.class);
95 testedLispService.setNotificationProvider(nps);
96 lispNotificationSaver = new ValueSaverAction<LispNotification>();
97 //mapRegisterSaver = new ValueSaverAction<MapRegister>();
98 //mapRequestSaver = new ValueSaverAction<MapRequest>();
99 // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
100 // LISP(Type = 8 - Encapsulated)
101 // IP: 192.168.136.10 -> 1.2.3.4
103 // LISP(Type = 1 Map-Request
107 // Source EID not present
108 // Nonce: 0x3d8d2acd39c8d608
109 // ITR-RLOC AFI=1 Address=192.168.136.10
110 // Record 1: 1.2.3.4/32
111 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
112 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
113 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
114 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
115 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
116 + "0050 2a cd 39 c8 d6 08 00 00 00 01 c0 a8 88 0a 00 20 " //
117 + "0060 00 01 01 02 03 04"));
118 mapReply = new MapReply();
119 eidToLocator = new EidToLocatorRecord();
120 eidToLocator.setPrefix(new LispIpv4Address(0));
121 mapReply.addEidToLocator(eidToLocator);
123 // IP: 192.168.136.10 -> 128.223.156.35
124 // UDP: 49289 -> 4342
125 // LISP(Type = 3 Map-Register, P=1, M=1
129 // AuthDataLength: 20 Data:
130 // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
131 // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
133 // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
134 // Priority/Weight: 1/100, Multicast Priority/Weight:
138 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
139 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
140 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
141 + "0030 00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
142 + "0040 71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
143 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
144 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
145 mapNotify = new MapNotify();
150 public void todos() throws Exception {
152 // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
153 // TODO: Non-Encapsulated packets
156 @Test(expected = LispMalformedPacketException.class)
157 public void mapRegister__IllegalPacket() throws Exception {
158 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
159 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 " //
160 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "));
162 handleMapRegisterPacket(mapRegisterPacket);
165 @Test(expected = LispMalformedPacketException.class)
166 public void mapRequest__IllegalPacket() throws Exception {
167 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
168 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
169 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
170 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 " //
171 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "));
172 handleMapRequestPacket(mapRequestPacket);
175 @Test(expected = LispMalformedPacketException.class)
176 public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
177 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
178 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 " //
179 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "));
180 handleMapRequestPacket(mapRequestPacket);
183 private MapRegister lastMapRegister() {
184 MapRegisterNotification lastValue = (MapRegisterNotification) lispNotificationSaver.lastValue;
185 return lastValue.getMapRegister();
188 private MapRequest lastMapRequest() {
189 MapRequestNotification lastValue = (MapRequestNotification) lispNotificationSaver.lastValue;
190 return lastValue.getMapRequest();
194 public void mapRegister__TwoRlocs() throws Exception {
196 // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
197 // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
198 // Priority/Weight: 255/0
199 // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
200 // Multicast Priority/Weight: 255/0
201 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
202 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 " //
203 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 " //
204 + "0030 00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 " //
205 + "0040 e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 " //
206 + "0050 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 " //
207 + "0060 ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 " //
208 + "0070 00 01 c0 a8 88 33"));
210 oneOf(nps).publish(with(lispNotificationSaver));
212 handleMapRegisterPacket(mapRegisterPacket);
214 List<EidToLocatorRecord> eidRecords = lastMapRegister().getEidToLocatorRecords();
215 assertEquals(1, eidRecords.size());
216 EidToLocatorRecord eidRecord = eidRecords.get(0);
217 assertEquals(2, eidRecord.getLocators().size());
218 assertEquals(new LispIpv4Address("10.1.0.110"), eidRecord.getLocators().get(0).getLocator());
219 assertEquals(new LispIpv4Address("192.168.136.51"), eidRecord.getLocators().get(1).getLocator());
223 public void mapRegister__Ipv6Rloc() throws Exception {
224 // P bit (Proxy-Map-Reply): Set
225 // M bit (Want-Map-Notify): Set
230 // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
231 // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
233 // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
234 // Priority/Weight: 255/0
236 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
237 + "0010 00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 " //
238 + "0020 01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 " //
239 + "0030 00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 " //
240 + "0040 0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 " //
241 + "0050 00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff " //
242 + "0060 01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 " //
243 + "0070 00 01 0a 00 3a 9c"));
245 oneOf(nps).publish(with(lispNotificationSaver));
247 handleMapRegisterPacket(mapRegisterPacket);
248 byte[] expectedIpv6Address = new byte[] { 0x26, 0x10, 0x00, (byte) 0xd0, (byte) 0xff, (byte) 0xff, 0x01, (byte) 0x92, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x01 };
251 EidToLocatorRecord eidToLocatorRecord = lastMapRegister().getEidToLocatorRecords().get(0);
252 assertEquals(new LispIpv6Address(expectedIpv6Address), eidToLocatorRecord.getPrefix());
253 assertEquals(AddressFamilyNumberEnum.IP6, eidToLocatorRecord.getPrefix().getAfi());
255 assertEquals(new LispIpv4Address(0x0A003A9C), eidToLocatorRecord.getLocators().get(0).getLocator());
259 public void mapRegister__VerifyBasicFields() throws Exception {
260 oneOf(nps).publish(with(lispNotificationSaver));
261 handleMapRegisterPacket(mapRegisterPacket);
263 EidToLocatorRecord eidToLocator = lastMapRegister().getEidToLocatorRecords().get(0);
264 assertEquals(new LispIpv4Address(0x9910FE01), eidToLocator.getPrefix());
266 assertEquals(1, eidToLocator.getLocators().size());
267 assertEquals(new LispIpv4Address(0xC0A8880A), eidToLocator.getLocators().get(0).getLocator());
271 public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
272 oneOf(nps).publish(with(lispNotificationSaver));
275 assertNull(handleMapRegisterPacket(mapRegisterPacket));
279 public void mapRegister__NonSetMBit() throws Exception {
280 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
281 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df " //
282 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
283 + "0030 00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
284 + "0040 83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 " //
285 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
286 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
287 stubMapRegister(true);
289 handleMapRegisterPacket(registerWithNonSetMBit);
291 assertFalse(lastMapRegister().isWantMapNotify());
295 public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
296 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
297 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
298 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
299 + "0030 00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
300 + "0040 e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
301 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
302 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
303 stubMapRegister(true);
305 handleMapRegisterPacket(registerWithNonSetMBit);
306 assertFalse(lastMapRegister().isWantMapNotify());
310 public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
311 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
312 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
313 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
314 + "0030 00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
315 + "0040 4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
316 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
317 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
318 stubMapRegister(true);
320 handleMapRegisterPacket(registerWithNonSetMBit);
321 assertTrue(lastMapRegister().isWantMapNotify());
325 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
326 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
327 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
328 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
329 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
330 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
331 + "0050 2a cd 39 c8 d6 08 00 00 00 01 c0 a8 88 0a 00 20 " //
332 + "0060 00 01 01 02 03 04"));
333 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
334 extraDataPacket[mapRegisterPacket.length] = 0x9;
335 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
336 stubMapRegister(true);
338 DatagramPacket dp = new DatagramPacket(extraDataPacket, extraDataPacket.length);
339 dp.setLength(mapRegisterPacket.length);
340 testedLispService.handlePacket(dp);
341 //byte[] notifyResult = testedLispService.handlePacket(dp).getData();
342 byte[] notifyResult = lastMapNotifyPacket().getData();
343 assertEquals(mapRegisterPacket.length, notifyResult.length);
347 private DatagramPacket lastMapReplyPacket() {
348 ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReply);
349 return new DatagramPacket(serialize.array(), serialize.array().length);
352 private DatagramPacket lastMapNotifyPacket() {
353 ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotify);
354 return new DatagramPacket(serialize.array(), serialize.array().length);
358 public void mapNotify__VerifyBasicFields() throws Exception {
359 byte registerType = mapRegisterPacket[0];
360 assertEquals(LispMessageEnum.MapRegister.getValue(), registerType >> 4);
362 stubMapRegister(true);
364 byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
366 assertEquals(mapRegisterPacket.length, result.length);
368 byte expectedType = (byte) (LispMessageEnum.MapNotify.getValue() << 4);
369 assertHexEquals(expectedType, result[0]);
370 assertHexEquals((byte) 0x00, result[1]);
371 assertHexEquals((byte) 0x00, result[2]);
373 byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(mapRegisterPacket, 3, 16),
374 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
375 byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
376 Arrays.copyOfRange(result, 36, result.length));
377 ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData, notifyWithoutTypeWithOutAuthenticationData);
382 public void mapNotify__VerifyPort() throws Exception {
383 stubMapRegister(true);
385 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
386 assertEquals(LispMessage.PORT_NUM, notifyPacket.getPort());
390 public void mapRequest__VerifyBasicFields() throws Exception {
391 oneOf(nps).publish(with(lispNotificationSaver));
392 handleMapRequestAsByteArray(mapRequestPacket);
393 List<EidRecord> eids = lastMapRequest().getEids();
394 assertEquals(1, eids.size());
395 LispAddress lispAddress = eids.get(0).getPrefix();
396 assertTrue(lispAddress instanceof LispIpv4Address);
397 assertEquals(asInet(0x01020304), ((LispIpv4Address) lispAddress).getAddress());
398 assertEquals((byte) 0x20, eids.get(0).getMaskLength());
399 assertEquals(0x3d8d2acd39c8d608L, lastMapRequest().getNonce());
400 assertEquals(AddressFamilyNumberEnum.RESERVED, lastMapRequest().getSourceEid().getAfi());
404 public void mapRequest__Ipv6Eid() throws Exception {
405 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
406 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
407 // (2610:d0:ffff:192::2)
410 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
411 // ITR-RLOC 1: 10.0.58.156
412 // Record 1: 2610:d0:ffff:192::2/128
413 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
414 // Authoritative, No-Action
416 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
417 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
418 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
419 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
420 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
421 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
422 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
423 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
424 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
425 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 " //
426 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 " //
427 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
429 oneOf(nps).publish(with(lispNotificationSaver));
432 handleMapRequestAsByteArray(mapRequestPacket);
433 assertEquals(new LispIpv6Address("2610:d0:ffff:192::1"), lastMapRequest().getSourceEid());
434 assertEquals(new LispIpv6Address("2610:d0:ffff:192::2"), lastMapRequest().getEids().get(0).getPrefix());
439 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
440 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
441 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
442 // (2610:d0:ffff:192::2)
443 // encapsulated UDP source port: 4342
445 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
446 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
447 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
448 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
449 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
450 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
451 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
452 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
453 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
454 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 " //
455 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 " //
456 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
457 oneOf(nps).publish(with(lispNotificationSaver));
460 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
461 assertEquals(4342, replyPacket.getPort());
465 public void mapRequest__WithSourceEid() throws Exception {
466 // encapsulated LISP packet
467 // Source EID = 153.16.254.1
469 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 " //
470 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
471 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
472 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
473 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 14 00 00 01 ba f9 "
474 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
475 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
476 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 " //
477 + "0080 00 01 0a 00 01 26"));
479 oneOf(nps).publish(with(lispNotificationSaver));
482 handleMapRequestAsByteArray(mapRequestPacket);
483 Assert.assertNotEquals(AddressFamilyNumberEnum.RESERVED, lastMapRequest().getSourceEid().getAfi());
488 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
489 eidToLocator.setMaskLength((byte) 0x20)//
490 .setPrefix(new LispIpv4Address(0x0a0014c8));
491 mapReply.setNonce(0x3d8d2acd39c8d608L);
495 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
497 assertEquals(28, result.length);
499 byte expectedLispMessageType = 2;
500 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
501 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
503 byte expectedRecordCount = (byte) 1;
504 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
506 assertEquals(eidToLocator.getMaskLength(), result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
507 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
508 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
512 public void mapReply__VerifyBasicIPv6() throws Exception {
513 eidToLocator.setMaskLength((byte) 0x80)//
514 .setPrefix(new LispIpv6Address("::1"));
518 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
520 assertEquals(40, result.length);
522 byte expectedRecordCount = (byte) 1;
523 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
525 assertEquals(eidToLocator.getMaskLength(), result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
526 assertEquals(AddressFamilyNumberEnum.IP6.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
527 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
529 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
533 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
534 eidToLocator.setPrefix(new LispIpv6Address("::1"));
535 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv6Address("::2")));
539 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
541 assertEquals(64, result.length);
543 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
544 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
546 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
547 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
552 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
555 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).getPort());
559 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
560 eidToLocator.setMaskLength((byte) 0x20)//
561 .setPrefix(new LispIpv4Address(0x0a0014c8));
562 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv4Address(0x04030201)).setRouted(false));
565 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
566 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
570 public void mapReply__WithSingleLocator() throws Exception {
571 eidToLocator.setMaskLength((byte) 0x20)//
572 .setPrefix(new LispIpv4Address(0x0a0014c8));
573 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv4Address(0x04030201)).setRouted(true));
576 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
577 assertEquals(40, result.length);
579 byte expectedLocCount = 1;
580 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
582 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
584 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
585 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
589 public void mapReply__WithMultipleLocator() throws Exception {
590 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv4Address(0x04030201)).setRouted(true));
591 eidToLocator.addLocator(new LocatorRecord().setLocator(new LispIpv6Address("::1")).setRouted(true));
594 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
595 assertEquals(64, result.length);
597 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
599 assertEquals(AddressFamilyNumberEnum.IP.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
600 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
601 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
603 assertEquals(AddressFamilyNumberEnum.IP6.getIanaCode(), ByteUtil.getShort(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
605 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
606 ArrayAssert.assertEquals(expectedIpv6Rloc,
607 Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR, MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
609 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
613 public void handleUnknownLispMessage() throws Exception {
614 // IP: 192.168.136.10 -> 128.223.156.35
615 // UDP: 49289 -> 4342
616 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
618 byte[] unknownTypePacket = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
619 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
620 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
621 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
622 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
623 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
624 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
625 assertNull(handlePacket(unknownTypePacket));
629 public void mapRequest__MultipleItrRlocs() throws Exception {
630 // this is what LISPmob sends when configured multiple RLOCs for single
632 // ITR-RLOC 1: 10.1.0.111
633 // ITR-RLOC 2: 192.168.136.51
635 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
636 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 " //
637 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 " //
638 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 " //
639 + "0040 08 08 10 f6 10 f6 00 56 63 14 14 00 01 01 79 67 " //
640 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 " //
641 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 " //
642 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 " //
643 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 " //
644 + "0090 00 05 00 01 c0 a8 88 33"));
646 oneOf(nps).publish(with(lispNotificationSaver));
647 handleMapRequestAsByteArray(mapRequestPacket);
651 private void stubMapRegister(final boolean setNotifyFromRegister) {
652 allowing(nps).publish(with(lispNotificationSaver));
653 will(new SimpleAction() {
656 public Object invoke(Invocation invocation) throws Throwable {
657 if (setNotifyFromRegister) {
658 mapNotify.setFromMapRegister(lastMapRegister());
665 private void stubHandleRequest() {
666 allowing(nps).publish(wany(LispNotification.class));
669 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
670 handleMapRequestPacket(inPacket);
671 return lastMapReplyPacket().getData();
674 private byte[] handlePacketAsByteArray(byte[] inPacket) {
675 return handlePacket(inPacket).getData();
678 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
679 handleMapRegisterPacket(inPacket);
680 return lastMapNotifyPacket().getData();
683 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
684 testedLispService.handlePacket(new DatagramPacket(inPacket, inPacket.length));
685 return lastMapReplyPacket();
688 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
689 testedLispService.handlePacket(new DatagramPacket(inPacket, inPacket.length));
690 if (mapNotify == null) {
693 return lastMapNotifyPacket();
697 private DatagramPacket handlePacket(byte[] inPacket) {
698 // TODO get from mock
699 testedLispService.handlePacket(new DatagramPacket(inPacket, inPacket.length));
703 private byte[] extractWSUdpByteArray(String wiresharkHex) {
704 final int HEADER_LEN = 42;
705 byte[] res = new byte[1000];
706 String[] split = wiresharkHex.split(" ");
708 for (String cur : split) {
710 if (cur.length() == 2) {
712 if (counter > HEADER_LEN) {
713 res[counter - HEADER_LEN - 1] = (byte) Integer.parseInt(cur, 16);
718 return Arrays.copyOf(res, counter - HEADER_LEN);
721 @Test(expected = LispMalformedPacketException.class)
722 public void mapRequest__NoIPITRRLOC() throws Exception {
723 mapRequestPacket = hexToByteBuffer("10 00 " //
724 + "02 " // This means 3 ITR - RLOCs
725 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
726 + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 3)
727 + "40 05 00 00 00 00 00 00 " // MAC (ITR-RLOC #2 of 3)
728 + "40 05 11 22 34 56 78 90 " // MAC (ITR-RLOC #3 of 3)
729 + "00 20 00 01 01 02 03 04").array();
730 handleMapRequestPacket(mapRequestPacket);
735 public void mapRequest__IPITRRLOCIsSecond() throws Exception {
736 mapRequestPacket = hexToByteBuffer("10 00 " //
737 + "01 " // This means 3 ITR - RLOCs
738 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
739 + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 2)
740 + "00 01 01 02 03 04 " // IP (ITR-RLOC #2 of 2)
741 + "00 20 00 01 01 02 03 04").array();
742 oneOf(nps).publish(with(lispNotificationSaver));
744 DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
745 assertEquals(2, lastMapRequest().getItrRlocs().size());
746 assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(), packet.getAddress());
751 public void mapRequest__MULTIPLEIPITRRLOCs() throws Exception {
752 mapRequestPacket = hexToByteBuffer("10 00 " //
753 + "01 " // This means 3 ITR - RLOCs
754 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
755 + "00 01 01 02 03 04 " // IP (ITR-RLOC #1 of 2)
756 + "00 01 c0 a8 88 0a " // MAC (ITR-RLOC #2 of 2)
757 + "00 20 00 01 01 02 03 04").array();
758 oneOf(nps).publish(with(lispNotificationSaver));
760 DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
761 assertEquals(2, lastMapRequest().getItrRlocs().size());
762 assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(), packet.getAddress());