blob: 0d75245730a2f52175fe1eee09f9d3df7a219472 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
alshabibc4901cd2014-09-05 16:50:40 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
alshabibc4901cd2014-09-05 16:50:40 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
alshabibc4901cd2014-09-05 16:50:40 -070016
17/**
18 *
19 */
20package org.onlab.packet;
21
22import java.nio.ByteBuffer;
23import java.util.Arrays;
24import java.util.Collection;
25import java.util.HashMap;
26import java.util.Map;
27
Jonathan Hart2a655752015-04-07 16:46:33 -070028import static org.onlab.packet.PacketUtils.*;
29
alshabibc4901cd2014-09-05 16:50:40 -070030/**
alshabibc4901cd2014-09-05 16:50:40 -070031 *
32 */
33public class IPv4 extends BasePacket {
34 public static final byte PROTOCOL_ICMP = 0x1;
35 public static final byte PROTOCOL_TCP = 0x6;
36 public static final byte PROTOCOL_UDP = 0x11;
Jonathan Hart2a655752015-04-07 16:46:33 -070037 public static final Map<Byte, Deserializer<? extends IPacket>> PROTOCOL_DESERIALIZER_MAP =
Ray Milkey241b96a2014-11-17 13:08:20 -080038 new HashMap<>();
alshabibc4901cd2014-09-05 16:50:40 -070039
40 static {
Jonathan Hart2a655752015-04-07 16:46:33 -070041 IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_ICMP, ICMP.deserializer());
42 IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_TCP, TCP.deserializer());
43 IPv4.PROTOCOL_DESERIALIZER_MAP.put(IPv4.PROTOCOL_UDP, UDP.deserializer());
alshabibc4901cd2014-09-05 16:50:40 -070044 }
45
Pavlin Radoslavovbf23c552015-02-20 14:20:30 -080046 private static final byte DSCP_MASK = 0x3f;
47 private static final byte DSCP_OFFSET = 2;
48 private static final byte ECN_MASK = 0x3;
49
Jonathan Hart2a655752015-04-07 16:46:33 -070050 private static final short HEADER_LENGTH = 20;
51
alshabibc4901cd2014-09-05 16:50:40 -070052 protected byte version;
53 protected byte headerLength;
54 protected byte diffServ;
55 protected short totalLength;
56 protected short identification;
57 protected byte flags;
58 protected short fragmentOffset;
59 protected byte ttl;
60 protected byte protocol;
61 protected short checksum;
62 protected int sourceAddress;
63 protected int destinationAddress;
64 protected byte[] options;
65
66 protected boolean isTruncated;
67
68 /**
69 * Default constructor that sets the version to 4.
70 */
71 public IPv4() {
72 super();
73 this.version = 4;
74 this.isTruncated = false;
75 }
76
77 /**
78 * @return the version
79 */
80 public byte getVersion() {
81 return this.version;
82 }
83
84 /**
85 * @param version
86 * the version to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -080087 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070088 */
89 public IPv4 setVersion(final byte version) {
90 this.version = version;
91 return this;
92 }
93
94 /**
95 * @return the headerLength
96 */
97 public byte getHeaderLength() {
98 return this.headerLength;
99 }
100
101 /**
Pavlin Radoslavovbf23c552015-02-20 14:20:30 -0800102 * Gets the DSCP value (6 bits).
103 *
104 * @return the DSCP value (6 bits)
105 */
106 public byte getDscp() {
107 return (byte) ((this.diffServ >>> DSCP_OFFSET) & DSCP_MASK);
108 }
109
110 /**
111 * Sets the DSCP value (6 bits).
112 *
113 * @param dscp the DSCP value (6 bits)
114 * @return this
115 */
116 public IPv4 setDscp(byte dscp) {
117 this.diffServ &= ~(DSCP_MASK << DSCP_OFFSET);
118 this.diffServ |= (dscp & DSCP_MASK) << DSCP_OFFSET;
119 return this;
120 }
121
122 /**
123 * Gets the ECN value (2 bits).
124 *
125 * @return the ECN value (2 bits)
126 */
127 public byte getEcn() {
128 return (byte) (this.diffServ & ECN_MASK);
129 }
130
131 /**
132 * Sets the ECN value (2 bits).
133 *
134 * @param ecn the ECN value (2 bits)
135 * @return this
136 */
137 public IPv4 setEcn(byte ecn) {
138 this.diffServ &= ~ECN_MASK;
139 this.diffServ |= (ecn & ECN_MASK);
140 return this;
141 }
142
143 /**
144 * Gets the DiffServ octet (including the DSCP and ECN bits).
145 *
146 * @return the diffServ octet (including the DSCP and ECN bits)
alshabibc4901cd2014-09-05 16:50:40 -0700147 */
148 public byte getDiffServ() {
149 return this.diffServ;
150 }
151
152 /**
Pavlin Radoslavovbf23c552015-02-20 14:20:30 -0800153 * Sets the DiffServ octet (including the DSCP and ECN bits).
154 *
155 * @param diffServ the diffServ octet to set (including the DSCP and ECN
156 * bits)
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800157 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700158 */
159 public IPv4 setDiffServ(final byte diffServ) {
160 this.diffServ = diffServ;
161 return this;
162 }
163
164 /**
165 * @return the totalLength
166 */
167 public short getTotalLength() {
168 return this.totalLength;
169 }
170
171 /**
172 * @return the identification
173 */
174 public short getIdentification() {
175 return this.identification;
176 }
177
178 public boolean isTruncated() {
179 return this.isTruncated;
180 }
181
182 public void setTruncated(final boolean isTruncated) {
183 this.isTruncated = isTruncated;
184 }
185
186 /**
187 * @param identification
188 * the identification to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800189 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700190 */
191 public IPv4 setIdentification(final short identification) {
192 this.identification = identification;
193 return this;
194 }
195
196 /**
197 * @return the flags
198 */
199 public byte getFlags() {
200 return this.flags;
201 }
202
203 /**
204 * @param flags
205 * the flags to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800206 * @return this
207s */
alshabibc4901cd2014-09-05 16:50:40 -0700208 public IPv4 setFlags(final byte flags) {
209 this.flags = flags;
210 return this;
211 }
212
213 /**
214 * @return the fragmentOffset
215 */
216 public short getFragmentOffset() {
217 return this.fragmentOffset;
218 }
219
220 /**
221 * @param fragmentOffset
222 * the fragmentOffset to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800223 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700224 */
225 public IPv4 setFragmentOffset(final short fragmentOffset) {
226 this.fragmentOffset = fragmentOffset;
227 return this;
228 }
229
230 /**
231 * @return the ttl
232 */
233 public byte getTtl() {
234 return this.ttl;
235 }
236
237 /**
238 * @param ttl
239 * the ttl to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800240 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700241 */
242 public IPv4 setTtl(final byte ttl) {
243 this.ttl = ttl;
244 return this;
245 }
246
247 /**
248 * @return the protocol
249 */
250 public byte getProtocol() {
251 return this.protocol;
252 }
253
254 /**
255 * @param protocol
256 * the protocol to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800257 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700258 */
259 public IPv4 setProtocol(final byte protocol) {
260 this.protocol = protocol;
261 return this;
262 }
263
264 /**
265 * @return the checksum
266 */
267 public short getChecksum() {
268 return this.checksum;
269 }
270
271 /**
272 * @param checksum
273 * the checksum to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800274 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700275 */
276 public IPv4 setChecksum(final short checksum) {
277 this.checksum = checksum;
278 return this;
279 }
280
281 @Override
282 public void resetChecksum() {
283 this.checksum = 0;
284 super.resetChecksum();
285 }
286
287 /**
288 * @return the sourceAddress
289 */
290 public int getSourceAddress() {
291 return this.sourceAddress;
292 }
293
294 /**
295 * @param sourceAddress
296 * the sourceAddress to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800297 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700298 */
299 public IPv4 setSourceAddress(final int sourceAddress) {
300 this.sourceAddress = sourceAddress;
301 return this;
302 }
303
304 /**
305 * @param sourceAddress
306 * the sourceAddress to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800307 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700308 */
309 public IPv4 setSourceAddress(final String sourceAddress) {
310 this.sourceAddress = IPv4.toIPv4Address(sourceAddress);
311 return this;
312 }
313
314 /**
315 * @return the destinationAddress
316 */
317 public int getDestinationAddress() {
318 return this.destinationAddress;
319 }
320
321 /**
322 * @param destinationAddress
323 * the destinationAddress to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800324 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700325 */
326 public IPv4 setDestinationAddress(final int destinationAddress) {
327 this.destinationAddress = destinationAddress;
328 return this;
329 }
330
331 /**
332 * @param destinationAddress
333 * the destinationAddress to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800334 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700335 */
336 public IPv4 setDestinationAddress(final String destinationAddress) {
337 this.destinationAddress = IPv4.toIPv4Address(destinationAddress);
338 return this;
339 }
340
341 /**
342 * @return the options
343 */
344 public byte[] getOptions() {
345 return this.options;
346 }
347
348 /**
349 * @param options
350 * the options to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800351 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700352 */
353 public IPv4 setOptions(final byte[] options) {
354 if (options != null && options.length % 4 > 0) {
355 throw new IllegalArgumentException(
356 "Options length must be a multiple of 4");
357 }
358 this.options = options;
359 return this;
360 }
361
362 /**
363 * Serializes the packet. Will compute and set the following fields if they
364 * are set to specific values at the time serialize is called: -checksum : 0
365 * -headerLength : 0 -totalLength : 0
366 */
367 @Override
368 public byte[] serialize() {
369 byte[] payloadData = null;
370 if (this.payload != null) {
371 this.payload.setParent(this);
372 payloadData = this.payload.serialize();
373 }
374
375 int optionsLength = 0;
376 if (this.options != null) {
377 optionsLength = this.options.length / 4;
378 }
379 this.headerLength = (byte) (5 + optionsLength);
380
381 this.totalLength = (short) (this.headerLength * 4 + (payloadData == null ? 0
382 : payloadData.length));
383
384 final byte[] data = new byte[this.totalLength];
385 final ByteBuffer bb = ByteBuffer.wrap(data);
386
387 bb.put((byte) ((this.version & 0xf) << 4 | this.headerLength & 0xf));
388 bb.put(this.diffServ);
389 bb.putShort(this.totalLength);
390 bb.putShort(this.identification);
391 bb.putShort((short) ((this.flags & 0x7) << 13 | this.fragmentOffset & 0x1fff));
392 bb.put(this.ttl);
393 bb.put(this.protocol);
394 bb.putShort(this.checksum);
395 bb.putInt(this.sourceAddress);
396 bb.putInt(this.destinationAddress);
397 if (this.options != null) {
398 bb.put(this.options);
399 }
400 if (payloadData != null) {
401 bb.put(payloadData);
402 }
403
404 // compute checksum if needed
405 if (this.checksum == 0) {
406 bb.rewind();
407 int accumulation = 0;
408 for (int i = 0; i < this.headerLength * 2; ++i) {
409 accumulation += 0xffff & bb.getShort();
410 }
411 accumulation = (accumulation >> 16 & 0xffff)
412 + (accumulation & 0xffff);
413 this.checksum = (short) (~accumulation & 0xffff);
414 bb.putShort(10, this.checksum);
415 }
416 return data;
417 }
418
419 @Override
420 public IPacket deserialize(final byte[] data, final int offset,
Jonathan Hart2a655752015-04-07 16:46:33 -0700421 final int length) {
alshabibc4901cd2014-09-05 16:50:40 -0700422 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
423 short sscratch;
424
425 this.version = bb.get();
426 this.headerLength = (byte) (this.version & 0xf);
427 this.version = (byte) (this.version >> 4 & 0xf);
428 this.diffServ = bb.get();
429 this.totalLength = bb.getShort();
430 this.identification = bb.getShort();
431 sscratch = bb.getShort();
432 this.flags = (byte) (sscratch >> 13 & 0x7);
433 this.fragmentOffset = (short) (sscratch & 0x1fff);
434 this.ttl = bb.get();
435 this.protocol = bb.get();
436 this.checksum = bb.getShort();
437 this.sourceAddress = bb.getInt();
438 this.destinationAddress = bb.getInt();
439
440 if (this.headerLength > 5) {
441 final int optionsLength = (this.headerLength - 5) * 4;
442 this.options = new byte[optionsLength];
443 bb.get(this.options);
444 }
445
alshabibc4901cd2014-09-05 16:50:40 -0700446 if (this.totalLength != length) {
447 this.isTruncated = true;
448 } else {
449 this.isTruncated = false;
450 }
451
Jonathan Hart2a655752015-04-07 16:46:33 -0700452 Deserializer<? extends IPacket> deserializer;
453 if (IPv4.PROTOCOL_DESERIALIZER_MAP.containsKey(this.protocol)) {
454 deserializer = IPv4.PROTOCOL_DESERIALIZER_MAP.get(this.protocol);
455 } else {
456 deserializer = Data.deserializer();
457 }
458 try {
459 this.payload = deserializer.deserialize(data, bb.position(),
460 bb.limit() - bb.position());
461 this.payload.setParent(this);
462 } catch (DeserializationException e) {
463 return this;
464 }
465
alshabibc4901cd2014-09-05 16:50:40 -0700466 return this;
467 }
468
469 /**
470 * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
471 * returns the corresponding 32 bit integer.
472 *
tom5f18cf32014-09-13 14:10:57 -0700473 * @param ipAddress ip address in string form
474 * @return int ip address value
alshabibc4901cd2014-09-05 16:50:40 -0700475 */
476 public static int toIPv4Address(final String ipAddress) {
477 if (ipAddress == null) {
478 throw new IllegalArgumentException("Specified IPv4 address must"
479 + "contain 4 sets of numerical digits separated by periods");
480 }
481 final String[] octets = ipAddress.split("\\.");
482 if (octets.length != 4) {
483 throw new IllegalArgumentException("Specified IPv4 address must"
484 + "contain 4 sets of numerical digits separated by periods");
485 }
486
487 int result = 0;
488 for (int i = 0; i < 4; ++i) {
Yuta HIGUCHIe5ca93b2014-10-23 09:49:00 -0700489 result |= Integer.parseInt(octets[i]) << (3 - i) * 8;
alshabibc4901cd2014-09-05 16:50:40 -0700490 }
491 return result;
492 }
493
494 /**
495 * Accepts an IPv4 address in a byte array and returns the corresponding
496 * 32-bit integer value.
497 *
tom5f18cf32014-09-13 14:10:57 -0700498 * @param ipAddress ip address in byte form
499 * @return int ip address value
alshabibc4901cd2014-09-05 16:50:40 -0700500 */
501 public static int toIPv4Address(final byte[] ipAddress) {
502 int ip = 0;
503 for (int i = 0; i < 4; i++) {
504 final int t = (ipAddress[i] & 0xff) << (3 - i) * 8;
505 ip |= t;
506 }
507 return ip;
508 }
509
510 /**
511 * Accepts an IPv4 address and returns of string of the form xxx.xxx.xxx.xxx,
512 * e.g., 192.168.0.1.
513 *
tom5f18cf32014-09-13 14:10:57 -0700514 * @param ipAddress ip address in form
515 * @return string form of ip address
alshabibc4901cd2014-09-05 16:50:40 -0700516 */
517 public static String fromIPv4Address(final int ipAddress) {
518 final StringBuffer sb = new StringBuffer();
519 int result = 0;
520 for (int i = 0; i < 4; ++i) {
521 result = ipAddress >> (3 - i) * 8 & 0xff;
Yuta HIGUCHIe5ca93b2014-10-23 09:49:00 -0700522 sb.append(result);
alshabib638dc712014-09-05 18:03:45 -0700523 if (i != 3) {
524 sb.append(".");
525 }
alshabibc4901cd2014-09-05 16:50:40 -0700526 }
527 return sb.toString();
528 }
529
530 /**
531 * Accepts a collection of IPv4 addresses as integers and returns a single
532 * String useful in toString method's containing collections of IP
533 * addresses.
534 *
535 * @param ipAddresses
536 * collection
tom5f18cf32014-09-13 14:10:57 -0700537 * @return ip addresses in comma-separated string form
alshabibc4901cd2014-09-05 16:50:40 -0700538 */
539 public static String fromIPv4AddressCollection(
540 final Collection<Integer> ipAddresses) {
541 if (ipAddresses == null) {
542 return "null";
543 }
544 final StringBuffer sb = new StringBuffer();
545 sb.append("[");
546 for (final Integer ip : ipAddresses) {
547 sb.append(IPv4.fromIPv4Address(ip));
548 sb.append(",");
549 }
550 sb.replace(sb.length() - 1, sb.length(), "]");
551 return sb.toString();
552 }
553
554 /**
555 * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
556 * returns the corresponding byte array.
557 *
558 * @param ipAddress
559 * The IP address in the form xx.xxx.xxx.xxx.
560 * @return The IP address separated into bytes
561 */
562 public static byte[] toIPv4AddressBytes(final String ipAddress) {
563 final String[] octets = ipAddress.split("\\.");
564 if (octets.length != 4) {
565 throw new IllegalArgumentException("Specified IPv4 address must"
566 + "contain 4 sets of numerical digits separated by periods");
567 }
568
569 final byte[] result = new byte[4];
570 for (int i = 0; i < 4; ++i) {
571 result[i] = Integer.valueOf(octets[i]).byteValue();
572 }
573 return result;
574 }
575
576 /**
577 * Accepts an IPv4 address in the form of an integer and returns the
578 * corresponding byte array.
579 *
580 * @param ipAddress
581 * The IP address as an integer.
582 * @return The IP address separated into bytes.
583 */
584 public static byte[] toIPv4AddressBytes(final int ipAddress) {
585 return new byte[] {(byte) (ipAddress >>> 24),
586 (byte) (ipAddress >>> 16), (byte) (ipAddress >>> 8),
587 (byte) ipAddress};
588 }
589
590 /*
591 * (non-Javadoc)
592 *
593 * @see java.lang.Object#hashCode()
594 */
595 @Override
596 public int hashCode() {
597 final int prime = 2521;
598 int result = super.hashCode();
599 result = prime * result + this.checksum;
600 result = prime * result + this.destinationAddress;
601 result = prime * result + this.diffServ;
602 result = prime * result + this.flags;
603 result = prime * result + this.fragmentOffset;
604 result = prime * result + this.headerLength;
605 result = prime * result + this.identification;
606 result = prime * result + Arrays.hashCode(this.options);
607 result = prime * result + this.protocol;
608 result = prime * result + this.sourceAddress;
609 result = prime * result + this.totalLength;
610 result = prime * result + this.ttl;
611 result = prime * result + this.version;
612 return result;
613 }
614
615 /*
616 * (non-Javadoc)
617 *
618 * @see java.lang.Object#equals(java.lang.Object)
619 */
620 @Override
621 public boolean equals(final Object obj) {
622 if (this == obj) {
623 return true;
624 }
625 if (!super.equals(obj)) {
626 return false;
627 }
628 if (!(obj instanceof IPv4)) {
629 return false;
630 }
631 final IPv4 other = (IPv4) obj;
632 if (this.checksum != other.checksum) {
633 return false;
634 }
635 if (this.destinationAddress != other.destinationAddress) {
636 return false;
637 }
638 if (this.diffServ != other.diffServ) {
639 return false;
640 }
641 if (this.flags != other.flags) {
642 return false;
643 }
644 if (this.fragmentOffset != other.fragmentOffset) {
645 return false;
646 }
647 if (this.headerLength != other.headerLength) {
648 return false;
649 }
650 if (this.identification != other.identification) {
651 return false;
652 }
653 if (!Arrays.equals(this.options, other.options)) {
654 return false;
655 }
656 if (this.protocol != other.protocol) {
657 return false;
658 }
659 if (this.sourceAddress != other.sourceAddress) {
660 return false;
661 }
662 if (this.totalLength != other.totalLength) {
663 return false;
664 }
665 if (this.ttl != other.ttl) {
666 return false;
667 }
668 if (this.version != other.version) {
669 return false;
670 }
671 return true;
672 }
Jonathan Hart2a655752015-04-07 16:46:33 -0700673
674 /**
675 * Deserializer function for IPv4 packets.
676 *
677 * @return deserializer function
678 */
679 public static Deserializer<IPv4> deserializer() {
680 return (data, offset, length) -> {
681 checkInput(data, offset, length, HEADER_LENGTH);
682
683 IPv4 ipv4 = new IPv4();
684
685 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
686
687 byte versionByte = bb.get();
688 ipv4.headerLength = (byte) (versionByte & 0xf);
689 ipv4.setVersion((byte) (versionByte >> 4 & 0xf));
690 ipv4.setDiffServ(bb.get());
691 ipv4.totalLength = bb.getShort();
692 ipv4.identification = bb.getShort();
693 short flagsFragment = bb.getShort();
694 ipv4.flags = (byte) (flagsFragment >> 13 & 0x7);
695 ipv4.fragmentOffset = (short) (flagsFragment & 0x1fff);
696 ipv4.ttl = bb.get();
697 ipv4.protocol = bb.get();
698 ipv4.checksum = bb.getShort();
699 ipv4.sourceAddress = bb.getInt();
700 ipv4.destinationAddress = bb.getInt();
701
702 if (ipv4.headerLength > 5) {
703 checkHeaderLength(length, ipv4.headerLength * 4);
704
705 int optionsLength = (ipv4.headerLength - 5) * 4;
706 ipv4.options = new byte[optionsLength];
707 bb.get(ipv4.options);
708 }
709
710 Deserializer<? extends IPacket> deserializer;
711 if (IPv4.PROTOCOL_DESERIALIZER_MAP.containsKey(ipv4.protocol)) {
712 deserializer = IPv4.PROTOCOL_DESERIALIZER_MAP.get(ipv4.protocol);
713 } else {
714 deserializer = Data.deserializer();
715 }
716 ipv4.payload = deserializer.deserialize(data, bb.position(),
717 bb.limit() - bb.position());
718 ipv4.payload.setParent(ipv4);
719
720 if (ipv4.totalLength != length) {
721 ipv4.isTruncated = true;
722 } else {
723 ipv4.isTruncated = false;
724 }
725
726 return ipv4;
727 };
728 }
alshabibc4901cd2014-09-05 16:50:40 -0700729}