summaryrefslogtreecommitdiff
path: root/common/device/com/android/net/module/util/PacketBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'common/device/com/android/net/module/util/PacketBuilder.java')
-rw-r--r--common/device/com/android/net/module/util/PacketBuilder.java302
1 files changed, 0 insertions, 302 deletions
diff --git a/common/device/com/android/net/module/util/PacketBuilder.java b/common/device/com/android/net/module/util/PacketBuilder.java
deleted file mode 100644
index 33e5bfad..00000000
--- a/common/device/com/android/net/module/util/PacketBuilder.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2021 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.system.OsConstants.IPPROTO_IP;
-import static android.system.OsConstants.IPPROTO_IPV6;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import static com.android.net.module.util.IpUtils.ipChecksum;
-import static com.android.net.module.util.IpUtils.tcpChecksum;
-import static com.android.net.module.util.IpUtils.udpChecksum;
-import static com.android.net.module.util.NetworkStackConstants.IPV4_CHECKSUM_OFFSET;
-import static com.android.net.module.util.NetworkStackConstants.IPV4_LENGTH_OFFSET;
-import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN;
-import static com.android.net.module.util.NetworkStackConstants.IPV6_LEN_OFFSET;
-import static com.android.net.module.util.NetworkStackConstants.TCP_CHECKSUM_OFFSET;
-import static com.android.net.module.util.NetworkStackConstants.UDP_CHECKSUM_OFFSET;
-import static com.android.net.module.util.NetworkStackConstants.UDP_LENGTH_OFFSET;
-
-import android.net.MacAddress;
-
-import androidx.annotation.NonNull;
-
-import com.android.net.module.util.structs.EthernetHeader;
-import com.android.net.module.util.structs.Ipv4Header;
-import com.android.net.module.util.structs.Ipv6Header;
-import com.android.net.module.util.structs.TcpHeader;
-import com.android.net.module.util.structs.UdpHeader;
-
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-
-/**
- * The class is used to build a packet.
- *
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Layer 2 header (EthernetHeader) | (optional)
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Layer 3 header (Ipv4Header, Ipv6Header) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Layer 4 header (TcpHeader, UdpHeader) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Payload | (optional)
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Below is a sample code to build a packet.
- *
- * // Initialize builder
- * final ByteBuffer buf = ByteBuffer.allocate(...);
- * final PacketBuilder pb = new PacketBuilder(buf);
- * // Write headers
- * pb.writeL2Header(...);
- * pb.writeIpHeader(...);
- * pb.writeTcpHeader(...);
- * // Write payload
- * buf.putInt(...);
- * buf.putShort(...);
- * buf.putByte(...);
- * // Finalize and use the packet
- * pb.finalizePacket();
- * sendPacket(buf);
- */
-public class PacketBuilder {
- private static final int INVALID_OFFSET = -1;
-
- private final ByteBuffer mBuffer;
-
- private int mIpv4HeaderOffset = INVALID_OFFSET;
- private int mIpv6HeaderOffset = INVALID_OFFSET;
- private int mTcpHeaderOffset = INVALID_OFFSET;
- private int mUdpHeaderOffset = INVALID_OFFSET;
-
- public PacketBuilder(@NonNull ByteBuffer buffer) {
- mBuffer = buffer;
- }
-
- /**
- * Write an ethernet header.
- *
- * @param srcMac source MAC address
- * @param dstMac destination MAC address
- * @param etherType ether type
- */
- public void writeL2Header(MacAddress srcMac, MacAddress dstMac, short etherType) throws
- IOException {
- final EthernetHeader ethHeader = new EthernetHeader(dstMac, srcMac, etherType);
- try {
- ethHeader.writeToByteBuffer(mBuffer);
- } catch (IllegalArgumentException | BufferOverflowException e) {
- throw new IOException("Error writing to buffer: ", e);
- }
- }
-
- /**
- * Write an IPv4 header.
- * The IP header length and checksum are calculated and written back in #finalizePacket.
- *
- * @param tos type of service
- * @param id the identification
- * @param flagsAndFragmentOffset flags and fragment offset
- * @param ttl time to live
- * @param protocol protocol
- * @param srcIp source IP address
- * @param dstIp destination IP address
- */
- public void writeIpv4Header(byte tos, short id, short flagsAndFragmentOffset, byte ttl,
- byte protocol, @NonNull final Inet4Address srcIp, @NonNull final Inet4Address dstIp)
- throws IOException {
- mIpv4HeaderOffset = mBuffer.position();
- final Ipv4Header ipv4Header = new Ipv4Header(tos,
- (short) 0 /* totalLength, calculate in #finalizePacket */, id,
- flagsAndFragmentOffset, ttl, protocol,
- (short) 0 /* checksum, calculate in #finalizePacket */, srcIp, dstIp);
-
- try {
- ipv4Header.writeToByteBuffer(mBuffer);
- } catch (IllegalArgumentException | BufferOverflowException e) {
- throw new IOException("Error writing to buffer: ", e);
- }
- }
-
- /**
- * Write an IPv6 header.
- * The IP header length is calculated and written back in #finalizePacket.
- *
- * @param vtf version, traffic class and flow label
- * @param nextHeader the transport layer protocol
- * @param hopLimit hop limit
- * @param srcIp source IP address
- * @param dstIp destination IP address
- */
- public void writeIpv6Header(int vtf, byte nextHeader, short hopLimit,
- @NonNull final Inet6Address srcIp, @NonNull final Inet6Address dstIp)
- throws IOException {
- mIpv6HeaderOffset = mBuffer.position();
- final Ipv6Header ipv6Header = new Ipv6Header(vtf,
- (short) 0 /* payloadLength, calculate in #finalizePacket */, nextHeader,
- hopLimit, srcIp, dstIp);
-
- try {
- ipv6Header.writeToByteBuffer(mBuffer);
- } catch (IllegalArgumentException | BufferOverflowException e) {
- throw new IOException("Error writing to buffer: ", e);
- }
- }
-
- /**
- * Write a TCP header.
- * The TCP header checksum is calculated and written back in #finalizePacket.
- *
- * @param srcPort source port
- * @param dstPort destination port
- * @param seq sequence number
- * @param ack acknowledgement number
- * @param tcpFlags tcp flags
- * @param window window size
- * @param urgentPointer urgent pointer
- */
- public void writeTcpHeader(short srcPort, short dstPort, short seq, short ack,
- byte tcpFlags, short window, short urgentPointer) throws IOException {
- mTcpHeaderOffset = mBuffer.position();
- final TcpHeader tcpHeader = new TcpHeader(srcPort, dstPort, seq, ack,
- (short) ((short) 0x5000 | ((byte) 0x3f & tcpFlags)) /* dataOffsetAndControlBits,
- dataOffset is always 5(*4bytes) because options not supported */, window,
- (short) 0 /* checksum, calculate in #finalizePacket */,
- urgentPointer);
-
- try {
- tcpHeader.writeToByteBuffer(mBuffer);
- } catch (IllegalArgumentException | BufferOverflowException e) {
- throw new IOException("Error writing to buffer: ", e);
- }
- }
-
- /**
- * Write a UDP header.
- * The UDP header length and checksum are calculated and written back in #finalizePacket.
- *
- * @param srcPort source port
- * @param dstPort destination port
- */
- public void writeUdpHeader(short srcPort, short dstPort) throws IOException {
- mUdpHeaderOffset = mBuffer.position();
- final UdpHeader udpHeader = new UdpHeader(srcPort, dstPort,
- (short) 0 /* length, calculate in #finalizePacket */,
- (short) 0 /* checksum, calculate in #finalizePacket */);
-
- try {
- udpHeader.writeToByteBuffer(mBuffer);
- } catch (IllegalArgumentException | BufferOverflowException e) {
- throw new IOException("Error writing to buffer: ", e);
- }
- }
-
- /**
- * Finalize the packet.
- *
- * Call after writing L4 header (no payload) or payload to the buffer used by the builder.
- * L3 header length, L3 header checksum and L4 header checksum are calculated and written back
- * after finalization.
- */
- @NonNull
- public ByteBuffer finalizePacket() throws IOException {
- // [1] Finalize IPv4 or IPv6 header.
- int ipHeaderOffset = INVALID_OFFSET;
- if (mIpv4HeaderOffset != INVALID_OFFSET) {
- ipHeaderOffset = mIpv4HeaderOffset;
-
- // Populate the IPv4 totalLength field.
- mBuffer.putShort(mIpv4HeaderOffset + IPV4_LENGTH_OFFSET,
- (short) (mBuffer.position() - mIpv4HeaderOffset));
-
- // Populate the IPv4 header checksum field.
- mBuffer.putShort(mIpv4HeaderOffset + IPV4_CHECKSUM_OFFSET,
- ipChecksum(mBuffer, mIpv4HeaderOffset /* headerOffset */));
- } else if (mIpv6HeaderOffset != INVALID_OFFSET) {
- ipHeaderOffset = mIpv6HeaderOffset;
-
- // Populate the IPv6 payloadLength field.
- // The payload length doesn't include IPv6 header length. See rfc8200 section 3.
- mBuffer.putShort(mIpv6HeaderOffset + IPV6_LEN_OFFSET,
- (short) (mBuffer.position() - mIpv6HeaderOffset - IPV6_HEADER_LEN));
- } else {
- throw new IOException("Packet is missing neither IPv4 nor IPv6 header");
- }
-
- // [2] Finalize TCP or UDP header.
- if (mTcpHeaderOffset != INVALID_OFFSET) {
- // Populate the TCP header checksum field.
- mBuffer.putShort(mTcpHeaderOffset + TCP_CHECKSUM_OFFSET, tcpChecksum(mBuffer,
- ipHeaderOffset /* ipOffset */, mTcpHeaderOffset /* transportOffset */,
- mBuffer.position() - mTcpHeaderOffset /* transportLen */));
- } else if (mUdpHeaderOffset != INVALID_OFFSET) {
- // Populate the UDP header length field.
- mBuffer.putShort(mUdpHeaderOffset + UDP_LENGTH_OFFSET,
- (short) (mBuffer.position() - mUdpHeaderOffset));
-
- // Populate the UDP header checksum field.
- mBuffer.putShort(mUdpHeaderOffset + UDP_CHECKSUM_OFFSET, udpChecksum(mBuffer,
- ipHeaderOffset /* ipOffset */, mUdpHeaderOffset /* transportOffset */));
- } else {
- throw new IOException("Packet is missing neither TCP nor UDP header");
- }
-
- mBuffer.flip();
- return mBuffer;
- }
-
- /**
- * Allocate bytebuffer for building the packet.
- *
- * @param hasEther has ethernet header. Set this flag to indicate that the packet has an
- * ethernet header.
- * @param l3proto the layer 3 protocol. Only {@code IPPROTO_IP} and {@code IPPROTO_IPV6}
- * currently supported.
- * @param l4proto the layer 4 protocol. Only {@code IPPROTO_TCP} and {@code IPPROTO_UDP}
- * currently supported.
- * @param payloadLen length of the payload.
- */
- @NonNull
- public static ByteBuffer allocate(boolean hasEther, int l3proto, int l4proto, int payloadLen) {
- if (l3proto != IPPROTO_IP && l3proto != IPPROTO_IPV6) {
- throw new IllegalArgumentException("Unsupported layer 3 protocol " + l3proto);
- }
-
- if (l4proto != IPPROTO_TCP && l4proto != IPPROTO_UDP) {
- throw new IllegalArgumentException("Unsupported layer 4 protocol " + l4proto);
- }
-
- if (payloadLen < 0) {
- throw new IllegalArgumentException("Invalid payload length " + payloadLen);
- }
-
- int packetLen = 0;
- if (hasEther) packetLen += Struct.getSize(EthernetHeader.class);
- packetLen += (l3proto == IPPROTO_IP) ? Struct.getSize(Ipv4Header.class)
- : Struct.getSize(Ipv6Header.class);
- packetLen += (l4proto == IPPROTO_TCP) ? Struct.getSize(TcpHeader.class)
- : Struct.getSize(UdpHeader.class);
- packetLen += payloadLen;
-
- return ByteBuffer.allocate(packetLen);
- }
-}