2 * Copyright (c) 2014 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 io.netty.buffer.Unpooled.wrappedBuffer;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertTrue;
15 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA1;
16 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA2;
17 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA3;
18 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.KEY_ID;
19 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.NONCE;
20 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.SITE_ID;
21 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.XTR_ID;
22 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.joinArrays;
24 import io.netty.channel.socket.DatagramPacket;
25 import java.net.InetSocketAddress;
26 import java.net.UnknownHostException;
27 import java.nio.ByteBuffer;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.List;
32 import junitx.framework.ArrayAssert;
33 import org.apache.commons.lang3.ArrayUtils;
34 import org.junit.Before;
35 import org.junit.BeforeClass;
36 import org.junit.Ignore;
37 import org.junit.Test;
38 import org.mockito.AdditionalMatchers;
39 import org.mockito.ArgumentCaptor;
40 import org.mockito.ArgumentMatchers;
41 import org.mockito.InOrder;
42 import org.mockito.Mockito;
43 import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
44 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
45 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
46 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
47 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
48 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
49 import org.opendaylight.lispflowmapping.mapcache.AuthKeyDb;
50 import org.opendaylight.lispflowmapping.southbound.ConcurrentLispSouthboundStats;
51 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
52 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterCache;
53 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
54 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
55 import org.opendaylight.mdsal.binding.api.DataBroker;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.afn.safi.rev130704.AddressFamily;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4BinaryAfi;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4PrefixBinaryAfi;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv6PrefixBinaryAfi;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKeyBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValue;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValueBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecord;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecord.Action;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecordBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.list.MappingRecordItem;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.list.MappingRecordItemBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkeyBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapreplymessage.MapReplyBuilder;
81 import org.opendaylight.yangtools.yang.binding.Notification;
82 import org.opendaylight.yangtools.yang.common.Uint16;
83 import org.opendaylight.yangtools.yang.common.Uint32;
85 public class LispSouthboundHandlerTest extends BaseTestCase {
87 private LispSouthboundHandler testedLispService;
88 private byte[] mapRequestPacket;
89 private byte[] mapRegisterPacket;
90 private MapNotifyBuilder mapNotifyBuilder;
91 private MapReplyBuilder mapReplyBuilder;
92 private MappingRecordBuilder mappingRecordBuilder;
93 private MapRegisterCache mapRegisterCache;
94 private LispSouthboundPlugin mockLispSouthboundPlugin;
95 private LispSouthboundPlugin contextMockLispSouthboundPlugin;
96 private static final long CACHE_RECORD_TIMEOUT = 90000;
98 private static AuthKeyDb akdb;
99 private static AuthenticationKeyDataListener akdl;
101 private interface MapReplyIpv4SingleLocatorPos {
102 int RECORD_COUNT = 3;
104 int LOCATOR_COUNT = 16;
105 int EID_MASK_LEN = 17;
109 int LOCATOR_RBIT = 33;
113 private interface MapReplyIpv4SecondLocatorPos {
114 int FIRST_LOCATOR_IPV4_LENGTH = 12;
115 int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
116 int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
117 int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
121 public static void initTests() {
122 akdb = Mockito.mock(AuthKeyDb.class);
123 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
125 .thenReturn(new MappingAuthkeyBuilder().setKeyType(Uint16.ONE).setKeyString("password").build());
126 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
127 "2610:d0:ffff:192:0:0:0:1/128"))))
128 .thenReturn(new MappingAuthkeyBuilder().setKeyType(Uint16.ONE).setKeyString("password").build());
129 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
130 "153.16.254.1/32"))))
131 .thenReturn(new MappingAuthkeyBuilder().setKeyType(Uint16.ONE).setKeyString("password").build());
132 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
133 "125.124.123.122/8", new InstanceIdType(Uint32.valueOf(21))))))
134 .thenReturn(new MappingAuthkeyBuilder().setKeyType(Uint16.ONE).setKeyString("password").build());
135 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asMacEid(
136 "0a:0b:0c:0d:0e:0f"))))
137 .thenReturn(new MappingAuthkeyBuilder().setKeyType(Uint16.ONE).setKeyString("password").build());
138 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
139 "f0f:f0f:f0f:f0f:f0f:f0f:f0f:f0f/8"))))
140 .thenReturn(new MappingAuthkeyBuilder().setKeyType(Uint16.ONE).setKeyString("password").build());
141 Mockito.when(akdb.getAuthenticationKey(ArgumentMatchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid(
143 .thenReturn(new MappingAuthkeyBuilder().setKeyType(Uint16.ONE).setKeyString("password").build());
145 akdl = Mockito.mock(AuthenticationKeyDataListener.class);
146 Mockito.when(akdl.authKeysForEidsUnchanged(Mockito.anyMap(), Mockito.anyLong())).thenReturn(true);
151 public void before() throws Exception {
153 mockLispSouthboundPlugin = Mockito.mock(LispSouthboundPlugin.class);
154 contextMockLispSouthboundPlugin = context.mock(LispSouthboundPlugin.class);
155 Mockito.when(mockLispSouthboundPlugin.isMapRegisterCacheEnabled()).thenReturn(true);
156 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCacheTimeout()).thenReturn(CACHE_RECORD_TIMEOUT);
157 mapRegisterCache = new MapRegisterCache();
158 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
159 Mockito.when(mockLispSouthboundPlugin.getDataBroker()).thenReturn(Mockito.mock(DataBroker.class));
160 Mockito.when(mockLispSouthboundPlugin.getAkdb()).thenReturn(akdb);
161 Mockito.when(mockLispSouthboundPlugin.getAuthenticationKeyDataListener()).thenReturn(akdl);
162 ConcurrentLispSouthboundStats lispSouthboundStats = new ConcurrentLispSouthboundStats();
163 Mockito.when(mockLispSouthboundPlugin.getStats()).thenReturn(lispSouthboundStats);
164 testedLispService = new LispSouthboundHandler(mockLispSouthboundPlugin);
166 // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
167 // LISP(Type = 8 - Encapsulated)
168 // IP: 192.168.136.10 -> 1.2.3.4
170 // LISP(Type = 1 Map-Request
174 // Source EID not present
175 // Nonce: 0x3d8d2acd39c8d608
176 // ITR-RLOC AFI=1 Address=192.168.136.10
177 // Record 1: 1.2.3.4/32
178 mapRequestPacket = extractWSUdpByteArray(
179 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
180 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
181 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
182 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
183 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
184 + "0050 2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 c0 a8 88 0a 00 20 "
185 + "0060 00 01 01 02 03 04");
186 mapReplyBuilder = new MapReplyBuilder();
187 mapReplyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
188 mapReplyBuilder.setNonce((long) 0);
189 mapReplyBuilder.setEchoNonceEnabled(false);
190 mapReplyBuilder.setProbe(true);
191 mapReplyBuilder.setSecurityEnabled(true);
192 mappingRecordBuilder = new MappingRecordBuilder();
193 String ip = "0.0.0.0";
194 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid(ip + "/0"));
195 mappingRecordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
196 mappingRecordBuilder.setRecordTtl(10);
197 mappingRecordBuilder.setMapVersion((short) 0);
198 mappingRecordBuilder.setAction(Action.NativelyForward);
199 mappingRecordBuilder.setAuthoritative(false);
200 // eidToLocatorBuilder.setPrefix(new LispIpv4Address(0));
201 // mapReply.addEidToLocator(eidToLocatorBuilder);
203 // IP: 192.168.136.10 -> 128.223.156.35
204 // UDP: 49289 -> 4342
205 // LISP(Type = 3 Map-Register, P=1, M=1
209 // AuthDataLength: 20 Data:
210 // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
211 // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
213 // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
214 // Priority/Weight: 1/100, Multicast Priority/Weight:
218 mapRegisterPacket = extractWSUdpByteArray(
219 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
220 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
221 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
222 + "0030 00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
223 + "0040 71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
224 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
225 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
226 mapNotifyBuilder = new MapNotifyBuilder();
227 mapNotifyBuilder.setAuthenticationData(new byte[0]);
232 public void todos() throws Exception {
234 // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
235 // TODO: Non-Encapsulated packets
238 @Test(expected = LispMalformedPacketException.class)
239 public void mapRegister__IllegalPacket() throws Exception {
240 mapRegisterPacket = extractWSUdpByteArray(
241 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
242 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
243 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 ");
245 handleMapRegisterPacket(mapRegisterPacket);
248 @Test(expected = LispMalformedPacketException.class)
249 public void mapRequest__IllegalPacket() throws Exception {
250 mapRequestPacket = extractWSUdpByteArray(
251 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
252 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
253 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
254 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
255 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d ");
256 handleMapRequestPacket(mapRequestPacket);
259 @Test(expected = LispMalformedPacketException.class)
260 public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
261 mapRequestPacket = extractWSUdpByteArray(
262 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
263 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
264 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 ");
265 handleMapRequestPacket(mapRequestPacket);
269 public void mapRegister__TwoRlocs() throws Exception {
271 // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
272 // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
273 // Priority/Weight: 255/0
274 // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
275 // Multicast Priority/Weight: 255/0
276 mapRegisterPacket = extractWSUdpByteArray(
277 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
278 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
279 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "
280 + "0030 00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 "
281 + "0040 e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 "
282 + "0050 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 "
283 + "0060 ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 "
284 + "0070 00 01 c0 a8 88 33");
286 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
287 handleMapRegisterPacket(mapRegisterPacket);
288 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
290 List<MappingRecordItem> eidRecords = captor.getValue().getMapRegister().getMappingRecordItem();
291 assertEquals(1, eidRecords.size());
292 MappingRecord eidRecord = eidRecords.get(0).getMappingRecord();
293 assertEquals(2, eidRecord.getLocatorRecord().size());
294 assertEquals(LispAddressUtil.asIpv4Rloc("10.1.0.110"), eidRecord.getLocatorRecord().get(0).getRloc());
295 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.51"), eidRecord.getLocatorRecord().get(1).getRloc());
299 public void mapRegister__Ipv6Rloc() throws Exception {
300 // P bit (Proxy-Map-Reply): Set
301 // M bit (Want-Map-Notify): Set
306 // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
307 // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
309 // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
310 // Priority/Weight: 255/0
312 mapRegisterPacket = extractWSUdpByteArray(
313 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
314 + "0010 00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 "
315 + "0020 01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 "
316 + "0030 00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 "
317 + "0040 0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 "
318 + "0050 00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff "
319 + "0060 01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 "
320 + "0070 00 01 0a 00 3a 9c");
322 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
323 handleMapRegisterPacket(mapRegisterPacket);
324 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
325 MappingRecord eidToLocatorRecord =
326 captor.getValue().getMapRegister().getMappingRecordItem().get(0).getMappingRecord();
328 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:1/128"),
329 eidToLocatorRecord.getEid());
330 assertEquals(Ipv6PrefixBinaryAfi.VALUE, eidToLocatorRecord.getEid().getAddressType());
332 assertEquals(LispAddressUtil.asIpv4Rloc("10.0.58.156"), eidToLocatorRecord.getLocatorRecord().get(0).getRloc());
336 public void mapRegister__VerifyBasicFields() throws Exception {
337 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
338 handleMapRegisterPacket(mapRegisterPacket);
339 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
340 MappingRecord eidToLocator =
341 captor.getValue().getMapRegister().getMappingRecordItem().get(0).getMappingRecord();
343 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"), eidToLocator.getEid());
344 assertEquals(1, eidToLocator.getLocatorRecord().size());
345 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.10"), eidToLocator.getLocatorRecord().get(0).getRloc());
349 public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
350 mapNotifyBuilder = null;
351 assertNull(handleMapRegisterPacket(mapRegisterPacket));
355 public void mapRegister__NonSetMBit() throws Exception {
356 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
357 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
358 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
359 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
360 + "0030 00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
361 + "0040 83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 "
362 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
363 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
365 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
366 handleMapRegisterPacket(registerWithNonSetMBit);
367 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
368 assertFalse(captor.getValue().getMapRegister().getWantMapNotify());
372 public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
373 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
374 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
375 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
376 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
377 + "0030 00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
378 + "0040 e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
379 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
380 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
382 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
383 handleMapRegisterPacket(registerWithNonSetMBit);
384 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
385 assertFalse(captor.getValue().getMapRegister().getWantMapNotify());
389 public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
390 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
391 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
392 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
393 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
394 + "0030 00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
395 + "0040 4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
396 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
397 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
399 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
400 handleMapRegisterPacket(registerWithNonSetMBit);
401 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
402 assertTrue(captor.getValue().getMapRegister().getWantMapNotify());
406 * Tests whether handling of map-register message will generate mapping-keep-alive notification.
409 public void mapRegister_isMappingKeepAliveAndMapNotifyGenerated() throws InterruptedException,
410 UnknownHostException {
411 byte[] eidPrefixAfi = new byte[] {
416 byte[] eidPrefix = new byte[] {
418 0x0a, 0x0a, 0x0a, 0x0a
421 //send stream of byte -> map register message
422 InOrder inOrder = Mockito.inOrder(mockLispSouthboundPlugin);
423 final MapRegisterCacheKey cacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
424 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(cacheKey, mapRegisterCache);
425 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
426 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
427 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
428 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
429 cacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
431 //sending the same byte stream -> map register second time
432 captor = ArgumentCaptor.forClass(AddMapping.class);
433 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
434 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
436 //mapping-keep-alive message should be generated
437 MapRegisterCacheTestUtil.afterSecondMapRegisterInvocationValidation(
438 mockLispSouthboundPlugin, eidPrefixAfi, eidPrefix);
441 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix) {
442 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
445 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) {
446 final byte[] mapRegisterMessage = MapRegisterCacheTestUtil.joinArrays(DATA1, NONCE, KEY_ID,
447 authenticationData, DATA2, eidPrefixAfi, eidPrefix, DATA3, XTR_ID, SITE_ID);
448 handlePacket(mapRegisterMessage);
452 * It tests whether map register message is stored to local cache with Ipv4 EidPrefix.
455 public void mapRegister_cacheWithEidPrefixIpv4Test() throws InterruptedException {
456 byte[] eidPrefixAfi = new byte[] {
461 byte[] eidPrefix = new byte[] {
463 0x0a, 0x0a, 0x0a, 0x0a
466 cacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
470 * It tests whether map register message is stored to local cache with Ipv6 EidPrefix.
473 public void mapRegister_cacheWithEidPrefixIpv6Test() throws InterruptedException {
474 byte[] eidPrefixAfi = new byte[] {
479 byte[] eidPrefix = new byte[] {
481 0x0f, 0x0f, 0x0f, 0x0f,
483 0x0f, 0x0f, 0x0f, 0x0f,
485 0x0f, 0x0f, 0x0f, 0x0f,
487 0x0f, 0x0f, 0x0f, 0x0f
490 byte[] authenticationData = new byte[] {
492 0x41,(byte)0x83,0x13,0x7C,
493 0x48,(byte)0xEE,0x75,(byte)0x9A,
494 0x4,(byte)0x8C,0x46,(byte)0xA6,
495 0x1B,0x13,(byte)0xC8,0x4D,
496 (byte)0xA1,0x17,0x53,(byte)0xC3
499 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
503 * It tests whether map register message is stored to local cache with Mac 48bits EidPrefix.
506 public void mapRegister_cacheWithEidPrefixMac48Test() throws InterruptedException {
507 byte[] eidPrefixAfi = new byte[] {
512 byte[] eidPrefix = new byte[] {
514 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
517 byte[] authenticationData = new byte[] {
519 (byte)0xB2,(byte)0x8E,0x6,(byte)0x9D,
520 0x61,(byte)0xD8,0xC,0x24,
521 (byte)0x80,0x61,0x5A,0x20,
522 0xD,0x50,0x5E,(byte)0xAE,
523 0x47,(byte)0xF7,(byte)0x86,0x36
525 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
529 * It tests whether map register message is stored to local cache with Lcaf EidPrefix (inside Ipv4).
532 public void mapRegister_cacheWithEidPrefixLcafTest() throws InterruptedException {
533 byte[] eidPrefixAfi = new byte[] {
538 //following lcaf prefixed variables are defined according to https://tools.ietf
539 // .org/html/draft-ietf-lisp-lcaf-12#section-4.1
540 byte[] lcafRsvd1 = new byte[]{0x00};
541 byte[] lcafFlags = new byte[]{0x00};
542 byte[] lcafType = new byte[]{0x02};
543 byte[] lcafIIDMaskLength = new byte[]{0x20};
544 byte[] lcafLength = new byte[] {0x00, 0x0a};
545 byte[] lcafInstanceId = new byte[]{0x00, 0x00, 0x00, 0x15};
546 byte[] lcafAfi = new byte[] {0x00, 0x01};
547 byte[] lcafAddress = new byte[] {0x7d, 0x7c, 0x7b, 0x7a};
549 byte[] eidPrefix = joinArrays(lcafRsvd1, lcafFlags, lcafType, lcafIIDMaskLength, lcafLength, lcafInstanceId,
550 lcafAfi, lcafAddress);
552 byte[] authenticationData = new byte[] {
553 //authentication data length
556 0x68, 0x1d, (byte) 0x9e, 0x6e,
558 0x5e, 0x32, (byte) 0x88, 0x1a,
560 (byte) 0xae, 0x6b, (byte) 0xe3, 0x40,
562 0x30, (byte) 0x0b, (byte) 0xb6, (byte) 0xa0,
564 0x71, (byte) 0xf4, (byte) 0x8c, 0x5f
568 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
572 * It tests whether map register message is stored to local cache.
574 public void cacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) throws
575 InterruptedException {
576 final MapRegisterCacheKey mapRegisterCacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
578 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(mapRegisterCacheKey, mapRegisterCache);
579 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
580 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, authenticationData);
581 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
582 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
583 mapRegisterCacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
588 Checks whether old record from cache will expire and is replaced with new record.
590 add to empty cache record with timestamp older then 90 second - one object
591 add the same entry through calling of handleMapRegister
592 check that removeEntry() and addEntry() (or refreshEntry() was called on mocked object for mapRegisterCache
595 public void mapRegister_cacheRecordExpirationTest() throws InterruptedException {
596 //tests handling of map register message when next message comes:
598 //after cache entry timeout
599 cacheRecordExpirationTest(true);
601 //before cache entry timout
602 cacheRecordExpirationTest(false);
605 private void cacheRecordExpirationTest(boolean cacheRecordTimeouted) throws InterruptedException {
606 mapRegisterCache = Mockito.mock(MapRegisterCache.class);
607 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
609 final byte[] eidPrefixAfi = new byte[] {0x00, 0x01};
610 final byte[] eidPrefix = new byte[] {0x0a, 0x0a, 0x0a, 0x0a};
612 MapRegisterCacheKeyBuilder cacheKeyBld = new MapRegisterCacheKeyBuilder();
613 cacheKeyBld.setXtrId(XTR_ID);
614 cacheKeyBld.setEidPrefix(eidPrefix);
615 cacheKeyBld.setSiteId(SITE_ID);
617 MapRegisterCacheMetadataBuilder cacheMetadataBld = new MapRegisterCacheMetadataBuilder();
618 cacheMetadataBld.setTimestamp(System.currentTimeMillis() - (cacheRecordTimeouted ? CACHE_RECORD_TIMEOUT : 0L));
619 cacheMetadataBld.setWantMapNotify(false);
620 cacheMetadataBld.setEidLispAddress(Map.of());
622 MapRegisterCacheValueBuilder cacheValueBld = new MapRegisterCacheValueBuilder();
623 cacheValueBld.setMapRegisterCacheMetadata(cacheMetadataBld.build());
624 cacheValueBld.setPacketData(MapRegisterCacheTestUtil.joinArrays(DATA1, KEY_ID, DATA2, eidPrefixAfi,
625 eidPrefix, DATA3, XTR_ID, SITE_ID));
628 final MapRegisterCacheKey cacheKey = cacheKeyBld.build();
629 final MapRegisterCacheValue cacheValue = cacheValueBld.build();
631 Mockito.when(mapRegisterCache.getEntry(Mockito.eq(cacheKey))).thenReturn(cacheRecordTimeouted ? null :
633 Mockito.when(mapRegisterCache.refreshEntry(Mockito.eq(cacheKey))).thenReturn(cacheValue);
635 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
636 Mockito.verify(mockLispSouthboundPlugin, Mockito.atLeastOnce()).sendNotificationIfPossible(
637 Mockito.any(AddMapping.class));
639 InOrder inOrder = Mockito.inOrder(mapRegisterCache);
640 inOrder.verify(mapRegisterCache).getEntry(Mockito.eq(cacheKey));
642 if (cacheRecordTimeouted) {
643 inOrder.verify(mapRegisterCache).addEntry(Mockito.eq(cacheKey), AdditionalMatchers.not(Mockito.eq(
646 inOrder.verify(mapRegisterCache).refreshEntry(Mockito.eq(cacheKey));
652 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
653 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
654 extraDataPacket[mapRegisterPacket.length] = 0x9;
655 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
657 DatagramPacket dp = new DatagramPacket(wrappedBuffer(extraDataPacket), new InetSocketAddress(0),
658 new InetSocketAddress(0));
659 testedLispService.handlePacket(dp);
660 // Check map register fields.
662 // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
663 byte[] notifyResult = lastMapNotifyPacket().content().array();
664 assertEquals(mapRegisterPacket.length, notifyResult.length);
668 private DatagramPacket lastMapReplyPacket() {
669 ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
670 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
673 private DatagramPacket lastMapNotifyPacket() {
674 if (mapNotifyBuilder.getMappingRecordItem() == null) {
675 mapNotifyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
677 mapNotifyBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder()
678 .setMappingRecordItemId("foo")
679 .setMappingRecord(mappingRecordBuilder.build()).build());
680 mapNotifyBuilder.setNonce((long) 0);
681 mapNotifyBuilder.setKeyId((short) 0);
682 mapNotifyBuilder.setAuthenticationData(new byte[0]);
683 ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotifyBuilder.build());
684 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
689 public void mapNotify__VerifyBasicFields() throws Exception {
690 byte registerType = mapRegisterPacket[0];
691 assertEquals(MessageType.MapRegister.getIntValue(), registerType >> 4);
693 byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
695 assertEquals(mapRegisterPacket.length, result.length);
697 byte expectedType = (byte) (MessageType.MapNotify.getIntValue() << 4);
698 assertHexEquals(expectedType, result[0]);
699 assertHexEquals((byte) 0x00, result[1]);
700 assertHexEquals((byte) 0x00, result[2]);
702 byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(
703 Arrays.copyOfRange(mapRegisterPacket, 3, 16),
704 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
705 byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
706 Arrays.copyOfRange(result, 36, result.length));
707 ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData,
708 notifyWithoutTypeWithOutAuthenticationData);
713 public void mapNotify__VerifyPort() throws Exception {
714 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
715 assertEquals(LispMessage.PORT_NUM, notifyPacket.recipient().getPort());
719 public void mapRequest__VerifyBasicFields() throws Exception {
720 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
721 handleMapRequestAsByteArray(mapRequestPacket);
722 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
723 List<EidItem> eids = captor.getValue().getMapRequest().getEidItem();
724 assertEquals(1, eids.size());
725 Eid lispAddress = eids.get(0).getEid();
726 assertEquals(Ipv4PrefixBinaryAfi.VALUE, lispAddress.getAddressType());
727 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32"), lispAddress);
728 assertEquals(0x3d8d2acd39c8d608L, captor.getValue().getMapRequest().getNonce().longValue());
732 public void mapRequest__Ipv6Eid() throws Exception {
733 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
734 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
735 // (2610:d0:ffff:192::2)
738 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
739 // ITR-RLOC 1: 10.0.58.156
740 // Record 1: 2610:d0:ffff:192::2/128
741 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
742 // Authoritative, No-Action
744 mapRequestPacket = extractWSUdpByteArray(
745 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
746 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
747 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
748 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
749 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
750 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
751 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
752 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
753 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
754 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
755 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
756 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
758 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
759 handleMapRequestAsByteArray(mapRequestPacket);
760 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
761 assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"),
762 captor.getValue().getMapRequest().getSourceEid().getEid());
763 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:2/128"),
764 captor.getValue().getMapRequest().getEidItem().get(0).getEid());
769 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
770 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
771 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
772 // (2610:d0:ffff:192::2)
773 // encapsulated UDP source port: 4342
775 mapRequestPacket = extractWSUdpByteArray(
776 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
777 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
778 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
779 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
780 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
781 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
782 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
783 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
784 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
785 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
786 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
787 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
789 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
790 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
791 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any());
792 assertEquals(4342, replyPacket.recipient().getPort());
796 public void mapRequest__WithSourceEid() throws Exception {
797 // encapsulated LISP packet
798 // Source EID = 153.16.254.1
800 mapRequestPacket = extractWSUdpByteArray(
801 "0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 "
802 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
803 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
804 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
805 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
806 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
807 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
808 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 "
809 + "0080 00 01 0a 00 01 26");
811 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
812 handleMapRequestAsByteArray(mapRequestPacket);
813 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
814 assertEquals(Ipv4BinaryAfi.VALUE, captor.getValue().getMapRequest().getSourceEid().getEid().getAddressType());
820 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
821 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
822 mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
826 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
828 assertEquals(28, result.length);
830 byte expectedLispMessageType = 2;
831 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
832 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
834 byte expectedRecordCount = (byte) 1;
835 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
837 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
838 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
839 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
840 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
845 public void mapReply_q_VerifyBasicIPv6() throws Exception {
846 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
850 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
852 assertEquals(40, result.length);
854 byte expectedRecordCount = (byte) 1;
855 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
857 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
858 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
859 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
860 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
862 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
867 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
868 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
869 mappingRecordBuilder.getLocatorRecord().add(
870 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
874 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
876 assertEquals(64, result.length);
878 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
879 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
881 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
882 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
887 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
890 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).recipient().getPort());
895 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
896 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
897 mappingRecordBuilder.getLocatorRecord().add(
898 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
901 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
902 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
907 public void mapReply__WithSingleLocator() throws Exception {
908 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
909 mappingRecordBuilder.getLocatorRecord().add(
910 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
913 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
914 assertEquals(40, result.length);
916 byte expectedLocCount = 1;
917 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
919 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
921 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
922 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
927 public void mapReply__WithMultipleLocator() throws Exception {
928 mappingRecordBuilder.getLocatorRecord().add(
929 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
930 mappingRecordBuilder.getLocatorRecord().add(
931 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1"))
935 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
936 assertEquals(64, result.length);
938 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
940 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
941 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
942 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
944 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
946 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
947 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
948 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
950 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
954 public void handleUnknownLispMessage() throws Exception {
955 // IP: 192.168.136.10 -> 128.223.156.35
956 // UDP: 49289 -> 4342
957 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
959 byte[] unknownTypePacket = extractWSUdpByteArray(
960 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
961 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
962 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
963 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
964 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
965 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
966 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
967 assertNull(handlePacket(unknownTypePacket));
971 public void mapRequest__MultipleItrRlocs() throws Exception {
972 // this is what LISPmob sends when configured multiple RLOCs for single
974 // ITR-RLOC 1: 10.1.0.111
975 // ITR-RLOC 2: 192.168.136.51
977 mapRequestPacket = extractWSUdpByteArray(
978 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
979 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 "
980 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 "
981 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 "
982 + "0040 08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 "
983 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 "
984 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 "
985 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 "
986 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 "
987 + "0090 00 05 00 01 c0 a8 88 33");
989 handleMapRequestAsByteArray(mapRequestPacket);
990 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any(RequestMapping.class));
993 private void stubHandleRequest() {
995 allowing(contextMockLispSouthboundPlugin).sendNotificationIfPossible(wany(Notification.class));
996 } catch (InterruptedException e) {
997 LOG.debug("Interrupted", e);
1001 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
1002 handleMapRequestPacket(inPacket);
1003 return lastMapReplyPacket().content().array();
1006 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
1007 handleMapRegisterPacket(inPacket);
1008 return lastMapNotifyPacket().content().array();
1011 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
1012 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1013 new InetSocketAddress(0));
1014 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1015 // This is till not the real port number, but it's better
1016 //dp.setPort(LispMessage.PORT_NUM);
1017 testedLispService.handlePacket(dp);
1018 return lastMapReplyPacket();
1021 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
1022 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1023 new InetSocketAddress(0));
1024 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1025 // This is till not the real port number, but it's better
1026 //dp.setPort(LispMessage.PORT_NUM);
1027 testedLispService.handlePacket(dp);
1028 if (mapNotifyBuilder == null) {
1031 return lastMapNotifyPacket();
1035 private DatagramPacket handlePacket(byte[] inPacket) {
1036 // TODO get from mock
1037 testedLispService.handlePacket(new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1038 new InetSocketAddress(0)));
1042 private byte[] extractWSUdpByteArray(String wiresharkHex) {
1043 final int headerLen = 42;
1044 byte[] res = new byte[1000];
1045 String[] split = wiresharkHex.split(" ");
1047 for (String cur : split) {
1049 if (cur.length() == 2) {
1051 if (counter > headerLen) {
1052 res[counter - headerLen - 1] = (byte) Integer.parseInt(cur, 16);
1057 return Arrays.copyOf(res, counter - headerLen);
1060 @Test(expected = LispMalformedPacketException.class)
1061 public void mapRequest__NoIpItrRloc() throws Exception {
1062 mapRequestPacket = hexToByteBuffer("10 00 "
1063 // This means 3 ITR - RLOCs
1065 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 "
1066 // MAC (ITR-RLOC #1 of 3)
1067 + "40 05 c0 a8 88 0a 01 02 "
1068 // MAC (ITR-RLOC #2 of 3)
1069 + "40 05 00 00 00 00 00 00 "
1070 // MAC (ITR-RLOC #3 of 3)
1071 + "40 05 11 22 34 56 78 90 "
1072 + "00 20 00 01 01 02 03 04").array();
1073 handleMapRequestPacket(mapRequestPacket);