eth

package
v0.0.0-...-1201bab Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 27, 2024 License: BSD-3-Clause Imports: 5 Imported by: 2

Documentation

Overview

package eth implements Ethernet, ARP, IP, TCP among other datagram and protocol frame processing and manipulation tools.

ARP Frame (Address resolution protocol)

see https://www.youtube.com/watch?v=aamG4-tH_m8

Legend:

  • HW: Hardware
  • AT: Address type
  • AL: Address Length
  • AoS: Address of sender
  • AoT: Address of Target
  • Proto: Protocol (below is ipv4 example)

Below is the byte schema for an ARP header:

0      2          4       5          6         8       14          18       24          28
| HW AT | Proto AT | HW AL | Proto AL | OP Code | HW AoS | Proto AoS | HW AoT | Proto AoT |
|  2B   |  2B      |  1B   |  1B      | 2B      |   6B   |    4B     |  6B    |   4B
| ethern| IP       |macaddr|          |ask|reply|                    |for op=1|
| = 1   |=0x0800   |=6     |=4        | 1 | 2   |       known        |=0      |

See https://hpd.gasmi.net/ to decode Hex Frames.

TODO Handle IGMP Frame example: 01 00 5E 00 00 FB 28 D2 44 9A 2F F3 08 00 46 C0 00 20 00 00 40 00 01 02 41 04 C0 A8 01 70 E0 00 00 FB 94 04 00 00 16 00 09 04 E0 00 00 FB 00 00 00 00 00 00 00 00 00 00 00 00 00

TODO Handle LLC Logical Link Control Frame example: 05 62 70 73 D7 10 80 04 6C 00 02 00 00 04 00 00 10 20 41 70 00 00 00 0E 00 00 00 19 40 40 00 01 16 4E E9 B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Index

Constants

View Source
const (
	SizeEthernetHeader = 14
	SizeIPv4Header     = 20
	SizeUDPHeader      = 8
	SizeARPv4Header    = 28
	SizeTCPHeader      = 20
	SizeDHCPHeader     = 44
)

These are minimum sizes that do not take into consideration the presence of options or special tags (i.e: VLAN, IP/TCP Options).

Variables

This section is empty.

Functions

func BroadcastHW6

func BroadcastHW6() [6]byte

func IsBroadcastHW

func IsBroadcastHW(hwaddr net.HardwareAddr) bool

Types

type ARPv4Header

type ARPv4Header struct {
	// This field specifies the network link protocol type. Example: Ethernet is 1.
	HardwareType uint16 // 0:2
	// This field specifies the internetwork protocol for which the ARP request is
	// intended. For IPv4, this has the value 0x0800. The permitted PTYPE
	// values share a numbering space with those for EtherType.
	ProtoType uint16 // 2:4
	// Length (in octets) of a hardware address. Ethernet address length is 6.
	HardwareLength uint8 // 4:5
	// Length (in octets) of internetwork addresses. The internetwork protocol
	// is specified in PTYPE. Example: IPv4 address length is 4.
	ProtoLength uint8 // 5:6
	// Specifies the operation that the sender is performing: 1 for request, 2 for reply.
	Operation uint16 // 6:8
	// Media address of the sender. In an ARP request this field is used to indicate
	// the address of the host sending the request. In an ARP reply this field is
	// used to indicate the address of the host that the request was looking for.
	HardwareSender [6]byte // 8:14
	// Internetwork address of the sender.
	ProtoSender [4]byte // 14:18
	// Media address of the intended receiver. In an ARP request this field is ignored.
	// In an ARP reply this field is used to indicate the address of the host that originated the ARP request.
	HardwareTarget [6]byte // 18:24
	// Internetwork address of the intended receiver.
	ProtoTarget [4]byte // 24:28
}

ARPv4Header is the Address Resolution Protocol header for IPv4 address resolution and 6 byte hardware addresses. 28 bytes in size.

func DecodeARPv4Header

func DecodeARPv4Header(buf []byte) (arphdr ARPv4Header)

func (*ARPv4Header) AssertEtherType

func (ahdr *ARPv4Header) AssertEtherType() EtherType

