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 org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertTrue;
15 import java.net.DatagramPacket;
16 import java.nio.ByteBuffer;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.List;
21 import junitx.framework.ArrayAssert;
23 import org.apache.commons.lang3.ArrayUtils;
24 import org.jmock.api.Invocation;
25 import org.junit.Before;
26 import org.junit.Ignore;
27 import org.junit.Test;
28 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
29 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
30 import org.opendaylight.lispflowmapping.lisp.type.LispMessageEnum;
31 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
32 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
33 import org.opendaylight.lispflowmapping.lisp.util.MapNotifyBuilderHelper;
34 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
35 import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
36 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
37 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
38 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.afn.safi.rev130704.AddressFamily;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4Afi;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4PrefixAfi;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv6PrefixAfi;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord.Action;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapreplymessage.MapReplyBuilder;
59 import org.opendaylight.yangtools.yang.binding.Notification;
61 public class LispSouthboundServiceTest extends BaseTestCase {
63 private LispSouthboundService testedLispService;
64 private NotificationPublishService nps;
65 private byte[] mapRequestPacket;
66 private byte[] mapRegisterPacket;
67 private ValueSaverAction<Notification> lispNotificationSaver;
68 // private ValueSaverAction<MapRegister> mapRegisterSaver;
69 // private ValueSaverAction<MapRequest> mapRequestSaver;
70 private MapNotifyBuilder mapNotifyBuilder;
71 private MapReplyBuilder mapReplyBuilder;
72 private MappingRecordBuilder mappingRecordBuilder;
74 private interface MapReplyIpv4SingleLocatorPos {
77 int LOCATOR_COUNT = 16;
78 int EID_MASK_LEN = 17;
82 int LOCATOR_RBIT = 33;
86 private interface MapReplyIpv4SecondLocatorPos {
87 int FIRST_LOCATOR_IPV4_LENGTH = 12;
88 int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
89 int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
90 int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
95 public void before() throws Exception {
97 // mapResolver = context.mock(IMapResolver.class);
98 // mapServer = context.mock(IMapServer.class);
99 testedLispService = new LispSouthboundService(null);
100 nps = context.mock(NotificationPublishService.class);
101 testedLispService.setNotificationProvider(nps);
102 lispNotificationSaver = new ValueSaverAction<Notification>();
103 // mapRegisterSaver = new ValueSaverAction<MapRegister>();
104 // mapRequestSaver = new ValueSaverAction<MapRequest>();
105 // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
106 // LISP(Type = 8 - Encapsulated)
107 // IP: 192.168.136.10 -> 1.2.3.4
109 // LISP(Type = 1 Map-Request
113 // Source EID not present
114 // Nonce: 0x3d8d2acd39c8d608
115 // ITR-RLOC AFI=1 Address=192.168.136.10
116 // Record 1: 1.2.3.4/32
117 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
118 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
119 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
120 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
121 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
122 + "0050 2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 c0 a8 88 0a 00 20 " //
123 + "0060 00 01 01 02 03 04"));
124 mapReplyBuilder = new MapReplyBuilder();
125 mapReplyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
126 mapReplyBuilder.setNonce((long) 0);
127 mapReplyBuilder.setEchoNonceEnabled(false);
128 mapReplyBuilder.setProbe(true);
129 mapReplyBuilder.setSecurityEnabled(true);
130 mappingRecordBuilder = new MappingRecordBuilder();
131 String ip = "0.0.0.0";
132 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid(ip + "/0"));
133 mappingRecordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
134 mappingRecordBuilder.setRecordTtl(10);
135 mappingRecordBuilder.setMapVersion((short) 0);
136 mappingRecordBuilder.setMaskLength((short) 0);
137 mappingRecordBuilder.setAction(Action.NativelyForward);
138 mappingRecordBuilder.setAuthoritative(false);
139 // eidToLocatorBuilder.setPrefix(new LispIpv4Address(0));
140 // mapReply.addEidToLocator(eidToLocatorBuilder);
142 // IP: 192.168.136.10 -> 128.223.156.35
143 // UDP: 49289 -> 4342
144 // LISP(Type = 3 Map-Register, P=1, M=1
148 // AuthDataLength: 20 Data:
149 // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
150 // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
152 // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
153 // Priority/Weight: 1/100, Multicast Priority/Weight:
157 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
158 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
159 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
160 + "0030 00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
161 + "0040 71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
162 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
163 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
164 mapNotifyBuilder = new MapNotifyBuilder();
165 mapNotifyBuilder.setAuthenticationData(new byte[0]);
170 public void todos() throws Exception {
172 // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
173 // TODO: Non-Encapsulated packets
176 @Test(expected = LispMalformedPacketException.class)
177 public void mapRegister__IllegalPacket() throws Exception {
178 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
179 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 " //
180 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "));
182 handleMapRegisterPacket(mapRegisterPacket);
185 @Test(expected = LispMalformedPacketException.class)
186 public void mapRequest__IllegalPacket() throws Exception {
187 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
188 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
189 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
190 + "0030 00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 " //
191 + "0040 03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "));
192 handleMapRequestPacket(mapRequestPacket);
195 @Test(expected = LispMalformedPacketException.class)
196 public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
197 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
198 + "0010 00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 " //
199 + "0020 00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "));
200 handleMapRequestPacket(mapRequestPacket);
203 private MapRegister lastMapRegister() {
204 assertTrue(lispNotificationSaver.lastValue instanceof AddMapping);
205 AddMapping lastValue = (AddMapping) lispNotificationSaver.lastValue;
206 return lastValue.getMapRegister();
209 private MapRequest lastMapRequest() {
210 RequestMapping lastValue = (RequestMapping) lispNotificationSaver.lastValue;
211 return lastValue.getMapRequest();
215 public void mapRegister__TwoRlocs() throws Exception {
217 // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
218 // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
219 // Priority/Weight: 255/0
220 // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
221 // Multicast Priority/Weight: 255/0
222 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
223 + "0010 00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 " //
224 + "0020 00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 " //
225 + "0030 00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 " //
226 + "0040 e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 " //
227 + "0050 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 " //
228 + "0060 ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 " //
229 + "0070 00 01 c0 a8 88 33"));
231 oneOf(nps).putNotification(with(lispNotificationSaver));
233 handleMapRegisterPacket(mapRegisterPacket);
235 List<MappingRecordItem> eidRecords = lastMapRegister().getMappingRecordItem();
236 assertEquals(1, eidRecords.size());
237 MappingRecord eidRecord = eidRecords.get(0).getMappingRecord();
238 assertEquals(2, eidRecord.getLocatorRecord().size());
239 assertEquals(LispAddressUtil.asIpv4Rloc("10.1.0.110"), eidRecord.getLocatorRecord().get(0).getRloc());
240 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.51"), eidRecord.getLocatorRecord().get(1).getRloc());
244 public void mapRegister__Ipv6Rloc() throws Exception {
245 // P bit (Proxy-Map-Reply): Set
246 // M bit (Want-Map-Notify): Set
251 // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
252 // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
254 // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
255 // Priority/Weight: 255/0
257 mapRegisterPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
258 + "0010 00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 " //
259 + "0020 01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 " //
260 + "0030 00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 " //
261 + "0040 0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 " //
262 + "0050 00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff " //
263 + "0060 01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 " //
264 + "0070 00 01 0a 00 3a 9c"));
266 oneOf(nps).putNotification(with(lispNotificationSaver));
268 handleMapRegisterPacket(mapRegisterPacket);
270 MappingRecord eidToLocatorRecord = lastMapRegister().getMappingRecordItem().get(0).getMappingRecord();
271 assertEquals("2610:d0:ffff:192:0:0:0:1/128",
272 ((Ipv6Prefix) eidToLocatorRecord.getEid().getAddress()).getIpv6Prefix().getValue());
273 assertEquals(Ipv6PrefixAfi.class, eidToLocatorRecord.getEid().getAddressType());
275 assertEquals(LispAddressUtil.asIpv4Rloc("10.0.58.156"), eidToLocatorRecord.getLocatorRecord().get(0).getRloc());
279 public void mapRegister__VerifyBasicFields() throws Exception {
280 oneOf(nps).putNotification(with(lispNotificationSaver));
281 handleMapRegisterPacket(mapRegisterPacket);
283 MappingRecord eidToLocator = lastMapRegister().getMappingRecordItem().get(0).getMappingRecord();
284 assertEquals(LispAddressUtil.asIpv4PrefixEid("153.16.254.1/32"), eidToLocator.getEid());
286 assertEquals(1, eidToLocator.getLocatorRecord().size());
287 assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.10"), eidToLocator.getLocatorRecord().get(0).getRloc());
292 public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
293 oneOf(nps).putNotification(with(lispNotificationSaver));
294 mapNotifyBuilder = null;
296 assertNull(handleMapRegisterPacket(mapRegisterPacket));
300 public void mapRegister__NonSetMBit() throws Exception {
301 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
302 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df " //
303 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
304 + "0030 00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
305 + "0040 83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 " //
306 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
307 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
308 stubMapRegister(true);
310 handleMapRegisterPacket(registerWithNonSetMBit);
312 assertFalse(lastMapRegister().isWantMapNotify());
316 public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
317 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
318 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
319 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
320 + "0030 00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
321 + "0040 e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
322 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
323 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
324 stubMapRegister(true);
326 handleMapRegisterPacket(registerWithNonSetMBit);
327 assertFalse(lastMapRegister().isWantMapNotify());
331 public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
332 byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
333 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
334 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
335 + "0030 00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
336 + "0040 4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
337 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
338 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
339 stubMapRegister(true);
341 handleMapRegisterPacket(registerWithNonSetMBit);
342 assertTrue(lastMapRegister().isWantMapNotify());
347 public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
348 byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
349 extraDataPacket[mapRegisterPacket.length] = 0x9;
350 System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
351 stubMapRegister(true);
353 DatagramPacket dp = new DatagramPacket(extraDataPacket, extraDataPacket.length);
354 dp.setLength(mapRegisterPacket.length);
355 testedLispService.handlePacket(dp);
356 // Check map register fields.
358 // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
359 byte[] notifyResult = lastMapNotifyPacket().getData();
360 assertEquals(mapRegisterPacket.length, notifyResult.length);
364 private DatagramPacket lastMapReplyPacket() {
365 ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
366 return new DatagramPacket(serialize.array(), serialize.array().length);
369 private DatagramPacket lastMapNotifyPacket() {
370 if (mapNotifyBuilder.getMappingRecordItem() == null) {
371 mapNotifyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
373 mapNotifyBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
374 mappingRecordBuilder.build()).build());
375 mapNotifyBuilder.setNonce((long) 0);
376 mapNotifyBuilder.setKeyId((short) 0);
377 mapNotifyBuilder.setAuthenticationData(new byte[0]);
378 ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotifyBuilder.build());
379 return new DatagramPacket(serialize.array(), serialize.array().length);
384 public void mapNotify__VerifyBasicFields() throws Exception {
385 byte registerType = mapRegisterPacket[0];
386 assertEquals(LispMessageEnum.MapRegister.getValue(), registerType >> 4);
388 stubMapRegister(true);
390 byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
392 assertEquals(mapRegisterPacket.length, result.length);
394 byte expectedType = (byte) (LispMessageEnum.MapNotify.getValue() << 4);
395 assertHexEquals(expectedType, result[0]);
396 assertHexEquals((byte) 0x00, result[1]);
397 assertHexEquals((byte) 0x00, result[2]);
399 byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(mapRegisterPacket, 3, 16),
400 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
401 byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
402 Arrays.copyOfRange(result, 36, result.length));
403 ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData, notifyWithoutTypeWithOutAuthenticationData);
408 public void mapNotify__VerifyPort() throws Exception {
409 stubMapRegister(true);
411 DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
412 assertEquals(LispMessage.PORT_NUM, notifyPacket.getPort());
416 public void mapRequest__VerifyBasicFields() throws Exception {
417 oneOf(nps).putNotification(with(lispNotificationSaver));
418 handleMapRequestAsByteArray(mapRequestPacket);
419 List<EidItem> eids = lastMapRequest().getEidItem();
420 assertEquals(1, eids.size());
421 Eid lispAddress = eids.get(0).getEid();
422 assertEquals(Ipv4PrefixAfi.class, lispAddress.getAddressType());
423 assertEquals(LispAddressUtil.asIpv4PrefixEid("1.2.3.4/32"), lispAddress);
424 assertEquals(0x3d8d2acd39c8d608L, lastMapRequest().getNonce().longValue());
428 public void mapRequest__Ipv6Eid() throws Exception {
429 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
430 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
431 // (2610:d0:ffff:192::2)
434 // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
435 // ITR-RLOC 1: 10.0.58.156
436 // Record 1: 2610:d0:ffff:192::2/128
437 // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
438 // Authoritative, No-Action
440 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
441 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
442 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
443 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
444 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
445 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
446 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
447 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
448 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
449 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 " //
450 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 " //
451 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
453 oneOf(nps).putNotification(with(lispNotificationSaver));
456 handleMapRequestAsByteArray(mapRequestPacket);
457 assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"), lastMapRequest().getSourceEid().getEid());
458 assertEquals(LispAddressUtil.asIpv6PrefixEid("2610:d0:ffff:192:0:0:0:2/128"), lastMapRequest().getEidItem().get(0).getEid());
463 public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
464 // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
465 // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
466 // (2610:d0:ffff:192::2)
467 // encapsulated UDP source port: 4342
469 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 " //
470 + "0010 00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
471 + "0020 01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
472 + "0030 00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
473 + "0040 00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
474 + "0050 00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
475 + "0060 00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
476 + "0070 ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
477 + "0080 3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
478 + "0090 00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 " //
479 + "00a0 00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 " //
480 + "00b0 00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
481 oneOf(nps).putNotification(with(lispNotificationSaver));
484 DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
485 assertEquals(4342, replyPacket.getPort());
489 public void mapRequest__WithSourceEid() throws Exception {
490 // encapsulated LISP packet
491 // Source EID = 153.16.254.1
493 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 " //
494 + "0010 00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
495 + "0020 3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
496 + "0030 00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
497 + "0040 14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
498 + "0050 ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
499 + "0060 01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
500 + "0070 10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 " //
501 + "0080 00 01 0a 00 01 26"));
503 oneOf(nps).putNotification(with(lispNotificationSaver));
506 handleMapRequestAsByteArray(mapRequestPacket);
507 assertEquals(Ipv4Afi.class, lastMapRequest().getSourceEid().getEid().getAddressType());
513 public void mapReply__VerifyBasicIPv4Fields() throws Exception {
514 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
515 mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
519 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
521 assertEquals(28, result.length);
523 byte expectedLispMessageType = 2;
524 assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
525 assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
527 byte expectedRecordCount = (byte) 1;
528 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
530 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()), result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
531 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
532 assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
537 public void mapReply__VerifyBasicIPv6() throws Exception {
538 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
542 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
544 assertEquals(40, result.length);
546 byte expectedRecordCount = (byte) 1;
547 assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
549 assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()), result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
550 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
551 byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
553 ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
558 public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
559 mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
560 mappingRecordBuilder.getLocatorRecord().add(
561 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
565 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
567 assertEquals(64, result.length);
569 byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
570 ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
572 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
573 ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
578 public void mapReply__UseEncapsulatedUdpPort() throws Exception {
581 assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).getPort());
586 public void mapReply__WithNonRoutableSingleLocator() throws Exception {
587 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
588 mappingRecordBuilder.getLocatorRecord().add(
589 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
592 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
593 assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
598 public void mapReply__WithSingleLocator() throws Exception {
599 mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
600 mappingRecordBuilder.getLocatorRecord().add(
601 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
604 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
605 assertEquals(40, result.length);
607 byte expectedLocCount = 1;
608 assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
610 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
612 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
613 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
618 public void mapReply__WithMultipleLocator() throws Exception {
619 mappingRecordBuilder.getLocatorRecord().add(
620 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
621 mappingRecordBuilder.getLocatorRecord().add(
622 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1")).build());
625 byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
626 assertEquals(64, result.length);
628 assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
630 assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
631 assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
632 assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
634 assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
636 byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
637 ArrayAssert.assertEquals(expectedIpv6Rloc,
638 Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR, MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
640 assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
644 public void handleUnknownLispMessage() throws Exception {
645 // IP: 192.168.136.10 -> 128.223.156.35
646 // UDP: 49289 -> 4342
647 // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
649 byte[] unknownTypePacket = extractWSUdpByteArray(new String("0000 00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
650 + "0010 00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
651 + "0020 9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
652 + "0030 00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
653 + "0040 b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
654 + "0050 00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
655 + "0060 ff 00 00 05 00 01 c0 a8 88 0a"));
656 assertNull(handlePacket(unknownTypePacket));
660 public void mapRequest__MultipleItrRlocs() throws Exception {
661 // this is what LISPmob sends when configured multiple RLOCs for single
663 // ITR-RLOC 1: 10.1.0.111
664 // ITR-RLOC 2: 192.168.136.51
666 mapRequestPacket = extractWSUdpByteArray(new String("0000 00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
667 + "0010 00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 " //
668 + "0020 00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 " //
669 + "0030 00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 " //
670 + "0040 08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 " //
671 + "0050 ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 " //
672 + "0060 00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 " //
673 + "0070 00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 " //
674 + "0080 01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 " //
675 + "0090 00 05 00 01 c0 a8 88 33"));
677 oneOf(nps).putNotification(with(lispNotificationSaver));
678 handleMapRequestAsByteArray(mapRequestPacket);
682 private void stubMapRegister(final boolean setNotifyFromRegister) {
684 allowing(nps).putNotification(with(lispNotificationSaver));
685 } catch (InterruptedException e) {
687 will(new SimpleAction() {
690 public Object invoke(Invocation invocation) throws Throwable {
691 if (setNotifyFromRegister) {
692 MapNotifyBuilderHelper.setFromMapRegister(mapNotifyBuilder, lastMapRegister());
699 private void stubHandleRequest() {
701 allowing(nps).putNotification(wany(Notification.class));
702 } catch (InterruptedException e) {
706 private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
707 handleMapRequestPacket(inPacket);
708 return lastMapReplyPacket().getData();
711 private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
712 handleMapRegisterPacket(inPacket);
713 return lastMapNotifyPacket().getData();
716 private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
717 DatagramPacket dp = new DatagramPacket(inPacket, inPacket.length);
718 // Unless we explicitly set the source port, it will be -1, which breaks some tests
719 // This is till not the real port number, but it's better
720 dp.setPort(LispMessage.PORT_NUM);
721 testedLispService.handlePacket(dp);
722 return lastMapReplyPacket();
725 private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
726 DatagramPacket dp = new DatagramPacket(inPacket, inPacket.length);
727 // Unless we explicitly set the source port, it will be -1, which breaks some tests
728 // This is till not the real port number, but it's better
729 dp.setPort(LispMessage.PORT_NUM);
730 testedLispService.handlePacket(dp);
731 if (mapNotifyBuilder == null) {
734 return lastMapNotifyPacket();
738 private DatagramPacket handlePacket(byte[] inPacket) {
739 // TODO get from mock
740 testedLispService.handlePacket(new DatagramPacket(inPacket, inPacket.length));
744 private byte[] extractWSUdpByteArray(String wiresharkHex) {
745 final int HEADER_LEN = 42;
746 byte[] res = new byte[1000];
747 String[] split = wiresharkHex.split(" ");
749 for (String cur : split) {
751 if (cur.length() == 2) {
753 if (counter > HEADER_LEN) {
754 res[counter - HEADER_LEN - 1] = (byte) Integer.parseInt(cur, 16);
759 return Arrays.copyOf(res, counter - HEADER_LEN);
762 @Test(expected = LispMalformedPacketException.class)
763 public void mapRequest__NoIPITRRLOC() throws Exception {
764 mapRequestPacket = hexToByteBuffer("10 00 " //
765 + "02 " // This means 3 ITR - RLOCs
766 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
767 + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 3)
768 + "40 05 00 00 00 00 00 00 " // MAC (ITR-RLOC #2 of 3)
769 + "40 05 11 22 34 56 78 90 " // MAC (ITR-RLOC #3 of 3)
770 + "00 20 00 01 01 02 03 04").array();
771 handleMapRequestPacket(mapRequestPacket);
776 // public void mapRequest__IPITRRLOCIsSecond() throws Exception {
777 // mapRequestPacket = hexToByteBuffer("10 00 " //
778 // + "01 " // This means 3 ITR - RLOCs
779 // + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
780 // + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 2)
781 // + "00 01 01 02 03 04 " // IP (ITR-RLOC #2 of 2)
782 // + "00 20 00 01 01 02 03 04").array();
783 // oneOf(nps).putNotification(with(lispNotificationSaver));
785 // DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
786 // assertEquals(2, lastMapRequest().getItrRlocs().size());
787 // assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(),
788 // packet.getAddress());
793 // public void mapRequest__MULTIPLEIPITRRLOCs() throws Exception {
794 // mapRequestPacket = hexToByteBuffer("10 00 " //
795 // + "01 " // This means 3 ITR - RLOCs
796 // + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
797 // + "00 01 01 02 03 04 " // IP (ITR-RLOC #1 of 2)
798 // + "00 01 c0 a8 88 0a " // MAC (ITR-RLOC #2 of 2)
799 // + "00 20 00 01 01 02 03 04").array();
800 // oneOf(nps).putNotification(with(lispNotificationSaver));
802 // DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
803 // assertEquals(2, lastMapRequest().getItrRloc().size());
804 // assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(),
805 // packet.getAddress());