diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index 0bcb757..6325b46 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -96,12 +96,17 @@
     srcs: [
     "framework/**/DnsPacket.java",
     "framework/**/DnsPacketUtils.java",
+    "framework/**/DnsSvcbPacket.java",
+    "framework/**/DnsSvcbRecord.java",
+    "framework/**/HexDump.java",
+    "framework/**/NetworkStackConstants.java",
     ],
     sdk_version: "module_current",
     visibility: [
         "//packages/services/Iwlan:__subpackages__",
     ],
     libs: [
+        "androidx.annotation_annotation",
         "framework-annotations-lib",
         "framework-connectivity.stubs.module_lib",
     ],
diff --git a/staticlibs/framework/com/android/net/module/util/DnsPacket.java b/staticlibs/framework/com/android/net/module/util/DnsPacket.java
index 0dcdf1e..63106a1 100644
--- a/staticlibs/framework/com/android/net/module/util/DnsPacket.java
+++ b/staticlibs/framework/com/android/net/module/util/DnsPacket.java
@@ -56,6 +56,7 @@
      */
     // TODO: Define the constant as a public constant in DnsResolver since it can never change.
     private static final int TYPE_CNAME = 5;
+    public static final int TYPE_SVCB = 64;
 
     /**
      * Thrown when parsing packet failed.
@@ -282,7 +283,7 @@
          * @param buf ByteBuffer input of record, must be in network byte order
          *         (which is the default).
          */
