blob: 9329e791a97ca7c4d8fb63dc38be62fdd5408a49 [file] [log] [blame]
Amit Ghosh8951f042017-08-10 13:48:10 +01001/*
2 * Copyright 2017-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Matteo Scandolo57af5d12019-04-29 17:11:41 -070017package org.opencord.dhcpl2relay.impl;
Amit Ghosh8951f042017-08-10 13:48:10 +010018
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030019import static com.google.common.base.Preconditions.checkState;
20import static org.junit.Assert.assertEquals;
Saurav Dasb4e3e102018-10-02 15:31:17 -070021import static org.junit.Assert.fail;
22
23import java.nio.ByteBuffer;
24import java.nio.charset.StandardCharsets;
25import java.util.ArrayList;
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030026import java.util.Collection;
27import java.util.Dictionary;
28import java.util.Hashtable;
Saurav Dasb4e3e102018-10-02 15:31:17 -070029import java.util.LinkedList;
30import java.util.List;
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030031import java.util.Set;
32import java.util.concurrent.Callable;
33import java.util.concurrent.ExecutionException;
34import java.util.concurrent.Future;
35import java.util.concurrent.ScheduledFuture;
36import java.util.concurrent.ScheduledExecutorService;
37import java.util.concurrent.TimeoutException;
38import java.util.concurrent.TimeUnit;
Saurav Dasb4e3e102018-10-02 15:31:17 -070039
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030040import com.google.common.collect.ImmutableSet;
Amit Ghosh8951f042017-08-10 13:48:10 +010041import org.onlab.packet.BasePacket;
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030042import org.onlab.packet.ChassisId;
Amit Ghosh8951f042017-08-10 13:48:10 +010043import org.onlab.packet.DHCP;
Amit Ghosh8951f042017-08-10 13:48:10 +010044import org.onlab.packet.DHCPPacketType;
45import org.onlab.packet.Ethernet;
46import org.onlab.packet.IPv4;
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030047import org.onlab.packet.IpAddress;
Amit Ghosh8951f042017-08-10 13:48:10 +010048import org.onlab.packet.Ip4Address;
49import org.onlab.packet.MacAddress;
50import org.onlab.packet.UDP;
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030051import org.onlab.packet.VlanId;
Jonathan Hartedbf6422018-05-02 17:30:05 -070052import org.onlab.packet.dhcp.DhcpOption;
Saurav Dasb4e3e102018-10-02 15:31:17 -070053import org.onosproject.core.ApplicationId;
54import org.onosproject.core.CoreServiceAdapter;
55import org.onosproject.core.DefaultApplicationId;
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030056import org.onosproject.event.DefaultEventSinkRegistry;
57import org.onosproject.event.Event;
58import org.onosproject.event.EventDeliveryService;
59import org.onosproject.event.EventSink;
60import org.onosproject.mastership.MastershipServiceAdapter;
61import org.onosproject.net.AnnotationKeys;
62import org.onosproject.net.Annotations;
Amit Ghosh8951f042017-08-10 13:48:10 +010063import org.onosproject.net.ConnectPoint;
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030064import org.onosproject.net.DefaultAnnotations;
65import org.onosproject.net.DefaultDevice;
66import org.onosproject.net.DefaultHost;
67import org.onosproject.net.Device;
68import org.onosproject.net.DeviceId;
69import org.onosproject.net.Element;
70import org.onosproject.net.Host;
71import org.onosproject.net.HostId;
72import org.onosproject.net.HostLocation;
73import org.onosproject.net.Port;
74import org.onosproject.net.PortNumber;
75import org.onosproject.net.device.DeviceServiceAdapter;
76import org.onosproject.net.host.HostServiceAdapter;
Amit Ghosh8951f042017-08-10 13:48:10 +010077import org.onosproject.net.packet.DefaultInboundPacket;
78import org.onosproject.net.packet.DefaultPacketContext;
79import org.onosproject.net.packet.InboundPacket;
80import org.onosproject.net.packet.OutboundPacket;
81import org.onosproject.net.packet.PacketContext;
82import org.onosproject.net.packet.PacketProcessor;
83import org.onosproject.net.packet.PacketServiceAdapter;
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -030084import org.onosproject.net.provider.ProviderId;
85import org.opencord.sadis.BandwidthProfileInformation;
86import org.opencord.sadis.BaseInformationService;
87import org.opencord.sadis.SadisService;
88import org.opencord.sadis.SubscriberAndDeviceInformation;
89import org.osgi.framework.Bundle;
90import org.osgi.framework.BundleContext;
91import org.osgi.framework.ServiceReference;
92import org.osgi.service.component.ComponentContext;
93import org.osgi.service.component.ComponentInstance;
Amit Ghosh8951f042017-08-10 13:48:10 +010094import org.slf4j.Logger;
95import org.slf4j.LoggerFactory;
96
Amit Ghosh8951f042017-08-10 13:48:10 +010097
98/**
99 * Common methods for AAA app testing.
100 */
101public class DhcpL2RelayTestBase {
102 private final Logger log = LoggerFactory.getLogger(getClass());
103
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -0300104 static final VlanId CLIENT_C_TAG = VlanId.vlanId((short) 999);
105 static final VlanId CLIENT_S_TAG = VlanId.vlanId((short) 111);
106 static final String CLIENT_ID_1 = "SUBSCRIBER_ID_1";
107 static final String CLIENT_NAS_PORT_ID = "PON 1/1";
108 static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
Amit Ghosh8951f042017-08-10 13:48:10 +0100109
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -0300110 static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
111 static final MacAddress SERVER_MAC = MacAddress.valueOf("bb:bb:bb:bb:bb:bb");
112 static final String DESTINATION_ADDRESS_IP = "1.1.1.1";
113 static final String DHCP_CLIENT_IP_ADDRESS = "2.2.2.2";
114 static final int UPLINK_PORT = 5;
115
116 static final String EXPECTED_IP = "10.2.0.2";
117 static final String OLT_DEV_ID = "of:00000000000000aa";
118 static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(OLT_DEV_ID);
119 static final int TRANSACTION_ID = 1000;
120 static final String SCHEME_NAME = "dhcpl2relay";
121 static final MacAddress OLT_MAC_ADDRESS = MacAddress.valueOf("01:02:03:04:05:06");
122
123 static final ConnectPoint SERVER_CONNECT_POINT =
124 ConnectPoint.deviceConnectPoint("of:00000000000000aa/5");
125
126 static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
127 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
Amit Ghosh8951f042017-08-10 13:48:10 +0100128
129 List<BasePacket> savedPackets = new LinkedList<>();
130 PacketProcessor packetProcessor;
131
132
133 /**
134 * Saves the given packet onto the saved packets list.
135 *
136 * @param packet packet to save
137 */
138 void savePacket(BasePacket packet) {
139 savedPackets.add(packet);
140 }
141
142 BasePacket getPacket() {
143 return savedPackets.remove(0);
144 }
145
146 /**
Saurav Dasb4e3e102018-10-02 15:31:17 -0700147 * Mock core service adaptor that provides an appId.
148 */
149 class MockCoreServiceAdapter extends CoreServiceAdapter {
150
151 @Override
152 public ApplicationId registerApplication(String name) {
153 return new DefaultApplicationId(10, name);
154 }
155 }
156
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -0300157 class MockDeviceService extends DeviceServiceAdapter {
158
159 private ProviderId providerId = new ProviderId("of", "foo");
160 private final Device device1 = new DhcpL2RelayTestBase.MockDevice(providerId, DEVICE_ID_1, Device.Type.SWITCH,
161 "foo.inc", "0", "0", OLT_DEV_ID, new ChassisId(),
162 DEVICE_ANNOTATIONS);
163
164 @Override
165 public Device getDevice(DeviceId devId) {
166 return device1;
167
168 }
169
170 @Override
171 public Port getPort(ConnectPoint cp) {
172 return new DhcpL2RelayTestBase.MockPort();
173 }
174
175 @Override
176 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
177 return new DhcpL2RelayTestBase.MockPort();
178 }
179
180 @Override
181 public boolean isAvailable(DeviceId d) {
182 return true;
183 }
184 }
185
186 class MockDevice extends DefaultDevice {
187
188 public MockDevice(ProviderId providerId, DeviceId id, Type type,
189 String manufacturer, String hwVersion, String swVersion,
190 String serialNumber, ChassisId chassisId, Annotations... annotations) {
191 super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
192 chassisId, annotations);
193 }
194 }
195
196 class MockHostService extends HostServiceAdapter {
197
198 @Override
199 public Set<Host> getHostsByMac(MacAddress mac) {
200
201 HostLocation loc = new HostLocation(DEVICE_ID_1, PortNumber.portNumber(22), 0);
202
203 IpAddress ip = IpAddress.valueOf("10.100.200.10");
204
205 Host h = new DefaultHost(ProviderId.NONE, HostId.hostId(mac, VlanId.NONE),
206 mac, VlanId.NONE, loc, ImmutableSet.of(ip));
207
208 return ImmutableSet.of(h);
209 }
210 }
211
212 class MockMastershipService extends MastershipServiceAdapter {
213 @Override
214 public boolean isLocalMaster(DeviceId d) {
215 return true;
216 }
217 }
218
219 class MockPort implements Port {
220
221 @Override
222 public boolean isEnabled() {
223 return true;
224 }
225 @Override
226 public long portSpeed() {
227 return 1000;
228 }
229 @Override
230 public Element element() {
231 return null;
232 }
233 @Override
234 public PortNumber number() {
235 return null;
236 }
237 @Override
238 public Annotations annotations() {
239 return new MockAnnotations();
240 }
241 @Override
242 public Type type() {
243 return Port.Type.FIBER;
244 }
245
246 private class MockAnnotations implements Annotations {
247
248 @Override
249 public String value(String val) {
250 return "PON 1/1";
251 }
252 @Override
253 public Set<String> keys() {
254 return null;
255 }
256 }
257 }
258
Saurav Dasb4e3e102018-10-02 15:31:17 -0700259 /**
Amit Ghosh8951f042017-08-10 13:48:10 +0100260 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
261 */
262 class MockPacketService extends PacketServiceAdapter {
263
264 @Override
265 public void addProcessor(PacketProcessor processor, int priority) {
266 packetProcessor = processor;
267 }
268
269 @Override
270 public void emit(OutboundPacket packet) {
271 try {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530272 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
Amit Ghosh8951f042017-08-10 13:48:10 +0100273 0, packet.data().array().length);
274 savePacket(eth);
275 } catch (Exception e) {
276 fail(e.getMessage());
277 }
278 }
279 }
280
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -0300281 class MockSadisService implements SadisService {
282 @Override
283 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
284 return new DhcpL2RelayTestBase.MockSubService();
285 }
286
287 @Override
288 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
289 return null;
290 }
291 }
292
293 class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
294 DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation device =
295 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation(OLT_DEV_ID, VlanId.NONE, VlanId.NONE, null,
296 null, OLT_MAC_ADDRESS, Ip4Address.valueOf("10.10.10.10"), UPLINK_PORT);
297 DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation sub =
298 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation(CLIENT_ID_1, CLIENT_C_TAG,
299 CLIENT_S_TAG, CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null, -1);
300 @Override
301 public SubscriberAndDeviceInformation get(String id) {
302 if (id.equals(OLT_DEV_ID)) {
303 return device;
304 } else {
305 return sub;
306 }
307 }
308
309 @Override
310 public void invalidateAll() {}
311 @Override
312 public void invalidateId(String id) {}
313 @Override
314 public SubscriberAndDeviceInformation getfromCache(String id) {
315 return null;
316 }
317 }
318
319 class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
320
321 MockSubscriberAndDeviceInformation(String id, VlanId ctag,
322 VlanId stag, String nasPortId,
323 String circuitId, MacAddress hardId,
324 Ip4Address ipAddress, int uplinkPort) {
325 this.setCTag(ctag);
326 this.setHardwareIdentifier(hardId);
327 this.setId(id);
328 this.setIPAddress(ipAddress);
329 this.setSTag(stag);
330 this.setNasPortId(nasPortId);
331 this.setCircuitId(circuitId);
332 this.setUplinkPort(uplinkPort);
333 }
334 }
335
336 class MockComponentContext implements ComponentContext {
337
338 @Override
339 public Dictionary<String, Object> getProperties() {
340 Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
341 cfgDict.put("publishCountersRate", 10);
342 return cfgDict;
343 }
344
345 @Override
346 public Object locateService(String name) {
347 // TODO Auto-generated method stub
348 return null;
349 }
350
351 @Override
352 public Object locateService(String name, ServiceReference reference) {
353 // TODO Auto-generated method stub
354 return null;
355 }
356
357 @Override
358 public Object[] locateServices(String name) {
359 // TODO Auto-generated method stub
360 return null;
361 }
362
363 @Override
364 public BundleContext getBundleContext() {
365 // TODO Auto-generated method stub
366 return null;
367 }
368
369 @Override
370 public Bundle getUsingBundle() {
371 // TODO Auto-generated method stub
372 return null;
373 }
374
375 @Override
376 public ComponentInstance getComponentInstance() {
377 // TODO Auto-generated method stub
378 return null;
379 }
380
381 @Override
382 public void enableComponent(String name) {
383 // TODO Auto-generated method stub
384 }
385
386 @Override
387 public void disableComponent(String name) {
388 // TODO Auto-generated method stub
389 }
390
391 @Override
392 public ServiceReference getServiceReference() {
393 // TODO Auto-generated method stub
394 return null;
395 }
396 }
397
398
Amit Ghosh8951f042017-08-10 13:48:10 +0100399 /**
400 * Mocks the DefaultPacketContext.
401 */
402 final class TestPacketContext extends DefaultPacketContext {
403
404 private TestPacketContext(long time, InboundPacket inPkt,
405 OutboundPacket outPkt, boolean block) {
406 super(time, inPkt, outPkt, block);
407 }
408
409 @Override
410 public void send() {
411 // We don't send anything out.
412 }
413 }
414
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -0300415 public static class TestEventDispatcher extends DefaultEventSinkRegistry
416 implements EventDeliveryService {
417 @Override
418 @SuppressWarnings("unchecked")
419 public synchronized void post(Event event) {
420 EventSink sink = getSink(event.getClass());
421 checkState(sink != null, "No sink for event %s", event);
422 sink.process(event);
423 }
424
425 @Override
426 public void setDispatchTimeLimit(long millis) {
427 }
428
429 @Override
430 public long getDispatchTimeLimit() {
431 return 0;
432 }
433 }
434
435 /**
436 * Creates a mock object for a scheduled executor service.
437 *
438 */
439 public static final class MockExecutor implements ScheduledExecutorService {
440 private ScheduledExecutorService executor;
441
442 MockExecutor(ScheduledExecutorService executor) {
443 this.executor = executor;
444 }
445
446 String lastMethodCalled = "";
447 long lastInitialDelay;
448 long lastDelay;
449 TimeUnit lastUnit;
450
451 public void assertLastMethodCalled(String method, long initialDelay, long delay, TimeUnit unit) {
452 assertEquals(method, lastMethodCalled);
453 assertEquals(initialDelay, lastInitialDelay);
454 assertEquals(delay, lastDelay);
455 assertEquals(unit, lastUnit);
456 }
457
458 @Override
459 public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
460 lastMethodCalled = "scheduleRunnable";
461 lastDelay = delay;
462 lastUnit = unit;
463 return null;
464 }
465
466 @Override
467 public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
468 lastMethodCalled = "scheduleCallable";
469 lastDelay = delay;
470 lastUnit = unit;
471 return null;
472 }
473
474 @Override
475 public ScheduledFuture<?> scheduleAtFixedRate(
476 Runnable command, long initialDelay, long period, TimeUnit unit) {
477 lastMethodCalled = "scheduleAtFixedRate";
478 lastInitialDelay = initialDelay;
479 lastDelay = period;
480 lastUnit = unit;
481 return null;
482 }
483
484 @Override
485 public ScheduledFuture<?> scheduleWithFixedDelay(
486 Runnable command, long initialDelay, long delay, TimeUnit unit) {
487 lastMethodCalled = "scheduleWithFixedDelay";
488 lastInitialDelay = initialDelay;
489 lastDelay = delay;
490 lastUnit = unit;
491 command.run();
492 return null;
493 }
494
495 @Override
496 public boolean awaitTermination(long timeout, TimeUnit unit) {
497 throw new UnsupportedOperationException();
498 }
499
500 @Override
501 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
502 throws InterruptedException {
503 throw new UnsupportedOperationException();
504 }
505
506 @Override
507 public <T> List<Future<T>> invokeAll(
508 Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
509 throws InterruptedException {
510 throw new UnsupportedOperationException();
511 }
512
513 @Override
514 public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
515 throws ExecutionException, InterruptedException {
516 throw new UnsupportedOperationException();
517 }
518
519 @Override
520 public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
521 throws ExecutionException, InterruptedException, TimeoutException {
522 throw new UnsupportedOperationException();
523 }
524
525 @Override
526 public boolean isShutdown() {
527 throw new UnsupportedOperationException();
528 }
529
530 @Override
531 public boolean isTerminated() {
532 throw new UnsupportedOperationException();
533 }
534
535 @Override
536 public void shutdown() {
537 throw new UnsupportedOperationException();
538 }
539
540 @Override
541 public List<Runnable> shutdownNow() {
542 return null;
543 }
544
545 @Override
546 public <T> Future<T> submit(Callable<T> task) {
547 throw new UnsupportedOperationException();
548 }
549
550 @Override
551 public Future<?> submit(Runnable task) {
552 throw new UnsupportedOperationException();
553 }
554
555 @Override
556 public <T> Future<T> submit(Runnable task, T result) {
557 throw new UnsupportedOperationException();
558 }
559
560 @Override
561 public void execute(Runnable command) {
562 throw new UnsupportedOperationException();
563 }
564 }
565
Amit Ghosh8951f042017-08-10 13:48:10 +0100566 /**
567 * Sends an Ethernet packet to the process method of the Packet Processor.
568 *
569 * @param pkt Ethernet packet
570 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530571 void sendPacket(Ethernet pkt, ConnectPoint cp) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100572 final ByteBuffer byteBuffer = ByteBuffer.wrap(pkt.serialize());
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530573 InboundPacket inPacket = new DefaultInboundPacket(cp, pkt, byteBuffer);
Amit Ghosh8951f042017-08-10 13:48:10 +0100574
575 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
576 packetProcessor.process(context);
577 }
578
579 /**
580 * Constructs an Ethernet packet with IP/UDP/DHCP payload.
581 *
582 * @return Ethernet packet
583 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530584 private Ethernet construcEthernetPacket(MacAddress srcMac, MacAddress dstMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100585 String dstIp, byte dhcpReqRsp,
586 MacAddress clientHwAddress,
587 Ip4Address dhcpClientIpAddress) {
588 // Ethernet Frame.
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530589 Ethernet ethPkt = new Ethernet();
590 ethPkt.setSourceMACAddress(srcMac);
591 ethPkt.setDestinationMACAddress(dstMac);
Amit Ghosh8951f042017-08-10 13:48:10 +0100592 ethPkt.setEtherType(Ethernet.TYPE_IPV4);
593 ethPkt.setVlanID((short) 2);
594 ethPkt.setPriorityCode((byte) 6);
595
596 // IP Packet
597 IPv4 ipv4Reply = new IPv4();
598 ipv4Reply.setSourceAddress(0);
599 ipv4Reply.setDestinationAddress(dstIp);
600
601 ipv4Reply.setTtl((byte) 127);
602
603 // UDP Datagram.
604 UDP udpReply = new UDP();
605 udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
606 udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
607
608 // DHCP Payload.
609 DHCP dhcpReply = new DHCP();
610 dhcpReply.setOpCode(dhcpReqRsp);
611
612 dhcpReply.setYourIPAddress(dhcpClientIpAddress.toInt());
613 dhcpReply.setServerIPAddress(0);
614
615 final byte[] serverNameBytes = new byte[64];
616 String result = new String(serverNameBytes, StandardCharsets.US_ASCII).trim();
617 dhcpReply.setServerName(result);
618
619 final byte[] bootFileBytes = new byte[128];
620 String result1 = new String(bootFileBytes, StandardCharsets.US_ASCII).trim();
621 dhcpReply.setBootFileName(result1);
622
623 dhcpReply.setTransactionId(TRANSACTION_ID);
624 dhcpReply.setClientHardwareAddress(clientHwAddress.toBytes());
625 dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
626 dhcpReply.setHardwareAddressLength((byte) 6);
627
628 udpReply.setPayload(dhcpReply);
629 ipv4Reply.setPayload(udpReply);
630 ethPkt.setPayload(ipv4Reply);
631
632 return ethPkt;
633 }
634
635 /**
636 * Constructs DHCP Discover Packet.
637 *
638 * @return Ethernet packet
639 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530640 Ethernet constructDhcpDiscoverPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100641
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530642 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100643 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
644 Ip4Address.valueOf("0.0.0.0"));
645
646 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
647 UDP udpPacket = (UDP) ipv4Packet.getPayload();
648 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
649
650 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPDISCOVER));
651
652 return pkt;
653 }
654
655 /**
656 * Constructs DHCP Request Packet.
657 *
658 * @return Ethernet packet
659 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530660 Ethernet constructDhcpRequestPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100661
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530662 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100663 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
664 Ip4Address.valueOf("0.0.0.0"));
665
666 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
667 UDP udpPacket = (UDP) ipv4Packet.getPayload();
668 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
669
670 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPREQUEST));
671
672 return pkt;
673 }
674
675 /**
676 * Constructs DHCP Offer Packet.
677 *
678 * @return Ethernet packet
679 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530680 Ethernet constructDhcpOfferPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100681 String ipAddress, String dhcpClientIpAddress) {
682
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530683 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100684 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
685
686 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
687 UDP udpPacket = (UDP) ipv4Packet.getPayload();
688 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
689
690 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPOFFER));
691
692 return pkt;
693 }
694
695 /**
696 * Constructs DHCP Ack Packet.
697 *
698 * @return Ethernet packet
699 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530700 Ethernet constructDhcpAckPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100701 String ipAddress, String dhcpClientIpAddress) {
702
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530703 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100704 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
705
706 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
707 UDP udpPacket = (UDP) ipv4Packet.getPayload();
708 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
709
710 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPACK));
711
712 return pkt;
713 }
714
715 /**
716 * Constructs DHCP Discover Options.
717 *
718 * @return Ethernet packet
719 */
Jonathan Hartedbf6422018-05-02 17:30:05 -0700720 private List<DhcpOption> constructDhcpOptions(DHCPPacketType packetType) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100721
722 // DHCP Options.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700723 DhcpOption option = new DhcpOption();
724 List<DhcpOption> optionList = new ArrayList<>();
Amit Ghosh8951f042017-08-10 13:48:10 +0100725
726
727 // DHCP Message Type.
728 option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
729 option.setLength((byte) 1);
730 byte[] optionData = {(byte) packetType.getValue()};
731 option.setData(optionData);
732 optionList.add(option);
733
734 // DHCP Requested IP.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700735 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100736 option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
737 option.setLength((byte) 4);
738 optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
739 option.setData(optionData);
740 optionList.add(option);
741
742 // End Option.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700743 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100744 option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
745 option.setLength((byte) 1);
746 optionList.add(option);
747
748 return optionList;
749 }
Marcos Aurelio Carrerodadb3572019-11-25 13:34:25 -0300750}