Diff comments:
> diff --git a/src/maasagent/internal/arp/ethernet.go
> b/src/maasagent/internal/arp/ethernet.go
> new file mode 100644
> index 0000000..0d3e7d3
> --- /dev/null
> +++ b/src/maasagent/internal/arp/ethernet.go
> @@ -0,0 +1,133 @@
> +package arp
> +
> +/*
> + Copyright 2023 Canonical Ltd. This software is licensed under the
> + GNU Affero General Public License version 3 (see the file LICENSE).
> +*/
> +
> +import (
> + "encoding/binary"
> + "errors"
> + "io"
> + "net"
> +)
> +
> +const (
> + minEthernetLen = 14
> +)
> +
> +const (
> + // EthernetTypeLLC is a special ethernet type, if found the frame is
> truncated
> + EthernetTypeLLC uint16 = 0
> + // EthernetTypeIPv4 is the ethernet type for a frame containing an IPv4
> packet
> + EthernetTypeIPv4 uint16 = 0x0800
> + // EthernetTypeARP is the ethernet type for a frame containing an ARP
> packet
> + EthernetTypeARP uint16 = 0x0806
> + // EthernetTypeIPv6 is the ethernet type for a frame containing an IPv6
> packet
> + EthernetTypeIPv6 uint16 = 0x86dd
> + // EthernetTypeVLAN is the ethernet type for a frame containing a VLAN
> tag,
> + // the VLAN tag bytes will indicate the actual type of packet the frame
> contains
> + EthernetTypeVLAN uint16 = 0x8100
> +
> + // NonStdLenEthernetTypes is a magic number to find any non-standard
> types
> + // and mark them as EthernetTypeLLC
> + NonStdLenEthernetTypes uint16 = 0x600
> +)
> +
> +var (
> + // ErrNotVLAN is an error returned when calling
> EthernetFrame.ExtractVLAN
> + // if the frame is not of type EthernetTypeVLAN
> + ErrNotVLAN = errors.New("ethernet frame not of type VLAN")
> + // ErrMalformedVLAN is an error returned when parsing a VLAN tag
> + // that is malformed
> + ErrMalformedVLAN = errors.New("VLAN tag is malformed")
> +)
> +
> +// VLAN represents a VLAN tag within an ethernet frame
> +type VLAN struct {
> + Priority uint8
> + DropEligible bool
> + ID uint16
> + EthernetType uint16
> +}
> +
> +// UnmarshalBinary will take the ethernet frame's payload
> +// and extract a VLAN tag if one is present
> +func (v *VLAN) UnmarshalBinary(buf []byte) error {
> + if len(buf) < 4 {
> + return ErrMalformedVLAN
> + }
> +
> + // extract the first 3 bits
> + v.Priority = (buf[0] & 0xe0) >> 5
> + // extract the next bit and turn it into a bool
> + v.DropEligible = buf[0]&0x10 != 0
> + // extract the next 12 bits for an ID
> + v.ID = binary.BigEndian.Uint16(buf[:2]) & 0x0fff
> + // last 2 bytes are ethernet type
> + v.EthernetType = binary.BigEndian.Uint16(buf[2:])
> + return nil
> +}
> +
> +// EthernetFrame represents an ethernet frame
> +type EthernetFrame struct {
> + SrcMAC net.HardwareAddr
> + DstMAC net.HardwareAddr
> + EthernetType uint16
> + Len uint16
> + Payload []byte
> +}
> +
> +// ExtractARPPacket will extract an ARP packet from the ethernet frame's
> +// payload
> +func (e *EthernetFrame) ExtractARPPacket() (*Packet, error) {
> + var buf []byte
actually after looking more closely, `sync.Pool` shouldn't make a difference
here, as `var buf []byte` is set to an existing slice that is coming from the
ethernet frame's payload, so we can't really use `sync.Pool` here, nor would it
prevent allocation.
> + if e.EthernetType == EthernetTypeVLAN {
> + buf = e.Payload[4:]
> + } else {
> + buf = e.Payload
> + }
> + a := &Packet{}
> + err := a.UnmarshalBinary(buf)
> + if err != nil {
> + return nil, err
> + }
> + return a, nil
> +}
> +
> +// ExtractVLAN will extract the VLAN tag from the ethernet frame's
> +// payload if one is present and return ErrNotVLAN if not
> +func (e *EthernetFrame) ExtractVLAN() (*VLAN, error) {
> + if e.EthernetType != EthernetTypeVLAN {
> + return nil, ErrNotVLAN
> + }
> + v := &VLAN{}
> + err := v.UnmarshalBinary(e.Payload[0:4])
> + if err != nil {
> + return nil, err
> + }
> + return v, nil
> +}
> +
> +// UnmarshalBinary parses ethernet frame bytes into an EthernetFrame
> +func (eth *EthernetFrame) UnmarshalBinary(buf []byte) error {
> + if len(buf) < minEthernetLen {
> + return io.ErrUnexpectedEOF
> + }
> +
> + eth.DstMAC = buf[0:6]
> + eth.SrcMAC = buf[6:12]
> + eth.EthernetType = binary.BigEndian.Uint16(buf[12:14])
> + eth.Payload = buf[14:]
> + if eth.EthernetType < NonStdLenEthernetTypes {
> + eth.Len = eth.EthernetType
> + eth.EthernetType = EthernetTypeLLC
> + cmp := len(eth.Payload) - int(eth.Len)
> + if cmp < 0 {
> + return io.ErrUnexpectedEOF
> + } else if cmp > 0 {
> + eth.Payload = eth.Payload[:len(eth.Payload)-cmp]
> + }
> + }
> + return nil
> +}
--
https://code.launchpad.net/~cgrabowski/maas/+git/maas/+merge/441702
Your team MAAS Committers is subscribed to branch maas:master.
--
Mailing list: https://launchpad.net/~sts-sponsors
Post to : sts-sponsors@lists.launchpad.net
Unsubscribe : https://launchpad.net/~sts-sponsors
More help : https://help.launchpad.net/ListHelp