Adding authentication data to map register cache.
[lispflowmapping.git] / mappingservice / southbound / src / test / java / org / opendaylight / lispflowmapping / southbound / lisp / LispSouthboundServiceTest.java
1 /*
2  * Copyright (c) 2014 Contextream, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.lispflowmapping.southbound.lisp;
10
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.mockito.Mockito.mock;
16 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.data1;
17 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.data2;
18 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.data3;
19 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.joinArrays;
20 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.keyId;
21 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.nonce;
22 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.siteId;
23 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.xTRId;
24 import io.netty.channel.socket.DatagramPacket;
25
26 import java.net.InetSocketAddress;
27 import java.net.UnknownHostException;
28 import java.nio.ByteBuffer;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
32
33 import junitx.framework.ArrayAssert;
34
35 import org.apache.commons.lang3.ArrayUtils;
36 import org.jmock.api.Invocation;
37 import org.junit.Before;
38 import org.junit.BeforeClass;
39 import org.junit.Ignore;
40 import org.junit.Test;
41 import org.mockito.AdditionalMatchers;
42 import org.mockito.InOrder;
43 import org.mockito.Matchers;
44 import org.mockito.Mockito;
45 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
46 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
47 import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
48 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
49 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
50 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
51 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
52 import org.opendaylight.lispflowmapping.lisp.util.MapNotifyBuilderHelper;
53 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
54 import org.opendaylight.lispflowmapping.mapcache.SimpleMapCache;
55 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
56 import org.opendaylight.lispflowmapping.southbound.LispSouthboundStats;
57 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterCache;
58 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
59 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.afn.safi.rev130704.AddressFamily;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4BinaryAfi;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4PrefixBinaryAfi;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv6PrefixBinaryAfi;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKey;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKeyBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValue;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValueBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord.Action;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapreplymessage.MapReplyBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.authkey.container.MappingAuthkeyBuilder;
87 import org.opendaylight.yangtools.yang.binding.Notification;
88
89 public class LispSouthboundServiceTest extends BaseTestCase {
90
91     private LispSouthboundHandler testedLispService;
92     private NotificationPublishService nps;
93     private byte[] mapRequestPacket;
94     private byte[] mapRegisterPacket;
95     private ValueSaverAction<Notification> lispNotificationSaver;
96     // private ValueSaverAction<MapRegister> mapRegisterSaver;
97     // private ValueSaverAction<MapRequest> mapRequestSaver;
98     private MapNotifyBuilder mapNotifyBuilder;
99     private MapReplyBuilder mapReplyBuilder;
100     private MappingRecordBuilder mappingRecordBuilder;
101     private MapRegisterCache mapRegisterCache;
102     private LispSouthboundPlugin mockLispSouthboundPlugin;
103     private static final long CACHE_RECORD_TIMEOUT = 90000;
104
105     private static SimpleMapCache smc;
106
107     private interface MapReplyIpv4SingleLocatorPos {
108         int RECORD_COUNT = 3;
109         int NONCE = 4;
110         int LOCATOR_COUNT = 16;
111         int EID_MASK_LEN = 17;
112         int AFI_TYPE = 22;
113         int EID_PREFIX = 24;
114         int LOC_AFI = 34;
115         int LOCATOR_RBIT = 33;
116         int LOCATOR = 36;
117     }
118
119     private interface MapReplyIpv4SecondLocatorPos {
120         int FIRST_LOCATOR_IPV4_LENGTH = 12;
121         int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
122         int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
123         int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
124     }
125
126     @BeforeClass
127     public static void initTests() {
128         smc = Mockito.mock(SimpleMapCache.class);
129         Mockito.when(smc.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("10.10.10.10/8"))))
130                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
131         Mockito.when(smc.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid
132                 ("2610:d0:ffff:192:0:0:0:1/128"))))
133                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
134         Mockito.when(smc.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"))))
135                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
136         Mockito.when(smc.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("125.124.123.122/8", new
137                 InstanceIdType(21L)))))
138                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
139         Mockito.when(smc.getAuthenticationKey(Matchers.eq(LispAddressUtil.asMacEid("0a:0b:0c:0d:0e:0f"))))
140                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
141         Mockito.when(smc.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid
142                 ("f0f:f0f:f0f:f0f:f0f:f0f:f0f:f0f/8"))))
143                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
144         Mockito.when(smc.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("172.1.1.2/32"))))
145                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
146     }
147
148     @Override
149     @Before
150     public void before() throws Exception {
151         super.before();
152         // mapResolver = context.mock(IMapResolver.class);
153         // mapServer = context.mock(IMapServer.class);
154         mockLispSouthboundPlugin = mock(LispSouthboundPlugin.class);
155         Mockito.when(mockLispSouthboundPlugin.getStats()).thenReturn(Mockito.mock(LispSouthboundStats.class));
156         testedLispService = new LispSouthboundHandler(mockLispSouthboundPlugin);
157         mapRegisterCache = new MapRegisterCache();
158         testedLispService.setMapRegisterCache(mapRegisterCache);
159         testedLispService.setDataBroker(Mockito.mock(DataBroker.class));
160         testedLispService.setSimpleMapCache(smc);
161         testedLispService.init();
162         nps = context.mock(NotificationPublishService.class);
163         testedLispService.setNotificationProvider(nps);
164         lispNotificationSaver = new ValueSaverAction<Notification>();
165         // mapRegisterSaver = new ValueSaverAction<MapRegister>();
166         // mapRequestSaver = new ValueSaverAction<MapRequest>();
167         // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
168         // LISP(Type = 8 - Encapsulated)
169         // IP: 192.168.136.10 -> 1.2.3.4
170         // UDP: 56756
171         // LISP(Type = 1 Map-Request
172         // Record Count: 1
173         // ITR-RLOC count: 0
174         // Source EID AFI: 0
175         // Source EID not present
176         // Nonce: 0x3d8d2acd39c8d608
177         // ITR-RLOC AFI=1 Address=192.168.136.10
178         // Record 1: 1.2.3.4/32
179         mapRequestPacket = extractWSUdpByteArray(new String(
180                   "0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
181                 + "0010   00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
182                 + "0020   00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
183                 + "0030   00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
184                 + "0040   03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
185                 + "0050   2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 c0 a8 88 0a 00 20 "
186                 + "0060   00 01 01 02 03 04"));
187         mapReplyBuilder = new MapReplyBuilder();
188         mapReplyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
189         mapReplyBuilder.setNonce((long) 0);
190         mapReplyBuilder.setEchoNonceEnabled(false);
191         mapReplyBuilder.setProbe(true);
192         mapReplyBuilder.setSecurityEnabled(true);
193         mappingRecordBuilder = new MappingRecordBuilder();
194         String ip = "0.0.0.0";
195         mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid(ip + "/0"));
196         mappingRecordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
197         mappingRecordBuilder.setRecordTtl(10);
198         mappingRecordBuilder.setMapVersion((short) 0);
199         mappingRecordBuilder.setAction(Action.NativelyForward);
200         mappingRecordBuilder.setAuthoritative(false);
201         // eidToLocatorBuilder.setPrefix(new LispIpv4Address(0));
202         // mapReply.addEidToLocator(eidToLocatorBuilder);
203
204         // IP: 192.168.136.10 -> 128.223.156.35
205         // UDP: 49289 -> 4342
206         // LISP(Type = 3 Map-Register, P=1, M=1
207         // Record Counter: 1
208         // Nonce: 0
209         // Key ID: 0x0001
210         // AuthDataLength: 20 Data:
211         // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
212         // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
213         // No-Action
214         // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
215         // Priority/Weight: 1/100, Multicast Priority/Weight:
216         // 255/0
217         //
218
219         mapRegisterPacket = extractWSUdpByteArray(new String(
220                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
221                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
222                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
223                 + "0030   00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
224                 + "0040   71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
225                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
226                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
227         mapNotifyBuilder = new MapNotifyBuilder();
228         mapNotifyBuilder.setAuthenticationData(new byte[0]);
229     }
230
231     @Test
232     @Ignore
233     public void todos() throws Exception {
234
235         // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
236         // TODO: Non-Encapsulated packets
237     }
238
239     @Test(expected = LispMalformedPacketException.class)
240     public void mapRegister__IllegalPacket() throws Exception {
241         mapRegisterPacket = extractWSUdpByteArray(new String(
242                   "0000   00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
243                 + "0010   00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
244                 + "0020   00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "));
245
246         handleMapRegisterPacket(mapRegisterPacket);
247     }
248
249     @Test(expected = LispMalformedPacketException.class)
250     public void mapRequest__IllegalPacket() throws Exception {
251         mapRequestPacket = extractWSUdpByteArray(new String(
252                   "0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
253                 + "0010   00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
254                 + "0020   00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
255                 + "0030   00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
256                 + "0040   03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "));
257         handleMapRequestPacket(mapRequestPacket);
258     }
259
260     @Test(expected = LispMalformedPacketException.class)
261     public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
262         mapRequestPacket = extractWSUdpByteArray(new String(
263                   "0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
264                 + "0010   00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
265                 + "0020   00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "));
266         handleMapRequestPacket(mapRequestPacket);
267     }
268
269     private MapRegister lastMapRegister() {
270         assertTrue(lispNotificationSaver.lastValue instanceof AddMapping);
271         AddMapping lastValue = (AddMapping) lispNotificationSaver.lastValue;
272         return lastValue.getMapRegister();
273     }
274
275     private MapRequest lastMapRequest() {
276         RequestMapping lastValue = (RequestMapping) lispNotificationSaver.lastValue;
277         return lastValue.getMapRequest();
278     }
279
280     @Test
281     public void mapRegister__TwoRlocs() throws Exception {
282         // P Bit & M Bit set
283         // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
284         // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
285         // Priority/Weight: 255/0
286         // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
287         // Multicast Priority/Weight: 255/0
288         mapRegisterPacket = extractWSUdpByteArray(new String(
289                   "0000   00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
290                 + "0010   00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
291                 + "0020   00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "
292                 + "0030   00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 "
293                 + "0040   e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 "
294                 + "0050   00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 "
295                 + "0060   ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 "
296                 + "0070   00 01 c0 a8 88 33"));
297
298         oneOf(nps).putNotification(with(lispNotificationSaver));
299
300         handleMapRegisterPacket(mapRegisterPacket);
301
302         List<MappingRecordItem> eidRecords = lastMapRegister().getMappingRecordItem();
303         assertEquals(1, eidRecords.size());
304         MappingRecord eidRecord = eidRecords.get(0).getMappingRecord();
305         assertEquals(2, eidRecord.getLocatorRecord().size());
306         assertEquals(LispAddressUtil.asIpv4Rloc("10.1.0.110"), eidRecord.getLocatorRecord().get(0).getRloc());
307         assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.51"), eidRecord.getLocatorRecord().get(1).getRloc());
308     }
309
310     @Test
311     public void mapRegister__Ipv6Rloc() throws Exception {
312         // P bit (Proxy-Map-Reply): Set
313         // M bit (Want-Map-Notify): Set
314         // Record Counter: 1
315         // Nonce: 0
316         // Key ID: 1
317         // AuthLength: 20
318         // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
319         // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
320         // No-Action
321         // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
322         // Priority/Weight: 255/0
323
324         mapRegisterPacket = extractWSUdpByteArray(new String(
325                   "0000   00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
326                 + "0010   00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 "
327                 + "0020   01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 "
328                 + "0030   00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 "
329                 + "0040   0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 "
330                 + "0050   00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff "
331                 + "0060   01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 "
332                 + "0070   00 01 0a 00 3a 9c"));
333
334         oneOf(nps).putNotification(with(lispNotificationSaver));
335
336         handleMapRegisterPacket(mapRegisterPacket);
337
338         MappingRecord eidToLocatorRecord = lastMapRegister().getMappingRecordItem().get(0).getMappingRecord();
339         assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:1/128"),
340                 eidToLocatorRecord.getEid());
341         assertEquals(Ipv6PrefixBinaryAfi.class, eidToLocatorRecord.getEid().getAddressType());
342
343         assertEquals(LispAddressUtil.asIpv4Rloc("10.0.58.156"), eidToLocatorRecord.getLocatorRecord().get(0).getRloc());
344     }
345
346     @Test
347     public void mapRegister__VerifyBasicFields() throws Exception {
348         oneOf(nps).putNotification(with(lispNotificationSaver));
349         handleMapRegisterPacket(mapRegisterPacket);
350
351         MappingRecord eidToLocator = lastMapRegister().getMappingRecordItem().get(0).getMappingRecord();
352         assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"), eidToLocator.getEid());
353
354         assertEquals(1, eidToLocator.getLocatorRecord().size());
355         assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.10"), eidToLocator.getLocatorRecord().get(0).getRloc());
356     }
357
358     @Test
359     @Ignore
360     public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
361         oneOf(nps).putNotification(with(lispNotificationSaver));
362         mapNotifyBuilder = null;
363
364         assertNull(handleMapRegisterPacket(mapRegisterPacket));
365     }
366
367     @Test
368     public void mapRegister__NonSetMBit() throws Exception {
369         byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String(
370                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
371                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
372                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
373                 + "0030   00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
374                 + "0040   83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 "
375                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
376                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
377         stubMapRegister(true);
378
379         handleMapRegisterPacket(registerWithNonSetMBit);
380
381         assertFalse(lastMapRegister().isWantMapNotify());
382     }
383
384     @Test
385     public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
386         byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String(
387                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
388                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
389                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
390                 + "0030   00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
391                 + "0040   e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
392                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
393                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
394         stubMapRegister(true);
395
396         handleMapRegisterPacket(registerWithNonSetMBit);
397         assertFalse(lastMapRegister().isWantMapNotify());
398     }
399
400     @Test
401     public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
402         byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String(
403                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
404                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
405                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
406                 + "0030   00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
407                 + "0040   4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
408                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
409                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
410         stubMapRegister(true);
411
412         handleMapRegisterPacket(registerWithNonSetMBit);
413         assertTrue(lastMapRegister().isWantMapNotify());
414     }
415
416     /**
417      * Tests whether handling of map-register message will generate mapping-keep-alive notification
418      */
419     @Test
420     public void mapRegister_isMappingKeepAliveAndMapNotifyGenerated() throws InterruptedException,
421             UnknownHostException {
422         byte[] eidPrefixAfi = new byte[] {
423                 0x00, 0x01                  //eid-prefix-afi
424         };
425
426         byte[] eidPrefix = new byte[] {
427                 0x0a, 0x0a, 0x0a, 0x0a     //ipv4 address
428         };
429
430         NotificationPublishService notifServiceMock = MapRegisterCacheTestUtil.resetMockForNotificationProvider
431                 (testedLispService);
432
433         //send stream of byte -> map register message
434         final MapRegisterCacheKey cacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
435         MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(cacheKey, mapRegisterCache);
436         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
437         MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(notifServiceMock,
438                 cacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
439
440         //sending the same byte stream -> map register second time
441         notifServiceMock = MapRegisterCacheTestUtil.resetMockForNotificationProvider(testedLispService);
442         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
443
444         //mapping-keep-alive message should be generated
445         MapRegisterCacheTestUtil.afterSecondMapRegisterInvocationValidation(notifServiceMock,
446                 mockLispSouthboundPlugin, eidPrefixAfi, eidPrefix);
447     }
448
449     void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix) {
450         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.authenticationData);
451     }
452
453     void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) {
454         final byte[] mapRegisterMessage = MapRegisterCacheTestUtil.joinArrays(data1, nonce, keyId,
455                 authenticationData, data2, eidPrefixAfi, eidPrefix, data3, xTRId, siteId);
456         handlePacket(mapRegisterMessage);
457     }
458
459     /**
460      * It tests whether map register message is stored to local cache with Ipv4 EidPrefix
461      */
462     @Test
463     public void mapRegister_cacheWithEidPrefixIpv4Test() throws InterruptedException {
464         byte[] eidPrefixAfi = new byte[] {
465                 0x00, 0x01                  //eid-prefix-afi
466         };
467
468         byte[] eidPrefix = new byte[] {
469                 0x0a, 0x0a, 0x0a, 0x0a     //ipv4 address
470         };
471
472         cacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.authenticationData);
473     }
474
475     /**
476      * It tests whether map register message is stored to local cache with Ipv6 EidPrefix
477      */
478     @Test
479     public void mapRegister_cacheWithEidPrefixIpv6Test() throws InterruptedException {
480         byte[] eidPrefixAfi = new byte[] {
481                 0x00, 0x02                  //eid-prefix-afi
482         };
483
484         byte[] eidPrefix = new byte[] {
485                 0x0f, 0x0f, 0x0f, 0x0f     //ipv6 address
486                 ,0x0f, 0x0f, 0x0f, 0x0f     //ipv6 address
487                 ,0x0f, 0x0f, 0x0f, 0x0f     //ipv6 address
488                 ,0x0f, 0x0f, 0x0f, 0x0f     //ipv6 address
489         };
490
491         byte[] authenticationData = new byte[]{
492                 0x00, 0x14
493                 ,0x41,(byte)0x83,0x13,0x7C
494                 ,0x48,(byte)0xEE,0x75,(byte)0x9A
495                 ,0x4,(byte)0x8C,0x46,(byte)0xA6
496                 ,0x1B,0x13,(byte)0xC8,0x4D
497                 ,(byte)0xA1,0x17,0x53,(byte)0xC3
498         };
499
500         cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
501     }
502
503     /**
504      * It tests whether map register message is stored to local cache with Mac 48bits EidPrefix
505      */
506     @Test
507     public void mapRegister_cacheWithEidPrefixMac48Test() throws InterruptedException {
508         byte[] eidPrefixAfi = new byte[] {
509                 0x40, 0x05                  //eid-prefix-afi
510         };
511
512         byte[] eidPrefix = new byte[] {
513                 0x0a, 0x0b, 0x0c, 0x0d     //mac address
514                 ,0x0e, 0x0f                 //mac address
515         };
516         byte[] authenticationData = new byte[]{
517                 0x00, 0x14
518                 ,(byte)0xB2,(byte)0x8E,0x6,(byte)0x9D
519                 ,0x61,(byte)0xD8,0xC,0x24
520                 ,(byte)0x80,0x61,0x5A,0x20
521                 ,0xD,0x50,0x5E,(byte)0xAE
522                 ,0x47,(byte)0xF7,(byte)0x86,0x36
523         };
524         cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
525     }
526
527     /**
528      * It tests whether map register message is stored to local cache with Lcaf EidPrefix (inside Ipv4)
529      */
530     @Test
531     public void mapRegister_cacheWithEidPrefixLcafTest() throws InterruptedException {
532         byte[] eidPrefixAfi = new byte[] {
533                 0x40, 0x03                  //eid-prefix-afi
534         };
535
536         //following lcaf prefixed variables are defined according to https://tools.ietf
537         // .org/html/draft-ietf-lisp-lcaf-12#section-4.1
538         byte[] lcafRsvd1 = new byte[]{0x00};
539         byte[] lcafFlags = new byte[]{0x00};
540         byte[] lcafType = new byte[]{0x02};
541         byte[] lcafIIDMaskLength = new byte[]{0x20};
542         byte[] lcafLength = new byte[] {0x00, 0x0a};
543         byte[] lcafInstanceId = new byte[]{0x00, 0x00, 0x00, 0x15};
544         byte[] lcafAfi = new byte[] {0x00, 0x01};
545         byte[] lcafAddress = new byte[] {0x7d, 0x7c, 0x7b, 0x7a};
546
547         byte[] eidPrefix = joinArrays(lcafRsvd1, lcafFlags, lcafType, lcafIIDMaskLength, lcafLength, lcafInstanceId,
548                 lcafAfi, lcafAddress);
549
550         byte[] authenticationData = new byte[]{
551                 0x00, 0x14                 //authentication data length
552                 ,0x68, 0x1d, (byte) 0x9e, 0x6e    //auth data
553                 ,0x5e, 0x32, (byte) 0x88, 0x1a    //auth data
554                 ,(byte) 0xae, 0x6b, (byte) 0xe3, 0x40    //auth data
555                 ,0x30, (byte) 0x0b, (byte) 0xb6, (byte) 0xa0    //auth data
556                 ,0x71, (byte) 0xf4, (byte) 0x8c, 0x5f    //auth data
557         };
558
559
560         cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
561     }
562
563     /**
564      * It tests whether map register message is stored to local cache
565      * @param eidPrefixAfi
566      * @param eidPrefix
567      */
568     public void cacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) throws
569             InterruptedException {
570         final MapRegisterCacheKey mapRegisterCacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
571
572         final NotificationPublishService mockedNotificationProvider = mock(NotificationPublishService.class);
573         testedLispService.setNotificationProvider(mockedNotificationProvider);
574
575         MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(mapRegisterCacheKey, mapRegisterCache);
576         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, authenticationData);
577         MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(mockedNotificationProvider,
578                 mapRegisterCacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
579     }
580
581
582     /*
583         Checks whether old record from cache will expire and is replaced with new record.
584
585         add to empty cache record with timestamp older then 90 second - one object
586         add the same entry through calling of handleMapRegister
587         check that removeEntry() and addEntry() (or refreshEntry() was called on mocked object for mapRegisterCache
588     */
589     @Test
590     public void mapRegister_cacheRecordExpirationTest() throws InterruptedException {
591         //tests handling of map register message when next message comes:
592
593         //after cache entry timeout
594         cacheRecordExpirationTest(true);
595
596         //before cache entry timout
597         cacheRecordExpirationTest(false);
598     }
599
600     private void cacheRecordExpirationTest(boolean cacheRecordTimeouted) throws InterruptedException {
601         mapRegisterCache = Mockito.mock(MapRegisterCache.class);
602         testedLispService.setMapRegisterCache(mapRegisterCache);
603         testedLispService.setNotificationProvider(Mockito.mock(NotificationPublishService.class));
604
605         byte[] eidPrefixAfi = new byte[] {0x00, 0x01};
606         byte[] eidPrefix = new byte[] {0x0a, 0x0a, 0x0a, 0x0a};
607
608         MapRegisterCacheKeyBuilder cacheKeyBld = new MapRegisterCacheKeyBuilder();
609         MapRegisterCacheValueBuilder cacheValueBld = new MapRegisterCacheValueBuilder();
610         cacheKeyBld.setXtrId(xTRId);
611         cacheKeyBld.setEidPrefix(eidPrefix);
612         cacheKeyBld.setSiteId(siteId);
613
614         MapRegisterCacheMetadataBuilder cacheMetadataBld = new MapRegisterCacheMetadataBuilder();
615         cacheMetadataBld.setTimestamp(System.currentTimeMillis() - (cacheRecordTimeouted ? CACHE_RECORD_TIMEOUT : 0L));
616         cacheMetadataBld.setWantMapNotify(false);
617         cacheValueBld.setMapRegisterCacheMetadata(cacheMetadataBld.build());
618         cacheValueBld.setPacketData(MapRegisterCacheTestUtil.joinArrays(data1, keyId, data2, eidPrefixAfi,
619                 eidPrefix, data3, xTRId, siteId));
620
621
622         final MapRegisterCacheKey cacheKey = cacheKeyBld.build();
623         final MapRegisterCacheValue cacheValue = cacheValueBld.build();
624
625         Mockito.when(mapRegisterCache.getEntry(Mockito.eq(cacheKey))).thenReturn(cacheRecordTimeouted ? null :
626                 cacheValue);
627         Mockito.when(mapRegisterCache.refreshEntry(Mockito.eq(cacheKey))).thenReturn(cacheValue);
628
629         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
630
631         InOrder inOrder = Mockito.inOrder(mapRegisterCache);
632             inOrder.verify(mapRegisterCache).getEntry(Mockito.eq(cacheKey));
633
634         if (cacheRecordTimeouted) {
635             inOrder.verify(mapRegisterCache).addEntry(Mockito.eq(cacheKey), AdditionalMatchers.not(Mockito.eq
636                     (cacheValue)));
637         } else {
638             inOrder.verify(mapRegisterCache).refreshEntry(Mockito.eq(cacheKey));
639         }
640     }
641
642     @Test
643     @Ignore
644     public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
645         byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
646         extraDataPacket[mapRegisterPacket.length] = 0x9;
647         System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
648         stubMapRegister(true);
649
650         DatagramPacket dp = new DatagramPacket(wrappedBuffer(extraDataPacket), new InetSocketAddress(0),
651                 new InetSocketAddress(0));
652         testedLispService.handlePacket(dp);
653         // Check map register fields.
654         // XXX: test
655         // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
656         byte[] notifyResult = lastMapNotifyPacket().content().array();
657         assertEquals(mapRegisterPacket.length, notifyResult.length);
658
659     }
660
661     private DatagramPacket lastMapReplyPacket() {
662         ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
663         return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
664     }
665
666     private DatagramPacket lastMapNotifyPacket() {
667         if (mapNotifyBuilder.getMappingRecordItem() == null) {
668             mapNotifyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
669         }
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));
677     }
678
679     @Test
680     @Ignore
681     public void mapNotify__VerifyBasicFields() throws Exception {
682         byte registerType = mapRegisterPacket[0];
683         assertEquals(MessageType.MapRegister.getIntValue(), registerType >> 4);
684
685         stubMapRegister(true);
686
687         byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
688
689         assertEquals(mapRegisterPacket.length, result.length);
690
691         byte expectedType = (byte) (MessageType.MapNotify.getIntValue() << 4);
692         assertHexEquals(expectedType, result[0]);
693         assertHexEquals((byte) 0x00, result[1]);
694         assertHexEquals((byte) 0x00, result[2]);
695
696         byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(
697                 Arrays.copyOfRange(mapRegisterPacket, 3, 16),
698                 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
699         byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
700                 Arrays.copyOfRange(result, 36, result.length));
701         ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData,
702                 notifyWithoutTypeWithOutAuthenticationData);
703     }
704
705     @Ignore
706     @Test
707     public void mapNotify__VerifyPort() throws Exception {
708         stubMapRegister(true);
709
710         DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
711         assertEquals(LispMessage.PORT_NUM, notifyPacket.recipient().getPort());
712     }
713
714     @Test
715     public void mapRequest__VerifyBasicFields() throws Exception {
716         oneOf(nps).putNotification(with(lispNotificationSaver));
717         handleMapRequestAsByteArray(mapRequestPacket);
718         List<EidItem> eids = lastMapRequest().getEidItem();
719         assertEquals(1, eids.size());
720         Eid lispAddress = eids.get(0).getEid();
721         assertEquals(Ipv4PrefixBinaryAfi.class, lispAddress.getAddressType());
722         assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32"), lispAddress);
723         assertEquals(0x3d8d2acd39c8d608L, lastMapRequest().getNonce().longValue());
724     }
725
726     @Test
727     public void mapRequest__Ipv6Eid() throws Exception {
728         // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
729         // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
730         // (2610:d0:ffff:192::2)
731         // MBIT: SET
732         // EID AFI: 2
733         // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
734         // ITR-RLOC 1: 10.0.58.156
735         // Record 1: 2610:d0:ffff:192::2/128
736         // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
737         // Authoritative, No-Action
738
739         mapRequestPacket = extractWSUdpByteArray(new String(
740                   "0000   00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
741                 + "0010   00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
742                 + "0020   01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
743                 + "0030   00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
744                 + "0040   00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
745                 + "0050   00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
746                 + "0060   00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
747                 + "0070   ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
748                 + "0080   3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
749                 + "0090   00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
750                 + "00a0   00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
751                 + "00b0   00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
752
753         oneOf(nps).putNotification(with(lispNotificationSaver));
754         // ret(mapReply);
755
756         handleMapRequestAsByteArray(mapRequestPacket);
757         assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"), lastMapRequest().getSourceEid().getEid());
758         assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:2/128"),
759                 lastMapRequest().getEidItem().get(0).getEid());
760     }
761
762     @Ignore
763     @Test
764     public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
765         // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
766         // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
767         // (2610:d0:ffff:192::2)
768         // encapsulated UDP source port: 4342
769
770         mapRequestPacket = extractWSUdpByteArray(new String(
771                   "0000   00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
772                 + "0010   00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
773                 + "0020   01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
774                 + "0030   00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
775                 + "0040   00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
776                 + "0050   00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
777                 + "0060   00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
778                 + "0070   ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
779                 + "0080   3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
780                 + "0090   00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
781                 + "00a0   00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
782                 + "00b0   00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
783         oneOf(nps).putNotification(with(lispNotificationSaver));
784         // ret(mapReply);
785
786         DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
787         assertEquals(4342, replyPacket.recipient().getPort());
788     }
789
790     @Test
791     public void mapRequest__WithSourceEid() throws Exception {
792         // encapsulated LISP packet
793         // Source EID = 153.16.254.1
794
795         mapRequestPacket = extractWSUdpByteArray(new String(
796                   "0000   00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 "
797                 + "0010   00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
798                 + "0020   3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
799                 + "0030   00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
800                 + "0040   14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
801                 + "0050   ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
802                 + "0060   01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
803                 + "0070   10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 "
804                 + "0080   00 01 0a 00 01 26"));
805
806         oneOf(nps).putNotification(with(lispNotificationSaver));
807         // ret(mapReply);
808
809         handleMapRequestAsByteArray(mapRequestPacket);
810         assertEquals(Ipv4BinaryAfi.class, lastMapRequest().getSourceEid().getEid().getAddressType());
811
812     }
813
814     @Test
815     @Ignore
816     public void mapReply__VerifyBasicIPv4Fields() throws Exception {
817         mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
818         mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
819
820         stubHandleRequest();
821
822         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
823
824         assertEquals(28, result.length);
825
826         byte expectedLispMessageType = 2;
827         assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
828         assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
829
830         byte expectedRecordCount = (byte) 1;
831         assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
832
833         assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
834                 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
835         assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
836         assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
837     }
838
839     @Test
840     @Ignore
841     public void mapReply__VerifyBasicIPv6() throws Exception {
842         mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
843
844         stubHandleRequest();
845
846         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
847
848         assertEquals(40, result.length);
849
850         byte expectedRecordCount = (byte) 1;
851         assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
852
853         assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
854                 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
855         assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
856         byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
857
858         ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
859     }
860
861     @Test
862     @Ignore
863     public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
864         mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
865         mappingRecordBuilder.getLocatorRecord().add(
866                 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
867
868         stubHandleRequest();
869
870         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
871
872         assertEquals(64, result.length);
873
874         byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
875         ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
876
877         byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
878         ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
879     }
880
881     @Ignore
882     @Test
883     public void mapReply__UseEncapsulatedUdpPort() throws Exception {
884         stubHandleRequest();
885
886         assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).recipient().getPort());
887     }
888
889     @Test
890     @Ignore
891     public void mapReply__WithNonRoutableSingleLocator() throws Exception {
892         mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
893         mappingRecordBuilder.getLocatorRecord().add(
894                 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
895         stubHandleRequest();
896
897         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
898         assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
899     }
900
901     @Test
902     @Ignore
903     public void mapReply__WithSingleLocator() throws Exception {
904         mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
905         mappingRecordBuilder.getLocatorRecord().add(
906                 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
907         stubHandleRequest();
908
909         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
910         assertEquals(40, result.length);
911
912         byte expectedLocCount = 1;
913         assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
914
915         assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
916
917         assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
918         assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
919     }
920
921     @Test
922     @Ignore
923     public void mapReply__WithMultipleLocator() throws Exception {
924         mappingRecordBuilder.getLocatorRecord().add(
925                 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
926         mappingRecordBuilder.getLocatorRecord().add(
927                 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1"))
928                 .build());
929         stubHandleRequest();
930
931         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
932         assertEquals(64, result.length);
933
934         assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
935
936         assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
937         assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
938         assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
939
940         assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
941
942         byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
943         ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
944                 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
945
946         assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
947     }
948
949     @Test
950     public void handleUnknownLispMessage() throws Exception {
951         // IP: 192.168.136.10 -> 128.223.156.35
952         // UDP: 49289 -> 4342
953         // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
954
955         byte[] unknownTypePacket = extractWSUdpByteArray(new String(
956                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
957                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
958                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
959                 + "0030   00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
960                 + "0040   b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
961                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
962                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
963         assertNull(handlePacket(unknownTypePacket));
964     }
965
966     @Test
967     public void mapRequest__MultipleItrRlocs() throws Exception {
968         // this is what LISPmob sends when configured multiple RLOCs for single
969         // EID.
970         // ITR-RLOC 1: 10.1.0.111
971         // ITR-RLOC 2: 192.168.136.51
972         //
973         mapRequestPacket = extractWSUdpByteArray(new String(
974                   "0000   00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
975                 + "0010   00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 "
976                 + "0020   00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 "
977                 + "0030   00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 "
978                 + "0040   08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 "
979                 + "0050   ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 "
980                 + "0060   00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 "
981                 + "0070   00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 "
982                 + "0080   01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 "
983                 + "0090   00 05 00 01 c0 a8 88 33"));
984
985         oneOf(nps).putNotification(with(lispNotificationSaver));
986         handleMapRequestAsByteArray(mapRequestPacket);
987
988     }
989
990     private void stubMapRegister(final boolean setNotifyFromRegister) {
991         try {
992             allowing(nps).putNotification(with(lispNotificationSaver));
993         } catch (InterruptedException e) {
994         }
995         will(new SimpleAction() {
996
997             @Override
998             public Object invoke(Invocation invocation) throws Throwable {
999                 if (setNotifyFromRegister) {
1000                     MapNotifyBuilderHelper.setFromMapRegister(mapNotifyBuilder, lastMapRegister());
1001                 }
1002                 return null;
1003             }
1004         });
1005     }
1006
1007     private void stubHandleRequest() {
1008         try {
1009             allowing(nps).putNotification(wany(Notification.class));
1010         } catch (InterruptedException e) {
1011         }
1012     }
1013
1014     private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
1015         handleMapRequestPacket(inPacket);
1016         return lastMapReplyPacket().content().array();
1017     }
1018
1019     private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
1020         handleMapRegisterPacket(inPacket);
1021         return lastMapNotifyPacket().content().array();
1022     }
1023
1024     private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
1025         DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1026                 new InetSocketAddress(0));
1027         // Unless we explicitly set the source port, it will be -1, which breaks some tests
1028         // This is till not the real port number, but it's better
1029         //dp.setPort(LispMessage.PORT_NUM);
1030         testedLispService.handlePacket(dp);
1031         return lastMapReplyPacket();
1032     }
1033
1034     private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
1035         DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1036                 new InetSocketAddress(0));
1037         // Unless we explicitly set the source port, it will be -1, which breaks some tests
1038         // This is till not the real port number, but it's better
1039         //dp.setPort(LispMessage.PORT_NUM);
1040         testedLispService.handlePacket(dp);
1041         if (mapNotifyBuilder == null) {
1042             return null;
1043         } else {
1044             return lastMapNotifyPacket();
1045         }
1046     }
1047
1048     private DatagramPacket handlePacket(byte[] inPacket) {
1049         // TODO get from mock
1050         testedLispService.handlePacket(new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1051                 new InetSocketAddress(0)));
1052         return null;
1053     }
1054
1055     private byte[] extractWSUdpByteArray(String wiresharkHex) {
1056         final int HEADER_LEN = 42;
1057         byte[] res = new byte[1000];
1058         String[] split = wiresharkHex.split(" ");
1059         int counter = 0;
1060         for (String cur : split) {
1061             cur = cur.trim();
1062             if (cur.length() == 2) {
1063                 ++counter;
1064                 if (counter > HEADER_LEN) {
1065                     res[counter - HEADER_LEN - 1] = (byte) Integer.parseInt(cur, 16);
1066                 }
1067
1068             }
1069         }
1070         return Arrays.copyOf(res, counter - HEADER_LEN);
1071     }
1072
1073     @Test(expected = LispMalformedPacketException.class)
1074     public void mapRequest__NoIPITRRLOC() throws Exception {
1075         mapRequestPacket = hexToByteBuffer("10 00 " //
1076                 + "02 " // This means 3 ITR - RLOCs
1077                 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
1078                 + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 3)
1079                 + "40 05 00 00 00 00 00 00 " // MAC (ITR-RLOC #2 of 3)
1080                 + "40 05 11 22 34 56 78 90 " // MAC (ITR-RLOC #3 of 3)
1081                 + "00 20 00 01 01 02 03 04").array();
1082         handleMapRequestPacket(mapRequestPacket);
1083     }
1084
1085     // @Ignore
1086     // @Test
1087     // public void mapRequest__IPITRRLOCIsSecond() throws Exception {
1088     // mapRequestPacket = hexToByteBuffer("10 00 " //
1089     // + "01 " // This means 3 ITR - RLOCs
1090     // + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
1091     // + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 2)
1092     // + "00 01 01 02 03 04 " // IP (ITR-RLOC #2 of 2)
1093     // + "00 20 00 01 01 02 03 04").array();
1094     // oneOf(nps).putNotification(with(lispNotificationSaver));
1095     // // ret(mapReply);
1096     // DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
1097     // assertEquals(2, lastMapRequest().getItrRlocs().size());
1098     // assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(),
1099     // packet.getAddress());
1100     // }
1101     //
1102     // @Ignore
1103     // @Test
1104     // public void mapRequest__MULTIPLEIPITRRLOCs() throws Exception {
1105     // mapRequestPacket = hexToByteBuffer("10 00 " //
1106     // + "01 " // This means 3 ITR - RLOCs
1107     // + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
1108     // + "00 01 01 02 03 04 " // IP (ITR-RLOC #1 of 2)
1109     // + "00 01 c0 a8 88 0a " // MAC (ITR-RLOC #2 of 2)
1110     // + "00 20 00 01 01 02 03 04").array();
1111     // oneOf(nps).putNotification(with(lispNotificationSaver));
1112     // // ret(mapReply);
1113     // DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
1114     // assertEquals(2, lastMapRequest().getItrRloc().size());
1115     // assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(),
1116     // packet.getAddress());
1117     // }
1118
1119 }