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(new String(
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(new String(
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(new String(
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(new String(
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(new String(
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(new String(
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(new String(
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(new String(
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(new String(
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(new String(
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[] {
406 0x00, 0x01 //eid-prefix-afi
409 byte[] eidPrefix = new byte[] {
410 0x0a, 0x0a, 0x0a, 0x0a //ipv4 address
413 //send stream of byte -> map register message
414 InOrder inOrder = Mockito.inOrder(mockLispSouthboundPlugin);
415 final MapRegisterCacheKey cacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
416 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(cacheKey, mapRegisterCache);
417 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
418 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
419 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
420 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
421 cacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
423 //sending the same byte stream -> map register second time
424 captor = ArgumentCaptor.forClass(AddMapping.class);
425 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
426 inOrder.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
428 //mapping-keep-alive message should be generated
429 MapRegisterCacheTestUtil.afterSecondMapRegisterInvocationValidation(
430 mockLispSouthboundPlugin, eidPrefixAfi, eidPrefix);
433 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix) {
434 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
437 void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) {
438 final byte[] mapRegisterMessage = MapRegisterCacheTestUtil.joinArrays(DATA1, NONCE, KEY_ID,
439 authenticationData, DATA2, eidPrefixAfi, eidPrefix, DATA3, XTR_ID, SITE_ID);
440 handlePacket(mapRegisterMessage);
444 * It tests whether map register message is stored to local cache with Ipv4 EidPrefix.
447 public void mapRegister_cacheWithEidPrefixIpv4Test() throws InterruptedException {
448 byte[] eidPrefixAfi = new byte[] {
449 0x00, 0x01 //eid-prefix-afi
452 byte[] eidPrefix = new byte[] {
453 0x0a, 0x0a, 0x0a, 0x0a //ipv4 address
456 cacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
460 * It tests whether map register message is stored to local cache with Ipv6 EidPrefix.
463 public void mapRegister_cacheWithEidPrefixIpv6Test() throws InterruptedException {
464 byte[] eidPrefixAfi = new byte[] {
465 0x00, 0x02 //eid-prefix-afi
468 byte[] eidPrefix = new byte[] {
469 0x0f, 0x0f, 0x0f, 0x0f, //ipv6 address
470 0x0f, 0x0f, 0x0f, 0x0f, //ipv6 address
471 0x0f, 0x0f, 0x0f, 0x0f, //ipv6 address
472 0x0f, 0x0f, 0x0f, 0x0f //ipv6 address
475 byte[] authenticationData = new byte[]{
477 0x41,(byte)0x83,0x13,0x7C,
478 0x48,(byte)0xEE,0x75,(byte)0x9A,
479 0x4,(byte)0x8C,0x46,(byte)0xA6,
480 0x1B,0x13,(byte)0xC8,0x4D,
481 (byte)0xA1,0x17,0x53,(byte)0xC3
484 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
488 * It tests whether map register message is stored to local cache with Mac 48bits EidPrefix.
491 public void mapRegister_cacheWithEidPrefixMac48Test() throws InterruptedException {
492 byte[] eidPrefixAfi = new byte[] {
493 0x40, 0x05 //eid-prefix-afi
496 byte[] eidPrefix = new byte[] {
497 0x0a, 0x0b, 0x0c, 0x0d, //mac address
498 0x0e, 0x0f //mac address
500 byte[] authenticationData = new byte[]{
502 (byte)0xB2,(byte)0x8E,0x6,(byte)0x9D,
503 0x61,(byte)0xD8,0xC,0x24,
504 (byte)0x80,0x61,0x5A,0x20,
505 0xD,0x50,0x5E,(byte)0xAE,
506 0x47,(byte)0xF7,(byte)0x86,0x36
508 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
512 * It tests whether map register message is stored to local cache with Lcaf EidPrefix (inside Ipv4).
515 public void mapRegister_cacheWithEidPrefixLcafTest() throws InterruptedException {
516 byte[] eidPrefixAfi = new byte[] {
517 0x40, 0x03 //eid-prefix-afi
520 //following lcaf prefixed variables are defined according to https://tools.ietf
521 // .org/html/draft-ietf-lisp-lcaf-12#section-4.1
522 byte[] lcafRsvd1 = new byte[]{0x00};
523 byte[] lcafFlags = new byte[]{0x00};
524 byte[] lcafType = new byte[]{0x02};
525 byte[] lcafIIDMaskLength = new byte[]{0x20};
526 byte[] lcafLength = new byte[] {0x00, 0x0a};
527 byte[] lcafInstanceId = new byte[]{0x00, 0x00, 0x00, 0x15};
528 byte[] lcafAfi = new byte[] {0x00, 0x01};
529 byte[] lcafAddress = new byte[] {0x7d, 0x7c, 0x7b, 0x7a};
531 byte[] eidPrefix = joinArrays(lcafRsvd1, lcafFlags, lcafType, lcafIIDMaskLength, lcafLength, lcafInstanceId,
532 lcafAfi, lcafAddress);
534 byte[] authenticationData = new byte[]{
535 0x00, 0x14, //authentication data length
536 0x68, 0x1d, (byte) 0x9e, 0x6e, //auth data
537 0x5e, 0x32, (byte) 0x88, 0x1a, //auth data
538 (byte) 0xae, 0x6b, (byte) 0xe3, 0x40, //auth data
539 0x30, (byte) 0x0b, (byte) 0xb6, (byte) 0xa0, //auth data
540 0x71, (byte) 0xf4, (byte) 0x8c, 0x5f //auth data
544 cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
548 * It tests whether map register message is stored to local cache.
550 public void cacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) throws
551 InterruptedException {
552 final MapRegisterCacheKey mapRegisterCacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
554 MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(mapRegisterCacheKey, mapRegisterCache);
555 ArgumentCaptor<AddMapping> captor = ArgumentCaptor.forClass(AddMapping.class);
556 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, authenticationData);
557 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
558 MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(
559 mapRegisterCacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
564 Checks whether old record from cache will expire and is replaced with new record.
566 add to empty cache record with timestamp older then 90 second - one object
567 add the same entry through calling of handleMapRegister
568 check that removeEntry() and addEntry() (or refreshEntry() was called on mocked object for mapRegisterCache
571 public void mapRegister_cacheRecordExpirationTest() throws InterruptedException {
572 //tests handling of map register message when next message comes:
574 //after cache entry timeout
575 cacheRecordExpirationTest(true);
577 //before cache entry timout
578 cacheRecordExpirationTest(false);
581 private void cacheRecordExpirationTest(boolean cacheRecordTimeouted) throws InterruptedException {
582 mapRegisterCache = Mockito.mock(MapRegisterCache.class);
583 Mockito.when(mockLispSouthboundPlugin.getMapRegisterCache()).thenReturn(mapRegisterCache);
585 final byte[] eidPrefixAfi = new byte[] {0x00, 0x01};
586 final byte[] eidPrefix = new byte[] {0x0a, 0x0a, 0x0a, 0x0a};
588 MapRegisterCacheKeyBuilder cacheKeyBld = new MapRegisterCacheKeyBuilder();
589 cacheKeyBld.setXtrId(XTR_ID);
590 cacheKeyBld.setEidPrefix(eidPrefix);
591 cacheKeyBld.setSiteId(SITE_ID);
593 MapRegisterCacheMetadataBuilder cacheMetadataBld = new MapRegisterCacheMetadataBuilder();
594 cacheMetadataBld.setTimestamp(System.currentTimeMillis() - (cacheRecordTimeouted ? CACHE_RECORD_TIMEOUT : 0L));
595 cacheMetadataBld.setWantMapNotify(false);
597 MapRegisterCacheValueBuilder cacheValueBld = new MapRegisterCacheValueBuilder();
598 cacheValueBld.setMapRegisterCacheMetadata(cacheMetadataBld.build());
599 cacheValueBld.setPacketData(MapRegisterCacheTestUtil.joinArrays(DATA1, KEY_ID, DATA2, eidPrefixAfi,
600 eidPrefix, DATA3, XTR_ID, SITE_ID));
603 final MapRegisterCacheKey cacheKey = cacheKeyBld.build();
604 final MapRegisterCacheValue cacheValue = cacheValueBld.build();
606 Mockito.when(mapRegisterCache.getEntry(Mockito.eq(cacheKey))).thenReturn(cacheRecordTimeouted ? null :
608 Mockito.when(mapRegisterCache.refreshEntry(Mockito.eq(cacheKey))).thenReturn(cacheValue);
610 mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
611 Mockito.verify(mockLispSouthboundPlugin, Mockito.atLeastOnce()).sendNotificationIfPossible(
612 Mockito.any(AddMapping.class));
614 InOrder inOrder = Mockito.inOrder(mapRegisterCache);
615 inOrder.verify(mapRegisterCache).getEntry(Mockito.eq(cacheKey));
617 if (cacheRecordTimeouted) {
618 inOrder.verify(mapRegisterCache).addEntry(Mockito.eq(cacheKey), AdditionalMatchers.not(Mockito.eq(
621 inOrder.verify(mapRegisterCache).refreshEntry(Mockito.eq(cacheKey));
627 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
628 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
629 extraDataPacket[mapRegisterPacket.length] = 0x9;
630 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
632 DatagramPacket dp = new DatagramPacket(wrappedBuffer(extraDataPacket), new InetSocketAddress(0),
633 new InetSocketAddress(0));
634 testedLispService.handlePacket(dp);
635 // Check map register fields.
637 // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
638 byte[] notifyResult = lastMapNotifyPacket().content().array();
639 assertEquals(mapRegisterPacket.length, notifyResult.length);
643 private DatagramPacket lastMapReplyPacket() {
644 ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
645 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
648 private DatagramPacket lastMapNotifyPacket() {
649 if (mapNotifyBuilder.getMappingRecordItem() == null) {
650 mapNotifyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
652 mapNotifyBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
653 mappingRecordBuilder.build()).build());
654 mapNotifyBuilder.setNonce((long) 0);
655 mapNotifyBuilder.setKeyId((short) 0);
656 mapNotifyBuilder.setAuthenticationData(new byte[0]);
657 ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotifyBuilder.build());
658 return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
663 public void mapNotify__VerifyBasicFields() throws Exception {
664 byte registerType = mapRegisterPacket[0];
665 assertEquals(MessageType.MapRegister.getIntValue(), registerType >> 4);
667 byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
669 assertEquals(mapRegisterPacket.length, result.length);
671 byte expectedType = (byte) (MessageType.MapNotify.getIntValue() << 4);
672 assertHexEquals(expectedType, result[0]);
673 assertHexEquals((byte) 0x00, result[1]);
674 assertHexEquals((byte) 0x00, result[2]);
676 byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(
677 Arrays.copyOfRange(mapRegisterPacket, 3, 16),
678 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
679 byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
680 Arrays.copyOfRange(result, 36, result.length));
681 ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData,
682 notifyWithoutTypeWithOutAuthenticationData);
687 public void mapNotify__VerifyPort() throws Exception {
688 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
689 assertEquals(LispMessage.PORT_NUM, notifyPacket.recipient().getPort());
693 public void mapRequest__VerifyBasicFields() throws Exception {
694 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
695 handleMapRequestAsByteArray(mapRequestPacket);
696 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
697 List<EidItem> eids = captor.getValue().getMapRequest().getEidItem();
698 assertEquals(1, eids.size());
699 Eid lispAddress = eids.get(0).getEid();
700 assertEquals(Ipv4PrefixBinaryAfi.class, lispAddress.getAddressType());
701 assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32"), lispAddress);
702 assertEquals(0x3d8d2acd39c8d608L, captor.getValue().getMapRequest().getNonce().longValue());
706 public void mapRequest__Ipv6Eid() throws Exception {
707 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
708 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
709 // (2610:d0:ffff:192::2)
712 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
713 // ITR-RLOC 1: 10.0.58.156
714 // Record 1: 2610:d0:ffff:192::2/128
715 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
716 // Authoritative, No-Action
718 mapRequestPacket = extractWSUdpByteArray(new String(
719 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
720 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
721 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
722 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
723 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
724 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
725 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
726 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
727 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
728 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
729 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
730 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
732 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
733 handleMapRequestAsByteArray(mapRequestPacket);
734 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
735 assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"),
736 captor.getValue().getMapRequest().getSourceEid().getEid());
737 assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:2/128"),
738 captor.getValue().getMapRequest().getEidItem().get(0).getEid());
743 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
744 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
745 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
746 // (2610:d0:ffff:192::2)
747 // encapsulated UDP source port: 4342
749 mapRequestPacket = extractWSUdpByteArray(new String(
750 "0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
751 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
752 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
753 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
754 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
755 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
756 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
757 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
758 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
759 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
760 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
761 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
763 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
764 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
765 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any());
766 assertEquals(4342, replyPacket.recipient().getPort());
770 public void mapRequest__WithSourceEid() throws Exception {
771 // encapsulated LISP packet
772 // Source EID = 153.16.254.1
774 mapRequestPacket = extractWSUdpByteArray(new String(
775 "0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 "
776 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
777 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
778 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
779 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
780 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
781 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
782 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 "
783 + "0080 00 01 0a 00 01 26"));
785 ArgumentCaptor<RequestMapping> captor = ArgumentCaptor.forClass(RequestMapping.class);
786 handleMapRequestAsByteArray(mapRequestPacket);
787 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(captor.capture());
788 assertEquals(Ipv4BinaryAfi.class, captor.getValue().getMapRequest().getSourceEid().getEid().getAddressType());
794 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
795 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
796 mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
800 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
802 assertEquals(28, result.length);
804 byte expectedLispMessageType = 2;
805 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
806 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
808 byte expectedRecordCount = (byte) 1;
809 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
811 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
812 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
813 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
814 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
819 public void mapReply_q_VerifyBasicIPv6() throws Exception {
820 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
824 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
826 assertEquals(40, result.length);
828 byte expectedRecordCount = (byte) 1;
829 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
831 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
832 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
833 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
834 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
836 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
841 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
842 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
843 mappingRecordBuilder.getLocatorRecord().add(
844 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
848 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
850 assertEquals(64, result.length);
852 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
853 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
855 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
856 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
861 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
864 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).recipient().getPort());
869 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
870 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
871 mappingRecordBuilder.getLocatorRecord().add(
872 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
875 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
876 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
881 public void mapReply__WithSingleLocator() throws Exception {
882 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
883 mappingRecordBuilder.getLocatorRecord().add(
884 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
887 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
888 assertEquals(40, result.length);
890 byte expectedLocCount = 1;
891 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
893 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
895 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
896 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
901 public void mapReply__WithMultipleLocator() throws Exception {
902 mappingRecordBuilder.getLocatorRecord().add(
903 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
904 mappingRecordBuilder.getLocatorRecord().add(
905 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1"))
909 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
910 assertEquals(64, result.length);
912 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
914 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
915 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
916 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
918 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
920 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
921 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
922 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
924 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
928 public void handleUnknownLispMessage() throws Exception {
929 // IP: 192.168.136.10 -> 128.223.156.35
930 // UDP: 49289 -> 4342
931 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
933 byte[] unknownTypePacket = extractWSUdpByteArray(new String(
934 "0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
935 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
936 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
937 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
938 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
939 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
940 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
941 assertNull(handlePacket(unknownTypePacket));
945 public void mapRequest__MultipleItrRlocs() throws Exception {
946 // this is what LISPmob sends when configured multiple RLOCs for single
948 // ITR-RLOC 1: 10.1.0.111
949 // ITR-RLOC 2: 192.168.136.51
951 mapRequestPacket = extractWSUdpByteArray(new String(
952 "0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
953 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 "
954 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 "
955 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 "
956 + "0040 08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 "
957 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 "
958 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 "
959 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 "
960 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 "
961 + "0090 00 05 00 01 c0 a8 88 33"));
963 handleMapRequestAsByteArray(mapRequestPacket);
964 Mockito.verify(mockLispSouthboundPlugin).sendNotificationIfPossible(Mockito.any(RequestMapping.class));
967 private void stubHandleRequest() {
969 allowing(contextMockLispSouthboundPlugin).sendNotificationIfPossible(wany(Notification.class));
970 } catch (InterruptedException e) {
971 LOG.debug("Interrupted", e);
975 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
976 handleMapRequestPacket(inPacket);
977 return lastMapReplyPacket().content().array();
980 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
981 handleMapRegisterPacket(inPacket);
982 return lastMapNotifyPacket().content().array();
985 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
986 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
987 new InetSocketAddress(0));
988 // Unless we explicitly set the source port, it will be -1, which breaks some tests
989 // This is till not the real port number, but it's better
990 //dp.setPort(LispMessage.PORT_NUM);
991 testedLispService.handlePacket(dp);
992 return lastMapReplyPacket();
995 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
996 DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
997 new InetSocketAddress(0));
998 // Unless we explicitly set the source port, it will be -1, which breaks some tests
999 // This is till not the real port number, but it's better
1000 //dp.setPort(LispMessage.PORT_NUM);
1001 testedLispService.handlePacket(dp);
1002 if (mapNotifyBuilder == null) {
1005 return lastMapNotifyPacket();
1009 private DatagramPacket handlePacket(byte[] inPacket) {
1010 // TODO get from mock
1011 testedLispService.handlePacket(new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1012 new InetSocketAddress(0)));
1016 private byte[] extractWSUdpByteArray(String wiresharkHex) {
1017 final int headerLen = 42;
1018 byte[] res = new byte[1000];
1019 String[] split = wiresharkHex.split(" ");
1021 for (String cur : split) {
1023 if (cur.length() == 2) {
1025 if (counter > headerLen) {
1026 res[counter - headerLen - 1] = (byte) Integer.parseInt(cur, 16);
1031 return Arrays.copyOf(res, counter - headerLen);
1034 @Test(expected = LispMalformedPacketException.class)
1035 public void mapRequest__NoIpItrRloc() throws Exception {
1036 mapRequestPacket = hexToByteBuffer("10 00 " //
1037 + "02 " // This means 3 ITR - RLOCs
1038 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
1039 + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 3)
1040 + "40 05 00 00 00 00 00 00 " // MAC (ITR-RLOC #2 of 3)
1041 + "40 05 11 22 34 56 78 90 " // MAC (ITR-RLOC #3 of 3)
1042 + "00 20 00 01 01 02 03 04").array();
1043 handleMapRequestPacket(mapRequestPacket);