AssertEtherType returns the ProtoType field of the ARP header as EtherType.

func (*ARPv4Header) Put

func (ahdr *ARPv4Header) Put(buf []byte)

Put marshals the ARP header onto buf. buf needs to be 28 bytes in length or Put panics.

func (*ARPv4Header) String

func (ahdr *ARPv4Header) String() string

type CRC791

type CRC791 struct {
	// contains filtered or unexported fields
}

CRC791 function as defined by RFC 791. The Checksum field for TCP+IP is the 16-bit ones' complement of the ones' complement sum of all 16-bit words in the header. In case of uneven number of octet the last word is LSB padded with zeros.

The zero value of CRC791 is ready to use.

func (*CRC791) AddUint16

func (c *CRC791) AddUint16(value uint16)

Add16 adds value to the running checksum interpreted as BigEndian (network order).

func (*CRC791) AddUint32

func (c *CRC791) AddUint32(value uint32)

Add16 adds value to the running checksum interpreted as BigEndian (network order).

func (*CRC791) AddUint8

func (c *CRC791) AddUint8(value uint8)

Add16 adds value to the running checksum interpreted as BigEndian (network order).

func (*CRC791) Reset

func (c *CRC791) Reset()

Reset zeros out the CRC791, resetting it to the initial state.

func (*CRC791) Sum16

func (c *CRC791) Sum16() uint16

Sum16 calculates the checksum with the data written to c thus far.

func (*CRC791) Write

func (c *CRC791) Write(buff []byte) (n int, err error)

Write adds the bytes in p to the running checksum.

type EtherType

type EtherType uint16
const (
	EtherTypeIPv4                EtherType = 0x0800
	EtherTypeARP                 EtherType = 0x0806
	EtherTypeWakeOnLAN           EtherType = 0x0842
	EtherTypeTRILL               EtherType = 0x22F3
	EtherTypeDECnetPhase4        EtherType = 0x6003
	EtherTypeRARP                EtherType = 0x8035
	EtherTypeAppleTalk           EtherType = 0x809B
	EtherTypeAARP                EtherType = 0x80F3
	EtherTypeIPX1                EtherType = 0x8137
	EtherTypeIPX2                EtherType = 0x8138
	EtherTypeQNXQnet             EtherType = 0x8204
	EtherTypeIPv6                EtherType = 0x86DD
	EtherTypeEthernetFlowControl EtherType = 0x8808
	EtherTypeIEEE802_3           EtherType = 0x8809
	EtherTypeCobraNet            EtherType = 0x8819
	EtherTypeMPLSUnicast         EtherType = 0x8847
	EtherTypeMPLSMulticast       EtherType = 0x8848
	EtherTypePPPoEDiscovery      EtherType = 0x8863
	EtherTypePPPoESession        EtherType = 0x8864
	EtherTypeJumboFrames         EtherType = 0x8870
	EtherTypeHomePlug1_0MME      EtherType = 0x887B
	EtherTypeIEEE802_1X          EtherType = 0x888E
	EtherTypePROFINET            EtherType = 0x8892
	EtherTypeHyperSCSI           EtherType = 0x889A
	EtherTypeAoE                 EtherType = 0x88A2
	EtherTypeEtherCAT            EtherType = 0x88A4
	EtherTypeEthernetPowerlink   EtherType = 0x88AB
	EtherTypeLLDP                EtherType = 0x88CC
	EtherTypeSERCOS3             EtherType = 0x88CD
	EtherTypeHomePlugAVMME       EtherType = 0x88E1
	EtherTypeMRP                 EtherType = 0x88E3
	EtherTypeIEEE802_1AE         EtherType = 0x88E5
	EtherTypeIEEE1588            EtherType = 0x88F7
	EtherTypeIEEE802_1ag         EtherType = 0x8902
	EtherTypeFCoE                EtherType = 0x8906
	EtherTypeFCoEInit            EtherType = 0x8914
	EtherTypeRoCE                EtherType = 0x8915
	EtherTypeCTP                 EtherType = 0x9000
	EtherTypeVeritasLLT          EtherType = 0xCAFE
	EtherTypeVLAN                EtherType = 0x8100
	EtherTypeServiceVLAN         EtherType = 0x88a8
)

