DHCPv6 addr reg: build an IA Address option inside Dhcp6AddrRegInform.

Flag: EXEMPT guarded by an legacy experiment flag
Bug: 293393743
Test: TH
Change-Id: Ia16ba2b5ca9af3810506548085c995eed172b772
This commit is contained in:
Xiao Ma 2025-06-05 19:32:33 +09:00
commit 8b1f9c1772
2 changed files with 36 additions and 19 deletions

View file

@ -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;

View file

@ -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.
*/