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

Reply via email to