2 * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.l2switch.packethandler.decoders;
10 import java.util.List;
11 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
12 import org.opendaylight.l2switch.packethandler.decoders.utils.BitBufferHelper;
13 import org.opendaylight.l2switch.packethandler.decoders.utils.BufferException;
14 import org.opendaylight.l2switch.packethandler.decoders.utils.NetUtils;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.PacketChain;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.PacketChainBuilder;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.packet.chain.Packet;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.icmp.rev140528.IcmpPacketReceived;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.icmp.rev140528.IcmpPacketReceivedBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.icmp.rev140528.icmp.packet.received.packet.chain.packet.IcmpPacketBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.Ipv4PacketListener;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.Ipv4PacketReceived;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.KnownIpProtocols;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ipv4.rev140528.ipv4.packet.received.packet.chain.packet.Ipv4Packet;
25 import org.opendaylight.yangtools.yang.binding.NotificationListener;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 public class IcmpDecoder extends AbstractPacketDecoder<Ipv4PacketReceived, IcmpPacketReceived>
30 implements Ipv4PacketListener {
32 private static final Logger LOG = LoggerFactory.getLogger(IcmpDecoder.class);
34 public IcmpDecoder(NotificationProviderService notificationProviderService) {
35 super(IcmpPacketReceived.class, notificationProviderService);
39 * Decode an EthernetPacket into an IcmpPacket.
42 public IcmpPacketReceived decode(Ipv4PacketReceived ipv4PacketReceived) {
43 IcmpPacketReceivedBuilder icmpReceivedBuilder = new IcmpPacketReceivedBuilder();
45 // Find the latest packet in the packet-chain, which is an
47 List<PacketChain> packetChainList = ipv4PacketReceived.getPacketChain();
48 Ipv4Packet ipv4Packet = (Ipv4Packet) packetChainList.get(packetChainList.size() - 1).getPacket();
49 int bitOffset = ipv4Packet.getPayloadOffset() * NetUtils.NUM_BITS_IN_A_BYTE;
50 byte[] data = ipv4PacketReceived.getPayload();
52 IcmpPacketBuilder builder = new IcmpPacketBuilder();
54 // Decode the ICMP type and ICMP code
55 builder.setType(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 0, 8)));
56 builder.setCode(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 8, 8)));
58 // Decode the checksum
59 builder.setCrc(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 16, 16)));
61 // Decode the identifier and sequence number
62 builder.setIdentifier(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 32, 16)));
63 builder.setSequenceNumber(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 48, 16)));
65 // Decode the ICMP Payload
66 int payloadStartInBits = bitOffset + 64;
67 int payloadEndInBits = data.length * NetUtils.NUM_BITS_IN_A_BYTE - payloadStartInBits - 4
68 * NetUtils.NUM_BITS_IN_A_BYTE;
69 int start = payloadStartInBits / NetUtils.NUM_BITS_IN_A_BYTE;
70 int end = start + payloadEndInBits / NetUtils.NUM_BITS_IN_A_BYTE;
71 builder.setPayloadOffset(start);
72 builder.setPayloadLength(end - start);
73 } catch (BufferException e) {
74 LOG.debug("Exception while decoding ICMP packet", e);
78 packetChainList.add(new PacketChainBuilder().setPacket(builder.build()).build());
79 icmpReceivedBuilder.setPacketChain(packetChainList);
81 // carry forward the original payload.
82 icmpReceivedBuilder.setPayload(ipv4PacketReceived.getPayload());
84 return icmpReceivedBuilder.build();
88 public NotificationListener getConsumedNotificationListener() {
93 public void onIpv4PacketReceived(Ipv4PacketReceived notification) {
94 decodeAndPublish(notification);
98 public boolean canDecode(Ipv4PacketReceived ipv4PacketReceived) {
99 if (ipv4PacketReceived == null || ipv4PacketReceived.getPacketChain() == null) {
103 // Only decode the latest packet in the chain
104 Ipv4Packet ipv4Packet = null;
105 if (!ipv4PacketReceived.getPacketChain().isEmpty()) {
106 Packet packet = ipv4PacketReceived.getPacketChain().get(ipv4PacketReceived.getPacketChain().size() - 1)
108 if (packet instanceof Ipv4Packet) {
109 ipv4Packet = (Ipv4Packet) packet;
113 return ipv4Packet != null && KnownIpProtocols.Icmp.equals(ipv4Packet.getProtocol());