-        private DnsRecord(@RecordType int rType, @NonNull ByteBuffer buf)
+        protected DnsRecord(@RecordType int rType, @NonNull ByteBuffer buf)
                 throws BufferUnderflowException, ParseException {
             Objects.requireNonNull(buf);
             this.rType = rType;
@@ -326,6 +327,8 @@
             // Return a DnsRecord instance by default for backward compatibility, this is useful
             // when a partner supports new type of DnsRecord but does not inherit DnsRecord.
             switch (nsType) {
+                case TYPE_SVCB:
+                    return new DnsSvcbRecord(rType, buf);
                 default:
                     return new DnsRecord(rType, buf);
             }
diff --git a/staticlibs/framework/com/android/net/module/util/DnsSvcbPacket.java b/staticlibs/framework/com/android/net/module/util/DnsSvcbPacket.java
new file mode 100644
index 0000000..c7ed3e6
--- /dev/null
+++ b/staticlibs/framework/com/android/net/module/util/DnsSvcbPacket.java
@@ -0,0 +1,182 @@
+/*
+ * 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;
+
+import static android.net.DnsResolver.TYPE_A;
+import static android.net.DnsResolver.TYPE_AAAA;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * A class for a DNS SVCB response packet.
+ *
+ * @hide
+ */
+public class DnsSvcbPacket extends DnsPacket {
+    public static final int TYPE_SVCB = 64;
+
+    private static final String TAG = DnsSvcbPacket.class.getSimpleName();
+
+    /**
+     * Creates a DnsSvcbPacket object from the given wire-format DNS packet.
+     */
+    private DnsSvcbPacket(@NonNull byte[] data) throws DnsPacket.ParseException {
+        // If data is null, ParseException will be thrown.
+        super(data);
+
+        final int questions = mHeader.getRecordCount(QDSECTION);
+        if (questions != 1) {
+            throw new DnsPacket.ParseException("Unexpected question count " + questions);
+        }
+        final int nsType = mRecords[QDSECTION].get(0).nsType;
+        if (nsType != TYPE_SVCB) {
+            throw new DnsPacket.ParseException("Unexpected query type " + nsType);
+        }
+    }
+
+    /**
+     * Returns true if the DnsSvcbPacket is a DNS response.
+     */
+    public boolean isResponse() {
+        return mHeader.isResponse();
+    }
+
+    /**
+     * Returns whether the given protocol alpn is supported.
+     */
+    public boolean isSupported(@NonNull String alpn) {
+        return findSvcbRecord(alpn) != null;
+    }
+
+    /**
+     * Returns the TargetName associated with the given protocol alpn.
+     * If the alpn is not supported, a null is returned.
+     */
+    @Nullable
+    public String getTargetName(@NonNull String alpn) {
+        final DnsSvcbRecord record = findSvcbRecord(alpn);
+        return (record != null) ? record.getTargetName() : null;
+    }
+
+    /**
+     * Returns the TargetName that associated with the given protocol alpn.
+     * If the alpn is not supported, -1 is returned.
+     */
+    public int getPort(@NonNull String alpn) {
+        final DnsSvcbRecord record = findSvcbRecord(alpn);
+        return (record != null) ? record.getPort() : -1;
+    }
+
+    /**
+     * Returns the IP addresses that support the given protocol alpn.
+     * If the alpn is not supported, an empty list is returned.
+     */
+    @NonNull
+    public List<InetAddress> getAddresses(@NonNull String alpn) {
+        final DnsSvcbRecord record = findSvcbRecord(alpn);
+        if (record == null) return Collections.EMPTY_LIST;
+
+        // As per draft-ietf-dnsop-svcb-https-10#section-7.4 and draft-ietf-add-ddr-10#section-4,
+        // if A/AAAA records are available in the Additional section, use the IP addresses in
+        // those records instead of the IP addresses in ipv4hint/ipv6hint.
+        final List<InetAddress> out = getAddressesFromAdditionalSection();
+        if (out.size() > 0) return out;
+
+        return record.getAddresses();
+    }
+
+    /**
+     * Returns the value of SVCB key dohpath that associated with the given protocol alpn.
+     * If the alpn is not supported, a null is returned.
+     */
+    @Nullable
+    public String getDohPath(@NonNull String alpn) {
+        final DnsSvcbRecord record = findSvcbRecord(alpn);
+        return (record != null) ? record.getDohPath() : null;
+    }
+
+    /**
+     * Returns the DnsSvcbRecord associated with the given protocol alpn.
+     * If the alpn is not supported, a null is returned.
+     */
+    @Nullable
+    private DnsSvcbRecord findSvcbRecord(@NonNull String alpn) {
+        for (final DnsRecord record : mRecords[ANSECTION]) {
+            if (record instanceof DnsSvcbRecord) {
+                final DnsSvcbRecord svcbRecord = (DnsSvcbRecord) record;
+                if (svcbRecord.getAlpns().contains(alpn)) {
+                    return svcbRecord;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the IP addresses in additional section.
+     */
+    @NonNull
+    private List<InetAddress> getAddressesFromAdditionalSection() {
+        final List<InetAddress> out = new ArrayList<InetAddress>();
+        if (mHeader.getRecordCount(ARSECTION) == 0) {
+            return out;
+        }
+        for (final DnsRecord record : mRecords[ARSECTION]) {
+            if (record.nsType != TYPE_A && record.nsType != TYPE_AAAA) {
+                Log.d(TAG, "Found type other than A/AAAA in Additional section: " + record.nsType);
+                continue;
+            }
+            try {
+                out.add(InetAddress.getByAddress(record.getRR()));
+            } catch (UnknownHostException e) {
+                Log.w(TAG, "Failed to parse address");
+            }
+        }
+        return out;
+    }
+
+    @Override
+    public String toString() {
+        final StringJoiner out = new StringJoiner(" ");
+        out.add("QUERY: [" + TextUtils.join(", ", mRecords[QDSECTION]) + "]");
+        out.add("ANSWER: [" + TextUtils.join(", ", mRecords[ANSECTION]) + "]");
+        out.add("AUTHORITY: [" + TextUtils.join(", ", mRecords[NSSECTION]) + "]");
+        out.add("ADDITIONAL: [" + TextUtils.join(", ", mRecords[ARSECTION]) + "]");
+        return out.toString();
+    }
+
+    /**
+     * Creates a DnsSvcbPacket object from the given wire-format DNS answer.
+     */
+    public static DnsSvcbPacket fromResponse(@NonNull byte[] data) throws DnsPacket.ParseException {
+        DnsSvcbPacket out = new DnsSvcbPacket(data);
+        if (!out.isResponse()) {
+            throw new DnsPacket.ParseException("Not an answer packet");
+        }
+        return out;
+    }
+}
diff --git a/staticlibs/framework/com/android/net/module/util/DnsSvcbRecord.java b/staticlibs/framework/com/android/net/module/util/DnsSvcbRecord.java
new file mode 100644
index 0000000..669725c
--- /dev/null
+++ b/staticlibs/framework/com/android/net/module/util/DnsSvcbRecord.java
@@ -0,0 +1,516 @@
+/*
+ * 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;
+
+import static android.net.DnsResolver.CLASS_IN;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import static com.android.net.module.util.DnsPacket.ParseException;
+
+import android.annotation.NonNull;
+import android.text.TextUtils;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * A class for an SVCB record.
+ * https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml
+ * @hide
+ */
+@VisibleForTesting(visibility = PACKAGE)
+public final class DnsSvcbRecord extends DnsPacket.DnsRecord {
+    /**
+     * The following SvcParamKeys KEY_* are defined in
+     * https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml.
+     */
+
+    // The SvcParamKey "mandatory". The associated implementation of SvcParam is SvcParamMandatory.
+    private static final int KEY_MANDATORY = 0;
+
+    // The SvcParamKey "alpn". The associated implementation of SvcParam is SvcParamAlpn.
+    private static final int KEY_ALPN = 1;
+
+    // The SvcParamKey "no-default-alpn". The associated implementation of SvcParam is
+    // SvcParamNoDefaultAlpn.
+    private static final int KEY_NO_DEFAULT_ALPN = 2;
+
+    // The SvcParamKey "port". The associated implementation of SvcParam is SvcParamPort.
+    private static final int KEY_PORT = 3;
+
+    // The SvcParamKey "ipv4hint". The associated implementation of SvcParam is SvcParamIpv4Hint.
+    private static final int KEY_IPV4HINT = 4;
+
+    // The SvcParamKey "ech". The associated implementation of SvcParam is SvcParamEch.
+    private static final int KEY_ECH = 5;
+
+    // The SvcParamKey "ipv6hint". The associated implementation of SvcParam is SvcParamIpv6Hint.
+    private static final int KEY_IPV6HINT = 6;
+
+    // The SvcParamKey "dohpath". The associated implementation of SvcParam is SvcParamDohPath.
+    private static final int KEY_DOHPATH = 7;
+
+    // The minimal size of a SvcParam.
+    // https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-12.html#name-rdata-wire-format
+    private static final int MINSVCPARAMSIZE = 4;
+
+    private static final String TAG = DnsSvcbRecord.class.getSimpleName();
+
+    private final int mSvcPriority;
+
+    @NonNull
+    private final String mTargetName;
+
+    @NonNull
+    private final SparseArray<SvcParam> mAllSvcParams = new SparseArray<>();
+
+    @VisibleForTesting(visibility = PACKAGE)
+    public DnsSvcbRecord(@DnsPacket.RecordType int rType, @NonNull ByteBuffer buff)
+            throws IllegalStateException, ParseException {
+        super(rType, buff);
+        if (nsType != DnsPacket.TYPE_SVCB) {
+            throw new IllegalStateException("incorrect nsType: " + nsType);
+        }
+        if (nsClass != CLASS_IN) {
+            throw new ParseException("incorrect nsClass: " + nsClass);
+        }
+
+        // DNS Record in Question Section doesn't have Rdata.
+        if (rType == DnsPacket.QDSECTION) {
+            mSvcPriority = 0;
+            mTargetName = "";
+            return;
+        }
+
+        final byte[] rdata = getRR();
+        if (rdata == null) {
+            throw new ParseException("SVCB rdata is empty");
+        }
+
+        final ByteBuffer buf = ByteBuffer.wrap(rdata).asReadOnlyBuffer();
+        mSvcPriority = Short.toUnsignedInt(buf.getShort());
+        mTargetName = DnsPacketUtils.DnsRecordParser.parseName(buf, 0 /* Parse depth */,
+                false /* isNameCompressionSupported */);
+
+        if (mTargetName.length() > DnsPacket.DnsRecord.MAXNAMESIZE) {
+            throw new ParseException(
+                    "Failed to parse SVCB target name, name size is too long: "
+                            + mTargetName.length());
+        }
+        while (buf.remaining() >= MINSVCPARAMSIZE) {
+            final SvcParam svcParam = parseSvcParam(buf);
+            final int key = svcParam.getKey();
+            if (mAllSvcParams.get(key) != null) {
+                throw new ParseException("Invalid DnsSvcbRecord, key " + key + " is repeated");
+            }
+            mAllSvcParams.put(key, svcParam);
+        }
+        if (buf.hasRemaining()) {
+            throw new ParseException("Invalid DnsSvcbRecord. Got "
+                    + buf.remaining() + " remaining bytes after parsing");
+        }
+    }
+
+    /**
+     * Returns the TargetName.
+     */
+    @VisibleForTesting(visibility = PACKAGE)
+    @NonNull
+    public String getTargetName() {
+        return mTargetName;
+    }
+
+    /**
+     * Returns an unmodifiable list of alpns from SvcParam alpn.
+     */
+    @VisibleForTesting(visibility = PACKAGE)
+    @NonNull
+    public List<String> getAlpns() {
+        final SvcParamAlpn sp = (SvcParamAlpn) mAllSvcParams.get(KEY_ALPN);
+        final List<String> list = (sp != null) ? sp.getValue() : Collections.EMPTY_LIST;
+        return Collections.unmodifiableList(list);
+    }
+
+    /**
+     * Returns the port number from SvcParam port.
+     */
+    @VisibleForTesting(visibility = PACKAGE)
+    public int getPort() {
+        final SvcParamPort sp = (SvcParamPort) mAllSvcParams.get(KEY_PORT);
+        return (sp != null) ? sp.getValue() : -1;
+    }
+
+    /**
+     * Returns a list of the IP addresses from both of SvcParam ipv4hint and ipv6hint.
+     */
+    @VisibleForTesting(visibility = PACKAGE)
+    @NonNull
+    public List<InetAddress> getAddresses() {
+        final List<InetAddress> out = new ArrayList<>();
+        final SvcParamIpHint sp4 = (SvcParamIpHint) mAllSvcParams.get(KEY_IPV4HINT);
+        if (sp4 != null) {
+            out.addAll(sp4.getValue());
+        }
+        final SvcParamIpHint sp6 = (SvcParamIpHint) mAllSvcParams.get(KEY_IPV6HINT);
+        if (sp6 != null) {
+            out.addAll(sp6.getValue());
+        }
+        return out;
+    }
+
+    /**
+     * Returns the doh path from SvcParam dohPath.
+     */
+    @VisibleForTesting(visibility = PACKAGE)
+    @NonNull
+    public String getDohPath() {
+        final SvcParamDohPath sp = (SvcParamDohPath) mAllSvcParams.get(KEY_DOHPATH);
+        return (sp != null) ? sp.getValue() : "";
+    }
+
+    @Override
+    public String toString() {
+        if (rType == DnsPacket.QDSECTION) {
+            return dName + " IN SVCB";
+        }
+
+        final StringJoiner sj = new StringJoiner(" ");
+        for (int i = 0; i < mAllSvcParams.size(); i++) {
+            sj.add(mAllSvcParams.valueAt(i).toString());
+        }
+        return dName + " " + ttl + " IN SVCB " + mSvcPriority + " " + mTargetName + " "
+                + sj.toString();
+    }
+
+    private static SvcParam parseSvcParam(@NonNull ByteBuffer buf) throws ParseException {
+        try {
+            final int key = Short.toUnsignedInt(buf.getShort());
+            switch (key) {
+                case KEY_MANDATORY: return new SvcParamMandatory(buf);
+                case KEY_ALPN: return new SvcParamAlpn(buf);
+                case KEY_NO_DEFAULT_ALPN: return new SvcParamNoDefaultAlpn(buf);
+                case KEY_PORT: return new SvcParamPort(buf);
+                case KEY_IPV4HINT: return new SvcParamIpv4Hint(buf);
+                case KEY_ECH: return new SvcParamEch(buf);
+                case KEY_IPV6HINT: return new SvcParamIpv6Hint(buf);
+                case KEY_DOHPATH: return new SvcParamDohPath(buf);
+                default: return new SvcParamGeneric(key, buf);
+            }
+        } catch (BufferUnderflowException e) {
+            throw new ParseException("Malformed packet", e);
+        }
+    }
+
+    /**
+     * The base class for all SvcParam.
+     */
+    private abstract static class SvcParam {
+        private final int mKey;
+
+        SvcParam(int key) {
+            mKey = key;
+        }
+
+        int getKey() {
+            return mKey;
+        }
+    }
+
+    private static class SvcParamMandatory extends SvcParam {
+        private final short[] mValue;
+
+        private SvcParamMandatory(@NonNull ByteBuffer buf) throws BufferUnderflowException,
+                ParseException {
+            super(KEY_MANDATORY);
+            // The caller already read 2 bytes for SvcParamKey.
+            final int len = Short.toUnsignedInt(buf.getShort());
+            final ByteBuffer svcParamValue = sliceAndAdvance(buf, len);
+            mValue = SvcParamValueUtil.toShortArray(svcParamValue);
+            if (mValue.length == 0) {
+                throw new ParseException("mandatory value must be non-empty");
+            }
+        }
+
+        @Override
+        public String toString() {
+            final StringJoiner valueJoiner = new StringJoiner(",");
+            for (short key : mValue) {
+                valueJoiner.add(toKeyName(key));
+            }
+            return toKeyName(getKey()) + "=" + valueJoiner.toString();
+        }
+    }
+
+    private static class SvcParamAlpn extends SvcParam {
+        private final List<String> mValue;
+
+        SvcParamAlpn(@NonNull ByteBuffer buf) throws BufferUnderflowException, ParseException {
+            super(KEY_ALPN);
+            // The caller already read 2 bytes for SvcParamKey.
+            final int len = Short.toUnsignedInt(buf.getShort());
+            final ByteBuffer svcParamValue = sliceAndAdvance(buf, len);
+            mValue = SvcParamValueUtil.toStringList(svcParamValue);
+            if (mValue.isEmpty()) {
+                throw new ParseException("alpn value must be non-empty");
+            }
+        }
+
+        List<String> getValue() {
+            return Collections.unmodifiableList(mValue);
+        }
+
+        @Override
+        public String toString() {
+            return toKeyName(getKey()) + "=" + TextUtils.join(",", mValue);
+        }
+    }
+
+    private static class SvcParamNoDefaultAlpn extends SvcParam {
+        SvcParamNoDefaultAlpn(@NonNull ByteBuffer buf) throws BufferUnderflowException,
+                ParseException {
+            super(KEY_NO_DEFAULT_ALPN);
+            // The caller already read 2 bytes for SvcParamKey.
+            final int len = buf.getShort();
+            if (len != 0) {
+                throw new ParseException("no-default-alpn value must be empty");
+            }
+        }
+
+        @Override
+        public String toString() {
+            return toKeyName(getKey());
+        }
+    }
+
+    private static class SvcParamPort extends SvcParam {
+        private final int mValue;
+
+        SvcParamPort(@NonNull ByteBuffer buf) throws BufferUnderflowException, ParseException {
+            super(KEY_PORT);
+            // The caller already read 2 bytes for SvcParamKey.
+            final int len = buf.getShort();
+            if (len != Short.BYTES) {
+                throw new ParseException("key port len is not 2 but " + len);
+            }
+            mValue = Short.toUnsignedInt(buf.getShort());
+        }
+
+        int getValue() {
+            return mValue;
+        }
+
+        @Override
+        public String toString() {
+            return toKeyName(getKey()) + "=" + mValue;
+        }
+    }
+
+    private static class SvcParamIpHint extends SvcParam {
+        private final List<InetAddress> mValue;
+
+        private SvcParamIpHint(int key, @NonNull ByteBuffer buf, int addrLen) throws
+                BufferUnderflowException, ParseException {
+            super(key);
+            // The caller already read 2 bytes for SvcParamKey.
+            final int len = Short.toUnsignedInt(buf.getShort());
+            final ByteBuffer svcParamValue = sliceAndAdvance(buf, len);
+            mValue = SvcParamValueUtil.toInetAddressList(svcParamValue, addrLen);
+            if (mValue.isEmpty()) {
+                throw new ParseException(toKeyName(getKey()) + " value must be non-empty");
+            }
+        }
+
+        List<InetAddress> getValue() {
+            return Collections.unmodifiableList(mValue);
+        }
+
+        @Override
+        public String toString() {
+            final StringJoiner valueJoiner = new StringJoiner(",");
+            for (InetAddress ip : mValue) {
+                valueJoiner.add(ip.getHostAddress());
+            }
+            return toKeyName(getKey()) + "=" + valueJoiner.toString();
+        }
+    }
+
+    private static class SvcParamIpv4Hint extends SvcParamIpHint {
+        SvcParamIpv4Hint(@NonNull ByteBuffer buf) throws BufferUnderflowException, ParseException {
+            super(KEY_IPV4HINT, buf, NetworkStackConstants.IPV4_ADDR_LEN);
+        }
+    }
+
+    private static class SvcParamIpv6Hint extends SvcParamIpHint {
+        SvcParamIpv6Hint(@NonNull ByteBuffer buf) throws BufferUnderflowException, ParseException {
+            super(KEY_IPV6HINT, buf, NetworkStackConstants.IPV6_ADDR_LEN);
+        }
+    }
+
+    private static class SvcParamEch extends SvcParamGeneric {
+        SvcParamEch(@NonNull ByteBuffer buf) throws BufferUnderflowException, ParseException {
+            super(KEY_ECH, buf);
+        }
+    }
+
+    private static class SvcParamDohPath extends SvcParam {
+        private final String mValue;
+
+        SvcParamDohPath(@NonNull ByteBuffer buf) throws BufferUnderflowException, ParseException {
+            super(KEY_DOHPATH);
+            // The caller already read 2 bytes for SvcParamKey.
+            final int len = Short.toUnsignedInt(buf.getShort());
+            final byte[] value = new byte[len];
+            buf.get(value);
+            mValue = new String(value, StandardCharsets.UTF_8);
+        }
+
+        String getValue() {
+            return mValue;
+        }
+
+        @Override
+        public String toString() {
+            return toKeyName(getKey()) + "=" + mValue;
+        }
+    }
+
+    // For other unrecognized and unimplemented SvcParams, they are stored as SvcParamGeneric.
+    private static class SvcParamGeneric extends SvcParam {
+        private final byte[] mValue;
+
+        SvcParamGeneric(int key, @NonNull ByteBuffer buf) throws BufferUnderflowException,
+                ParseException {
+            super(key);
+            // The caller already read 2 bytes for SvcParamKey.
+            final int len = Short.toUnsignedInt(buf.getShort());
+            mValue = new byte[len];
+            buf.get(mValue);
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder out = new StringBuilder();
+            out.append(toKeyName(getKey()));
+            if (mValue != null && mValue.length > 0) {
+                out.append("=");
+                out.append(HexDump.toHexString(mValue));
+            }
+            return out.toString();
+        }
+    }
+
+    private static String toKeyName(int key) {
+        switch (key) {
+            case KEY_MANDATORY: return "mandatory";
+            case KEY_ALPN: return "alpn";
+            case KEY_NO_DEFAULT_ALPN: return "no-default-alpn";
+            case KEY_PORT: return "port";
+            case KEY_IPV4HINT: return "ipv4hint";
+            case KEY_ECH: return "ech";
+            case KEY_IPV6HINT: return "ipv6hint";
+            case KEY_DOHPATH: return "dohpath";
+            default: return "key" + key;
+        }
+    }
+
+    /**
+     * Returns a read-only ByteBuffer (with position = 0, limit = `length`, and capacity = `length`)
+     * sliced from `buf`'s current position, and moves the position of `buf` by `length`.
+     */
+    @VisibleForTesting(visibility = PRIVATE)
+    public static ByteBuffer sliceAndAdvance(@NonNull ByteBuffer buf, int length)
+            throws BufferUnderflowException {
+        if (buf.remaining() < length) {
+            throw new BufferUnderflowException();
+        }
+        final int pos = buf.position();
+
+        // `out` equals to `buf.slice(pos, length)` that is supported in API level 34.
+        final ByteBuffer out = ((ByteBuffer) buf.slice().limit(length)).slice();
+
+        buf.position(pos + length);
+        return out.asReadOnlyBuffer();
+    }
+
+    // A utility to convert the byte array of SvcParamValue to other types.
+    private static class SvcParamValueUtil {
+        // Refer to draft-ietf-dnsop-svcb-https-10#section-7.1 for the wire format of alpn.
+        @NonNull
+        private static List<String> toStringList(@NonNull ByteBuffer buf)
+                throws BufferUnderflowException, ParseException {
+            final List<String> out = new ArrayList<>();
+            while (buf.hasRemaining()) {
+                final int alpnLen = Byte.toUnsignedInt(buf.get());
+                if (alpnLen == 0) {
+                    throw new ParseException("alpn should not be an empty string");
+                }
+                final byte[] alpn = new byte[alpnLen];
+                buf.get(alpn);
+                out.add(new String(alpn, StandardCharsets.UTF_8));
+            }
+            return out;
+        }
+
+        // Refer to draft-ietf-dnsop-svcb-https-10#section-7.5 for the wire format of SvcParamKey
+        // "mandatory".
+        @NonNull
+        private static short[] toShortArray(@NonNull ByteBuffer buf)
+                throws BufferUnderflowException, ParseException {
+            if (buf.remaining() % Short.BYTES != 0) {
+                throw new ParseException("Can't parse whole byte array");
+            }
+            final ShortBuffer sb = buf.asShortBuffer();
+            final short[] out = new short[sb.remaining()];
+            sb.get(out);
+            return out;
+        }
+
+        // Refer to draft-ietf-dnsop-svcb-https-10#section-7.4 for the wire format of ipv4hint and
+        // ipv6hint.
+        @NonNull
+        private static List<InetAddress> toInetAddressList(@NonNull ByteBuffer buf, int addrLen)
+                throws BufferUnderflowException, ParseException {
+            if (buf.remaining() % addrLen != 0) {
+                throw new ParseException("Can't parse whole byte array");
+            }
+
+            final List<InetAddress> out = new ArrayList<>();
+            final byte[] addr = new byte[addrLen];
+            while (buf.remaining() >= addrLen) {
+                buf.get(addr);
+                try {
+                    out.add(InetAddress.getByAddress(addr));
+                } catch (UnknownHostException e) {
+                    throw new ParseException("Can't parse byte array as an IP address");
+                }
+            }
+            return out;
+        }
+    }
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/DnsPacketTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/DnsPacketTest.java
index 28e183a..88d9e1e 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/DnsPacketTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/DnsPacketTest.java
@@ -203,6 +203,30 @@
                 "test.com", CLASS_IN, 0 /* ttl */, "example.com"));
     }
 
+    /** Verifies that the type of implementation returned from DnsRecord#parse is correct */
+    @Test
+    public void testDnsRecordParse() throws IOException {
+        final byte[] svcbQuestionRecord = new byte[] {
+                0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00, /* Name */
+                0x00, 0x40, /* Type */
+                0x00, 0x01, /* Class */
+        };
+        assertTrue(DnsPacket.DnsRecord.parse(DnsPacket.QDSECTION,
+                ByteBuffer.wrap(svcbQuestionRecord)) instanceof DnsSvcbRecord);
+
+        final byte[] svcbAnswerRecord = new byte[] {
+                0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00, /* Name */
+                0x00, 0x40, /* Type */
+                0x00, 0x01, /* Class */
+                0x00, 0x00, 0x01, 0x2b, /* TTL */
+                0x00, 0x0b, /* Data length */
+                0x00, 0x01, /* SvcPriority */
+                0x03, 'd', 'o', 't', 0x03, 'c', 'o', 'm', 0x00, /* TargetName */
+        };
+        assertTrue(DnsPacket.DnsRecord.parse(DnsPacket.ANSECTION,
+                ByteBuffer.wrap(svcbAnswerRecord)) instanceof DnsSvcbRecord);
+    }
+
     /**
      * Verifies ttl/rData error handling when parsing
      * {@link DnsPacket.DnsRecord} from bytes.
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/DnsSvcbPacketTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/DnsSvcbPacketTest.java
new file mode 100644
index 0000000..6778f8a
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/DnsSvcbPacketTest.java
@@ -0,0 +1,606 @@
+/*
+ * 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;
+
+import static android.net.DnsResolver.CLASS_IN;
+import static android.net.DnsResolver.TYPE_A;
+import static android.net.DnsResolver.TYPE_AAAA;
+
+import static com.android.net.module.util.DnsPacket.TYPE_SVCB;
+import static com.android.testutils.MiscAsserts.assertThrows;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.NonNull;
+import android.net.InetAddresses;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class DnsSvcbPacketTest {
+    private static final short TEST_TRANSACTION_ID = 0x4321;
+    private static final byte[] TEST_DNS_RESPONSE_HEADER_FLAG =  new byte[] { (byte) 0x81, 0x00 };
+
+    // A common DNS SVCB Question section with Name = "_dns.resolver.arpa".
+    private static final byte[] TEST_DNS_SVCB_QUESTION_SECTION = new byte[] {
+            0x04, '_', 'd', 'n', 's', 0x08, 'r', 'e', 's', 'o', 'l', 'v', 'e', 'r',
+            0x04, 'a', 'r', 'p', 'a', 0x00, 0x00, 0x40, 0x00, 0x01,
+    };
+
+    // mandatory=ipv4hint,alpn,key333
+    private static final byte[] TEST_SVC_PARAM_MANDATORY = new byte[] {
+            0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x01, 0x01, 0x4d,
+    };
+
+    // alpn=doq
+    private static final byte[] TEST_SVC_PARAM_ALPN_DOQ = new byte[] {
+            0x00, 0x01, 0x00, 0x04, 0x03, 'd', 'o', 'q'
+    };
+
+    // alpn=h2,http/1.1
+    private static final byte[] TEST_SVC_PARAM_ALPN_HTTPS = new byte[] {
+            0x00, 0x01, 0x00, 0x0c, 0x02, 'h', '2',
+            0x08, 'h', 't', 't', 'p', '/', '1', '.', '1',
+    };
+
+    // no-default-alpn
+    private static final byte[] TEST_SVC_PARAM_NO_DEFAULT_ALPN = new byte[] {
+            0x00, 0x02, 0x00, 0x00,
+    };
+
+    // port=5353
+    private static final byte[] TEST_SVC_PARAM_PORT = new byte[] {
+            0x00, 0x03, 0x00, 0x02, 0x14, (byte) 0xe9,
+    };
+
+    // ipv4hint=1.2.3.4,6.7.8.9
+    private static final byte[] TEST_SVC_PARAM_IPV4HINT_1 = new byte[] {
+            0x00, 0x04, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08, 0x09,
+    };
+
+    // ipv4hint=4.3.2.1
+    private static final byte[] TEST_SVC_PARAM_IPV4HINT_2 = new byte[] {
+            0x00, 0x04, 0x00, 0x04, 0x04, 0x03, 0x02, 0x01,
+    };
+
+    // ech=aBcDe
+    private static final byte[] TEST_SVC_PARAM_ECH = new byte[] {
+            0x00, 0x05, 0x00, 0x05, 'a', 'B', 'c', 'D', 'e',
+    };
+
+    // ipv6hint=2001:db8::1
+    private static final byte[] TEST_SVC_PARAM_IPV6HINT = new byte[] {
+            0x00, 0x06, 0x00, 0x10, 0x20, 0x01, 0x0d, (byte) 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    };
+
+    // dohpath=/some-path{?dns}
+    private static final byte[] TEST_SVC_PARAM_DOHPATH = new byte[] {
+            0x00, 0x07, 0x00, 0x10,
+            '/', 's', 'o', 'm', 'e', '-', 'p', 'a', 't', 'h', '{', '?', 'd', 'n', 's', '}',
+    };
+
+    // key12345=1A2B0C
+    private static final byte[] TEST_SVC_PARAM_GENERIC_WITH_VALUE = new byte[] {
+            0x30, 0x39, 0x00, 0x03, 0x1a, 0x2b, 0x0c,
+    };
+
+    // key12346
+    private static final byte[] TEST_SVC_PARAM_GENERIC_WITHOUT_VALUE = new byte[] {
+            0x30, 0x3a, 0x00, 0x00,
+    };
+
+    private static byte[] makeDnsResponseHeaderAsByteArray(int qdcount, int ancount, int nscount,
+                int arcount) {
+        final ByteBuffer buffer = ByteBuffer.wrap(new byte[12]);
+        buffer.putShort(TEST_TRANSACTION_ID); /* Transaction ID */
+        buffer.put(TEST_DNS_RESPONSE_HEADER_FLAG); /* Flags */
+        buffer.putShort((short) qdcount);
+        buffer.putShort((short) ancount);
+        buffer.putShort((short) nscount);
+        buffer.putShort((short) arcount);
+        return buffer.array();
+    }
+
+    private static DnsSvcbRecord makeDnsSvcbRecordFromByteArray(@NonNull byte[] data)
+                throws IOException {
+        return new DnsSvcbRecord(DnsPacket.ANSECTION, ByteBuffer.wrap(data));
+    }
+
+    private static DnsSvcbRecord makeDnsSvcbRecordWithSingleSvcParam(@NonNull byte[] svcParam)
+            throws IOException {
+        return makeDnsSvcbRecordFromByteArray(new TestDnsRecordByteArrayBuilder()
+                .setRRType(TYPE_SVCB)
+                .setTargetName("test.com")
+                .addRdata(svcParam)
+                .build());
+    }
+
+    // Converts a Short to a byte array in big endian.
+    private static byte[] shortToByteArray(short value) {
+        return new byte[] { (byte) (value >> 8), (byte) value };
+    }
+
+    private static byte[] getRemainingByteArray(@NonNull ByteBuffer buffer) {
+        final byte[] out = new byte[buffer.remaining()];
+        buffer.get(out);
+        return out;
+    }
+
+    // A utility to make a DNS record as byte array.
+    private static class TestDnsRecordByteArrayBuilder {
+        private static final byte[] NAME_COMPRESSION_POINTER = new byte[] { (byte) 0xc0, 0x0c };
+
+        private final String mRRName = "dns.com";
+        private short mRRType = 0;
+        private final short mRRClass = CLASS_IN;
+        private final int mRRTtl = 10;
+        private int mRdataLen = 0;
+        private final ArrayList<byte[]> mRdata = new ArrayList<>();
+        private String mTargetName = null;
+        private short mSvcPriority = 1;
+        private boolean mNameCompression = false;
+
+        TestDnsRecordByteArrayBuilder setNameCompression(boolean value) {
+            mNameCompression = value;
+            return this;
+        }
+
+        TestDnsRecordByteArrayBuilder setRRType(int value) {
+            mRRType = (short) value;
+            return this;
+        }
+
+        TestDnsRecordByteArrayBuilder setTargetName(@NonNull String value) throws IOException {
+            mTargetName = value;
+            return this;
+        }
+
+        TestDnsRecordByteArrayBuilder setSvcPriority(int value) {
+            mSvcPriority = (short) value;
+            return this;
+        }
+
+        TestDnsRecordByteArrayBuilder addRdata(@NonNull byte[] value) {
+            mRdata.add(value);
+            mRdataLen += value.length;
+            return this;
+        }
+
+        byte[] build() throws IOException {
+            final ByteArrayOutputStream os = new ByteArrayOutputStream();
+            final byte[] name = mNameCompression ? NAME_COMPRESSION_POINTER
+                    : DnsPacketUtils.DnsRecordParser.domainNameToLabels(mRRName);
+            os.write(name);
+            os.write(shortToByteArray(mRRType));
+            os.write(shortToByteArray(mRRClass));
+            os.write(HexDump.toByteArray(mRRTtl));
+            if (mTargetName == null) {
+                os.write(shortToByteArray((short) mRdataLen));
+            } else {
+                final byte[] targetNameLabels =
+                                DnsPacketUtils.DnsRecordParser.domainNameToLabels(mTargetName);
+                mRdataLen += (Short.BYTES + targetNameLabels.length);
+                os.write(shortToByteArray((short) mRdataLen));
+                os.write(shortToByteArray(mSvcPriority));
+                os.write(targetNameLabels);
+            }
+            for (byte[] data : mRdata) {
+                os.write(data);
+            }
+            return os.toByteArray();
+        }
+    }
+
+    @Test
+    public void testSliceAndAdvance() throws Exception {
+        final ByteBuffer buffer = ByteBuffer.wrap(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9});
+        final ByteBuffer slice1 = DnsSvcbRecord.sliceAndAdvance(buffer, 3);
+        final ByteBuffer slice2 = DnsSvcbRecord.sliceAndAdvance(buffer, 4);
+        assertEquals(0, slice1.position());
+        assertEquals(3, slice1.capacity());
+        assertEquals(3, slice1.remaining());
+        assertTrue(slice1.isReadOnly());
+        assertArrayEquals(new byte[] {1, 2, 3}, getRemainingByteArray(slice1));
+        assertEquals(0, slice2.position());
+        assertEquals(4, slice2.capacity());
+        assertEquals(4, slice2.remaining());
+        assertTrue(slice2.isReadOnly());
+        assertArrayEquals(new byte[] {4, 5, 6, 7}, getRemainingByteArray(slice2));
+
+        // Nothing is read if out-of-bound access happens.
+        assertThrows(BufferUnderflowException.class,
+                () -> DnsSvcbRecord.sliceAndAdvance(buffer, 5));
+        assertEquals(7, buffer.position());
+        assertEquals(9, buffer.capacity());
+        assertEquals(2, buffer.remaining());
+        assertArrayEquals(new byte[] {8, 9}, getRemainingByteArray(buffer));
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamMandatory() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(TEST_SVC_PARAM_MANDATORY);
+        // Check the content returned from toString() for now because the getter function for
+        // this SvcParam hasn't been implemented.
+        // TODO(b/240259333): Consider adding DnsSvcbRecord.isMandatory(String alpn) when needed.
+        assertTrue(record.toString().contains("mandatory=ipv4hint,alpn,key333"));
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamAlpn() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(TEST_SVC_PARAM_ALPN_HTTPS);
+        assertEquals(Arrays.asList("h2", "http/1.1"), record.getAlpns());
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamNoDefaultAlpn() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(
+                TEST_SVC_PARAM_NO_DEFAULT_ALPN);
+        // Check the content returned from toString() for now because the getter function for
+        // this SvcParam hasn't been implemented.
+        // TODO(b/240259333): Consider adding DnsSvcbRecord.hasNoDefaultAlpn() when needed.
+        assertTrue(record.toString().contains("no-default-alpn"));
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamPort() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(TEST_SVC_PARAM_PORT);
+        assertEquals(5353, record.getPort());
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamIpv4Hint() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(TEST_SVC_PARAM_IPV4HINT_2);
+        assertEquals(Arrays.asList(InetAddresses.parseNumericAddress("4.3.2.1")),
+                record.getAddresses());
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamEch() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(TEST_SVC_PARAM_ECH);
+        // Check the content returned from toString() for now because the getter function for
+        // this SvcParam hasn't been implemented.
+        // TODO(b/240259333): Consider adding DnsSvcbRecord.getEch() when needed.
+        assertTrue(record.toString().contains("ech=6142634465"));
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamIpv6Hint() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(TEST_SVC_PARAM_IPV6HINT);
+        assertEquals(Arrays.asList(InetAddresses.parseNumericAddress("2001:db8::1")),
+                record.getAddresses());
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamDohPath() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(TEST_SVC_PARAM_DOHPATH);
+        assertEquals("/some-path{?dns}", record.getDohPath());
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamGeneric_withValue() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(
+                TEST_SVC_PARAM_GENERIC_WITH_VALUE);
+        // Check the content returned from toString() for now because the getter function for
+        // generic SvcParam hasn't been implemented.
+        // TODO(b/240259333): Consider adding DnsSvcbRecord.getValueFromGenericSvcParam(int key)
+        // when needed.
+        assertTrue(record.toString().contains("key12345=1A2B0C"));
+    }
+
+    @Test
+    public void testDnsSvcbRecord_svcParamGeneric_withoutValue() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordWithSingleSvcParam(
+                TEST_SVC_PARAM_GENERIC_WITHOUT_VALUE);
+        // Check the content returned from toString() for now because the getter function for
+        // generic SvcParam hasn't been implemented.
+        // TODO(b/240259333): Consider adding DnsSvcbRecord.getValueFromGenericSvcParam(int key)
+        // when needed.
+        assertTrue(record.toString().contains("key12346"));
+    }
+
+    @Test
+    public void testDnsSvcbRecord() throws Exception {
+        final DnsSvcbRecord record = makeDnsSvcbRecordFromByteArray(
+                new TestDnsRecordByteArrayBuilder()
+                .setRRType(TYPE_SVCB)
+                .setTargetName("doh.dns.com")
+                .addRdata(TEST_SVC_PARAM_ALPN_HTTPS)
+                .addRdata(TEST_SVC_PARAM_IPV4HINT_1)
+                .addRdata(TEST_SVC_PARAM_IPV6HINT)
+                .addRdata(TEST_SVC_PARAM_PORT)
+                .addRdata(TEST_SVC_PARAM_DOHPATH)
+                .build());
+        assertEquals("doh.dns.com", record.getTargetName());
+        assertEquals(Arrays.asList("h2", "http/1.1"), record.getAlpns());
+        assertEquals(5353, record.getPort());
+        assertEquals(Arrays.asList(
+                InetAddresses.parseNumericAddress("1.2.3.4"),
+                InetAddresses.parseNumericAddress("6.7.8.9"),
+                InetAddresses.parseNumericAddress("2001:db8::1")), record.getAddresses());
+        assertEquals("/some-path{?dns}", record.getDohPath());
+    }
+
+    @Test
+    public void testDnsSvcbRecord_createdFromNullObject() throws Exception {
+        assertThrows(NullPointerException.class, () -> makeDnsSvcbRecordFromByteArray(null));
+    }
+
+    @Test
+    public void testDnsSvcbRecord_invalidDnsRecord() throws Exception {
+        // The type is not SVCB.
+        final byte[] bytes1 = new TestDnsRecordByteArrayBuilder()
+                .setRRType(TYPE_A)
+                .addRdata(InetAddresses.parseNumericAddress("1.2.3.4").getAddress())
+                .build();
+        assertThrows(IllegalStateException.class, () -> makeDnsSvcbRecordFromByteArray(bytes1));
+
+        // TargetName is missing.
+        final byte[] bytes2 = new TestDnsRecordByteArrayBuilder()
+                .setRRType(TYPE_SVCB)
+                .addRdata(new byte[] { 0x01, 0x01 })
+                .build();
+        assertThrows(BufferUnderflowException.class, () -> makeDnsSvcbRecordFromByteArray(bytes2));
+
+        // Rdata is empty.
+        final byte[] bytes3 = new TestDnsRecordByteArrayBuilder()
+                .setRRType(TYPE_SVCB)
+                .build();
+        assertThrows(BufferUnderflowException.class, () -> makeDnsSvcbRecordFromByteArray(bytes3));
+    }
+
+    @Test
+    public void testDnsSvcbRecord_repeatedKeyIsInvalid() throws Exception {
+        final byte[] bytes = new TestDnsRecordByteArrayBuilder()
+                .setRRType(TYPE_SVCB)
+                .addRdata(TEST_SVC_PARAM_ALPN_HTTPS)
+                .addRdata(TEST_SVC_PARAM_ALPN_DOQ)
+                .build();
+        assertThrows(DnsPacket.ParseException.class, () -> makeDnsSvcbRecordFromByteArray(bytes));
+    }
+
+    @Test
+    public void testDnsSvcbRecord_invalidContent() throws Exception {
+        final List<byte[]> invalidContents = Arrays.asList(
+                // Invalid SvcParamValue for "mandatory":
+                // - SvcParamValue must not be empty.
+                // - SvcParamValue has less data than expected.
+                // - SvcParamValue has more data than expected.
+                // - SvcParamValue must be multiple of 2.
+                new byte[] { 0x00, 0x00, 0x00, 0x00},
+                new byte[] { 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x06 },
+                new byte[] { 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, },
+                new byte[] { 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00 },
+
+                // Invalid SvcParamValue for "alpn":
+                // - SvcParamValue must not be empty.
+                // - SvcParamValue has less data than expected.
+                // - SvcParamValue has more data than expected.
+                // - Alpn length is less than the actual data size.
+                // - Alpn length is more than the actual data size.
+                // - Alpn must be a non-empty string.
+                new byte[] { 0x00, 0x01, 0x00, 0x00},
+                new byte[] { 0x00, 0x01, 0x00, 0x02, 0x02, 'h', '2' },
+                new byte[] { 0x00, 0x01, 0x00, 0x05, 0x02, 'h', '2' },
+                new byte[] { 0x00, 0x01, 0x00, 0x04, 0x02, 'd', 'o', 't' },
+                new byte[] { 0x00, 0x01, 0x00, 0x04, 0x08, 'd', 'o', 't' },
+                new byte[] { 0x00, 0x01, 0x00, 0x08, 0x02, 'h', '2', 0x00 },
+
+                // Invalid SvcParamValue for "no-default-alpn":
+                // - SvcParamValue must be empty.
+                // - SvcParamValue length must be 0.
+                new byte[] { 0x00, 0x02, 0x00, 0x04, 'd', 'a', 't', 'a' },
+                new byte[] { 0x00, 0x02, 0x00, 0x04 },
+
+                // Invalid SvcParamValue for "port":
+                // - SvcParamValue must not be empty.
+                // - SvcParamValue has less data than expected.
+                // - SvcParamValue has more data than expected.
+                // - SvcParamValue length must be multiple of 2.
+                new byte[] { 0x00, 0x03, 0x00, 0x00 },
+                new byte[] { 0x00, 0x03, 0x00, 0x02, 0x01 },
+                new byte[] { 0x00, 0x03, 0x00, 0x02, 0x01, 0x02, 0x03 },
+                new byte[] { 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x03 },
+
+                // Invalid SvcParamValue for "ipv4hint":
+                // - SvcParamValue must not be empty.
+                // - SvcParamValue has less data than expected.
+                // - SvcParamValue has more data than expected.
+                // - SvcParamValue must be multiple of 4.
+                new byte[] { 0x00, 0x04, 0x00, 0x00 },
+                new byte[] { 0x00, 0x04, 0x00, 0x04, 0x08 },
+                new byte[] { 0x00, 0x04, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08 },
+                new byte[] { 0x00, 0x04, 0x00, 0x05, 0x08, 0x08, 0x08, 0x08 },
+
+                // Invalid SvcParamValue for "ipv6hint":
+                // - SvcParamValue must not be empty.
+                // - SvcParamValue has less data than expected.
+                // - SvcParamValue has more data than expected.
+                // - SvcParamValue must be multiple of 16.
+                new byte[] { 0x00, 0x06, 0x00, 0x00 },
+                new byte[] { 0x00, 0x06, 0x00, 0x10, 0x01 },
+                new byte[] { 0x00, 0x06, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+                        0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
+                new byte[] { 0x00, 0x06, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+                        0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }
+        );
+
+        for (byte[] content : invalidContents) {
+            final byte[] bytes = new TestDnsRecordByteArrayBuilder()
+                        .setRRType(TYPE_SVCB)
+                        .addRdata(content)
+                        .build();
+            assertThrows(DnsPacket.ParseException.class,
+                        () -> makeDnsSvcbRecordFromByteArray(bytes));
+        }
+    }
+
+    @Test
+    public void testDnsSvcbPacket_createdFromNullObject() throws Exception {
+        assertThrows(DnsPacket.ParseException.class, () -> DnsSvcbPacket.fromResponse(null));
+    }
+
+    @Test
+    public void testDnsSvcbPacket() throws Exception {
+        final String dohTargetName = "https.dns.com";
+        final String doqTargetName = "doq.dns.com";
+        final InetAddress[] expectedIpAddressesForHttps = new InetAddress[] {
+                InetAddresses.parseNumericAddress("1.2.3.4"),
+                InetAddresses.parseNumericAddress("6.7.8.9"),
+                InetAddresses.parseNumericAddress("2001:db8::1"),
+        };
+        final InetAddress[] expectedIpAddressesForDoq = new InetAddress[] {
+                InetAddresses.parseNumericAddress("4.3.2.1"),
+        };
+
+        final ByteArrayOutputStream os = new ByteArrayOutputStream();
+        os.write(makeDnsResponseHeaderAsByteArray(1 /* qdcount */, 2 /* ancount */, 0 /* nscount */,
+                0 /* arcount */));
+        os.write(TEST_DNS_SVCB_QUESTION_SECTION);
+        // Add answer for alpn h2 and http/1.1.
+        os.write(new TestDnsRecordByteArrayBuilder()
+                .setNameCompression(true)
+                .setRRType(TYPE_SVCB)
+                .setTargetName(dohTargetName)
+                .addRdata(TEST_SVC_PARAM_ALPN_HTTPS)
+                .addRdata(TEST_SVC_PARAM_IPV4HINT_1)
+                .addRdata(TEST_SVC_PARAM_IPV6HINT)
+                .addRdata(TEST_SVC_PARAM_PORT)
+                .addRdata(TEST_SVC_PARAM_DOHPATH)
+                .build());
+        // Add answer for alpn doq.
+        os.write(new TestDnsRecordByteArrayBuilder()
+                .setNameCompression(true)
+                .setRRType(TYPE_SVCB)
+                .setTargetName(doqTargetName)
+                .setSvcPriority(2)
+                .addRdata(TEST_SVC_PARAM_ALPN_DOQ)
+                .addRdata(TEST_SVC_PARAM_IPV4HINT_2)
+                .build());
+        final DnsSvcbPacket pkt = DnsSvcbPacket.fromResponse(os.toByteArray());
+
+        assertTrue(pkt.isSupported("http/1.1"));
+        assertTrue(pkt.isSupported("h2"));
+        assertTrue(pkt.isSupported("doq"));
+        assertFalse(pkt.isSupported("http"));
+        assertFalse(pkt.isSupported("h3"));
+        assertFalse(pkt.isSupported(""));
+
+        assertEquals(dohTargetName, pkt.getTargetName("http/1.1"));
+        assertEquals(dohTargetName, pkt.getTargetName("h2"));
+        assertEquals(doqTargetName, pkt.getTargetName("doq"));
+        assertEquals(null, pkt.getTargetName("http"));
+        assertEquals(null, pkt.getTargetName("h3"));
+        assertEquals(null, pkt.getTargetName(""));
+
+        assertEquals(5353, pkt.getPort("http/1.1"));
+        assertEquals(5353, pkt.getPort("h2"));
+        assertEquals(-1, pkt.getPort("doq"));
+        assertEquals(-1, pkt.getPort("http"));
+        assertEquals(-1, pkt.getPort("h3"));
+        assertEquals(-1, pkt.getPort(""));
+
+        assertArrayEquals(expectedIpAddressesForHttps, pkt.getAddresses("http/1.1").toArray());
+        assertArrayEquals(expectedIpAddressesForHttps, pkt.getAddresses("h2").toArray());
+        assertArrayEquals(expectedIpAddressesForDoq, pkt.getAddresses("doq").toArray());
+        assertTrue(pkt.getAddresses("http").isEmpty());
+        assertTrue(pkt.getAddresses("h3").isEmpty());
+        assertTrue(pkt.getAddresses("").isEmpty());
+
+        assertEquals("/some-path{?dns}", pkt.getDohPath("http/1.1"));
+        assertEquals("/some-path{?dns}", pkt.getDohPath("h2"));
+        assertEquals("", pkt.getDohPath("doq"));
+        assertEquals(null, pkt.getDohPath("http"));
+        assertEquals(null, pkt.getDohPath("h3"));
+        assertEquals(null, pkt.getDohPath(""));
+    }
+
+    @Test
+    public void testDnsSvcbPacket_noIpHint() throws Exception {
+        final String targetName = "doq.dns.com";
+        final ByteArrayOutputStream os = new ByteArrayOutputStream();
+        os.write(makeDnsResponseHeaderAsByteArray(1 /* qdcount */, 1 /* ancount */, 0 /* nscount */,
+                0 /* arcount */));
+        os.write(TEST_DNS_SVCB_QUESTION_SECTION);
+        // Add answer for alpn doq.
+        os.write(new TestDnsRecordByteArrayBuilder()
+                .setNameCompression(true)
+                .setRRType(TYPE_SVCB)
+                .setTargetName(targetName)
+                .addRdata(TEST_SVC_PARAM_ALPN_DOQ)
+                .build());
+        final DnsSvcbPacket pkt = DnsSvcbPacket.fromResponse(os.toByteArray());
+
+        assertTrue(pkt.isSupported("doq"));
+        assertEquals(targetName, pkt.getTargetName("doq"));
+        assertEquals(-1, pkt.getPort("doq"));
+        assertArrayEquals(new InetAddress[] {}, pkt.getAddresses("doq").toArray());
+        assertEquals("", pkt.getDohPath("doq"));
+    }
+
+    @Test
+    public void testDnsSvcbPacket_hasAnswerInAdditionalSection() throws Exception {
+        final InetAddress[] expectedIpAddresses = new InetAddress[] {
+                InetAddresses.parseNumericAddress("1.2.3.4"),
+                InetAddresses.parseNumericAddress("2001:db8::2"),
+        };
+
+        final ByteArrayOutputStream os = new ByteArrayOutputStream();
+        os.write(makeDnsResponseHeaderAsByteArray(1 /* qdcount */, 1 /* ancount */, 0 /* nscount */,
+                2 /* arcount */));
+        os.write(TEST_DNS_SVCB_QUESTION_SECTION);
+        // Add SVCB record in the Answer section.
+        os.write(new TestDnsRecordByteArrayBuilder()
+                .setNameCompression(true)
+                .setRRType(TYPE_SVCB)
+                .setTargetName("doq.dns.com")
+                .addRdata(TEST_SVC_PARAM_ALPN_DOQ)
+                .addRdata(TEST_SVC_PARAM_IPV4HINT_2)
+                .addRdata(TEST_SVC_PARAM_IPV6HINT)
+                .build());
+        // Add A/AAAA records in the Additional section.
+        os.write(new TestDnsRecordByteArrayBuilder()
+                .setNameCompression(true)
+                .setRRType(TYPE_A)
+                .addRdata(InetAddresses.parseNumericAddress("1.2.3.4").getAddress())
+                .build());
+        os.write(new TestDnsRecordByteArrayBuilder()
+                .setNameCompression(true)
+                .setRRType(TYPE_AAAA)
+                .addRdata(InetAddresses.parseNumericAddress("2001:db8::2").getAddress())
+                .build());
+        final DnsSvcbPacket pkt = DnsSvcbPacket.fromResponse(os.toByteArray());
+
+        // If there are A/AAAA records in the Additional section, getAddresses() returns the IP
+        // addresses in those records instead of the IP addresses in ipv4hint/ipv6hint.
+        assertArrayEquals(expectedIpAddresses, pkt.getAddresses("doq").toArray());
+    }
+}
