diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmId.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmId.java new file mode 100644 index 0000000000000000000000000000000000000000..bdcdcd8ae4310f7b7fa7f3f9d484ebbe522c32b6 --- /dev/null +++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmId.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.net.module.util.netlink.xfrm; + +import androidx.annotation.NonNull; + +import com.android.net.module.util.Struct; + +import java.net.InetAddress; + +/** + * Struct xfrm_id + * + * <p>see include/uapi/linux/xfrm.h + * + * <pre> + * struct xfrm_id { + * xfrm_address_t daddr; + * __be32 spi; + * __u8 proto; + * }; + * </pre> + * + * @hide + */ +public class StructXfrmId extends Struct { + public static final int STRUCT_SIZE = 24; + + @Field(order = 0, type = Type.ByteArray, arraysize = 16) + public final byte[] nestedStructDAddr; + + @Field(order = 1, type = Type.UBE32) + public final long spi; + + @Field(order = 2, type = Type.U8, padding = 3) + public final short proto; + + @Computed private final StructXfrmAddressT mDestXfrmAddressT; + + // Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work + public StructXfrmId(@NonNull final byte[] nestedStructDAddr, long spi, short proto) { + this.nestedStructDAddr = nestedStructDAddr.clone(); + this.spi = spi; + this.proto = proto; + + mDestXfrmAddressT = new StructXfrmAddressT(this.nestedStructDAddr); + } + + // Constructor to build a new message + public StructXfrmId(@NonNull final InetAddress destAddress, long spi, short proto) { + this(new StructXfrmAddressT(destAddress).writeToBytes(), spi, proto); + } + + /** Return the destination address */ + public InetAddress getDestAddress(int family) { + return mDestXfrmAddressT.getAddress(family); + } +} diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmSelector.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmSelector.java new file mode 100644 index 0000000000000000000000000000000000000000..7bd2ca1d2541ddc02830eec9534fab662f7a3c52 --- /dev/null +++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmSelector.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.net.module.util.netlink.xfrm; + +import androidx.annotation.NonNull; + +import com.android.net.module.util.Struct; +import com.android.net.module.util.Struct.Field; +import com.android.net.module.util.Struct.Type; + +/** + * Struct xfrm_selector + * + * <p>see include/uapi/linux/xfrm.h + * + * <pre> + * struct xfrm_selector { + * xfrm_address_t daddr; + * xfrm_address_t saddr; + * __be16 dport; + * __be16 dport_mask; + * __be16 sport; + * __be16 sport_mask; + * __u16 family; + * __u8 prefixlen_d; + * __u8 prefixlen_s; + * __u8 proto; + * int ifindex; + * __kernel_uid32_t user; + * }; + * </pre> + * + * @hide + */ +public class StructXfrmSelector extends Struct { + public static final int STRUCT_SIZE = 56; + + @Field(order = 0, type = Type.ByteArray, arraysize = 16) + public final byte[] nestedStructDAddr; + + @Field(order = 1, type = Type.ByteArray, arraysize = 16) + public final byte[] nestedStructSAddr; + + @Field(order = 2, type = Type.UBE16) + public final int dPort; + + @Field(order = 3, type = Type.UBE16) + public final int dPortMask; + + @Field(order = 4, type = Type.UBE16) + public final int sPort; + + @Field(order = 5, type = Type.UBE16) + public final int sPortMask; + + @Field(order = 6, type = Type.U16) + public final int selectorFamily; + + @Field(order = 7, type = Type.U8, padding = 1) + public final short prefixlenD; + + @Field(order = 8, type = Type.U8, padding = 1) + public final short prefixlenS; + + @Field(order = 9, type = Type.U8, padding = 1) + public final short proto; + + @Field(order = 10, type = Type.S32) + public final int ifIndex; + + @Field(order = 11, type = Type.S32) + public final int user; + + // Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work + public StructXfrmSelector( + @NonNull final byte[] nestedStructDAddr, + @NonNull final byte[] nestedStructSAddr, + int dPort, + int dPortMask, + int sPort, + int sPortMask, + int selectorFamily, + short prefixlenD, + short prefixlenS, + short proto, + int ifIndex, + int user) { + this.nestedStructDAddr = nestedStructDAddr.clone(); + this.nestedStructSAddr = nestedStructSAddr.clone(); + this.dPort = dPort; + this.dPortMask = dPortMask; + this.sPort = sPort; + this.sPortMask = sPortMask; + this.selectorFamily = selectorFamily; + this.prefixlenD = prefixlenD; + this.prefixlenS = prefixlenS; + this.proto = proto; + this.ifIndex = ifIndex; + this.user = user; + } + + // Constructor to build a new message + public StructXfrmSelector(int selectorFamily) { + this( + new byte[StructXfrmAddressT.STRUCT_SIZE], + new byte[StructXfrmAddressT.STRUCT_SIZE], + 0 /* dPort */, + 0 /* dPortMask */, + 0 /* sPort */, + 0 /* sPortMask */, + selectorFamily, + (short) 0 /* prefixlenD */, + (short) 0 /* prefixlenS */, + (short) 0 /* proto */, + 0 /* ifIndex */, + 0 /* user */); + } +} diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmIdTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmIdTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c9741cfacfb3603a61cb91e7440fd6050f2fd2cf --- /dev/null +++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmIdTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.net.module.util.netlink.xfrm; + +import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.IPPROTO_ESP; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import android.net.InetAddresses; +import android.system.OsConstants; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.net.module.util.HexDump; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class StructXfrmIdTest { + private static final String EXPECTED_HEX_STRING = + "C0000201000000000000000000000000" + "53FA0FDD32000000"; + private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING); + private static final InetAddress DEST_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1"); + private static final long SPI = 0x53fa0fdd; + private static final short PROTO = IPPROTO_ESP; + + @Test + public void testEncode() throws Exception { + final StructXfrmId struct = new StructXfrmId(DEST_ADDRESS, SPI, PROTO); + + final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length); + buffer.order(ByteOrder.nativeOrder()); + struct.writeToByteBuffer(buffer); + + assertArrayEquals(EXPECTED_HEX, buffer.array()); + } + + @Test + public void testDecode() throws Exception { + final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX); + buffer.order(ByteOrder.nativeOrder()); + final StructXfrmId struct = StructXfrmId.parse(StructXfrmId.class, buffer); + + assertEquals(DEST_ADDRESS, struct.getDestAddress(OsConstants.AF_INET)); + assertEquals(SPI, struct.spi); + assertEquals(PROTO, struct.proto); + } +} diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmSelectorTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmSelectorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..99f3b2a0ec65abb60f734821a5adb2b1e280b89d --- /dev/null +++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmSelectorTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.net.module.util.netlink.xfrm; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import android.system.OsConstants; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.net.module.util.HexDump; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class StructXfrmSelectorTest { + private static final String EXPECTED_HEX_STRING = + "00000000000000000000000000000000" + + "00000000000000000000000000000000" + + "00000000000000000200000000000000" + + "0000000000000000"; + private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING); + + private static final byte[] XFRM_ADDRESS_T_ANY_BYTES = new byte[16]; + private static final int FAMILY = OsConstants.AF_INET; + + @Test + public void testEncode() throws Exception { + final StructXfrmSelector struct = new StructXfrmSelector(FAMILY); + + final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length); + buffer.order(ByteOrder.nativeOrder()); + struct.writeToByteBuffer(buffer); + + assertArrayEquals(EXPECTED_HEX, buffer.array()); + } + + @Test + public void testDecode() throws Exception { + final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX); + buffer.order(ByteOrder.nativeOrder()); + final StructXfrmSelector struct = + StructXfrmSelector.parse(StructXfrmSelector.class, buffer); + + assertArrayEquals(XFRM_ADDRESS_T_ANY_BYTES, struct.nestedStructDAddr); + assertArrayEquals(XFRM_ADDRESS_T_ANY_BYTES, struct.nestedStructSAddr); + assertEquals(0, struct.dPort); + assertEquals(0, struct.dPortMask); + assertEquals(0, struct.sPort); + assertEquals(0, struct.sPortMask); + assertEquals(FAMILY, struct.selectorFamily); + assertEquals(0, struct.prefixlenD); + assertEquals(0, struct.prefixlenS); + assertEquals(0, struct.proto); + assertEquals(0, struct.ifIndex); + assertEquals(0, struct.user); + } +}