genetlink

package module
v1.3.2 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2023 License: MIT Imports: 9 Imported by: 65

README

Package genetlink implements generic netlink interactions and data types. MIT Licensed.

For more information about how netlink and generic netlink work, check out my blog series on Linux, Netlink, and Go.

If you have any questions or you'd like some guidance, please join us on Gophers Slack in the #networking channel!

Stability

See the CHANGELOG file for a description of changes between releases.

This package has a stable v1 API and any future breaking changes will prompt the release of a new major version. Features and bug fixes will continue to occur in the v1.x.x series.

This package only supports the two most recent major versions of Go, mirroring Go's own release policy. Older versions of Go may lack critical features and bug fixes which are necessary for this package to function correctly.

Documentation

Overview

Package genetlink implements generic netlink interactions and data types.

If you have any questions or you'd like some guidance, please join us on Gophers Slack (https://invite.slack.golangbridge.org) in the #networking channel!

Index

Examples

Constants

View Source
const Protocol = 0x10 // unix.NETLINK_GENERIC

Protocol is the netlink protocol constant used to specify generic netlink.

Variables

This section is empty.

Functions

This section is empty.

Types

type Conn

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

A Conn is a generic netlink connection. A Conn can be used to send and receive generic netlink messages to and from netlink.

A Conn is safe for concurrent use, but to avoid contention in high-throughput applications, the caller should almost certainly create a pool of Conns and distribute them among workers.

Example (GetFamily)

This example demonstrates using a genetlink.Conn's high level interface to query for a specific generic netlink family.

package main

import (
	"errors"
	"log"
	"os"

	"github.com/mdlayher/genetlink"
)

func main() {
	c, err := genetlink.Dial(nil)
	if err != nil {
		log.Fatalf("failed to dial generic netlink: %v", err)
	}
	defer c.Close()

	// Ask generic netlink about the generic netlink controller (nlctrl)'s
	// family information.
	const name = "nlctrl"
	family, err := c.GetFamily(name)
	if err != nil {
		// If a family doesn't exist, nothing to do.
		if errors.Is(err, os.ErrNotExist) {
			log.Printf("%q family not available", name)
			return
		}

		log.Fatalf("failed to query for family: %v", err)
	}

	log.Printf("%s: %+v", name, family)
}
Output:

Example (ListFamilies)

This example demonstrates using a genetlink.Conn's high level interface to query for all known generic netlink families.

package main

import (
	"log"

	"github.com/mdlayher/genetlink"
)

func main() {
	c, err := genetlink.Dial(nil)
	if err != nil {
		log.Fatalf("failed to dial generic netlink: %v", err)
	}
	defer c.Close()

	// Ask generic netlink about all families registered with it.
	families, err := c.ListFamilies()
	if err != nil {
		log.Fatalf("failed to query for families: %v", err)
	}

	for i, f := range families {
		log.Printf("#%02d: %+v", i, f)
	}
}
Output:

Example (Nl80211WiFi)

This example demonstrates using a genetlink.Conn's high level and low level interfaces to detect if nl80211 (netlink 802.11 WiFi device generic netlink family) is available, and if it is, sending a request to it to retrieve all WiFi interfaces.

package main

import (
	"errors"
	"log"
	"net"
	"os"

	"github.com/mdlayher/genetlink"
	"github.com/mdlayher/netlink"
)

func main() {
	c, err := genetlink.Dial(nil)
	if err != nil {
		log.Fatalf("failed to dial generic netlink: %v", err)
	}
	defer c.Close()

	// Constants which are sourced from nl80211.h.
	const (
		name = "nl80211"

		nl80211CommandGetInterface = 5

		nl80211AttributeInterfaceIndex = 3
		nl80211AttributeInterfaceName  = 4
		nl80211AttributeAttributeMAC   = 6
	)

	// Ask generic netlink if nl80211 is available.
	family, err := c.GetFamily(name)
	if err != nil {
		if errors.Is(err, os.ErrNotExist) {
			log.Printf("%q family not available", name)
			return
		}

		log.Fatalf("failed to query for family: %v", err)
	}

	// Ask nl80211 to dump a list of all WiFi interfaces.
	req := genetlink.Message{
		Header: genetlink.Header{
			Command: nl80211CommandGetInterface,
			Version: family.Version,
		},
	}

	// Send request specifically to nl80211 instead of generic netlink
	// controller (nlctrl).
	msgs, err := c.Execute(req, family.ID, netlink.Request|netlink.Dump)
	if err != nil {
		log.Fatalf("failed to execute: %v", err)
	}

	// ifInfo contains basic information about a WiFi interface.
	type ifInfo struct {
		Index int
		Name  string
		MAC   net.HardwareAddr
	}

	infos := make([]ifInfo, 0, len(msgs))
	for _, m := range msgs {
		// nl80211's response contains packed netlink attributes.
		ad, err := netlink.NewAttributeDecoder(m.Data)
		if err != nil {
			log.Fatalf("failed to create attribute decoder: %v", err)
		}

		// Gather data about interface from attributes.
		var info ifInfo
		for ad.Next() {
			switch ad.Type() {
			case nl80211AttributeInterfaceIndex:
				info.Index = int(ad.Uint32())
			case nl80211AttributeInterfaceName:
				info.Name = ad.String()
			case nl80211AttributeAttributeMAC:
				info.MAC = ad.Bytes()
			}
		}

		// Were any of the attributes malformed?
		if err := ad.Err(); err != nil {
			log.Fatalf("failed to decode attributes: %v", err)
		}

		infos = append(infos, info)
	}

	for i, info := range infos {
		log.Printf("#%02d: %+v", i, info)
	}
}
Output:

