blob: 7a1dd1a744d9a610bdb8917244c5dcaada2a6ff6 [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;
Amit Ghosh8951f042017-08-10 13:48:10 +010021import org.onlab.packet.DHCPPacketType;
22import org.onlab.packet.Ethernet;
23import org.onlab.packet.IPv4;
24import org.onlab.packet.Ip4Address;
25import org.onlab.packet.MacAddress;
26import org.onlab.packet.UDP;
Jonathan Hartedbf6422018-05-02 17:30:05 -070027import org.onlab.packet.dhcp.DhcpOption;
Amit Ghosh8951f042017-08-10 13:48:10 +010028import 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;
Amit Ghosh8951f042017-08-10 13:48:10 +010036import org.slf4j.Logger;
37import org.slf4j.LoggerFactory;
38
39import java.nio.ByteBuffer;
40import java.nio.charset.StandardCharsets;
Amit Ghosh8951f042017-08-10 13:48:10 +010041import java.util.ArrayList;
42import java.util.LinkedList;
43import java.util.List;
44
45import static org.junit.Assert.fail;
46
47
48/**
49 * Common methods for AAA app testing.
50 */
51public class DhcpL2RelayTestBase {
52 private final Logger log = LoggerFactory.getLogger(getClass());
53
54 private static final int TRANSACTION_ID = 1000;
55
56 private static final String EXPECTED_IP = "10.2.0.2";
57
58 List<BasePacket> savedPackets = new LinkedList<>();
59 PacketProcessor packetProcessor;
60
61
62 /**
63 * Saves the given packet onto the saved packets list.
64 *
65 * @param packet packet to save
66 */
67 void savePacket(BasePacket packet) {
68 savedPackets.add(packet);
69 }
70
71 BasePacket getPacket() {
72 return savedPackets.remove(0);
73 }
74
75 /**
76 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
77 */
78 class MockPacketService extends PacketServiceAdapter {
79
80 @Override
81 public void addProcessor(PacketProcessor processor, int priority) {
82 packetProcessor = processor;
83 }
84
85 @Override
86 public void emit(OutboundPacket packet) {
87 try {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053088 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
Amit Ghosh8951f042017-08-10 13:48:10 +010089 0, packet.data().array().length);
90 savePacket(eth);
91 } catch (Exception e) {
92 fail(e.getMessage());
93 }
94 }
95 }
96
97 /**
98 * Mocks the DefaultPacketContext.
99 */
100 final class TestPacketContext extends DefaultPacketContext {
101
102 private TestPacketContext(long time, InboundPacket inPkt,
103 OutboundPacket outPkt, boolean block) {
104 super(time, inPkt, outPkt, block);
105 }
106
107 @Override
108 public void send() {
109 // We don't send anything out.
110 }
111 }
112
113 /**
114 * Sends an Ethernet packet to the process method of the Packet Processor.
115 *
116 * @param pkt Ethernet packet
117 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530118 void sendPacket(Ethernet pkt, ConnectPoint cp) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100119 final ByteBuffer byteBuffer = ByteBuffer.wrap(pkt.serialize());
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530120 InboundPacket inPacket = new DefaultInboundPacket(cp, pkt, byteBuffer);
Amit Ghosh8951f042017-08-10 13:48:10 +0100121
122 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
123 packetProcessor.process(context);
124 }
125
126 /**
127 * Constructs an Ethernet packet with IP/UDP/DHCP payload.
128 *
129 * @return Ethernet packet
130 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530131 private Ethernet construcEthernetPacket(MacAddress srcMac, MacAddress dstMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100132 String dstIp, byte dhcpReqRsp,
133 MacAddress clientHwAddress,
134 Ip4Address dhcpClientIpAddress) {
135 // Ethernet Frame.
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530136 Ethernet ethPkt = new Ethernet();
137 ethPkt.setSourceMACAddress(srcMac);
138 ethPkt.setDestinationMACAddress(dstMac);
Amit Ghosh8951f042017-08-10 13:48:10 +0100139 ethPkt.setEtherType(Ethernet.TYPE_IPV4);
140 ethPkt.setVlanID((short) 2);
141 ethPkt.setPriorityCode((byte) 6);
142
143 // IP Packet
144 IPv4 ipv4Reply = new IPv4();
145 ipv4Reply.setSourceAddress(0);
146 ipv4Reply.setDestinationAddress(dstIp);
147
148 ipv4Reply.setTtl((byte) 127);
149
150 // UDP Datagram.
151 UDP udpReply = new UDP();
152 udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
153 udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
154
155 // DHCP Payload.
156 DHCP dhcpReply = new DHCP();
157 dhcpReply.setOpCode(dhcpReqRsp);
158
159 dhcpReply.setYourIPAddress(dhcpClientIpAddress.toInt());
160 dhcpReply.setServerIPAddress(0);
161
162 final byte[] serverNameBytes = new byte[64];
163 String result = new String(serverNameBytes, StandardCharsets.US_ASCII).trim();
164 dhcpReply.setServerName(result);
165
166 final byte[] bootFileBytes = new byte[128];
167 String result1 = new String(bootFileBytes, StandardCharsets.US_ASCII).trim();
168 dhcpReply.setBootFileName(result1);
169
170 dhcpReply.setTransactionId(TRANSACTION_ID);
171 dhcpReply.setClientHardwareAddress(clientHwAddress.toBytes());
172 dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
173 dhcpReply.setHardwareAddressLength((byte) 6);
174
175 udpReply.setPayload(dhcpReply);
176 ipv4Reply.setPayload(udpReply);
177 ethPkt.setPayload(ipv4Reply);
178
179 return ethPkt;
180 }
181
182 /**
183 * Constructs DHCP Discover Packet.
184 *
185 * @return Ethernet packet
186 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530187 Ethernet constructDhcpDiscoverPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100188
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530189 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100190 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
191 Ip4Address.valueOf("0.0.0.0"));
192
193 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
194 UDP udpPacket = (UDP) ipv4Packet.getPayload();
195 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
196
197 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPDISCOVER));
198
199 return pkt;
200 }
201
202 /**
203 * Constructs DHCP Request Packet.
204 *
205 * @return Ethernet packet
206 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530207 Ethernet constructDhcpRequestPacket(MacAddress clientMac) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100208
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530209 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Amit Ghosh8951f042017-08-10 13:48:10 +0100210 "255.255.255.255", DHCP.OPCODE_REQUEST, MacAddress.NONE,
211 Ip4Address.valueOf("0.0.0.0"));
212
213 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
214 UDP udpPacket = (UDP) ipv4Packet.getPayload();
215 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
216
217 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPREQUEST));
218
219 return pkt;
220 }
221
222 /**
223 * Constructs DHCP Offer Packet.
224 *
225 * @return Ethernet packet
226 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530227 Ethernet constructDhcpOfferPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100228 String ipAddress, String dhcpClientIpAddress) {
229
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530230 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100231 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
232
233 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
234 UDP udpPacket = (UDP) ipv4Packet.getPayload();
235 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
236
237 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPOFFER));
238
239 return pkt;
240 }
241
242 /**
243 * Constructs DHCP Ack Packet.
244 *
245 * @return Ethernet packet
246 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530247 Ethernet constructDhcpAckPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100248 String ipAddress, String dhcpClientIpAddress) {
249
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530250 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100251 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
252
253 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
254 UDP udpPacket = (UDP) ipv4Packet.getPayload();
255 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
256
257 dhcpPacket.setOptions(constructDhcpOptions(DHCPPacketType.DHCPACK));
258
259 return pkt;
260 }
261
262 /**
263 * Constructs DHCP Discover Options.
264 *
265 * @return Ethernet packet
266 */
Jonathan Hartedbf6422018-05-02 17:30:05 -0700267 private List<DhcpOption> constructDhcpOptions(DHCPPacketType packetType) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100268
269 // DHCP Options.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700270 DhcpOption option = new DhcpOption();
271 List<DhcpOption> optionList = new ArrayList<>();
Amit Ghosh8951f042017-08-10 13:48:10 +0100272
273
274 // DHCP Message Type.
275 option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
276 option.setLength((byte) 1);
277 byte[] optionData = {(byte) packetType.getValue()};
278 option.setData(optionData);
279 optionList.add(option);
280
281 // DHCP Requested IP.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700282 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100283 option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
284 option.setLength((byte) 4);
285 optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
286 option.setData(optionData);
287 optionList.add(option);
288
289 // End Option.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700290 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100291 option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
292 option.setLength((byte) 1);
293 optionList.add(option);
294
295 return optionList;
296 }
297}