/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.arp; import static com.google.common.base.Preconditions.checkNotNull; import io.netty.buffer.Unpooled; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.opendaylight.controller.liblldp.EtherTypes; import org.opendaylight.controller.liblldp.NetUtils; import org.opendaylight.controller.liblldp.Packet; import org.opendaylight.controller.liblldp.PacketException; /** * Represents ARP packet. Contains methods ({@link #setSHAFieldCoordinate(Pair)} * {@link #setSPAFieldCoordinate(Pair)} {@link #setTHAFieldCoordinate(Pair)} * {@link #setTPAFieldCoordinate(Pair)}) for customization of ARP. * Arp by default contain fields for IPv4 as protocol address and MAC as hardware address. */ public class Arp extends Packet { private static final String HTYPE = "htype"; private static final String PTYPE = "ptype"; private static final String HLEN = "hlen"; private static final String PLEN = "plen"; private static final String OPERATION = "operation"; private static final String SHA = "sha"; private static final String SPA = "spa"; private static final String THA = "tha"; private static final String TPA = "tpa"; private static final int ARP_FIELDS_COUNT = 9; private static final int ETHERNET_HW_TYPE = 1; private final Map<String, Pair<Integer, Integer>> ARP_FIELD_COORDINATES = new LinkedHashMap<String, Pair<Integer, Integer>>() { private static final long serialVersionUID = 1L; { put(HTYPE, ImmutablePair.of(0, 16)); put(PTYPE, ImmutablePair.of(16, 16)); put(HLEN, ImmutablePair.of(32, 8)); put(PLEN, ImmutablePair.of(40, 8)); put(OPERATION, ImmutablePair.of(48, 16)); put(SHA, ImmutablePair.of(64, 48)); put(SPA, ImmutablePair.of(112, 32)); put(THA, ImmutablePair.of(144, 48)); put(TPA, ImmutablePair.of(192, 32)); } }; public Arp() { payload = null; hdrFieldsMap = new HashMap<String, byte[]>(ARP_FIELDS_COUNT); setHardwareLength((short) 6); // MAC address length setProtocolLength((short) 4); // IPv4 address length setHardwareType(ETHERNET_HW_TYPE); setProtocolType(EtherTypes.IPv4.intValue()); hdrFieldCoordMap = ARP_FIELD_COORDINATES; } public Pair<Integer, Integer> setSHAFieldCoordinate(Pair<Integer, Integer> bitOffsetAndBitLength) { checkNotNullPair(bitOffsetAndBitLength); return ARP_FIELD_COORDINATES.put(SHA, bitOffsetAndBitLength); } public Pair<Integer, Integer> setSPAFieldCoordinate(Pair<Integer, Integer> bitOffsetAndBitLength) { checkNotNullPair(bitOffsetAndBitLength); return ARP_FIELD_COORDINATES.put(SPA, bitOffsetAndBitLength); } public Pair<Integer, Integer> setTHAFieldCoordinate(Pair<Integer, Integer> bitOffsetAndBitLength) { checkNotNullPair(bitOffsetAndBitLength); return ARP_FIELD_COORDINATES.put(THA, bitOffsetAndBitLength); } public Pair<Integer, Integer> setTPAFieldCoordinate(Pair<Integer, Integer> bitOffsetAndBitLength) { checkNotNullPair(bitOffsetAndBitLength); return ARP_FIELD_COORDINATES.put(TPA, bitOffsetAndBitLength); } private void checkNotNullPair(Pair<Integer, Integer> pair) { checkNotNull(pair); checkNotNull(pair.getLeft()); checkNotNull(pair.getRight()); } @Override public Packet deserialize(byte[] data, int bitOffset, int size) throws PacketException { return super.deserialize(data, bitOffset, size); } @Override public byte[] serialize() throws PacketException { return super.serialize(); } @Override public int getfieldnumBits(String fieldName) { if (fieldName.equals(SHA) || fieldName.equals(THA)) { return getHardwareLength() * NetUtils.NumBitsInAByte; } else if (fieldName.equals(SPA) || fieldName.equals(TPA)) { return getProtocolLength() * NetUtils.NumBitsInAByte; } return hdrFieldCoordMap.get(fieldName).getRight(); } public Arp setHardwareType(int value) { hdrFieldsMap.put(HTYPE, Unpooled.copyShort(value).array()); return this; } public Arp setProtocolType(int value) { hdrFieldsMap.put(PTYPE, Unpooled.copyShort(value).array()); return this; } /** * * @param value hardware length in Bytes * @return {@link Arp} */ public Arp setHardwareLength(short value) { hdrFieldsMap.put(HLEN, Unpooled.buffer(1).writeByte(value).array()); return this; } /** * * @param value protocol length in Bytes * @return {@link Arp} */ public Arp setProtocolLength(short value) { hdrFieldsMap.put(PLEN, Unpooled.buffer(1).writeByte(value).array()); return this; } public Arp setOperation(int value) { hdrFieldsMap.put(OPERATION, Unpooled.copyShort(value).array()); return this; } public Arp setSenderHardwareAddress(byte[] value) { hdrFieldsMap.put(SHA, value); return this; } public Arp setSenderProtocolAddress(byte[] value) { hdrFieldsMap.put(SPA, value); return this; } public Arp setTargetHardwareAddress(byte[] value) { hdrFieldsMap.put(THA, value); return this; } public Arp setTargetProtocolAddress(byte[] value) { hdrFieldsMap.put(TPA, value); return this; } public int getHardwareType() { byte[] htype = hdrFieldsMap.get(HTYPE); return Unpooled.wrappedBuffer(htype).readUnsignedShort(); } public int getProtocolType() { byte[] ptype = hdrFieldsMap.get(PTYPE); return Unpooled.wrappedBuffer(ptype).readUnsignedShort(); } public short getHardwareLength() { byte[] hlen = hdrFieldsMap.get(HLEN); return Unpooled.wrappedBuffer(hlen).readUnsignedByte(); } public short getProtocolLength() { byte[] plen = hdrFieldsMap.get(PLEN); return Unpooled.wrappedBuffer(plen).readUnsignedByte(); } public int getOperation() { byte[] operation = hdrFieldsMap.get(OPERATION); return Unpooled.wrappedBuffer(operation).readUnsignedShort(); } public byte[] getSenderHardwareAddress() { return hdrFieldsMap.get(SHA); } public byte[] getSenderProtocolAddress() { return hdrFieldsMap.get(SPA); } public byte[] getTargetHardwareAddress() { return hdrFieldsMap.get(THA); } public byte[] getTargetProtocolAddress() { return hdrFieldsMap.get(TPA); } }