1 package org.opendaylight.l2switch.packethandler.decoders;
3 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
4 import org.opendaylight.controller.sal.packet.BitBufferHelper;
5 import org.opendaylight.controller.sal.packet.BufferException;
6 import org.opendaylight.controller.sal.utils.HexEncode;
7 import org.opendaylight.controller.sal.utils.NetUtils;
8 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketOverEthernetReceived;
9 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketOverEthernetReceivedBuilder;
10 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.KnownHardwareType;
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.KnownOperation;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.arp.packet.over.ethernet.fields.ArpPacketBuilder;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.arp.packet.over.ethernet.fields.EthernetOverRawPacket;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.arp.packet.over.ethernet.fields.EthernetOverRawPacketBuilder;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketListener;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketOverRawReceived;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.KnownEtherType;
18 import org.opendaylight.yangtools.yang.binding.NotificationListener;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
22 import java.net.InetAddress;
23 import java.net.UnknownHostException;
26 * ARP (Address Resolution Protocol) Packet Decoder
28 public class ArpDecoder extends AbstractPacketDecoder<EthernetPacketOverRawReceived, ArpPacketOverEthernetReceived>
29 implements EthernetPacketListener {
31 private static final Logger _logger = LoggerFactory.getLogger(ArpDecoder.class);
33 public ArpDecoder(NotificationProviderService notificationProviderService) {
34 super(ArpPacketOverEthernetReceived.class, notificationProviderService);
38 * Decode an EthernetPacket into an ArpPacket
41 public ArpPacketOverEthernetReceived decode(EthernetPacketOverRawReceived ethernetPacketOverRawReceived) {
42 ArpPacketOverEthernetReceivedBuilder arpReceivedBuilder = new ArpPacketOverEthernetReceivedBuilder();
44 byte[] data = ethernetPacketOverRawReceived.getPayload();
45 int bitOffset = ethernetPacketOverRawReceived.getEthernetPacket().getPayloadOffset() * NetUtils.NumBitsInAByte;
47 ArpPacketBuilder builder = new ArpPacketBuilder();
50 // Decode the hardware-type (HTYPE) and protocol-type (PTYPE) fields
51 builder.setHardwareType(KnownHardwareType.forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 0, 16))));
52 builder.setProtocolType(KnownEtherType.forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset+16, 16))));
54 // Decode the hardware-length and protocol-length fields
55 builder.setHardwareLength(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset+32, 8)));
56 builder.setProtocolLength(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset+40, 8)));
58 // Decode the operation field
59 builder.setOperation(KnownOperation.forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset+48, 16))));
61 // Decode the address fields
62 int indexSrcProtAdd = 64 + 8 * builder.getHardwareLength();
63 int indexDstHardAdd = indexSrcProtAdd + 8 * builder.getProtocolLength();
64 int indexDstProtAdd = indexDstHardAdd + 8 * builder.getHardwareLength();
65 if(builder.getHardwareType().equals(KnownHardwareType.Ethernet)) {
66 builder.setSourceHardwareAddress(HexEncode.bytesToHexStringFormat(BitBufferHelper.getBits(data, bitOffset + 64, 8 * builder.getHardwareLength())));
67 builder.setDestinationHardwareAddress(HexEncode.bytesToHexStringFormat(BitBufferHelper.getBits(data, bitOffset + indexDstHardAdd, 8 * builder.getHardwareLength())));
69 _logger.debug("Unknown HardwareType -- sourceHardwareAddress and destinationHardwareAddress are not decoded");
72 if(builder.getProtocolType().equals(KnownEtherType.Ipv4) || builder.getProtocolType().equals(KnownEtherType.Ipv6)) {
73 builder.setSourceProtocolAddress(InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset + indexSrcProtAdd, 8 * builder.getProtocolLength())).getHostAddress());
74 builder.setDestinationProtocolAddress(InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset + indexDstProtAdd, 8 * builder.getProtocolLength())).getHostAddress());
76 _logger.debug("Unknown ProtocolType -- sourceProtocolAddress and destinationProtocolAddress are not decoded");
78 } catch(BufferException | UnknownHostException e) {
79 _logger.debug("Exception while decoding APR packet", e.getMessage());
83 arpReceivedBuilder.setArpPacket(builder.build());
85 // extract ethernet over raw context from the consumed notification and set it and set it in Produced notification
86 EthernetOverRawPacketBuilder ethernetOverRawPacketBuilder = new EthernetOverRawPacketBuilder();
87 ethernetOverRawPacketBuilder.setRawPacket(ethernetPacketOverRawReceived.getRawPacket());
88 ethernetOverRawPacketBuilder.setEthernetPacket(ethernetPacketOverRawReceived.getEthernetPacket());
90 //set the context of previous decoded fields
91 arpReceivedBuilder.setEthernetOverRawPacket(ethernetOverRawPacketBuilder.build());
93 // carry forward the original payload.
94 arpReceivedBuilder.setPayload(ethernetPacketOverRawReceived.getPayload());
96 return arpReceivedBuilder.build();
100 public NotificationListener getConsumedNotificationListener() {
105 public void onEthernetPacketOverRawReceived(EthernetPacketOverRawReceived notification) {
106 decodeAndPublish(notification);
110 public boolean canDecode(EthernetPacketOverRawReceived ethernetPacketOverRawReceived) {
111 if(ethernetPacketOverRawReceived==null || ethernetPacketOverRawReceived.getEthernetPacket()==null)
113 return KnownEtherType.Arp.equals(ethernetPacketOverRawReceived.getEthernetPacket().getEthertype());