func Dial

func Dial(config *netlink.Config) (*Conn, error)

Dial dials a generic netlink connection. Config specifies optional configuration for the underlying netlink connection. If config is nil, a default configuration will be used.

func NewConn

func NewConn(c *netlink.Conn) *Conn

NewConn creates a Conn that wraps an existing *netlink.Conn for generic netlink communications.

NewConn is primarily useful for tests. Most applications should use Dial instead.

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection and unblocks any pending read operations.

func (*Conn) Execute

func (c *Conn) Execute(m Message, family uint16, flags netlink.HeaderFlags) ([]Message, error)

Execute sends a single Message to netlink using Send, receives one or more replies using Receive, and then checks the validity of the replies against the request using netlink.Validate.

Execute acquires a lock for the duration of the function call which blocks concurrent calls to Send and Receive, in order to ensure consistency between generic netlink request/reply messages.

See the documentation of Send, Receive, and netlink.Validate for details about each function.

func (*Conn) GetFamily

func (c *Conn) GetFamily(name string) (Family, error)

GetFamily retrieves a generic netlink family with the specified name.

If the family does not exist, the error value can be checked using `errors.Is(err, os.ErrNotExist)`.

func (*Conn) JoinGroup

func (c *Conn) JoinGroup(group uint32) error

JoinGroup joins a netlink multicast group by its ID.

func (*Conn) LeaveGroup

func (c *Conn) LeaveGroup(group uint32) error

LeaveGroup leaves a netlink multicast group by its ID.

func (*Conn) ListFamilies

func (c *Conn) ListFamilies() ([]Family, error)

ListFamilies retrieves all registered generic netlink families.

func (*Conn) Receive

func (c *Conn) Receive() ([]Message, []netlink.Message, error)

Receive receives one or more Messages from netlink. The netlink.Messages used to wrap each Message are available for later validation.

func (*Conn) RemoveBPF

func (c *Conn) RemoveBPF() error

RemoveBPF removes a BPF filter from a Conn.

func (*Conn) Send

func (c *Conn) Send(m Message, family uint16, flags netlink.HeaderFlags) (netlink.Message, error)

Send sends a single Message to netlink, wrapping it in a netlink.Message using the specified generic netlink family and flags. On success, Send returns a copy of the netlink.Message with all parameters populated, for later validation.

func (*Conn) SetBPF

func (c *Conn) SetBPF(filter []bpf.RawInstruction) error

SetBPF attaches an assembled BPF program to a Conn.

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline sets the read and write deadlines associated with the connection.

func (*Conn) SetOption

func (c *Conn) SetOption(option netlink.ConnOption, enable bool) error

SetOption enables or disables a netlink socket option for the Conn.

func (*Conn) SetReadBuffer

func (c *Conn) SetReadBuffer(bytes int) error

SetReadBuffer sets the size of the operating system's receive buffer associated with the Conn.

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline sets the read deadline associated with the connection.

func (*Conn) SetWriteBuffer

func (c *Conn) SetWriteBuffer(bytes int) error

SetWriteBuffer sets the size of the operating system's transmit buffer associated with the Conn.

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets the write deadline associated with the connection.

func (*Conn) SyscallConn

func (c *Conn) SyscallConn() (syscall.RawConn, error)

SyscallConn returns a raw network connection. This implements the syscall.Conn interface.

SyscallConn is intended for advanced use cases, such as getting and setting arbitrary socket options using the netlink socket's file descriptor.

Once invoked, it is the caller's responsibility to ensure that operations performed using Conn and the syscall.RawConn do not conflict with each other.

type Family

type Family struct {
	ID      uint16
	Version uint8
	Name    string
	Groups  []MulticastGroup
}

A Family is a generic netlink family.

type Header struct {
	// Command specifies a command to issue to netlink.
	Command uint8

	// Version specifies the version of a command to use.
	Version uint8
}

A Header is a generic netlink header. A Header is sent and received with each generic netlink message to indicate metadata regarding a Message.

type Message

type Message struct {
	Header Header
	Data   []byte
}

A Message is a generic netlink message. It contains a Header and an arbitrary byte payload, which may be decoded using information from the Header.

Data is encoded using the native endianness of the host system. Use the netlink.AttributeDecoder and netlink.AttributeEncoder types to decode and encode data.

func (Message) MarshalBinary

func (m Message) MarshalBinary() ([]byte, error)

MarshalBinary marshals a Message into a byte slice.

func (*Message) UnmarshalBinary

func (m *Message) UnmarshalBinary(b []byte) error

UnmarshalBinary unmarshals the contents of a byte slice into a Message.

type MulticastGroup

type MulticastGroup struct {
	ID   uint32
	Name string
}

A MulticastGroup is a generic netlink multicast group, which can be joined for notifications from generic netlink families when specific events take place.

Directories

Path Synopsis
Package genltest provides utilities for generic netlink testing.
Package genltest provides utilities for generic netlink testing.

Jump to

Keyboard shortcuts

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