/*
* Copyright 2009-2014 Jagornet Technologies, LLC. All Rights Reserved.
*
* This software is the proprietary information of Jagornet Technologies, LLC.
* Use is subject to license terms.
*
*/
/*
* This file TestDhcpRelayMessage.java is part of Jagornet DHCP.
*
* Jagornet DHCP is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Jagornet DHCP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jagornet DHCP. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.jagornet.dhcp.message;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import junit.framework.TestCase;
import com.jagornet.dhcp.message.DhcpV6Message;
import com.jagornet.dhcp.message.DhcpV6RelayMessage;
import com.jagornet.dhcp.option.v6.DhcpV6InterfaceIdOption;
import com.jagornet.dhcp.option.v6.DhcpV6RelayOption;
import com.jagornet.dhcp.util.DhcpConstants;
import com.jagornet.dhcp.xml.OpaqueData;
import com.jagornet.dhcp.xml.V6InterfaceIdOption;
public class TestDhcpRelayMessage extends TestCase
{
public static InetSocketAddress LOCALHOST_ADDR =
new InetSocketAddress("::1", DhcpConstants.V6_SERVER_PORT);
// the relay closest to the client
public static InetSocketAddress RELAY1_CLIENTSIDE_ADDR =
new InetSocketAddress("2001:DB8:1::1", DhcpConstants.V6_SERVER_PORT);
public static InetSocketAddress RELAY1_ADDR =
new InetSocketAddress("2001:DB8:2::1", DhcpConstants.V6_SERVER_PORT);
// when used, the relay closest to the server
public static InetSocketAddress RELAY2_RELAY1SIDE_ADDR =
new InetSocketAddress("2001:DB8:2::2", DhcpConstants.V6_SERVER_PORT);
public static InetSocketAddress RELAY2_ADDR =
new InetSocketAddress("2001:DB8:3::1", DhcpConstants.V6_SERVER_PORT);
public static DhcpV6RelayMessage buildMockDhcpRelayMessage() throws Exception
{
DhcpV6RelayMessage relayMessage = new DhcpV6RelayMessage(LOCALHOST_ADDR, RELAY1_ADDR);
relayMessage.setMessageType(DhcpConstants.V6MESSAGE_TYPE_RELAY_REPL);
relayMessage.setHopCount((byte)0);
relayMessage.setLinkAddress(RELAY1_CLIENTSIDE_ADDR.getAddress());
relayMessage.setPeerAddress(TestDhcpMessage.CLIENT_ADDR.getAddress());
// build a client info-request message
DhcpV6Message dhcpMessage = TestDhcpMessage.buildMockDhcpMessage();
// create relay message option - logically the encapsulated message
// comes from the client, i.e. peer address, so use that as the source
DhcpV6RelayOption relayOption = new DhcpV6RelayOption();
// the client's request is contained within the relay option
relayOption.setDhcpMessage(dhcpMessage);
// add the relay message option to the relay message
relayMessage.putDhcpOption(relayOption);
relayMessage.setRelayOption(relayOption);
return relayMessage;
}
public static DhcpV6InterfaceIdOption buildMockInterfaceIdOption()
{
V6InterfaceIdOption ifIdOption = V6InterfaceIdOption.Factory.newInstance();
OpaqueData opaque = OpaqueData.Factory.newInstance();
opaque.setHexValue(new byte[] { 0x01, 0x02, 0x03, 0x04 } );
ifIdOption.setOpaqueData(opaque);
return new DhcpV6InterfaceIdOption(ifIdOption);
}
public static void checkEncodedMockDhcpRelayMessage(ByteBuffer bb) throws Exception
{
// message type
assertEquals(DhcpConstants.V6MESSAGE_TYPE_RELAY_REPL, bb.get());
// hop count
assertEquals(0, bb.get());
byte[] b = new byte[16];
bb.get(b);
// link addr
assertEquals(RELAY1_CLIENTSIDE_ADDR.getAddress(),
InetAddress.getByAddress(b));
bb.get(b);
// peer addr
assertEquals(TestDhcpMessage.CLIENT_ADDR.getAddress(),
InetAddress.getByAddress(b));
// relayed message
assertEquals(DhcpConstants.V6OPTION_RELAY_MSG, bb.getShort());
assertEquals(75, bb.getShort());
TestDhcpMessage.checkEncodedMockDhcpMessage(bb);
}
public void testEncode() throws Exception
{
DhcpV6RelayMessage relayMessage = buildMockDhcpRelayMessage();
ByteBuffer bb = relayMessage.encode();
assertNotNull(bb);
// length = 34(relay message header) + 2 (relay option code)
// 2 (relay option length) + 75 (relay message option)
assertEquals(34+4+75, bb.limit());
checkEncodedMockDhcpRelayMessage(bb);
assertEquals(false, bb.hasRemaining());
}
public void testEncode2() throws Exception
{
DhcpV6RelayMessage relayMessage = buildMockDhcpRelayMessage();
// simulate another relay - logically, we receive it from the RELAY2_ADDR
DhcpV6RelayMessage relayMessage2 = new DhcpV6RelayMessage(LOCALHOST_ADDR, RELAY2_ADDR);
relayMessage2.setMessageType(DhcpConstants.V6MESSAGE_TYPE_RELAY_REPL);
relayMessage2.setHopCount((byte)1);
// the link address could be zero(0), but logically, it is the address
// of the interface connected to the link where relay 1 is located
relayMessage2.setLinkAddress(RELAY2_RELAY1SIDE_ADDR.getAddress());
// this relay agent's peer is relay 1
relayMessage2.setPeerAddress(RELAY1_ADDR.getAddress());
// put the first relay message in this relay message's relay message option
// logically, the encapsulated relay message comes from relay 1, so
// use that as the source address of the message in the relay option
DhcpV6RelayOption relayOption2 = new DhcpV6RelayOption();
relayOption2.setDhcpMessage(relayMessage);
relayMessage2.putDhcpOption(relayOption2);
ByteBuffer bb = relayMessage2.encode();
assertNotNull(bb);
// length = 2 x (34(relay message header) + 2 (relay option code)
// 2 (relay option length)) + 75 (relay message option)
assertEquals((2*(34+4))+75, bb.limit());
// message type
assertEquals(DhcpConstants.V6MESSAGE_TYPE_RELAY_REPL, bb.get());
// hop count
assertEquals(1, bb.get());
byte[] b = new byte[16];
bb.get(b);
// link addr
assertEquals(RELAY2_RELAY1SIDE_ADDR.getAddress(),
InetAddress.getByAddress(b));
bb.get(b);
// peer addr
assertEquals(RELAY1_ADDR.getAddress(),
InetAddress.getByAddress(b));
// relayed message
assertEquals(DhcpConstants.V6OPTION_RELAY_MSG, bb.getShort());
assertEquals(34+4+75, bb.getShort());
checkEncodedMockDhcpRelayMessage(bb);
}
public static ByteBuffer buildMockRelayFoward() throws Exception
{
ByteBuffer bb = ByteBuffer.allocate(1024);
bb.put((byte)DhcpConstants.V6MESSAGE_TYPE_RELAY_FORW);
bb.put((byte)0); // hop count
bb.put(RELAY1_CLIENTSIDE_ADDR.getAddress().getAddress()); // link addr
bb.put(TestDhcpMessage.CLIENT_ADDR.getAddress().getAddress()); // peer addr
bb.putShort((short)DhcpConstants.V6OPTION_RELAY_MSG);
ByteBuffer bb2 = TestDhcpMessage.buildMockClientRequest();
bb.putShort((short)bb2.limit());
bb.put(bb2);
bb.flip();
return bb;
}
public static void checkMockRelayFoward(DhcpV6RelayMessage relayMessage) throws Exception
{
assertEquals(RELAY1_ADDR.getAddress(), relayMessage.remoteAddress.getAddress());
assertEquals(0, relayMessage.getHopCount());
assertEquals(RELAY1_CLIENTSIDE_ADDR.getAddress(),
relayMessage.getLinkAddress());
assertEquals(TestDhcpMessage.CLIENT_ADDR.getAddress(),
relayMessage.getPeerAddress());
assertNotNull(relayMessage.getDhcpOptionMap());
assertNotNull(relayMessage.getRelayOption());
TestDhcpMessage.checkMockClientRequest(relayMessage.getRelayOption().getDhcpMessage());
}
public void testDecode() throws Exception
{
ByteBuffer bb = buildMockRelayFoward();
int len = bb.limit();
DhcpV6RelayMessage relayMessage = (DhcpV6RelayMessage)
DhcpV6RelayMessage.decode(bb, LOCALHOST_ADDR, RELAY1_ADDR);
assertNotNull(relayMessage);
assertEquals(len, relayMessage.getLength());
checkMockRelayFoward(relayMessage);
}
public void testDecode2() throws Exception
{
ByteBuffer bb = ByteBuffer.allocate(1024);
bb.put((byte)DhcpConstants.V6MESSAGE_TYPE_RELAY_FORW);
bb.put((byte)1); // hop count
bb.put(RELAY2_RELAY1SIDE_ADDR.getAddress().getAddress()); // link addr
bb.put(RELAY1_ADDR.getAddress().getAddress()); // peer addr
bb.putShort((short)DhcpConstants.V6OPTION_RELAY_MSG);
ByteBuffer bb2 = buildMockRelayFoward();
bb.putShort((short)bb2.limit());
bb.put(bb2);
bb.flip();
int len = bb.limit();
DhcpV6RelayMessage relayMessage = (DhcpV6RelayMessage)
DhcpV6RelayMessage.decode(bb, LOCALHOST_ADDR, RELAY2_ADDR);
assertNotNull(relayMessage);
assertEquals(len, relayMessage.getLength());
assertEquals(1, relayMessage.getHopCount());
assertEquals(RELAY2_RELAY1SIDE_ADDR.getAddress(),
relayMessage.getLinkAddress());
assertEquals(RELAY1_ADDR.getAddress(),
relayMessage.getPeerAddress());
assertNotNull(relayMessage.getDhcpOptionMap());
assertNotNull(relayMessage.getRelayOption());
checkMockRelayFoward((DhcpV6RelayMessage)
relayMessage.getRelayOption().getDhcpMessage());
}
}