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:
parent
b5cd28aec9
commit
8b1f9c1772
2 changed files with 36 additions and 19 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue