Dusan Pajin
Committed by Pavlin Radoslavov

ICMPv6 checksum calculation fixed in ICMPv6.java

Change-Id: I4ac4a9138e9256318c0345668e7692f2778c136e
...@@ -127,13 +127,35 @@ public class ICMP6 extends BasePacket { ...@@ -127,13 +127,35 @@ public class ICMP6 extends BasePacket {
127 } 127 }
128 128
129 final byte[] data = new byte[HEADER_LENGTH + payloadLength]; 129 final byte[] data = new byte[HEADER_LENGTH + payloadLength];
130 - final ByteBuffer bb = ByteBuffer.wrap(data); 130 + final ByteBuffer bbData = ByteBuffer.wrap(data);
131 131
132 - bb.put(this.icmpType); 132 + // Creating ByteBuffer for checksum calculation
133 - bb.put(this.icmpCode); 133 + final byte[] checksumData =
134 - bb.putShort(this.checksum); 134 + new byte[IPv6.FIXED_HEADER_LENGTH + HEADER_LENGTH + payloadLength];
135 + final ByteBuffer bbChecksum = ByteBuffer.wrap(checksumData);
136 +
137 + //
138 + // Creating IPv6 Pseudo Header for checksum calculation according
139 + // to RFC 4443 and RFC 2460
140 + //
141 + bbChecksum.put(((IPv6) this.parent).getSourceAddress());
142 + bbChecksum.put(((IPv6) this.parent).getDestinationAddress());
143 + bbChecksum.putInt(HEADER_LENGTH + payloadLength);
144 + bbChecksum.put((byte) 0);
145 + bbChecksum.put((byte) 0);
146 + bbChecksum.put((byte) 0);
147 + bbChecksum.put(IPv6.PROTOCOL_ICMP6);
148 + bbChecksum.put(this.icmpType);
149 + bbChecksum.put(this.icmpCode);
150 + bbChecksum.put((byte) 0);
151 + bbChecksum.put((byte) 0);
152 +
153 + bbData.put(this.icmpType);
154 + bbData.put(this.icmpCode);
155 + bbData.putShort(this.checksum);
135 if (payloadData != null) { 156 if (payloadData != null) {
136 - bb.put(payloadData); 157 + bbData.put(payloadData);
158 + bbChecksum.put(payloadData);
137 } 159 }
138 160
139 if (this.parent != null && this.parent instanceof IPv6) { 161 if (this.parent != null && this.parent instanceof IPv6) {
...@@ -142,21 +164,22 @@ public class ICMP6 extends BasePacket { ...@@ -142,21 +164,22 @@ public class ICMP6 extends BasePacket {
142 164
143 // compute checksum if needed 165 // compute checksum if needed
144 if (this.checksum == 0) { 166 if (this.checksum == 0) {
145 - bb.rewind(); 167 + bbData.rewind();
168 + bbChecksum.rewind();
146 int accumulation = 0; 169 int accumulation = 0;
147 170
148 - for (int i = 0; i < data.length / 2; ++i) { 171 + for (int i = 0; i < checksumData.length / 2; ++i) {
149 - accumulation += 0xffff & bb.getShort(); 172 + accumulation += 0xffff & bbChecksum.getShort();
150 } 173 }
151 // pad to an even number of shorts 174 // pad to an even number of shorts
152 - if (data.length % 2 > 0) { 175 + if (checksumData.length % 2 > 0) {
153 - accumulation += (bb.get() & 0xff) << 8; 176 + accumulation += (bbChecksum.get() & 0xff) << 8;
154 } 177 }
155 178
156 accumulation = (accumulation >> 16 & 0xffff) 179 accumulation = (accumulation >> 16 & 0xffff)
157 + (accumulation & 0xffff); 180 + (accumulation & 0xffff);
158 this.checksum = (short) (~accumulation & 0xffff); 181 this.checksum = (short) (~accumulation & 0xffff);
159 - bb.putShort(2, this.checksum); 182 + bbData.putShort(2, this.checksum);
160 } 183 }
161 return data; 184 return data;
162 } 185 }
......