blob: 540a691a85d1d462e6e8ea814e62019ba844822b [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
19import org.onlab.packet.BasePacket;
20import org.onlab.packet.DHCP;
21import org.onlab.packet.DHCPOption;
22import org.onlab.packet.DHCPPacketType;
23import org.onlab.packet.Ethernet;
24import org.onlab.packet.IPv4;
25import org.onlab.packet.Ip4Address;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.UDP;
28import org.onosproject.net.ConnectPoint;
29import org.onosproject.net.packet.DefaultInboundPacket;
30import org.onosproject.net.packet.DefaultPacketContext;
31import org.onosproject.net.packet.InboundPacket;
32import org.onosproject.net.packet.OutboundPacket;
33import org.onosproject.net.packet.PacketContext;
34import org.onosproject.net.packet.PacketProcessor;
35import org.onosproject.net.packet.PacketServiceAdapter;
36
Amit Ghosh8951f042017-08-10 13:48:10 +010037
38import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
41import java.nio.ByteBuffer;
42import java.nio.charset.StandardCharsets;
43
44import java.util.ArrayList;
45import java.util.LinkedList;
46import java.util.List;
47
48import static org.junit.Assert.fail;
49
50
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 /**
79 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
80 */
81 class MockPacketService extends PacketServiceAdapter {
82
83 @Override
84 public void addProcessor(PacketProcessor processor, int priority) {
85 packetProcessor = processor;
86 }
87
88 @Override
89 public void emit(OutboundPacket packet) {
90 try {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053091 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
Amit Ghosh8951f042017-08-10 13:48:10 +010092 0, packet.data().array().length);
93 savePacket(eth);
94 } catch (Exception e) {
95 fail(e.getMessage());
96 }
97 }
98 }
99
100 /**
101 * Mocks the DefaultPacketContext.
102 */
103 final class TestPacketContext extends DefaultPacketContext {
104
105 private TestPacketContext(long time, InboundPacket inPkt,
106 OutboundPacket outPkt, boolean block) {
107 super(time, inPkt, outPkt, block);
108 }
109
110 @Override
111 public void send() {
112 // We don't send anything out.
113 }
114 }
115
116 /**
117 * Sends an Ethernet packet to the process method of the Packet Processor.
118 *
119 * @param pkt Ethernet packet
120 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530121 void sendPacket(Ethernet pkt, ConnectPoint cp) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100122 final ByteBuffer byteBuffer = ByteBuffer.wrap(pkt.serialize());
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530123 InboundPacket inPacket = new DefaultInboundPacket(cp, pkt, byteBuffer);
Amit Ghosh8951f042017-08-10 13:48:10 +0100124
125 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
126 packetProcessor.process(context);
127 }
128
129 /**
130 * Constructs an Ethernet packet with IP/UDP/DHCP payload.
131 *
132 * @return Ethernet packet
133 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530134 private Ethernet construcEthernetPacket(MacAddress srcMac, MacAddress dstMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100135 String dstIp, byte dhcpReqRsp,
136 MacAddress clientHwAddress,
137 Ip4Address dhcpClientIpAddress) {
138 // Ethernet Frame.
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530139 Ethernet ethPkt = new Ethernet();
140 ethPkt.setSourceMACAddress(srcMac);
141 ethPkt.setDestinationMACAddress(dstMac);
Amit Ghosh8951f042017-08-10 13:48:10 +0100142 ethPkt.setEtherType(Ethernet.TYPE_IPV4);
143 ethPkt.setVlanID((short) 2);
144 ethPkt.setPriorityCode((byte) 6);
145
146 // IP Packet
147 IPv4 ipv4Reply = new IPv4();
148 ipv4Reply.setSourceAddress(0);
149 ipv4Reply.setDestinationAddress(dstIp);
150
151 ipv4Reply.setTtl((byte) 127);
152
153 // UDP Datagram.
154 UDP udpReply = new UDP();
155 udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
156 udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
157
158 // DHCP Payload.
159 DHCP dhcpReply = new DHCP();
160 dhcpReply.setOpCode(dhcpReqRsp);
161
162 dhcpReply.setYourIPAddress(dhcpClientIpAddress.toInt());
163 dhcpReply.setServerIPAddress(0);
164
165 final byte[] serverNameBytes = new byte[64];
166 String result = new String(serverNameBytes, StandardCharsets.US_ASCII).trim();
167 dhcpReply.setServerName(result);
168
169 final byte[] bootFileBytes = new byte[128];
170 String result1 = new String(bootFileBytes, StandardCharsets.US_ASCII).trim();
171 dhcpReply.setBootFileName(result1);
172
173 dhcpReply.setTransactionId(TRANSACTION_ID);
174 dhcpReply.setClientHardwareAddress(clientHwAddress.toBytes());
175 dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
176 dhcpReply.setHardwareAddressLength((byte) 6);
177
178 udpReply.setPayload(dhcpReply);
179 ipv4Reply.setPayload(udpReply);
180 ethPkt.setPayload(ipv4Reply);
181
182 return ethPkt;
183 }
184
185 /**
186 * Constructs DHCP Discover Packet.
187 *
188 * @return Ethernet packet
189 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530190 Ethernet constructDhcpDiscoverPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100191
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530192 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100193 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
194 Ip4Address.valueOf("0.0.0.0"));
195
196 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
197 UDP udpPacket = (UDP) ipv4Packet.getPayload();
198 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
199
200 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPDISCOVER));
201
202 return pkt;
203 }
204
205 /**
206 * Constructs DHCP Request Packet.
207 *
208 * @return Ethernet packet
209 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530210 Ethernet constructDhcpRequestPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100211
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530212 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100213 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
214 Ip4Address.valueOf("0.0.0.0"));
215
216 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
217 UDP udpPacket = (UDP) ipv4Packet.getPayload();
218 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
219
220 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPREQUEST));
221
222 return pkt;
223 }
224
225 /**
226 * Constructs DHCP Offer Packet.
227 *
228 * @return Ethernet packet
229 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530230 Ethernet constructDhcpOfferPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100231 String ipAddress, String dhcpClientIpAddress) {
232
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530233 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100234 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
235
236 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
237 UDP udpPacket = (UDP) ipv4Packet.getPayload();
238 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
239
240 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPOFFER));
241
242 return pkt;
243 }
244
245 /**
246 * Constructs DHCP Ack Packet.
247 *
248 * @return Ethernet packet
249 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530250 Ethernet constructDhcpAckPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100251 String ipAddress, String dhcpClientIpAddress) {
252
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530253 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100254 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
255
256 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
257 UDP udpPacket = (UDP) ipv4Packet.getPayload();
258 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
259
260 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPACK));
261
262 return pkt;
263 }
264
265 /**
266 * Constructs DHCP Discover Options.
267 *
268 * @return Ethernet packet
269 */
270 private List<DHCPOption> constructDhcpOptions(DHCPPacketType packetType) {
271
272 // DHCP Options.
273 DHCPOption option = new DHCPOption();
274 List<DHCPOption> optionList = new ArrayList<>();
275
276
277 // DHCP Message Type.
278 option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
279 option.setLength((byte) 1);
280 byte[] optionData = {(byte) packetType.getValue()};
281 option.setData(optionData);
282 optionList.add(option);
283
284 // DHCP Requested IP.
285 option = new DHCPOption();
286 option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
287 option.setLength((byte) 4);
288 optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
289 option.setData(optionData);
290 optionList.add(option);
291
292 // End Option.
293 option = new DHCPOption();
294 option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
295 option.setLength((byte) 1);
296 optionList.add(option);
297
298 return optionList;
299 }
300}