blob: a389ba40b0ddd141a8e3ecb77dd1152eb4db9492 [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
19import org.onlab.packet.BasePacket;
20import org.onlab.packet.DHCP;
Amit Ghosh8951f042017-08-10 13:48:10 +010021import org.onlab.packet.Ethernet;
22import org.onlab.packet.IPv4;
23import org.onlab.packet.Ip4Address;
24import org.onlab.packet.MacAddress;
25import org.onlab.packet.UDP;
Jonathan Hartedbf6422018-05-02 17:30:05 -070026import org.onlab.packet.dhcp.DhcpOption;
Saurav Dasb4e3e102018-10-02 15:31:17 -070027import org.onosproject.core.ApplicationId;
28import org.onosproject.core.CoreServiceAdapter;
29import org.onosproject.core.DefaultApplicationId;
Amit Ghosh8951f042017-08-10 13:48:10 +010030import org.onosproject.net.ConnectPoint;
31import org.onosproject.net.packet.DefaultInboundPacket;
32import org.onosproject.net.packet.DefaultPacketContext;
33import org.onosproject.net.packet.InboundPacket;
34import org.onosproject.net.packet.OutboundPacket;
35import org.onosproject.net.packet.PacketContext;
36import org.onosproject.net.packet.PacketProcessor;
37import org.onosproject.net.packet.PacketServiceAdapter;
Amit Ghosh8951f042017-08-10 13:48:10 +010038import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
Carmelo Casconede1e6e32019-07-15 19:39:08 -070041import java.nio.ByteBuffer;
42import java.nio.charset.StandardCharsets;
43import java.util.ArrayList;
44import java.util.LinkedList;
45import java.util.List;
46
47import static org.junit.Assert.fail;
48
Amit Ghosh8951f042017-08-10 13:48:10 +010049
50/**
51 * Common methods for AAA app testing.
52 */
53public class DhcpL2RelayTestBase {
54 private final Logger log = LoggerFactory.getLogger(getClass());
55
56 private static final int TRANSACTION_ID = 1000;
57
58 private static final String EXPECTED_IP = "10.2.0.2";
59
60 List<BasePacket> savedPackets = new LinkedList<>();
61 PacketProcessor packetProcessor;
62
63
64 /**
65 * Saves the given packet onto the saved packets list.
66 *
67 * @param packet packet to save
68 */
69 void savePacket(BasePacket packet) {
70 savedPackets.add(packet);
71 }
72
73 BasePacket getPacket() {
74 return savedPackets.remove(0);
75 }
76
77 /**
Saurav Dasb4e3e102018-10-02 15:31:17 -070078 * Mock core service adaptor that provides an appId.
79 */
80 class MockCoreServiceAdapter extends CoreServiceAdapter {
81
82 @Override
83 public ApplicationId registerApplication(String name) {
84 return new DefaultApplicationId(10, name);
85 }
86 }
87
88 /**
Amit Ghosh8951f042017-08-10 13:48:10 +010089 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
90 */
91 class MockPacketService extends PacketServiceAdapter {
92
93 @Override
94 public void addProcessor(PacketProcessor processor, int priority) {
95 packetProcessor = processor;
96 }
97
98 @Override
99 public void emit(OutboundPacket packet) {
100 try {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530101 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
Amit Ghosh8951f042017-08-10 13:48:10 +0100102 0, packet.data().array().length);
103 savePacket(eth);
104 } catch (Exception e) {
105 fail(e.getMessage());
106 }
107 }
108 }
109
110 /**
111 * Mocks the DefaultPacketContext.
112 */
113 final class TestPacketContext extends DefaultPacketContext {
114
115 private TestPacketContext(long time, InboundPacket inPkt,
116 OutboundPacket outPkt, boolean block) {
117 super(time, inPkt, outPkt, block);
118 }
119
120 @Override
121 public void send() {
122 // We don't send anything out.
123 }
124 }
125
126 /**
127 * Sends an Ethernet packet to the process method of the Packet Processor.
128 *
129 * @param pkt Ethernet packet
130 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530131 void sendPacket(Ethernet pkt, ConnectPoint cp) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100132 final ByteBuffer byteBuffer = ByteBuffer.wrap(pkt.serialize());
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530133 InboundPacket inPacket = new DefaultInboundPacket(cp, pkt, byteBuffer);
Amit Ghosh8951f042017-08-10 13:48:10 +0100134
135 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
136 packetProcessor.process(context);
137 }
138
139 /**
140 * Constructs an Ethernet packet with IP/UDP/DHCP payload.
141 *
142 * @return Ethernet packet
143 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530144 private Ethernet construcEthernetPacket(MacAddress srcMac, MacAddress dstMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100145 String dstIp, byte dhcpReqRsp,
146 MacAddress clientHwAddress,
147 Ip4Address dhcpClientIpAddress) {
148 // Ethernet Frame.
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530149 Ethernet ethPkt = new Ethernet();
150 ethPkt.setSourceMACAddress(srcMac);
151 ethPkt.setDestinationMACAddress(dstMac);
Amit Ghosh8951f042017-08-10 13:48:10 +0100152 ethPkt.setEtherType(Ethernet.TYPE_IPV4);
153 ethPkt.setVlanID((short) 2);
154 ethPkt.setPriorityCode((byte) 6);
155
156 // IP Packet
157 IPv4 ipv4Reply = new IPv4();
158 ipv4Reply.setSourceAddress(0);
159 ipv4Reply.setDestinationAddress(dstIp);
160
161 ipv4Reply.setTtl((byte) 127);
162
163 // UDP Datagram.
164 UDP udpReply = new UDP();
165 udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
166 udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
167
168 // DHCP Payload.
169 DHCP dhcpReply = new DHCP();
170 dhcpReply.setOpCode(dhcpReqRsp);
171
172 dhcpReply.setYourIPAddress(dhcpClientIpAddress.toInt());
173 dhcpReply.setServerIPAddress(0);
174
175 final byte[] serverNameBytes = new byte[64];
176 String result = new String(serverNameBytes, StandardCharsets.US_ASCII).trim();
177 dhcpReply.setServerName(result);
178
179 final byte[] bootFileBytes = new byte[128];
180 String result1 = new String(bootFileBytes, StandardCharsets.US_ASCII).trim();
181 dhcpReply.setBootFileName(result1);
182
183 dhcpReply.setTransactionId(TRANSACTION_ID);
184 dhcpReply.setClientHardwareAddress(clientHwAddress.toBytes());
185 dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
186 dhcpReply.setHardwareAddressLength((byte) 6);
187
188 udpReply.setPayload(dhcpReply);
189 ipv4Reply.setPayload(udpReply);
190 ethPkt.setPayload(ipv4Reply);
191
192 return ethPkt;
193 }
194
195 /**
196 * Constructs DHCP Discover Packet.
197 *
198 * @return Ethernet packet
199 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530200 Ethernet constructDhcpDiscoverPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100201
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530202 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100203 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
204 Ip4Address.valueOf("0.0.0.0"));
205
206 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
207 UDP udpPacket = (UDP) ipv4Packet.getPayload();
208 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
209
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700210 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPDISCOVER));
Amit Ghosh8951f042017-08-10 13:48:10 +0100211
212 return pkt;
213 }
214
215 /**
216 * Constructs DHCP Request Packet.
217 *
218 * @return Ethernet packet
219 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530220 Ethernet constructDhcpRequestPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100221
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530222 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100223 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
224 Ip4Address.valueOf("0.0.0.0"));
225
226 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
227 UDP udpPacket = (UDP) ipv4Packet.getPayload();
228 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
229
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700230 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPREQUEST));
Amit Ghosh8951f042017-08-10 13:48:10 +0100231
232 return pkt;
233 }
234
235 /**
236 * Constructs DHCP Offer Packet.
237 *
238 * @return Ethernet packet
239 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530240 Ethernet constructDhcpOfferPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100241 String ipAddress, String dhcpClientIpAddress) {
242
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530243 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100244 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
245
246 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
247 UDP udpPacket = (UDP) ipv4Packet.getPayload();
248 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
249
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700250 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPOFFER));
Amit Ghosh8951f042017-08-10 13:48:10 +0100251
252 return pkt;
253 }
254
255 /**
256 * Constructs DHCP Ack Packet.
257 *
258 * @return Ethernet packet
259 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530260 Ethernet constructDhcpAckPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100261 String ipAddress, String dhcpClientIpAddress) {
262
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530263 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100264 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
265
266 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
267 UDP udpPacket = (UDP) ipv4Packet.getPayload();
268 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
269
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700270 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPACK));
Amit Ghosh8951f042017-08-10 13:48:10 +0100271
272 return pkt;
273 }
274
275 /**
276 * Constructs DHCP Discover Options.
277 *
278 * @return Ethernet packet
279 */
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700280 private List<DhcpOption> constructDhcpOptions(DHCP.MsgType packetType) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100281
282 // DHCP Options.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700283 DhcpOption option = new DhcpOption();
284 List<DhcpOption> optionList = new ArrayList<>();
Amit Ghosh8951f042017-08-10 13:48:10 +0100285
286
287 // DHCP Message Type.
288 option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
289 option.setLength((byte) 1);
290 byte[] optionData = {(byte) packetType.getValue()};
291 option.setData(optionData);
292 optionList.add(option);
293
294 // DHCP Requested IP.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700295 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100296 option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
297 option.setLength((byte) 4);
298 optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
299 option.setData(optionData);
300 optionList.add(option);
301
302 // End Option.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700303 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100304 option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
305 option.setLength((byte) 1);
306 optionList.add(option);
307
308 return optionList;
309 }
310}