/* $Id$ */ package org.noreply.fancydress.type3.routing; import org.noreply.fancydress.misc.Util; import org.noreply.fancydress.crypto.*; import java.net.InetAddress; import java.net.Inet4Address; /** * The FWD/IP4 and SWAP-FWD/IP4 routing as specified in the type III spec. * * FWD/IP4 packets are forwarded to another type III node given by * an ip/port pair. * * This routing type is going to go away RSN. FIXME */ public class RoutingIP4 extends RoutingForward { /** * The IP address of the next hop */ private InetAddress ip; /** * Port at which the Type III server is listening */ private int port; /** * Keyid of the next hop's Packet Key */ private byte[] keyid; /** * Constructor that creates the routing as either FWD/IP4 or SWAP-FWD/IP4 * * @param ip IP address of the next hop * @param port TCP port at which the next hop is listening * @param keyid keyid of the packet key * @param boolean if true, have a SWAP-FWD/IP4 routing type, FWD/IP4 otherwhise */ private RoutingIP4(InetAddress ip, int port, byte[] keyid, boolean asSwap) { super (asSwap ? RoutingType.SWAP_FWD_IP4 : RoutingType.FWD_IP4); if (keyid.length != CryptoPrimitives.HASH_LEN) throw new Error("keyid must be HASH_LEN bytes long."); if (! (ip instanceof Inet4Address)) throw new Error("IP must be an instance of Inet4Address."); this.ip = ip; this.port = port; this.keyid = keyid; } /** * Create a FWD/IP4 routing. * * @param ip IP address of the next hop * @param port TCP port at which the next hop is listening * @param keyid keyid of the packet key */ public RoutingIP4(InetAddress ip, int port, byte[] keyid) { this(ip, port, keyid, false); } /** * Return a routing with the same information but with a SWAP_FWD_IP4 routing type. * * @return a SWAP_FWD_IP4 routing. */ public RoutingForward asSwap() { RoutingIP4 swap = new RoutingIP4(ip, port, keyid, true); return swap; } /** * Return the total length in octets of the routing information. * * @return total length in octets of the routing information */ public int getRoutingInformationLength() { return 4 + 2 + keyid.length; } /** * Get the routing type of this instance. * * @return routing type */ public byte[] getRoutingInformation() { int length = getRoutingInformationLength(); byte[] result = new byte[length]; byte[] address = ip.getAddress(); int pos = 0; if (address.length != 4) throw new Error("Expected 4 bytes from ip.getAddress()."); System.arraycopy(address, 0, result, pos, address.length); pos += address.length; result[pos] = (byte) ( (port >> 8) & 0xff); pos++; result[pos] = (byte) ( port & 0xff); pos++; System.arraycopy(keyid, 0, result, pos, keyid.length); pos += keyid.length; if (pos != length) throw new Error("Did not fill in expected amount of bytes!"); return result; } }