Ethertype values. From: http://en.wikipedia.org/wiki/Ethertype

func (EtherType) String

func (i EtherType) String() string

type EthernetHeader

type EthernetHeader struct {
	Destination     [6]byte // 0:6
	Source          [6]byte // 6:12
	SizeOrEtherType uint16  // 12:14
}

EthernetHeader is a 14 byte ethernet header representation with no VLAN support on its own.

func DecodeEthernetHeader

func DecodeEthernetHeader(b []byte) (ethdr EthernetHeader)

DecodeEthernetHeader decodes an ethernet frame from the first 14 bytes of buf. It does not handle 802.1Q VLAN situation where at least 4 more bytes must be decoded from wire.

func (EthernetHeader) AssertType

func (ehdr EthernetHeader) AssertType() EtherType

AssertType returns the Size or EtherType field of the Ethernet frame as EtherType.

func (*EthernetHeader) IsVLAN

func (ehdr *EthernetHeader) IsVLAN() bool

IsVLAN returns true if the SizeOrEtherType is set to the VLAN tag 0x8100. This indicates the EthernetHeader is invalid as-is and instead of EtherType the field contains the first two octets of a 4 octet 802.1Q VLAN tag. In this case 4 more bytes must be read from the wire, of which the last 2 of these bytes contain the actual SizeOrEtherType field, which needs to be validated yet again in case the packet is a VLAN double-tap packet.

func (*EthernetHeader) Put

func (ehdr *EthernetHeader) Put(buf []byte)

Put marshals the ethernet frame onto buf. buf needs to be 14 bytes in length or Put panics.

func (*EthernetHeader) String

func (ehdr *EthernetHeader) String() string

String returns a human readable representation of the Ethernet frame.

type IPFlags

type IPFlags uint16

func (IPFlags) DontFragment

func (f IPFlags) DontFragment() bool

func (IPFlags) FragmentOffset

func (f IPFlags) FragmentOffset() uint16

func (IPFlags) MoreFragments

func (f IPFlags) MoreFragments() bool

type IPv4Header

type IPv4Header struct {
	// VersionAndIHL contains union of both IP Version and IHL data.
	//
	// Version must be 4 for IPv4. It is force-set to its valid value in a call to Put.
	//
	// Internet Header Length (IHL) The IPv4 header is variable in size due to the
	// optional 14th field (options). The IHL field contains the size of the IPv4 header;
	// it has 4 bits that specify the number of 32-bit words in the header.
	// The minimum value for this field is 5, which indicates a length of
	// 5 × 32 bits = 160 bits = 20 bytes. As a 4-bit field, the maximum value is 15;
	// this means that the maximum size of the IPv4 header is 15 × 32 bits = 480 bits = 60 bytes.
	VersionAndIHL uint8 // 0:1 (first 4 bits are version, last 4 bits are IHL)

	// Type of Service contains Differential Services Code Point (DSCP) and
	// Explicit Congestion Notification (ECN) union data.
	//
	// DSCP originally defined as the type of service (ToS), this field specifies
	// differentiated services (DiffServ) per RFC 2474. Real-time data streaming
	// makes use of the DSCP field. An example is Voice over IP (VoIP), which is
	// used for interactive voice services.
	//
	// ECN is defined in RFC 3168 and allows end-to-end notification of
	// network congestion without dropping packets. ECN is an optional feature available
	// when both endpoints support it and effective when also supported by the underlying network.
	ToS uint8 // 1:2 (first 6 bits are DSCP, last 2 bits are ECN)

	// This 16-bit field defines the entire packet size in bytes, including header and data.
	// The minimum size is 20 bytes (header without data) and the maximum is 65,535 bytes.
	// All hosts are required to be able to reassemble datagrams of size up to 576 bytes,
	// but most modern hosts handle much larger packets.
	//
	// Links may impose further restrictions on the packet size, in which case datagrams
	// must be fragmented. Fragmentation in IPv4 is performed in either the
	// sending host or in routers. Reassembly is performed at the receiving host.
	TotalLength uint16 // 2:4

	// This field is an identification field and is primarily used for uniquely
	// identifying the group of fragments of a single IP datagram.
	ID uint16 // 4:6

	// A three-bit field follows and is used to control or identify fragments.
	//  - If the DF flag is set (bit 1), and fragmentation is required to route the packet, then the packet is dropped.
	//  - For fragmented packets, all fragments except the last have the MF flag set (bit 2).
	//  - Bit 0 is reserved and must be set to zero.
	Flags IPFlags // 6:8

	// An eight-bit time to live field limits a datagram's lifetime to prevent
	// network failure in the event of a routing loop. In practice, the field
	// is used as a hop count—when the datagram arrives at a router,
	// the router decrements the TTL field by one. When the TTL field hits zero,
	// the router discards the packet and typically sends an ICMP time exceeded message to the sender.
	TTL uint8 // 8:9

	// This field defines the protocol used in the data portion of the IP datagram. TCP is 6, UDP is 17.
	Protocol    uint8   // 9:10
	Checksum    uint16  // 10:12
	Source      [4]byte // 12:16
	Destination [4]byte // 16:20
}

