diff --git a/staticlibs/device/com/android/net/module/util/dhcp6/Dhcp6AddrRegInformPacket.java b/staticlibs/device/com/android/net/module/util/dhcp6/Dhcp6AddrRegInformPacket.java index 265c41ffa8..6cf1ea1f9e 100644 --- a/staticlibs/device/com/android/net/module/util/dhcp6/Dhcp6AddrRegInformPacket.java +++ b/staticlibs/device/com/android/net/module/util/dhcp6/Dhcp6AddrRegInformPacket.java @@ -20,6 +20,9 @@ import static com.android.net.module.util.NetworkStackConstants.DHCP_MAX_LENGTH; import androidx.annotation.NonNull; +import com.android.net.module.util.structs.IaAddressOption; + +import java.net.Inet6Address; import java.nio.ByteBuffer; /** @@ -29,13 +32,20 @@ import java.nio.ByteBuffer; * https://www.rfc-editor.org/rfc/rfc9686.html#section-4.2 */ public class Dhcp6AddrRegInformPacket extends Dhcp6Packet { + @NonNull + public final Inet6Address mIaAddress; + public final long mPreferred; + public final long mValid; + /** * Generates a ADDR-REG-INFORM packet with the specified parameters. */ Dhcp6AddrRegInformPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid, - @NonNull final byte[] iaAddress) { + @NonNull final Inet6Address iaAddress, long preferred, long valid) { super(transId, elapsedTime, clientDuid, null /* serverDuid */, null /* iapd */); mIaAddress = iaAddress; + mPreferred = preferred; + mValid = valid; } /** @@ -48,7 +58,9 @@ public class Dhcp6AddrRegInformPacket extends Dhcp6Packet { addTlv(packet, DHCP6_CLIENT_IDENTIFIER, mClientDuid); addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF)); - addTlv(packet, DHCP6_IA_ADDR, mIaAddress); + final ByteBuffer iaAddressOption = IaAddressOption.build( + (short) IaAddressOption.LENGTH, mIaAddress, mPreferred, mValid); + addTlv(packet, iaAddressOption); packet.flip(); return packet; diff --git a/staticlibs/device/com/android/net/module/util/dhcp6/Dhcp6Packet.java b/staticlibs/device/com/android/net/module/util/dhcp6/Dhcp6Packet.java index d93c1a2071..8447c8d3c8 100644 --- a/staticlibs/device/com/android/net/module/util/dhcp6/Dhcp6Packet.java +++ b/staticlibs/device/com/android/net/module/util/dhcp6/Dhcp6Packet.java @@ -28,6 +28,9 @@ import com.android.net.module.util.Struct; import com.android.net.module.util.structs.IaPdOption; import com.android.net.module.util.structs.IaPrefixOption; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -88,8 +91,6 @@ public class Dhcp6Packet { * DHCPv6 Optional Type: IA Address option. */ public static final byte DHCP6_IA_ADDR = 5; - @Nullable - protected byte[] mIaAddress; /** * DHCPv6 Optional Type: Option Request Option. @@ -212,14 +213,6 @@ public class Dhcp6Packet { return mServerDuid; } - /** - * Returns the IA Address option. - */ - @Nullable - public byte[] getIaAddress() { - return mIaAddress; - } - /** * Returns the SOL_MAX_RT option value in milliseconds. */ @@ -473,7 +466,9 @@ public class Dhcp6Packet { private static Dhcp6Packet decode(@NonNull final ByteBuffer packet) throws ParseException { int elapsedTime = 0; byte[] iapd = null; - byte[] iaAddress = null; + Inet6Address iaAddress = null; + long preferred = 0; + long valid = 0; byte[] serverDuid = null; byte[] clientDuid = null; short statusCode = STATUS_SUCCESS; @@ -549,10 +544,10 @@ public class Dhcp6Packet { expectedLen = optionLen; final byte[] iaAddressBytes = new byte[16]; packet.get(iaAddressBytes, 0 /* offset */, 16); - iaAddress = iaAddressBytes; - // TODO: support parsing preferred and valid lifetime. - packet.getInt(); // preferred lifetime - packet.getInt(); // valid lifetime + // UnknownHostException will be thrown if host address is not determined. + iaAddress = (Inet6Address) InetAddress.getByAddress(iaAddressBytes); + preferred = packet.getInt(); + valid = packet.getInt(); // IAaddr-options are currently unsupported, skip over them. final int remainingBytesLength = optionLen - 16 - 8; if (remainingBytesLength > 0) { @@ -578,7 +573,7 @@ public class Dhcp6Packet { "Invalid length " + optionLen + " for option " + optionType + ", expected " + expectedLen); } - } catch (BufferUnderflowException e) { + } catch (BufferUnderflowException | UnknownHostException e) { throw new ParseException(e.getMessage()); } } @@ -609,8 +604,11 @@ public class Dhcp6Packet { newPacket = new Dhcp6RebindPacket(transId, elapsedTime, clientDuid, iapd); break; case DHCP6_MESSAGE_TYPE_ADDR_REG_INFORM: + if (iaAddress == null) { + throw new ParseException("IA Address option isn't present in ADDR_REG_INFORM"); + } newPacket = new Dhcp6AddrRegInformPacket(transId, elapsedTime, clientDuid, - iaAddress); + iaAddress, preferred, valid); break; default: throw new ParseException("Unimplemented DHCP6 message type %d" + messageType); @@ -728,6 +726,13 @@ public class Dhcp6Packet { buf.putShort((short) 0); } + /** + * Adds an optional parameter containing a complete option (type, length, value). + */ + protected static void addTlv(ByteBuffer buf, ByteBuffer option) { + buf.put(option); + } + /** * Builds a DHCPv6 SOLICIT packet from the required specified parameters. */