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.assertArrayEquals;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertTrue;
16 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA1;
17 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA2;
18 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA3;
19 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.KEY_ID;
20 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.NONCE;
21 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.SITE_ID;
22 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.XTR_ID;
23 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.joinArrays;
25 import io.netty.channel.socket.DatagramPacket;
26 import java.net.InetSocketAddress;
27 import java.net.UnknownHostException;
28 import java.nio.ByteBuffer;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
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 assertArrayEquals(registerWithoutTypeWithoutAuthenticationData, notifyWithoutTypeWithOutAuthenticationData);
712 public void mapNotify__VerifyPort() throws Exception {
713 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
714 assertEquals(LispMessage.PORT_NUM, notifyPacket.recipient().getPort());
718 public void mapRequest__VerifyBasicFields() throws Exception {
719 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
720 handleMapRequestAsByteArray(mapRequestPacket);
721 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
722 List<EidItem> eids = captor.getValue().getMapRequest().getEidItem();
723 assertEquals(1, eids.size());
724 Eid lispAddress = eids.get(0).getEid();
725 assertEquals(Ipv4PrefixBinaryAfi.VALUE, lispAddress.getAddressType());
726 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32"), lispAddress);
727 assertEquals(0x3d8d2acd39c8d608L, captor.getValue().getMapRequest().getNonce().longValue());
731 public void mapRequest__Ipv6Eid() throws Exception {
732 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
733 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
734 // (2610:d0:ffff:192::2)
737 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
738 // ITR-RLOC 1: 10.0.58.156
739 // Record 1: 2610:d0:ffff:192::2/128
740 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
741 // Authoritative, No-Action
743 mapRequestPacket = extractWSUdpByteArray(
744 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
745 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
746 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
747 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
748 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
749 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
750 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
751 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
752 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
753 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
754 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
755 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
757 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
758 handleMapRequestAsByteArray(mapRequestPacket);
759 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
760 assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"),
761 captor.getValue().getMapRequest().getSourceEid().getEid());
762 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:2/128"),
763 captor.getValue().getMapRequest().getEidItem().get(0).getEid());
768 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
769 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
770 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
771 // (2610:d0:ffff:192::2)
772 // encapsulated UDP source port: 4342
774 mapRequestPacket = extractWSUdpByteArray(
775 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
776 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
777 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
778 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
779 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
780 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
781 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
782 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
783 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
784 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
785 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
786 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
788 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
789 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
790 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any());
791 assertEquals(4342, replyPacket.recipient().getPort());
795 public void mapRequest__WithSourceEid() throws Exception {
796 // encapsulated LISP packet
797 // Source EID = 153.16.254.1
799 mapRequestPacket = extractWSUdpByteArray(
800 "0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 "
801 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
802 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
803 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
804 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
805 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
806 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
807 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 "
808 + "0080 00 01 0a 00 01 26");
810 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
811 handleMapRequestAsByteArray(mapRequestPacket);
812 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
813 assertEquals(Ipv4BinaryAfi.VALUE, captor.getValue().getMapRequest().getSourceEid().getEid().getAddressType());
819 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
820 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
821 mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
825 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
827 assertEquals(28, result.length);
829 byte expectedLispMessageType = 2;
830 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
831 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
833 byte expectedRecordCount = (byte) 1;
834 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
836 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
837 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
838 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
839 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
844 public void mapReply_q_VerifyBasicIPv6() throws Exception {
845 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
849 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
851 assertEquals(40, result.length);
853 byte expectedRecordCount = (byte) 1;
854 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
856 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
857 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
858 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
859 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
861 assertArrayEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
866 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
867 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
868 mappingRecordBuilder.getLocatorRecord().add(
869 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
873 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
875 assertEquals(64, result.length);
877 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
878 assertArrayEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
880 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
881 assertArrayEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
886 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
889 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).recipient().getPort());
894 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
895 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
896 mappingRecordBuilder.getLocatorRecord().add(
897 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
900 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
901 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
906 public void mapReply__WithSingleLocator() throws Exception {
907 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
908 mappingRecordBuilder.getLocatorRecord().add(
909 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
912 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
913 assertEquals(40, result.length);
915 byte expectedLocCount = 1;
916 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
918 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
920 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
921 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
926 public void mapReply__WithMultipleLocator() throws Exception {
927 mappingRecordBuilder.getLocatorRecord().add(
928 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
929 mappingRecordBuilder.getLocatorRecord().add(
930 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1"))
934 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
935 assertEquals(64, result.length);
937 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
939 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
940 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
941 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
943 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
945 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
946 assertArrayEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
947 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
949 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
953 public void handleUnknownLispMessage() throws Exception {
954 // IP: 192.168.136.10 -> 128.223.156.35
955 // UDP: 49289 -> 4342
956 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
958 byte[] unknownTypePacket = extractWSUdpByteArray(
959 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
960 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
961 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
962 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
963 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
964 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
965 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
966 assertNull(handlePacket(unknownTypePacket));
970 public void mapRequest__MultipleItrRlocs() throws Exception {
971 // this is what LISPmob sends when configured multiple RLOCs for single
973 // ITR-RLOC 1: 10.1.0.111
974 // ITR-RLOC 2: 192.168.136.51
976 mapRequestPacket = extractWSUdpByteArray(
977 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
978 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 "
979 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 "
980 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 "
981 + "0040 08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 "
982 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 "
983 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 "
984 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 "
985 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 "
986 + "0090 00 05 00 01 c0 a8 88 33");
988 handleMapRequestAsByteArray(mapRequestPacket);
989 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any(RequestMapping.class));
992 private void stubHandleRequest() {
994 allowing(contextMockLispSouthboundPlugin).sendNotificationIfPossible(wany(Notification.class));
995 } catch (InterruptedException e) {
996 LOG.debug("Interrupted", e);
1000 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
1001 handleMapRequestPacket(inPacket);
1002 return lastMapReplyPacket().content().array();
1005 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
1006 handleMapRegisterPacket(inPacket);
1007 return lastMapNotifyPacket().content().array();
1010 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
1011 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1012 new InetSocketAddress(0));
1013 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1014 // This is till not the real port number, but it's better
1015 //dp.setPort(LispMessage.PORT_NUM);
1016 testedLispService.handlePacket(dp);
1017 return lastMapReplyPacket();
1020 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
1021 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1022 new InetSocketAddress(0));
1023 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1024 // This is till not the real port number, but it's better
1025 //dp.setPort(LispMessage.PORT_NUM);
1026 testedLispService.handlePacket(dp);
1027 if (mapNotifyBuilder == null) {
1030 return lastMapNotifyPacket();
1034 private DatagramPacket handlePacket(byte[] inPacket) {
1035 // TODO get from mock
1036 testedLispService.handlePacket(new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1037 new InetSocketAddress(0)));
1041 private byte[] extractWSUdpByteArray(String wiresharkHex) {
1042 final int headerLen = 42;
1043 byte[] res = new byte[1000];
1044 String[] split = wiresharkHex.split(" ");
1046 for (String cur : split) {
1048 if (cur.length() == 2) {
1050 if (counter > headerLen) {
1051 res[counter - headerLen - 1] = (byte) Integer.parseInt(cur, 16);
1056 return Arrays.copyOf(res, counter - headerLen);
1059 @Test(expected = LispMalformedPacketException.class)
1060 public void mapRequest__NoIpItrRloc() throws Exception {
1061 mapRequestPacket = hexToByteBuffer("10 00 "
1062 // This means 3 ITR - RLOCs
1064 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 "
1065 // MAC (ITR-RLOC #1 of 3)
1066 + "40 05 c0 a8 88 0a 01 02 "
1067 // MAC (ITR-RLOC #2 of 3)
1068 + "40 05 00 00 00 00 00 00 "
1069 // MAC (ITR-RLOC #3 of 3)
1070 + "40 05 11 22 34 56 78 90 "
1071 + "00 20 00 01 01 02 03 04").array();
1072 handleMapRequestPacket(mapRequestPacket);