IPv4Header is the Internet Protocol header. 20 bytes in size. Does not include options.

func DecodeIPv4Header

func DecodeIPv4Header(buf []byte) (iphdr IPv4Header, payloadOffset uint8)

DecodeIPv4Header decodes a 20 byte IPv4 header from buf and returns the IPv4Header and the offset in bytes to the payload as calculated from the IHL field.

func (*IPv4Header) CalculateChecksum

func (iphdr *IPv4Header) CalculateChecksum() uint16

func (*IPv4Header) DSCP

func (iphdr *IPv4Header) DSCP() uint8

func (*IPv4Header) ECN

func (iphdr *IPv4Header) ECN() uint8

func (*IPv4Header) HeaderLength

func (iphdr *IPv4Header) HeaderLength() int

OffsetInBytes returns the total header length in bytes.

func (*IPv4Header) IHL

func (iphdr *IPv4Header) IHL() uint8

IHL returns the internet header length in 32bit words and is guaranteed to be within 0..15. Valid values for IHL are 5..15. When multiplied by 4 this yields number of bytes of the header, 20..60.

func (*IPv4Header) Put

func (iphdr *IPv4Header) Put(buf []byte)

Put marshals the IPv4 frame onto buf. buf needs to be 20 bytes in length or Put panics.

func (*IPv4Header) PutPseudo

func (iphdr *IPv4Header) PutPseudo(buf []byte)

PutPseudo marshals the pseudo-header representation of IPv4 frame onto buf. buf needs to be 12 bytes in length or PutPseudo panics.

+--------+--------+--------+--------+
|           Source Address          |
+--------+--------+--------+--------+
|         Destination Address       |
+--------+--------+--------+--------+
|  zero  |  PTCL  |    TCP Length   |
+--------+--------+--------+--------+

The TCP Length is the TCP header length plus the data length in octets (this is not an explicitly transmitted quantity, but is computed), and it does not count the 12 octets of the pseudo header (See RFC 9293)

func (*IPv4Header) String

func (iphdr *IPv4Header) String() string

func (*IPv4Header) Version

func (iphdr *IPv4Header) Version() uint8

type TCPHeader

type TCPHeader struct {
	SourcePort      uint16 // 0:2
	DestinationPort uint16 // 2:4
	// The sequence number of the first data octet in this segment (except when SYN present)
	// If SYN present this is the Initial Sequence Number (ISN) and the first data octet would be ISN+1.
	Seq seqs.Value // 4:8
	// Value of the next sequence number (Seq field) the sender is expecting to receive (when ACK is present).
	// In other words an Ack of X indicates all octets up to but not including X have been received.
	// Once a connection is established the ACK flag should always be set.
	Ack seqs.Value // 8:12
	// Contains 4 bit TCP offset (in 32bit words), the 6 bit TCP flags field and a 6 bit reserved field.
	OffsetAndFlags [1]uint16 // 12:14 bitfield
	WindowSizeRaw  uint16    // 14:16
	Checksum       uint16    // 16:18
	UrgentPtr      uint16    // 18:20
}

