blob: fb519cfd20eff41169c05a4bdce3d6543fa5825e [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
17package org.opencord.dhcpl2relay;
18
Saurav Dasb4e3e102018-10-02 15:31:17 -070019import static org.junit.Assert.fail;
20
21import java.nio.ByteBuffer;
22import java.nio.charset.StandardCharsets;
23import java.util.ArrayList;
24import java.util.LinkedList;
25import java.util.List;
26
Amit Ghosh8951f042017-08-10 13:48:10 +010027import org.onlab.packet.BasePacket;
28import org.onlab.packet.DHCP;
Amit Ghosh8951f042017-08-10 13:48:10 +010029import org.onlab.packet.DHCPPacketType;
30import org.onlab.packet.Ethernet;
31import org.onlab.packet.IPv4;
32import org.onlab.packet.Ip4Address;
33import org.onlab.packet.MacAddress;
34import org.onlab.packet.UDP;
Jonathan Hartedbf6422018-05-02 17:30:05 -070035import org.onlab.packet.dhcp.DhcpOption;
Saurav Dasb4e3e102018-10-02 15:31:17 -070036import org.onosproject.core.ApplicationId;
37import org.onosproject.core.CoreServiceAdapter;
38import org.onosproject.core.DefaultApplicationId;
Amit Ghosh8951f042017-08-10 13:48:10 +010039import org.onosproject.net.ConnectPoint;
40import org.onosproject.net.packet.DefaultInboundPacket;
41import org.onosproject.net.packet.DefaultPacketContext;
42import org.onosproject.net.packet.InboundPacket;
43import org.onosproject.net.packet.OutboundPacket;
44import org.onosproject.net.packet.PacketContext;
45import org.onosproject.net.packet.PacketProcessor;
46import org.onosproject.net.packet.PacketServiceAdapter;
Amit Ghosh8951f042017-08-10 13:48:10 +010047import org.slf4j.Logger;
48import org.slf4j.LoggerFactory;
49
Amit Ghosh8951f042017-08-10 13:48:10 +010050
51/**
52 * Common methods for AAA app testing.
53 */
54public class DhcpL2RelayTestBase {
55 private final Logger log = LoggerFactory.getLogger(getClass());
56
57 private static final int TRANSACTION_ID = 1000;
58
59 private static final String EXPECTED_IP = "10.2.0.2";
60
61 List<BasePacket> savedPackets = new LinkedList<>();
62 PacketProcessor packetProcessor;
63
64
65 /**
66 * Saves the given packet onto the saved packets list.
67 *
68 * @param packet packet to save
69 */
70 void savePacket(BasePacket packet) {
71 savedPackets.add(packet);
72 }
73
74 BasePacket getPacket() {
75 return savedPackets.remove(0);
76 }
77
78 /**
Saurav Dasb4e3e102018-10-02 15:31:17 -070079 * Mock core service adaptor that provides an appId.
80 */
81 class MockCoreServiceAdapter extends CoreServiceAdapter {
82
83 @Override
84 public ApplicationId registerApplication(String name) {
85 return new DefaultApplicationId(10, name);
86 }
87 }
88
89 /**
Amit Ghosh8951f042017-08-10 13:48:10 +010090 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
91 */
92 class MockPacketService extends PacketServiceAdapter {
93
94 @Override
95 public void addProcessor(PacketProcessor processor, int priority) {
96 packetProcessor = processor;
97 }
98
99 @Override
100 public void emit(OutboundPacket packet) {
101 try {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530102 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
Amit Ghosh8951f042017-08-10 13:48:10 +0100103 0, packet.data().array().length);
104 savePacket(eth);
105 } catch (Exception e) {
106 fail(e.getMessage());
107 }
108 }
109 }
110
111 /**
112 * Mocks the DefaultPacketContext.
113 */
114 final class TestPacketContext extends DefaultPacketContext {
115
116 private TestPacketContext(long time, InboundPacket inPkt,
117 OutboundPacket outPkt, boolean block) {
118 super(time, inPkt, outPkt, block);
119 }
120
121 @Override
122 public void send() {
123 // We don't send anything out.
124 }
125 }
126
127 /**
128 * Sends an Ethernet packet to the process method of the Packet Processor.
129 *
130 * @param pkt Ethernet packet
131 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530132 void sendPacket(Ethernet pkt, ConnectPoint cp) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100133 final ByteBuffer byteBuffer = ByteBuffer.wrap(pkt.serialize());
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530134 InboundPacket inPacket = new DefaultInboundPacket(cp, pkt, byteBuffer);
Amit Ghosh8951f042017-08-10 13:48:10 +0100135
136 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
137 packetProcessor.process(context);
138 }
139
140 /**
141 * Constructs an Ethernet packet with IP/UDP/DHCP payload.
142 *
143 * @return Ethernet packet
144 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530145 private Ethernet construcEthernetPacket(MacAddress srcMac, MacAddress dstMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100146 String dstIp, byte dhcpReqRsp,
147 MacAddress clientHwAddress,
148 Ip4Address dhcpClientIpAddress) {
149 // Ethernet Frame.
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530150 Ethernet ethPkt = new Ethernet();
151 ethPkt.setSourceMACAddress(srcMac);
152 ethPkt.setDestinationMACAddress(dstMac);
Amit Ghosh8951f042017-08-10 13:48:10 +0100153 ethPkt.setEtherType(Ethernet.TYPE_IPV4);
154 ethPkt.setVlanID((short) 2);
155 ethPkt.setPriorityCode((byte) 6);
156
157 // IP Packet
158 IPv4 ipv4Reply = new IPv4();
159 ipv4Reply.setSourceAddress(0);
160 ipv4Reply.setDestinationAddress(dstIp);
161
162 ipv4Reply.setTtl((byte) 127);
163
164 // UDP Datagram.
165 UDP udpReply = new UDP();
166 udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
167 udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
168
169 // DHCP Payload.
170 DHCP dhcpReply = new DHCP();
171 dhcpReply.setOpCode(dhcpReqRsp);
172
173 dhcpReply.setYourIPAddress(dhcpClientIpAddress.toInt());
174 dhcpReply.setServerIPAddress(0);
175
176 final byte[] serverNameBytes = new byte[64];
177 String result = new String(serverNameBytes, StandardCharsets.US_ASCII).trim();
178 dhcpReply.setServerName(result);
179
180 final byte[] bootFileBytes = new byte[128];
181 String result1 = new String(bootFileBytes, StandardCharsets.US_ASCII).trim();
182 dhcpReply.setBootFileName(result1);
183
184 dhcpReply.setTransactionId(TRANSACTION_ID);
185 dhcpReply.setClientHardwareAddress(clientHwAddress.toBytes());
186 dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
187 dhcpReply.setHardwareAddressLength((byte) 6);
188
189 udpReply.setPayload(dhcpReply);
190 ipv4Reply.setPayload(udpReply);
191 ethPkt.setPayload(ipv4Reply);
192
193 return ethPkt;
194 }
195
196 /**
197 * Constructs DHCP Discover Packet.
198 *
199 * @return Ethernet packet
200 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530201 Ethernet constructDhcpDiscoverPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100202
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530203 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100204 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
205 Ip4Address.valueOf("0.0.0.0"));
206
207 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
208 UDP udpPacket = (UDP) ipv4Packet.getPayload();
209 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
210
211 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPDISCOVER));
212
213 return pkt;
214 }
215
216 /**
217 * Constructs DHCP Request Packet.
218 *
219 * @return Ethernet packet
220 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530221 Ethernet constructDhcpRequestPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100222
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530223 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100224 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
225 Ip4Address.valueOf("0.0.0.0"));
226
227 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
228 UDP udpPacket = (UDP) ipv4Packet.getPayload();
229 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
230
231 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPREQUEST));
232
233 return pkt;
234 }
235
236 /**
237 * Constructs DHCP Offer Packet.
238 *
239 * @return Ethernet packet
240 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530241 Ethernet constructDhcpOfferPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100242 String ipAddress, String dhcpClientIpAddress) {
243
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530244 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100245 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
246
247 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
248 UDP udpPacket = (UDP) ipv4Packet.getPayload();
249 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
250
251 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPOFFER));
252
253 return pkt;
254 }
255
256 /**
257 * Constructs DHCP Ack Packet.
258 *
259 * @return Ethernet packet
260 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530261 Ethernet constructDhcpAckPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100262 String ipAddress, String dhcpClientIpAddress) {
263
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530264 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100265 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
266
267 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
268 UDP udpPacket = (UDP) ipv4Packet.getPayload();
269 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
270
271 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPACK));
272
273 return pkt;
274 }
275
276 /**
277 * Constructs DHCP Discover Options.
278 *
279 * @return Ethernet packet
280 */
Jonathan Hartedbf6422018-05-02 17:30:05 -0700281 private List<DhcpOption> constructDhcpOptions(DHCPPacketType packetType) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100282
283 // DHCP Options.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700284 DhcpOption option = new DhcpOption();
285 List<DhcpOption> optionList = new ArrayList<>();
Amit Ghosh8951f042017-08-10 13:48:10 +0100286
287
288 // DHCP Message Type.
289 option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
290 option.setLength((byte) 1);
291 byte[] optionData = {(byte) packetType.getValue()};
292 option.setData(optionData);
293 optionList.add(option);
294
295 // DHCP Requested IP.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700296 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100297 option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
298 option.setLength((byte) 4);
299 optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
300 option.setData(optionData);
301 optionList.add(option);
302
303 // End Option.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700304 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100305 option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
306 option.setLength((byte) 1);
307 optionList.add(option);
308
309 return optionList;
310 }
311}