Committed by
Pavlin Radoslavov
ICMPv6 checksum calculation fixed in ICMPv6.java
Change-Id: I4ac4a9138e9256318c0345668e7692f2778c136e
Showing
1 changed file
with
34 additions
and
11 deletions
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment