Pavlin Radoslavov

Fix a bug when serliazing ICMPv6 packets and the IPv6 packet contains

hop-by-hop options.

This fixes ONOS-1201

Change-Id: I736f96268695dd7e74c99631f25273d1b34d8a6c
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
18 18
19 package org.onlab.packet; 19 package org.onlab.packet;
20 20
21 +import org.onlab.packet.ipv6.IExtensionHeader;
21 import org.onlab.packet.ndp.NeighborAdvertisement; 22 import org.onlab.packet.ndp.NeighborAdvertisement;
22 import org.onlab.packet.ndp.NeighborSolicitation; 23 import org.onlab.packet.ndp.NeighborSolicitation;
23 import org.onlab.packet.ndp.Redirect; 24 import org.onlab.packet.ndp.Redirect;
...@@ -53,6 +54,8 @@ public class ICMP6 extends BasePacket { ...@@ -53,6 +54,8 @@ public class ICMP6 extends BasePacket {
53 protected byte icmpCode; 54 protected byte icmpCode;
54 protected short checksum; 55 protected short checksum;
55 56
57 + private static final byte[] ZERO_ADDRESS = new byte[Ip6Address.BYTE_LENGTH];
58 +
56 /** 59 /**
57 * Gets ICMP6 type. 60 * Gets ICMP6 type.
58 * 61 *
...@@ -138,8 +141,21 @@ public class ICMP6 extends BasePacket { ...@@ -138,8 +141,21 @@ public class ICMP6 extends BasePacket {
138 // Creating IPv6 Pseudo Header for checksum calculation according 141 // Creating IPv6 Pseudo Header for checksum calculation according
139 // to RFC 4443 and RFC 2460 142 // to RFC 4443 and RFC 2460
140 // 143 //
141 - bbChecksum.put(((IPv6) this.parent).getSourceAddress()); 144 + IPv6 ipv6Parent = null;
142 - bbChecksum.put(((IPv6) this.parent).getDestinationAddress()); 145 + for (IPacket p = this.parent; p != null; p = p.getParent()) {
146 + if (p instanceof IPv6) {
147 + ipv6Parent = (IPv6) p;
148 + break;
149 + }
150 + }
151 + if (ipv6Parent != null) {
152 + bbChecksum.put(((IPv6) ipv6Parent).getSourceAddress());
153 + bbChecksum.put(((IPv6) ipv6Parent).getDestinationAddress());
154 + } else {
155 + // NOTE: IPv6 source and destination addresses unknown. Use zeroes.
156 + bbChecksum.put(ZERO_ADDRESS);
157 + bbChecksum.put(ZERO_ADDRESS);
158 + }
143 bbChecksum.putInt(HEADER_LENGTH + payloadLength); 159 bbChecksum.putInt(HEADER_LENGTH + payloadLength);
144 bbChecksum.put((byte) 0); 160 bbChecksum.put((byte) 0);
145 bbChecksum.put((byte) 0); 161 bbChecksum.put((byte) 0);
...@@ -158,8 +174,12 @@ public class ICMP6 extends BasePacket { ...@@ -158,8 +174,12 @@ public class ICMP6 extends BasePacket {
158 bbChecksum.put(payloadData); 174 bbChecksum.put(payloadData);
159 } 175 }
160 176
161 - if (this.parent != null && this.parent instanceof IPv6) { 177 + if (this.parent != null) {
162 - ((IPv6) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6); 178 + if (this.parent instanceof IPv6) {
179 + ((IPv6) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6);
180 + } else if (this.parent instanceof IExtensionHeader) {
181 + ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6);
182 + }
163 } 183 }
164 184
165 // compute checksum if needed 185 // compute checksum if needed
......