@Override protected int calcLength() { int len = 0; for (IpV6NeighborDiscoveryOption o : options) { len += o.length(); } return len + OPTIONS_OFFSET; }
private IcmpV6NeighborAdvertisementHeader(byte[] rawData, int offset, int length) throws IllegalRawDataException { if (length < OPTIONS_OFFSET) { StringBuilder sb = new StringBuilder(120); sb.append("The raw data must be more than ") .append(OPTIONS_OFFSET - 1) .append("bytes") .append(" to build this header. raw data: ") .append(ByteArrays.toHexString(rawData, " ")) .append(", offset: ") .append(offset) .append(", length: ") .append(length); throw new IllegalRawDataException(sb.toString()); } int tmp = ByteArrays.getInt(rawData, R_S_O_RESERVED_OFFSET + offset); this.routerFlag = (tmp & 0x80000000) != 0; this.solicitedFlag = (tmp & 0x40000000) != 0; this.overrideFlag = (tmp & 0x20000000) != 0; this.reserved = 0x1FFFFFFF & tmp; this.targetAddress = ByteArrays.getInet6Address(rawData, TARGET_ADDRESS_OFFSET + offset); this.options = new ArrayList<IpV6NeighborDiscoveryOption>(); int currentOffsetInHeader = OPTIONS_OFFSET; while (currentOffsetInHeader < length) { IpV6NeighborDiscoveryOptionType type = IpV6NeighborDiscoveryOptionType.getInstance(rawData[currentOffsetInHeader + offset]); IpV6NeighborDiscoveryOption newOne; try { newOne = PacketFactories.getFactory( IpV6NeighborDiscoveryOption.class, IpV6NeighborDiscoveryOptionType.class) .newInstance( rawData, currentOffsetInHeader + offset, length - currentOffsetInHeader, type); } catch (Exception e) { break; } options.add(newOne); currentOffsetInHeader += newOne.length(); } }