All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pcap.codec.sll.Sll Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2020-2023 Pcap Project
 * SPDX-License-Identifier: MIT OR Apache-2.0
 */
package pcap.codec.sll;

import java.util.Arrays;
import java.util.Objects;
import pcap.codec.AbstractPacket;
import pcap.codec.ethernet.Ethernet;
import pcap.common.util.Strings;
import pcap.common.util.Validate;
import pcap.spi.PacketBuffer;

/**
 * Linux cooked packet (SLL).
 *
 * @since 1.3.0
 */
public final class Sll extends AbstractPacket {

  public static final int TYPE = 113;

  private static final int SLL_ADDRLEN = 8;

  // offsets
  private final long packetTypeOffset;
  private final long addressTypeOffset;
  private final long addressLengthOffset;
  private final long addressOffset;
  private final long protocolOffset;

  private Sll(PacketBuffer buffer) {
    super(buffer);
    packetTypeOffset = superOffset;
    addressTypeOffset = packetTypeOffset + 2;
    addressLengthOffset = addressTypeOffset + 2;
    addressOffset = addressLengthOffset + 2;
    protocolOffset = addressOffset + SLL_ADDRLEN;
  }

  /**
   * Wrap buffer into {@link Ethernet}.
   *
   * @param size ethernet size.
   * @param buffer buffer.
   * @return returns {@link Ethernet} instance.
   * @since 1.3.0
   */
  public static Sll newInstance(int size, PacketBuffer buffer) {
    Validate.notIllegalArgument(
        size == 16 && buffer.readableBytes() >= 16, "buffer size is not sufficient.");
    return new Sll(buffer);
  }

  /**
   * Get packet type.
   *
   * @return returns this instance.
   * @since 1.3.0
   */
  public int packetType() {
    return superBuffer.getShort(packetTypeOffset);
  }

  /**
   * Set packet type.
   *
   * @param value packet type.
   * @return returns this instance.
   * @since 1.3.0
   */
  public Sll packetType(int value) {
    superBuffer.setShort(packetTypeOffset, value & 0xFFFF);
    return this;
  }

  /**
   * Get link layer address type.
   *
   * @return returns link layer address type.
   * @since 1.3.0
   */
  public int addressType() {
    return superBuffer.getShort(addressTypeOffset);
  }

  /**
   * Set link layer address type.
   *
   * @param value link layer address type.
   * @return returns this instance.
   * @since 1.3.0
   */
  public Sll addressType(int value) {
    superBuffer.setShort(addressTypeOffset, value & 0xFFFF);
    return this;
  }

  /**
   * Get link layer address length.
   *
   * @return returns link layer address length.
   * @since 1.3.0
   */
  public int addressLength() {
    return superBuffer.getShort(addressLengthOffset);
  }

  /**
   * Set link layer address length.
   *
   * @param value link layer address length.
   * @return returns this instance.
   * @since 1.3.0
   */
  public Sll addressLength(int value) {
    superBuffer.setShort(addressLengthOffset, value & 0xFFFF);
    return this;
  }

  /**
   * Get link layer address.
   *
   * @return returns link layer address.
   * @since 1.3.0
   */
  public byte[] address() {
    int addrLen = addressLength();
    if (addrLen > 0 && addrLen <= SLL_ADDRLEN) {
      byte[] addr = new byte[addrLen];
      superBuffer.getBytes(addressOffset, addr);
      return addr;
    } else {
      return new byte[SLL_ADDRLEN];
    }
  }

  /**
   * Set link layer address.
   *
   * @param value link layer address.
   * @return returns this instance.
   * @since 1.3.0
   */
  public Sll address(byte[] value) {
    int addrLen = addressLength();
    if (addrLen > 0 && addrLen <= SLL_ADDRLEN) {
      if (value == null) {
        superBuffer.setBytes(addrLen, new byte[addrLen], 0, addrLen);
      } else {
        superBuffer.setBytes(addressOffset, value, 0, addrLen);
      }
    } else {
      throw new IllegalArgumentException(
          String.format(
              "addressLength: %d (expected: addressLength(%d) > 0 and addressLength(%d) <= 8)",
              addrLen, addrLen, addrLen));
    }
    return this;
  }

  /**
   * Get next protocol type.
   *
   * @return returns protocol.
   * @since 1.3.0
   */
  public int protocol() {
    return superBuffer.getShort(protocolOffset);
  }

  /**
   * Set next protocol type.
   *
   * @param value protocol.
   * @return returns this instance.
   * @since 1.3.0
   */
  public Sll protocol(int value) {
    superBuffer.setShort(protocolOffset, value & 0xFFFF);
    return this;
  }

  /** {@inheritDoc} */
  @Override
  public int size() {
    return 16;
  }

  @Override
  public boolean equals(Object o) {
    return super.equals(o);
  }

  @Override
  public int hashCode() {
    return Objects.hash(
        super.hashCode(),
        packetType(),
        addressType(),
        addressLength(),
        Arrays.hashCode(address()),
        protocol());
  }

  @Override
  public String toString() {
    return Strings.toStringBuilder(this)
        .add("packetType", packetType())
        .add("addressType", addressType())
        .add("addressLength", addressLength())
        .add("address", String.format("0x%s", Strings.hex(address())))
        .add("protocol", protocol())
        .toString();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy