/** * Deserializer function for ARP packets. * * @return deserializer function */ public static Deserializer<ARP> deserializer() { return (data, offset, length) -> { checkInput(data, offset, length, INITIAL_HEADER_LENGTH); ARP arp = new ARP(); final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); arp.setHardwareType(bb.getShort()); arp.setProtocolType(bb.getShort()); byte hwAddressLength = bb.get(); arp.setHardwareAddressLength(hwAddressLength); byte protocolAddressLength = bb.get(); arp.setProtocolAddressLength(protocolAddressLength); arp.setOpCode(bb.getShort()); // Check we have enough space for the addresses checkHeaderLength( length, INITIAL_HEADER_LENGTH + 2 * hwAddressLength + 2 * protocolAddressLength); arp.senderHardwareAddress = new byte[0xff & hwAddressLength]; bb.get(arp.senderHardwareAddress, 0, arp.senderHardwareAddress.length); arp.senderProtocolAddress = new byte[0xff & protocolAddressLength]; bb.get(arp.senderProtocolAddress, 0, arp.senderProtocolAddress.length); arp.targetHardwareAddress = new byte[0xff & hwAddressLength]; bb.get(arp.targetHardwareAddress, 0, arp.targetHardwareAddress.length); arp.targetProtocolAddress = new byte[0xff & protocolAddressLength]; bb.get(arp.targetProtocolAddress, 0, arp.targetProtocolAddress.length); return arp; }; }
/** * Builds an ARP reply based on a request. * * @param srcIp the IP address to use as the reply source * @param srcMac the MAC address to use as the reply source * @param request the ARP request we got * @return an Ethernet frame containing the ARP reply */ public static Ethernet buildArpReply(Ip4Address srcIp, MacAddress srcMac, Ethernet request) { Ethernet eth = new Ethernet(); eth.setDestinationMACAddress(request.getSourceMAC()); eth.setSourceMACAddress(srcMac); eth.setEtherType(Ethernet.TYPE_ARP); eth.setVlanID(request.getVlanID()); ARP arp = new ARP(); arp.setOpCode(ARP.OP_REPLY); arp.setProtocolType(ARP.PROTO_TYPE_IP); arp.setHardwareType(ARP.HW_TYPE_ETHERNET); arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH); arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH); arp.setSenderHardwareAddress(srcMac.toBytes()); arp.setTargetHardwareAddress(request.getSourceMACAddress()); arp.setTargetProtocolAddress(((ARP) request.getPayload()).getSenderProtocolAddress()); arp.setSenderProtocolAddress(srcIp.toInt()); eth.setPayload(arp); return eth; }