TCPHeader are the first 20 bytes of a TCP header. Does not include options.

func DecodeTCPHeader

func DecodeTCPHeader(buf []byte) (thdr TCPHeader, payloadOffset uint8)

DecodeTCPHeader decodes a TCP header from buf and returns the TCPHeader and the offset in bytes to the payload. Panics if buf is less than 20 bytes in length.

func (*TCPHeader) CalculateChecksumIPv4

func (thdr *TCPHeader) CalculateChecksumIPv4(pseudoHeader *IPv4Header, tcpOptions, payload []byte) uint16

CalculateChecksumIPv4 calculates the checksum of the TCP header, options and payload.

func (*TCPHeader) Flags

func (thdr *TCPHeader) Flags() seqs.Flags

func (*TCPHeader) Offset

func (thdr *TCPHeader) Offset() (tcpWords uint8)

Offset specifies the size of the TCP header in 32-bit words. The minimum size header is 5 words and the maximum is 15 words thus giving the minimum size of 20 bytes and maximum of 60 bytes, allowing for up to 40 bytes of options in the header. This field gets its name from the fact that it is also the offset from the start of the TCP segment to the actual data.

func (*TCPHeader) OffsetInBytes

func (thdr *TCPHeader) OffsetInBytes() uint8

OffsetInBytes returns the size of the TCP header in bytes, including options. See TCPHeader.Offset for more information.

func (*TCPHeader) Put

func (thdr *TCPHeader) Put(buf []byte)

Put marshals the TCP frame onto buf. buf needs to be 20 bytes in length or Put panics.

func (*TCPHeader) Segment

func (thdr *TCPHeader) Segment(payloadSize int) seqs.Segment

Segment returns a seqs.Segment representation of the TCP header. It requires the payload length as an argument, which can be calculated from IP and TCP headers as follows:

offset := eth.SizeEthernetHeader + ipOffset + tcpOffset // Are payload offsets.
end := ip.TotalLength + eth.SizeEthernetHeader
payload := buf[offset:end]
payloadSize := len(payload)

func (*TCPHeader) SetFlags

func (thdr *TCPHeader) SetFlags(v seqs.Flags)

func (*TCPHeader) SetOffset

func (thdr *TCPHeader) SetOffset(tcpWords uint8)

func (*TCPHeader) String

func (thdr *TCPHeader) String() string

func (*TCPHeader) WindowSize

func (thdr *TCPHeader) WindowSize() seqs.Size

WindowSize is a convenience method for obtaining a seqs.Size from the TCP header internal WindowSize 16bit field.

type UDPHeader

type UDPHeader struct {
	SourcePort      uint16 // 0:2
	DestinationPort uint16 // 2:4
	// Length specifies length in bytes of UDP header and UDP payload. The minimum length
	// is 8 bytes (UDP header length). This field should match the result of the IP header
	// TotalLength field minus the IP header size: udp.Length == ip.TotalLength - 4*ip.IHL
	Length   uint16 // 4:6
	Checksum uint16 // 6:8
}

UDPHeader represents a UDP header. 8 bytes in size. UDP is protocol 17.

func DecodeUDPHeader

func DecodeUDPHeader(buf []byte) (udp UDPHeader)

DecodeUDPHeader decodes a UDP header from buf. Panics if buf is less than 8 bytes in length.

func (*UDPHeader) CalculateChecksumIPv4

func (uhdr *UDPHeader) CalculateChecksumIPv4(pseudoHeader *IPv4Header, payload []byte) uint16

CalculateChecksumIPv4 calculates the checksum for a UDP packet over IPv4.

func (*UDPHeader) Put

func (uhdr *UDPHeader) Put(buf []byte)

Put marshals the UDPHeader onto buf. If buf's length is less than 8 then Put panics.

func (*UDPHeader) String

func (uhdr *UDPHeader) String() string

Directories

Path Synopsis
Code generated by "stringer" command for the types within this file; DO NOT EDIT.
Code generated by "stringer" command for the types within this file; DO NOT EDIT.
package ntp implements the NTP protocol as described in RFC 5905.
package ntp implements the NTP protocol as described in RFC 5905.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL