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

pcap.codec.ethernet.Ethernet Maven / Gradle / Ivy

There is a newer version: 1.5.1
Show newest version
/** This code is licenced under the GPL version 2. */
package pcap.codec.ethernet;

import java.util.Objects;
import pcap.codec.AbstractPacket;
import pcap.codec.NetworkLayer;
import pcap.codec.Packet;
import pcap.common.annotation.Inclubating;
import pcap.common.memory.Memory;
import pcap.common.net.MacAddress;
import pcap.common.util.Strings;
import pcap.common.util.Validate;

/** @author Ardika Rommy Sanjaya */
@Inclubating
public class Ethernet extends AbstractPacket {

  private final Header header;
  private final Packet payload;
  private final Builder builder;

  private Ethernet(final Builder builder) {
    this.header = new Header(builder);
    this.payloadBuffer = builder.payloadBuffer;
    if (this.payloadBuffer != null
        && this.payloadBuffer.readerIndex() < this.payloadBuffer.writerIndex()) {
      this.payload =
          NetworkLayer.valueOf(this.header.payloadType().value()).newInstance(this.payloadBuffer);
    } else {
      this.payload = null;
    }
    this.builder = builder;
  }

  public static final Ethernet newPacket(final Memory buffer) {
    return new Builder().build(buffer);
  }

  @Override
  public Header header() {
    return header;
  }

  @Override
  public Packet payload() {
    return payload;
  }

  @Override
  public Builder builder() {
    return builder;
  }

  @Override
  public Memory buffer() {
    return header().buffer();
  }

  @Override
  public String toString() {
    return Strings.toStringBuilder(this)
        .add("header", header)
        .add("payload", payload != null ? payload.getClass().getSimpleName() : "(None)")
        .toString();
  }

  public static class Header extends AbstractPacket.Header {

    public static final int ETHERNET_HEADER_LENGTH = 14;

    private final MacAddress destinationMacAddress;
    private final MacAddress sourceMacAddress;
    private final NetworkLayer ethernetType;

    private final Builder builder;

    private Header(final Builder builder) {
      this.destinationMacAddress = builder.destinationMacAddress;
      this.sourceMacAddress = builder.sourceMacAddress;
      this.ethernetType = builder.ethernetType;
      this.buffer = resetIndex(builder.buffer, length());
      this.builder = builder;
    }

    public MacAddress destinationMacAddress() {
      return destinationMacAddress;
    }

    public MacAddress sourceMacAddress() {
      return sourceMacAddress;
    }

    public NetworkLayer ethernetType() {
      return ethernetType;
    }

    @Override
    public NetworkLayer payloadType() {
      return ethernetType;
    }

    @Override
    public int length() {
      return Header.ETHERNET_HEADER_LENGTH;
    }

    @Override
    public Memory buffer() {
      if (buffer == null) {
        buffer = ALLOCATOR.allocate(length());
        buffer.writeBytes(destinationMacAddress.address());
        buffer.writeBytes(sourceMacAddress.address());
        buffer.writeShort(ethernetType.value());
      }
      return buffer;
    }

    @Override
    public Builder builder() {
      return builder;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
      Header header = (Header) o;
      return destinationMacAddress.equals(header.destinationMacAddress)
          && sourceMacAddress.equals(header.sourceMacAddress)
          && ethernetType.equals(header.ethernetType);
    }

    @Override
    public int hashCode() {
      return Objects.hash(destinationMacAddress, sourceMacAddress, ethernetType);
    }

    @Override
    public String toString() {
      return Strings.toStringBuilder(this)
          .add("destinationMacAddress", destinationMacAddress)
          .add("sourceMacAddress", sourceMacAddress)
          .add("ethernetType", ethernetType)
          .toString();
    }
  }

  public static class Builder extends AbstractPacket.Builder {

    private MacAddress destinationMacAddress = MacAddress.BROADCAST;
    private MacAddress sourceMacAddress = MacAddress.ZERO;
    private NetworkLayer ethernetType = NetworkLayer.ARP;

    private Memory buffer;
    private Memory payloadBuffer;

    public Builder destinationMacAddress(final MacAddress destinationMacAddress) {
      this.destinationMacAddress = destinationMacAddress;
      return this;
    }

    public Builder sourceMacAddress(final MacAddress sourceMacAddress) {
      this.sourceMacAddress = sourceMacAddress;
      return this;
    }

    public Builder ethernetType(final NetworkLayer ethernetType) {
      this.ethernetType = ethernetType;
      return this;
    }

    @Override
    public Ethernet build() {
      return new Ethernet(this);
    }

    @Override
    public Ethernet build(final Memory buffer) {
      resetIndex(buffer);
      byte[] hardwareAddressBuffer;
      hardwareAddressBuffer = new byte[MacAddress.MAC_ADDRESS_LENGTH];
      buffer.readBytes(hardwareAddressBuffer);
      this.destinationMacAddress = MacAddress.valueOf(hardwareAddressBuffer);
      hardwareAddressBuffer = new byte[MacAddress.MAC_ADDRESS_LENGTH];
      buffer.readBytes(hardwareAddressBuffer);
      this.sourceMacAddress = MacAddress.valueOf(hardwareAddressBuffer);
      this.ethernetType = NetworkLayer.valueOf(buffer.readShort());
      this.buffer = buffer;
      this.payloadBuffer = buffer.slice();
      return new Ethernet(this);
    }

    @Override
    public Builder reset() {
      return reset(readerIndex, Header.ETHERNET_HEADER_LENGTH);
    }

    @Override
    public Builder reset(int offset, int length) {
      if (buffer != null) {
        resetIndex(buffer);
        Validate.notIllegalArgument(offset + length <= buffer.capacity());
        Validate.notIllegalArgument(destinationMacAddress != null, ILLEGAL_HEADER_EXCEPTION);
        Validate.notIllegalArgument(sourceMacAddress != null, ILLEGAL_HEADER_EXCEPTION);
        Validate.notIllegalArgument(ethernetType != null, ILLEGAL_HEADER_EXCEPTION);
        int index = offset;
        buffer.setBytes(index, destinationMacAddress.address());
        index += MacAddress.MAC_ADDRESS_LENGTH;
        buffer.setBytes(index, sourceMacAddress.address());
        index += MacAddress.MAC_ADDRESS_LENGTH;
        buffer.setShort(index, ethernetType.value());
      }
      return this;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy