use of org.onlab.packet.DHCP in project onos by opennetworkinglab.
the class DhcpTest method testDeserializeOffer.
/**
* Tests deserialize discover packet.
*/
@Test
public void testDeserializeOffer() throws Exception {
byte[] data = Resources.toByteArray(Dhcp6RelayTest.class.getResource(OFFER));
Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
DHCP dhcp = (DHCP) eth.getPayload().getPayload().getPayload();
assertEquals(DHCP.OPCODE_REPLY, dhcp.getOpCode());
assertEquals(HW_TYPE, dhcp.getHardwareType());
assertEquals(HW_ADDR_LEN, dhcp.getHardwareAddressLength());
assertEquals(HOPS, dhcp.getHops());
assertEquals(XID, dhcp.getTransactionId());
assertEquals(SECS, dhcp.getSeconds());
assertEquals(FLAGS, dhcp.getFlags());
assertEquals(NO_IP, dhcp.getClientIPAddress());
assertEquals(CLIENT_IP.toInt(), dhcp.getYourIPAddress());
assertEquals(SERVER_IP.toInt(), dhcp.getServerIPAddress());
assertEquals(GW_IP.toInt(), dhcp.getGatewayIPAddress());
assertTrue(Arrays.equals(CLIENT_HW_ADDR.toBytes(), dhcp.getClientHardwareAddress()));
assertEquals(EMPTY, dhcp.getServerName());
assertEquals(EMPTY, dhcp.getBootFileName());
assertEquals(9, dhcp.getOptions().size());
DhcpOption option = dhcp.getOptions().get(0);
assertEquals(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue(), option.code);
assertEquals(1, option.length);
assertEquals(DHCP.MsgType.DHCPOFFER.getValue(), (int) option.getData()[0]);
option = dhcp.getOptions().get(1);
assertEquals(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue(), option.code);
assertEquals(4, option.length);
assertArrayEquals(SERVER_IP.toOctets(), option.getData());
option = dhcp.getOptions().get(2);
assertEquals(DHCP.DHCPOptionCode.OptionCode_LeaseTime.getValue(), option.code);
assertEquals(4, option.length);
assertArrayEquals(new byte[] { 0, 0, 2, 88 }, option.getData());
option = dhcp.getOptions().get(3);
assertEquals(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue(), option.code);
assertEquals(4, option.length);
assertArrayEquals(SUBNET_MASK.toOctets(), option.getData());
option = dhcp.getOptions().get(4);
assertEquals(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue(), option.code);
assertEquals(4, option.length);
assertArrayEquals(GW_IP.toOctets(), option.getData());
option = dhcp.getOptions().get(5);
assertEquals(DHCP.DHCPOptionCode.OptionCode_DomainName.getValue(), option.code);
assertEquals(13, option.length);
assertArrayEquals(DOMAIN_NAME.getBytes(Charsets.US_ASCII), option.getData());
option = dhcp.getOptions().get(6);
assertEquals(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue(), option.code);
assertEquals(8, option.length);
assertArrayEquals(ArrayUtils.addAll(DNS_1.toOctets(), DNS_2.toOctets()), option.getData());
option = dhcp.getOptions().get(7);
assertTrue(option instanceof DhcpRelayAgentOption);
DhcpRelayAgentOption relayAgentOption = (DhcpRelayAgentOption) option;
assertEquals(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue(), relayAgentOption.code);
assertEquals(12, relayAgentOption.length);
DhcpOption subOption = relayAgentOption.getSubOption(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
assertEquals(10, subOption.getLength());
assertArrayEquals(CIRCUIT_ID.getBytes(Charsets.US_ASCII), subOption.getData());
option = dhcp.getOptions().get(8);
assertEquals(DHCP.DHCPOptionCode.OptionCode_END.getValue(), option.code);
assertEquals(0, option.length);
}
use of org.onlab.packet.DHCP in project onos by opennetworkinglab.
the class OpenstackSwitchingDhcpHandlerTest method constructDhcpPacket.
/**
* Constructs an Ethernet packet containing a DHCP payload.
*
* @param msgType DHCP message type
* @return Ethernet packet
*/
private Ethernet constructDhcpPacket(DHCP.MsgType msgType) {
// Ethernet frame
Ethernet ethFrame = new Ethernet();
ethFrame.setSourceMACAddress(CLIENT_HOST.mac());
ethFrame.setDestinationMACAddress(MacAddress.BROADCAST);
ethFrame.setEtherType(Ethernet.TYPE_IPV4);
ethFrame.setVlanID((short) 2);
// IP packet
IPv4 ipv4Pkt = new IPv4();
ipv4Pkt.setSourceAddress(0);
ipv4Pkt.setDestinationAddress(BROADCAST.toInt());
ipv4Pkt.setTtl((byte) 127);
// UDP datagram
UDP udpDatagram = new UDP();
udpDatagram.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
udpDatagram.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
// DHCP payload
DHCP dhcp = new DHCP();
dhcp.setOpCode(DHCP.OPCODE_REQUEST);
dhcp.setYourIPAddress(0);
dhcp.setServerIPAddress(0);
dhcp.setTransactionId(TRANSACTION_ID);
dhcp.setClientHardwareAddress(CLIENT_HOST.mac().toBytes());
dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
dhcp.setHardwareAddressLength((byte) 6);
// DHCP options start...
DhcpOption option = new DhcpOption();
List<DhcpOption> optionList = new ArrayList<>();
// DHCP message type
option.setCode(OptionCode_MessageType.getValue());
option.setLength((byte) 1);
byte[] optionData = { (byte) msgType.getValue() };
option.setData(optionData);
optionList.add(option);
// DHCP requested IP address
option = new DhcpOption();
option.setCode(OptionCode_RequestedIP.getValue());
option.setLength((byte) 4);
optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
option.setData(optionData);
optionList.add(option);
// DHCP domain server
Subnet subnet = dhcpHandler.osNetworkService.subnet("subnet");
option = new DhcpOption();
option.setCode(OptionCode_DomainServer.getValue());
option.setLength((byte) 8);
ByteBuffer dnsByteBuf = ByteBuffer.allocate(8);
dnsByteBuf.put(DEFAULT_PRIMARY_DNS.toOctets());
dnsByteBuf.put(DEFAULT_SECONDARY_DNS.toOctets());
option.setData(dnsByteBuf.array());
optionList.add(option);
// MTU
option = new DhcpOption();
option.setCode(DHCP_OPTION_MTU);
option.setLength((byte) 2);
option.setData(ByteBuffer.allocate(2).putShort(MTU).array());
optionList.add(option);
// classless static route
option = new DhcpOption();
option.setCode(OptionCode_Classless_Static_Route.getValue());
option.setLength((byte) HOST_ROUTES_SIZE);
ByteBuffer hostRouteByteBuf = ByteBuffer.allocate(HOST_ROUTES_SIZE);
subnet.getHostRoutes().forEach(h -> {
IpPrefix ipPrefix = IpPrefix.valueOf(h.getDestination());
hostRouteByteBuf.put(bytesDestinationDescriptor(ipPrefix));
hostRouteByteBuf.put(Ip4Address.valueOf(h.getNexthop()).toOctets());
});
option.setData(hostRouteByteBuf.array());
optionList.add(option);
// default router address setup
option = new DhcpOption();
option.setCode(OptionCode_RouterAddress.getValue());
option.setLength((byte) 4);
option.setData(Ip4Address.valueOf(subnet.getGateway()).toOctets());
optionList.add(option);
// DHCP options end...
option = new DhcpOption();
option.setCode(OptionCode_END.getValue());
option.setLength((byte) 1);
optionList.add(option);
dhcp.setOptions(optionList);
udpDatagram.setPayload(dhcp);
ipv4Pkt.setPayload(udpDatagram);
ethFrame.setPayload(ipv4Pkt);
return ethFrame;
}
use of org.onlab.packet.DHCP in project onos by opennetworkinglab.
the class DhcpManagerTest method constructDhcpPacket.
/**
* Constructs an Ethernet packet containing a DHCP Payload.
* @param packetType DHCP Message Type
* @return Ethernet packet
*/
private Ethernet constructDhcpPacket(DHCP.MsgType packetType) {
// Ethernet Frame.
Ethernet ethReply = new Ethernet();
ethReply.setSourceMACAddress(CLIENT1_HOST.mac());
ethReply.setDestinationMACAddress(MacAddress.BROADCAST);
ethReply.setEtherType(Ethernet.TYPE_IPV4);
ethReply.setVlanID((short) 2);
// IP Packet
IPv4 ipv4Reply = new IPv4();
ipv4Reply.setSourceAddress(0);
ipv4Reply.setDestinationAddress(BROADCAST.toInt());
ipv4Reply.setTtl((byte) 127);
// UDP Datagram.
UDP udpReply = new UDP();
udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
// DHCP Payload.
DHCP dhcpReply = new DHCP();
dhcpReply.setOpCode(DHCP.OPCODE_REQUEST);
dhcpReply.setYourIPAddress(0);
dhcpReply.setServerIPAddress(0);
dhcpReply.setTransactionId(TRANSACTION_ID);
dhcpReply.setClientHardwareAddress(CLIENT1_HOST.mac().toBytes());
dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
dhcpReply.setHardwareAddressLength((byte) 6);
// DHCP Options.
DhcpOption option = new DhcpOption();
List<DhcpOption> optionList = new ArrayList<>();
// DHCP Message Type.
option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
option.setLength((byte) 1);
byte[] optionData = { (byte) packetType.getValue() };
option.setData(optionData);
optionList.add(option);
// DHCP Requested IP.
option = new DhcpOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
option.setLength((byte) 4);
optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
option.setData(optionData);
optionList.add(option);
// End Option.
option = new DhcpOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
option.setLength((byte) 1);
optionList.add(option);
dhcpReply.setOptions(optionList);
udpReply.setPayload(dhcpReply);
ipv4Reply.setPayload(udpReply);
ethReply.setPayload(ipv4Reply);
return ethReply;
}
use of org.onlab.packet.DHCP in project onos by opennetworkinglab.
the class DhcpManagerTest method validatePacket.
/**
* Validates the contents of the packet sent by the DHCP Manager.
* @param packet Ethernet packet received
*/
private void validatePacket(Ethernet packet) {
DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload();
assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_HOST.mac());
assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP));
assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID);
}
use of org.onlab.packet.DHCP in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method processDhcpPacketFromServer.
/**
* Build the DHCP offer/ack with proper client port.
*
* @param ethernetPacket the original packet comes from server
* @return new packet which will send to the client
*/
private InternalPacket processDhcpPacketFromServer(PacketContext context, Ethernet ethernetPacket) {
// get dhcp header.
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
UDP udpPacket = (UDP) ipv4Packet.getPayload();
DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
// determine the vlanId of the client host - note that this vlan id
// could be different from the vlan in the packet from the server
Interface clientInterface = getClientInterface(ethernetPacket, dhcpPayload).orElse(null);
if (clientInterface == null) {
log.warn("Cannot find the interface for the DHCP {}", dhcpPayload);
return null;
}
VlanId vlanId;
ConnectPoint inPort = context.inPacket().receivedFrom();
boolean directConnFlag = directlyConnected(dhcpPayload);
DhcpServerInfo foundServerInfo = findServerInfoFromServer(directConnFlag, inPort);
if (foundServerInfo == null) {
log.warn("Cannot find server info for {} server, inPort {}", directConnFlag ? "direct" : "indirect", inPort);
return null;
} else {
if (Dhcp4HandlerUtil.isServerIpEmpty(foundServerInfo)) {
log.warn("Cannot find server info's ipaddress");
return null;
}
}
if (clientInterface.vlanTagged().isEmpty()) {
vlanId = clientInterface.vlan();
} else {
// might be multiple vlan in same interface
vlanId = getVlanIdFromRelayAgentOption(dhcpPayload);
}
if (vlanId == null) {
vlanId = VlanId.NONE;
}
etherReply.setVlanID(vlanId.toShort());
etherReply.setSourceMACAddress(clientInterface.mac());
if (!directlyConnected(dhcpPayload)) {
// if client is indirectly connected, try use next hop mac address
MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
HostId hostId = HostId.hostId(macAddress, vlanId);
if (((int) dhcpPayload.getFlags() & 0x8000) == 0x0000) {
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
if (record != null) {
// if next hop can be found, use mac address of next hop
record.nextHop().ifPresent(etherReply::setDestinationMACAddress);
} else {
// otherwise, discard the packet
log.warn("Can't find record for host id {}, discard packet", hostId);
return null;
}
} else {
etherReply.setDestinationMACAddress(MacAddress.BROADCAST);
}
} else {
etherReply.setDestinationMACAddress(dhcpPayload.getClientHardwareAddress());
}
Ip4Address ipFacingClient = getFirstIpFromInterface(clientInterface);
if (directlyConnected(dhcpPayload)) {
// figure out the relay agent IP corresponding to the original request
if (ipFacingClient == null) {
log.warn("Cannot determine relay agent interface Ipv4 addr for host {}/{}. " + "Aborting relay for dhcp packet from server {}", etherReply.getDestinationMAC(), clientInterface.vlan(), ethernetPacket);
return null;
}
// SRC_IP: IP facing client
ipv4Packet.setSourceAddress(ipFacingClient.toInt());
} else {
// Get the IP address of the relay agent
Ip4Address relayAgentIp = foundServerInfo.getRelayAgentIp4(clientInterface.connectPoint().deviceId()).orElse(null);
if (relayAgentIp == null) {
if (ipFacingClient == null) {
log.warn("Cannot determine relay agent interface Ipv4 addr for host {}/{}. " + "Aborting relay for dhcp packet from server for indirect host {}", etherReply.getDestinationMAC(), clientInterface.vlan(), ethernetPacket);
return null;
} else {
// SRC_IP: IP facing client
ipv4Packet.setSourceAddress(ipFacingClient.toInt());
}
} else {
// SRC_IP: relay agent IP
ipv4Packet.setSourceAddress(relayAgentIp.toInt());
}
}
// DST_IP: offered IP
if (((int) dhcpPayload.getFlags() & 0x8000) == 0x0000) {
ipv4Packet.setDestinationAddress(dhcpPayload.getYourIPAddress());
} else {
ipv4Packet.setDestinationAddress(BROADCAST_IP);
}
udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
if (directlyConnected(dhcpPayload)) {
udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
} else {
// TODO Implement component config to support for both L2 and L3 relay
// L2 relay expects destination port to be CLIENT_PORT while L3 relay expects SERVER_PORT
// Currently we only support L2 relay for DHCPv4
udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
}
udpPacket.setPayload(dhcpPayload);
ipv4Packet.setPayload(udpPacket);
etherReply.setPayload(ipv4Packet);
return InternalPacket.internalPacket(etherReply, clientInterface.connectPoint());
}
Aggregations