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;
31 import junitx.framework.ArrayAssert;
32 import org.apache.commons.lang3.ArrayUtils;
33 import org.junit.Before;
34 import org.junit.BeforeClass;
35 import org.junit.Ignore;
36 import org.junit.Test;
37 import org.mockito.AdditionalMatchers;
38 import org.mockito.ArgumentCaptor;
39 import org.mockito.InOrder;
40 import org.mockito.Matchers;
41 import org.mockito.Mockito;
42 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
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.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.afn.safi.rev130704.AddressFamily;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4BinaryAfi;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4PrefixBinaryAfi;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv6PrefixBinaryAfi;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKeyBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValue;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValueBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkeyBuilder;
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.mapreplymessage.MapReplyBuilder;
80 import org.opendaylight.yangtools.yang.binding.Notification;
82 public class LispSouthboundHandlerTest extends BaseTestCase {
84 private LispSouthboundHandler testedLispService;
85 private byte[] mapRequestPacket;
86 private byte[] mapRegisterPacket;
87 private MapNotifyBuilder mapNotifyBuilder;
88 private MapReplyBuilder mapReplyBuilder;
89 private MappingRecordBuilder mappingRecordBuilder;
90 private MapRegisterCache mapRegisterCache;
91 private LispSouthboundPlugin mockLispSouthboundPlugin;
92 private LispSouthboundPlugin contextMockLispSouthboundPlugin;
93 private static final long CACHE_RECORD_TIMEOUT = 90000;
95 private static AuthKeyDb akdb;
96 private static AuthenticationKeyDataListener akdl;
98 private interface MapReplyIpv4SingleLocatorPos {
101 int LOCATOR_COUNT = 16;
102 int EID_MASK_LEN = 17;
106 int LOCATOR_RBIT = 33;
110 private interface MapReplyIpv4SecondLocatorPos {
111 int FIRST_LOCATOR_IPV4_LENGTH = 12;
112 int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
113 int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
114 int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
117 @SuppressWarnings("unchecked")
119 public static void initTests() {
120 akdb = Mockito.mock(AuthKeyDb.class);
121 Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("10.10.10.10/8"))))
122 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
123 Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
124 "2610:d0:ffff:192:0:0:0:1/128"))))
125 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
126 Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"))))
127 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
128 Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("125.124.123.122/8",
129 new InstanceIdType(21L)))))
130 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
131 Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asMacEid("0a:0b:0c:0d:0e:0f"))))
132 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
133 Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
134 "f0f:f0f:f0f:f0f:f0f:f0f:f0f:f0f/8"))))
135 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
136 Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("172.1.1.2/32"))))
137 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
139 akdl = Mockito.mock(AuthenticationKeyDataListener.class);
140 Mockito.when(akdl.authKeysForEidsUnchanged(Mockito.anyList(), Mockito.anyLong())).thenReturn(true);
145 public void before() throws Exception {
147 mockLispSouthboundPlugin = Mockito.mock(LispSouthboundPlugin.class);
148 contextMockLispSouthboundPlugin = context.mock(LispSouthboundPlugin.class);
149 Mockito.when(mockLispSouthboundPlugin.isMapRegisterCacheEnabled()).thenReturn(true);
150 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCacheTimeout()).thenReturn(CACHE_RECORD_TIMEOUT);
151 mapRegisterCache = new MapRegisterCache();
152 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
153 Mockito.when(mockLispSouthboundPlugin.getDataBroker()).thenReturn(Mockito.mock(DataBroker.class));
154 Mockito.when(mockLispSouthboundPlugin.getAkdb()).thenReturn(akdb);
155 Mockito.when(mockLispSouthboundPlugin.getAuthenticationKeyDataListener()).thenReturn(akdl);
156 ConcurrentLispSouthboundStats lispSouthboundStats = new ConcurrentLispSouthboundStats();
157 Mockito.when(mockLispSouthboundPlugin.getStats()).thenReturn(lispSouthboundStats);
158 testedLispService = new LispSouthboundHandler(mockLispSouthboundPlugin);
160 // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
161 // LISP(Type = 8 - Encapsulated)
162 // IP: 192.168.136.10 -> 1.2.3.4
164 // LISP(Type = 1 Map-Request
168 // Source EID not present
169 // Nonce: 0x3d8d2acd39c8d608
170 // ITR-RLOC AFI=1 Address=192.168.136.10
171 // Record 1: 1.2.3.4/32
172 mapRequestPacket = extractWSUdpByteArray(
173 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
174 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
175 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
176 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
177 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
178 + "0050 2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 c0 a8 88 0a 00 20 "
179 + "0060 00 01 01 02 03 04");
180 mapReplyBuilder = new MapReplyBuilder();
181 mapReplyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
182 mapReplyBuilder.setNonce((long) 0);
183 mapReplyBuilder.setEchoNonceEnabled(false);
184 mapReplyBuilder.setProbe(true);
185 mapReplyBuilder.setSecurityEnabled(true);
186 mappingRecordBuilder = new MappingRecordBuilder();
187 String ip = "0.0.0.0";
188 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid(ip + "/0"));
189 mappingRecordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
190 mappingRecordBuilder.setRecordTtl(10);
191 mappingRecordBuilder.setMapVersion((short) 0);
192 mappingRecordBuilder.setAction(Action.NativelyForward);
193 mappingRecordBuilder.setAuthoritative(false);
194 // eidToLocatorBuilder.setPrefix(new LispIpv4Address(0));
195 // mapReply.addEidToLocator(eidToLocatorBuilder);
197 // IP: 192.168.136.10 -> 128.223.156.35
198 // UDP: 49289 -> 4342
199 // LISP(Type = 3 Map-Register, P=1, M=1
203 // AuthDataLength: 20 Data:
204 // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
205 // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
207 // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
208 // Priority/Weight: 1/100, Multicast Priority/Weight:
212 mapRegisterPacket = extractWSUdpByteArray(
213 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
214 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
215 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
216 + "0030 00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
217 + "0040 71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
218 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
219 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
220 mapNotifyBuilder = new MapNotifyBuilder();
221 mapNotifyBuilder.setAuthenticationData(new byte[0]);
226 public void todos() throws Exception {
228 // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
229 // TODO: Non-Encapsulated packets
232 @Test(expected = LispMalformedPacketException.class)
233 public void mapRegister__IllegalPacket() throws Exception {
234 mapRegisterPacket = extractWSUdpByteArray(
235 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
236 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
237 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 ");
239 handleMapRegisterPacket(mapRegisterPacket);
242 @Test(expected = LispMalformedPacketException.class)
243 public void mapRequest__IllegalPacket() throws Exception {
244 mapRequestPacket = extractWSUdpByteArray(
245 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
246 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
247 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
248 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
249 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d ");
250 handleMapRequestPacket(mapRequestPacket);
253 @Test(expected = LispMalformedPacketException.class)
254 public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
255 mapRequestPacket = extractWSUdpByteArray(
256 "0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
257 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
258 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 ");
259 handleMapRequestPacket(mapRequestPacket);
263 public void mapRegister__TwoRlocs() throws Exception {
265 // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
266 // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
267 // Priority/Weight: 255/0
268 // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
269 // Multicast Priority/Weight: 255/0
270 mapRegisterPacket = extractWSUdpByteArray(
271 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
272 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
273 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "
274 + "0030 00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 "
275 + "0040 e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 "
276 + "0050 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 "
277 + "0060 ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 "
278 + "0070 00 01 c0 a8 88 33");
280 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
281 handleMapRegisterPacket(mapRegisterPacket);
282 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
284 List<MappingRecordItem> eidRecords = captor.getValue().getMapRegister().getMappingRecordItem();
285 assertEquals(1, eidRecords.size());
286 MappingRecord eidRecord = eidRecords.get(0).getMappingRecord();
287 assertEquals(2, eidRecord.getLocatorRecord().size());
288 assertEquals(LispAddressUtil.asIpv4Rloc("10.1.0.110"), eidRecord.getLocatorRecord().get(0).getRloc());
289 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.51"), eidRecord.getLocatorRecord().get(1).getRloc());
293 public void mapRegister__Ipv6Rloc() throws Exception {
294 // P bit (Proxy-Map-Reply): Set
295 // M bit (Want-Map-Notify): Set
300 // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
301 // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
303 // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
304 // Priority/Weight: 255/0
306 mapRegisterPacket = extractWSUdpByteArray(
307 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
308 + "0010 00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 "
309 + "0020 01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 "
310 + "0030 00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 "
311 + "0040 0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 "
312 + "0050 00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff "
313 + "0060 01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 "
314 + "0070 00 01 0a 00 3a 9c");
316 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
317 handleMapRegisterPacket(mapRegisterPacket);
318 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
319 MappingRecord eidToLocatorRecord =
320 captor.getValue().getMapRegister().getMappingRecordItem().get(0).getMappingRecord();
322 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:1/128"),
323 eidToLocatorRecord.getEid());
324 assertEquals(Ipv6PrefixBinaryAfi.class, eidToLocatorRecord.getEid().getAddressType());
326 assertEquals(LispAddressUtil.asIpv4Rloc("10.0.58.156"), eidToLocatorRecord.getLocatorRecord().get(0).getRloc());
330 public void mapRegister__VerifyBasicFields() throws Exception {
331 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
332 handleMapRegisterPacket(mapRegisterPacket);
333 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
334 MappingRecord eidToLocator =
335 captor.getValue().getMapRegister().getMappingRecordItem().get(0).getMappingRecord();
337 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"), eidToLocator.getEid());
338 assertEquals(1, eidToLocator.getLocatorRecord().size());
339 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.10"), eidToLocator.getLocatorRecord().get(0).getRloc());
343 public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
344 mapNotifyBuilder = null;
345 assertNull(handleMapRegisterPacket(mapRegisterPacket));
349 public void mapRegister__NonSetMBit() throws Exception {
350 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
351 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
352 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
353 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
354 + "0030 00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
355 + "0040 83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 "
356 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
357 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
359 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
360 handleMapRegisterPacket(registerWithNonSetMBit);
361 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
362 assertFalse(captor.getValue().getMapRegister().isWantMapNotify());
366 public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
367 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
368 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
369 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
370 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
371 + "0030 00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
372 + "0040 e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
373 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
374 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
376 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
377 handleMapRegisterPacket(registerWithNonSetMBit);
378 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
379 assertFalse(captor.getValue().getMapRegister().isWantMapNotify());
383 public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
384 byte[] registerWithNonSetMBit = extractWSUdpByteArray(
385 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
386 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
387 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
388 + "0030 00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
389 + "0040 4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
390 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
391 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
393 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
394 handleMapRegisterPacket(registerWithNonSetMBit);
395 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
396 assertTrue(captor.getValue().getMapRegister().isWantMapNotify());
400 * Tests whether handling of map-register message will generate mapping-keep-alive notification.
403 public void mapRegister_isMappingKeepAliveAndMapNotifyGenerated() throws InterruptedException,
404 UnknownHostException {
405 byte[] eidPrefixAfi = new byte[] {
410 byte[] eidPrefix = new byte[] {
412 0x0a, 0x0a, 0x0a, 0x0a
415 //send stream of byte -> map register message
416 InOrder inOrder = Mockito.inOrder(mockLispSouthboundPlugin);
417 final MapRegisterCacheKey cacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
418 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(cacheKey, mapRegisterCache);
419 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
420 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
421 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
422 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
423 cacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
425 //sending the same byte stream -> map register second time
426 captor = ArgumentCaptor.forClass(AddMapping.class);
427 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
428 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
430 //mapping-keep-alive message should be generated
431 MapRegisterCacheTestUtil.afterSecondMapRegisterInvocationValidation(
432 mockLispSouthboundPlugin, eidPrefixAfi, eidPrefix);
435 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix) {
436 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
439 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) {
440 final byte[] mapRegisterMessage = MapRegisterCacheTestUtil.joinArrays(DATA1, NONCE, KEY_ID,
441 authenticationData, DATA2, eidPrefixAfi, eidPrefix, DATA3, XTR_ID, SITE_ID);
442 handlePacket(mapRegisterMessage);
446 * It tests whether map register message is stored to local cache with Ipv4 EidPrefix.
449 public void mapRegister_cacheWithEidPrefixIpv4Test() throws InterruptedException {
450 byte[] eidPrefixAfi = new byte[] {
455 byte[] eidPrefix = new byte[] {
457 0x0a, 0x0a, 0x0a, 0x0a
460 cacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
464 * It tests whether map register message is stored to local cache with Ipv6 EidPrefix.
467 public void mapRegister_cacheWithEidPrefixIpv6Test() throws InterruptedException {
468 byte[] eidPrefixAfi = new byte[] {
473 byte[] eidPrefix = new byte[] {
475 0x0f, 0x0f, 0x0f, 0x0f,
477 0x0f, 0x0f, 0x0f, 0x0f,
479 0x0f, 0x0f, 0x0f, 0x0f,
481 0x0f, 0x0f, 0x0f, 0x0f
484 byte[] authenticationData = new byte[] {
486 0x41,(byte)0x83,0x13,0x7C,
487 0x48,(byte)0xEE,0x75,(byte)0x9A,
488 0x4,(byte)0x8C,0x46,(byte)0xA6,
489 0x1B,0x13,(byte)0xC8,0x4D,
490 (byte)0xA1,0x17,0x53,(byte)0xC3
493 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
497 * It tests whether map register message is stored to local cache with Mac 48bits EidPrefix.
500 public void mapRegister_cacheWithEidPrefixMac48Test() throws InterruptedException {
501 byte[] eidPrefixAfi = new byte[] {
506 byte[] eidPrefix = new byte[] {
508 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
511 byte[] authenticationData = new byte[] {
513 (byte)0xB2,(byte)0x8E,0x6,(byte)0x9D,
514 0x61,(byte)0xD8,0xC,0x24,
515 (byte)0x80,0x61,0x5A,0x20,
516 0xD,0x50,0x5E,(byte)0xAE,
517 0x47,(byte)0xF7,(byte)0x86,0x36
519 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
523 * It tests whether map register message is stored to local cache with Lcaf EidPrefix (inside Ipv4).
526 public void mapRegister_cacheWithEidPrefixLcafTest() throws InterruptedException {
527 byte[] eidPrefixAfi = new byte[] {
532 //following lcaf prefixed variables are defined according to https://tools.ietf
533 // .org/html/draft-ietf-lisp-lcaf-12#section-4.1
534 byte[] lcafRsvd1 = new byte[]{0x00};
535 byte[] lcafFlags = new byte[]{0x00};
536 byte[] lcafType = new byte[]{0x02};
537 byte[] lcafIIDMaskLength = new byte[]{0x20};
538 byte[] lcafLength = new byte[] {0x00, 0x0a};
539 byte[] lcafInstanceId = new byte[]{0x00, 0x00, 0x00, 0x15};
540 byte[] lcafAfi = new byte[] {0x00, 0x01};
541 byte[] lcafAddress = new byte[] {0x7d, 0x7c, 0x7b, 0x7a};
543 byte[] eidPrefix = joinArrays(lcafRsvd1, lcafFlags, lcafType, lcafIIDMaskLength, lcafLength, lcafInstanceId,
544 lcafAfi, lcafAddress);
546 byte[] authenticationData = new byte[] {
547 //authentication data length
550 0x68, 0x1d, (byte) 0x9e, 0x6e,
552 0x5e, 0x32, (byte) 0x88, 0x1a,
554 (byte) 0xae, 0x6b, (byte) 0xe3, 0x40,
556 0x30, (byte) 0x0b, (byte) 0xb6, (byte) 0xa0,
558 0x71, (byte) 0xf4, (byte) 0x8c, 0x5f
562 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
566 * It tests whether map register message is stored to local cache.
568 public void cacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) throws
569 InterruptedException {
570 final MapRegisterCacheKey mapRegisterCacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
572 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(mapRegisterCacheKey, mapRegisterCache);
573 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
574 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, authenticationData);
575 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
576 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
577 mapRegisterCacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
582 Checks whether old record from cache will expire and is replaced with new record.
584 add to empty cache record with timestamp older then 90 second - one object
585 add the same entry through calling of handleMapRegister
586 check that removeEntry() and addEntry() (or refreshEntry() was called on mocked object for mapRegisterCache
589 public void mapRegister_cacheRecordExpirationTest() throws InterruptedException {
590 //tests handling of map register message when next message comes:
592 //after cache entry timeout
593 cacheRecordExpirationTest(true);
595 //before cache entry timout
596 cacheRecordExpirationTest(false);
599 private void cacheRecordExpirationTest(boolean cacheRecordTimeouted) throws InterruptedException {
600 mapRegisterCache = Mockito.mock(MapRegisterCache.class);
601 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
603 final byte[] eidPrefixAfi = new byte[] {0x00, 0x01};
604 final byte[] eidPrefix = new byte[] {0x0a, 0x0a, 0x0a, 0x0a};
606 MapRegisterCacheKeyBuilder cacheKeyBld = new MapRegisterCacheKeyBuilder();
607 cacheKeyBld.setXtrId(XTR_ID);
608 cacheKeyBld.setEidPrefix(eidPrefix);
609 cacheKeyBld.setSiteId(SITE_ID);
611 MapRegisterCacheMetadataBuilder cacheMetadataBld = new MapRegisterCacheMetadataBuilder();
612 cacheMetadataBld.setTimestamp(System.currentTimeMillis() - (cacheRecordTimeouted ? CACHE_RECORD_TIMEOUT : 0L));
613 cacheMetadataBld.setWantMapNotify(false);
615 MapRegisterCacheValueBuilder cacheValueBld = new MapRegisterCacheValueBuilder();
616 cacheValueBld.setMapRegisterCacheMetadata(cacheMetadataBld.build());
617 cacheValueBld.setPacketData(MapRegisterCacheTestUtil.joinArrays(DATA1, KEY_ID, DATA2, eidPrefixAfi,
618 eidPrefix, DATA3, XTR_ID, SITE_ID));
621 final MapRegisterCacheKey cacheKey = cacheKeyBld.build();
622 final MapRegisterCacheValue cacheValue = cacheValueBld.build();
624 Mockito.when(mapRegisterCache.getEntry(Mockito.eq(cacheKey))).thenReturn(cacheRecordTimeouted ? null :
626 Mockito.when(mapRegisterCache.refreshEntry(Mockito.eq(cacheKey))).thenReturn(cacheValue);
628 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
629 Mockito.verify(mockLispSouthboundPlugin, Mockito.atLeastOnce()).sendNotificationIfPossible(
630 Mockito.any(AddMapping.class));
632 InOrder inOrder = Mockito.inOrder(mapRegisterCache);
633 inOrder.verify(mapRegisterCache).getEntry(Mockito.eq(cacheKey));
635 if (cacheRecordTimeouted) {
636 inOrder.verify(mapRegisterCache).addEntry(Mockito.eq(cacheKey), AdditionalMatchers.not(Mockito.eq(
639 inOrder.verify(mapRegisterCache).refreshEntry(Mockito.eq(cacheKey));
645 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
646 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
647 extraDataPacket[mapRegisterPacket.length] = 0x9;
648 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
650 DatagramPacket dp = new DatagramPacket(wrappedBuffer(extraDataPacket), new InetSocketAddress(0),
651 new InetSocketAddress(0));
652 testedLispService.handlePacket(dp);
653 // Check map register fields.
655 // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
656 byte[] notifyResult = lastMapNotifyPacket().content().array();
657 assertEquals(mapRegisterPacket.length, notifyResult.length);
661 private DatagramPacket lastMapReplyPacket() {
662 ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
663 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
666 private DatagramPacket lastMapNotifyPacket() {
667 if (mapNotifyBuilder.getMappingRecordItem() == null) {
668 mapNotifyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
670 mapNotifyBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
671 mappingRecordBuilder.build()).build());
672 mapNotifyBuilder.setNonce((long) 0);
673 mapNotifyBuilder.setKeyId((short) 0);
674 mapNotifyBuilder.setAuthenticationData(new byte[0]);
675 ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotifyBuilder.build());
676 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
681 public void mapNotify__VerifyBasicFields() throws Exception {
682 byte registerType = mapRegisterPacket[0];
683 assertEquals(MessageType.MapRegister.getIntValue(), registerType >> 4);
685 byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
687 assertEquals(mapRegisterPacket.length, result.length);
689 byte expectedType = (byte) (MessageType.MapNotify.getIntValue() << 4);
690 assertHexEquals(expectedType, result[0]);
691 assertHexEquals((byte) 0x00, result[1]);
692 assertHexEquals((byte) 0x00, result[2]);
694 byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(
695 Arrays.copyOfRange(mapRegisterPacket, 3, 16),
696 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
697 byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
698 Arrays.copyOfRange(result, 36, result.length));
699 ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData,
700 notifyWithoutTypeWithOutAuthenticationData);
705 public void mapNotify__VerifyPort() throws Exception {
706 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
707 assertEquals(LispMessage.PORT_NUM, notifyPacket.recipient().getPort());
711 public void mapRequest__VerifyBasicFields() throws Exception {
712 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
713 handleMapRequestAsByteArray(mapRequestPacket);
714 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
715 List<EidItem> eids = captor.getValue().getMapRequest().getEidItem();
716 assertEquals(1, eids.size());
717 Eid lispAddress = eids.get(0).getEid();
718 assertEquals(Ipv4PrefixBinaryAfi.class, lispAddress.getAddressType());
719 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32"), lispAddress);
720 assertEquals(0x3d8d2acd39c8d608L, captor.getValue().getMapRequest().getNonce().longValue());
724 public void mapRequest__Ipv6Eid() throws Exception {
725 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
726 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
727 // (2610:d0:ffff:192::2)
730 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
731 // ITR-RLOC 1: 10.0.58.156
732 // Record 1: 2610:d0:ffff:192::2/128
733 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
734 // Authoritative, No-Action
736 mapRequestPacket = extractWSUdpByteArray(
737 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
738 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
739 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
740 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
741 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
742 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
743 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
744 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
745 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
746 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
747 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
748 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
750 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
751 handleMapRequestAsByteArray(mapRequestPacket);
752 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
753 assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"),
754 captor.getValue().getMapRequest().getSourceEid().getEid());
755 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:2/128"),
756 captor.getValue().getMapRequest().getEidItem().get(0).getEid());
761 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
762 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
763 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
764 // (2610:d0:ffff:192::2)
765 // encapsulated UDP source port: 4342
767 mapRequestPacket = extractWSUdpByteArray(
768 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
769 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
770 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
771 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
772 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
773 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
774 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
775 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
776 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
777 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
778 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
779 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c");
781 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
782 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
783 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any());
784 assertEquals(4342, replyPacket.recipient().getPort());
788 public void mapRequest__WithSourceEid() throws Exception {
789 // encapsulated LISP packet
790 // Source EID = 153.16.254.1
792 mapRequestPacket = extractWSUdpByteArray(
793 "0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 "
794 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
795 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
796 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
797 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
798 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
799 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
800 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 "
801 + "0080 00 01 0a 00 01 26");
803 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
804 handleMapRequestAsByteArray(mapRequestPacket);
805 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
806 assertEquals(Ipv4BinaryAfi.class, captor.getValue().getMapRequest().getSourceEid().getEid().getAddressType());
812 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
813 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
814 mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
818 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
820 assertEquals(28, result.length);
822 byte expectedLispMessageType = 2;
823 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
824 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
826 byte expectedRecordCount = (byte) 1;
827 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
829 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
830 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
831 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
832 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
837 public void mapReply_q_VerifyBasicIPv6() throws Exception {
838 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
842 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
844 assertEquals(40, result.length);
846 byte expectedRecordCount = (byte) 1;
847 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
849 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
850 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
851 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
852 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
854 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
859 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
860 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
861 mappingRecordBuilder.getLocatorRecord().add(
862 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
866 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
868 assertEquals(64, result.length);
870 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
871 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
873 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
874 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
879 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
882 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).recipient().getPort());
887 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
888 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
889 mappingRecordBuilder.getLocatorRecord().add(
890 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
893 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
894 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
899 public void mapReply__WithSingleLocator() throws Exception {
900 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
901 mappingRecordBuilder.getLocatorRecord().add(
902 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
905 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
906 assertEquals(40, result.length);
908 byte expectedLocCount = 1;
909 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
911 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
913 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
914 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
919 public void mapReply__WithMultipleLocator() throws Exception {
920 mappingRecordBuilder.getLocatorRecord().add(
921 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
922 mappingRecordBuilder.getLocatorRecord().add(
923 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1"))
927 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
928 assertEquals(64, result.length);
930 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
932 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
933 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
934 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
936 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
938 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
939 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
940 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
942 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
946 public void handleUnknownLispMessage() throws Exception {
947 // IP: 192.168.136.10 -> 128.223.156.35
948 // UDP: 49289 -> 4342
949 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
951 byte[] unknownTypePacket = extractWSUdpByteArray(
952 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
953 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
954 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
955 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
956 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
957 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
958 + "0060 ff 00 00 05 00 01 c0 a8 88 0a");
959 assertNull(handlePacket(unknownTypePacket));
963 public void mapRequest__MultipleItrRlocs() throws Exception {
964 // this is what LISPmob sends when configured multiple RLOCs for single
966 // ITR-RLOC 1: 10.1.0.111
967 // ITR-RLOC 2: 192.168.136.51
969 mapRequestPacket = extractWSUdpByteArray(
970 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
971 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 "
972 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 "
973 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 "
974 + "0040 08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 "
975 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 "
976 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 "
977 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 "
978 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 "
979 + "0090 00 05 00 01 c0 a8 88 33");
981 handleMapRequestAsByteArray(mapRequestPacket);
982 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any(RequestMapping.class));
985 private void stubHandleRequest() {
987 allowing(contextMockLispSouthboundPlugin).sendNotificationIfPossible(wany(Notification.class));
988 } catch (InterruptedException e) {
989 LOG.debug("Interrupted", e);
993 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
994 handleMapRequestPacket(inPacket);
995 return lastMapReplyPacket().content().array();
998 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
999 handleMapRegisterPacket(inPacket);
1000 return lastMapNotifyPacket().content().array();
1003 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
1004 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1005 new InetSocketAddress(0));
1006 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1007 // This is till not the real port number, but it's better
1008 //dp.setPort(LispMessage.PORT_NUM);
1009 testedLispService.handlePacket(dp);
1010 return lastMapReplyPacket();
1013 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
1014 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1015 new InetSocketAddress(0));
1016 // Unless we explicitly set the source port, it will be -1, which breaks some tests
1017 // This is till not the real port number, but it's better
1018 //dp.setPort(LispMessage.PORT_NUM);
1019 testedLispService.handlePacket(dp);
1020 if (mapNotifyBuilder == null) {
1023 return lastMapNotifyPacket();
1027 private DatagramPacket handlePacket(byte[] inPacket) {
1028 // TODO get from mock
1029 testedLispService.handlePacket(new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1030 new InetSocketAddress(0)));
1034 private byte[] extractWSUdpByteArray(String wiresharkHex) {
1035 final int headerLen = 42;
1036 byte[] res = new byte[1000];
1037 String[] split = wiresharkHex.split(" ");
1039 for (String cur : split) {
1041 if (cur.length() == 2) {
1043 if (counter > headerLen) {
1044 res[counter - headerLen - 1] = (byte) Integer.parseInt(cur, 16);
1049 return Arrays.copyOf(res, counter - headerLen);
1052 @Test(expected = LispMalformedPacketException.class)
1053 public void mapRequest__NoIpItrRloc() throws Exception {
1054 mapRequestPacket = hexToByteBuffer("10 00 "
1055 // This means 3 ITR - RLOCs
1057 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 "
1058 // MAC (ITR-RLOC #1 of 3)
1059 + "40 05 c0 a8 88 0a 01 02 "
1060 // MAC (ITR-RLOC #2 of 3)
1061 + "40 05 00 00 00 00 00 00 "
1062 // MAC (ITR-RLOC #3 of 3)
1063 + "40 05 11 22 34 56 78 90 "
1064 + "00 20 00 01 01 02 03 04").array();
1065 handleMapRequestPacket(mapRequestPacket);