FRAME(4)
β¨ NAME β¨
frame β frame protocol family. Hii bestie, welcome to FRAME(4) from the Kernel Interfaces Manual β we're about to make low-level frame stuff make sense π
π οΈ SYNOPSIS π οΈ
pseudo-device af_frame
#include <sys/types.h>
#include <net/frame.h>
π DESCRIPTION π
The frame protocol family is literally your interface for sending and receiving low level network interface frames through the normal socket(2) mechanisms. Slay.
It supports the SOCK_DGRAM socket type. And hear me out: only root may create frame protocol family sockets. That's the vibe check, bestie π
frame protocol family sockets are designed as an alternative to bpf(4) for handling low data and packet rate communication protocols. Rather than filtering every frame entering the system before the network stack, like bpf(4), processing of the frame protocol family runs after the built in protocol handlers in the kernel, thus avoiding the overhead β¨. For this reason, it is not possible to handle IPv4 or IPv6 packets with frame protocol sockets because the kernel network stack consumes them before the receive handling for frame sockets is run. Not me trying to catch those packets β they're already gone π.
Sockets can be created in the frame protocol family by using AF_FRAME as the domain argument to socket(2). The type of interface, as per <net/if_types.h>, is specified as the socket protocol. Currently only Ethernet interfaces are supported. Periodt.
Sockets bound to the frame family use the following address structure β copy it exactly, no freestyling:
#define FRAME_ADDRLEN 8
#define FRAME_DATALEN 32
struct sockaddr_frame {
uint8_t sfrm_len;
uint8_t sfrm_family;
uint16_t sfrm_proto;
unsigned int sfrm_ifindex;
uint8_t sfrm_addr[FRAME_ADDRLEN];
char sfrm_ifname[IFNAMSIZ];
uint8_t sfrm_data[FRAME_DATALEN];
};
The interface used for transmitting or receiving frames with a frame domain socket may be specified by using an interface index with sfrm_ifindex, or by name with sfrm_ifname. The use of other struct sockaddr_frame fields depends on the type of interface. Iykyk.
π Ethernet frame sockets π
A frame socket for use with Ethernet interfaces can be created using IFT_ETHER as the protocol argument to socket(2):
int sock = socket(AF_FRAME, SOCK_DGRAM, IFT_ETHER);
The Ethernet protocol is specified with sfrm_proto in network byte order. Ethernet addresses are specified using the first 6 bytes of sfrm_addr. Cute.
Ethernet frame sockets may receive frames on all interfaces by specifying 0 for sfrm_ifindex when using bind(2). Similarly, a βwildcardβ local address of all zeros can be specified in sfrm_addr. It's giving "catch everything" energy π¦.
An interface and address must be specified when sending Ethernet frames. No cap.
Ethernet sockets support the following frame socket options using IFT_ETHER as the level argument with setsockopt(2) and getsockopt(2):
FRAME_RECVDSTADDRintβ Enable or disable the reception of the Ethernet destination address as astruct ether_addrcontrol message for frames received withrecvmsg(2).FRAME_RECVPRIOintβ Enable or disable the reception of the mbuf packet priority field as anintsized control message for frames received withrecvmsg(2).FRAME_ADD_MEMBERSHIPstruct frame_mreqβ Configure an Ethernet interface to enable reception of frames destined to the specified multicast Ethernet address. An interface must be specified using eitherfmr_ifindexorfmr_ifname. The multicast Ethernet address is specified in the first 6 bytes offmr_addr. The struct is exactly:
struct frame_mreq {
unsigned int fmr_ifindex;
uint8_t fmr_addr[FRAME_ADDRLEN];
char fmr_ifname[IFNAMSIZ];
};
FRAME_DEL_MEMBERSHIPstruct frame_mreqβ Configure an Ethernet interface to disable reception of frames destined to the specified multicast Ethernet address. Uses the samestruct frame_mreqas above, bestie.FRAME_SENDPRIOintβ Specify an mbuf priority value betweenIF_HDRPRIO_MIN(0) andIF_HDRPRIO_MAX(7) for frames sent with the Ethernet frame socket, orIF_HDRPRIO_PACKETto use the existing mbuf priority value. The default isIF_HDRPRIO_PACKET.
π§ͺ EXAMPLES π§ͺ
To receive LLDP frames on the em0 Ethernet interface:
struct sockaddr_frame sfrm = {
.sfrm_family = AF_FRAME,
.sfrm_ifname = "em0",
.sfrm_proto = htons(ETHERTYPE_LLDP),
};
struct frame_mreq fmr = {
.fmr_ifname = "em0",
.fmr_addr = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e },
};
int sock;
sock = socket(AF_FRAME, SOCK_DGRAM, IFT_ETHER);
if (sock == -1)
err(1, "ethernet frame socket");
if (bind(sock, (struct sockaddr *)&sfrm, sizeof(sfrm)) == -1)
err(1, "bind");
if (setsockopt(sock, IFT_ETHER, FRAME_ADD_MEMBERSHIP,
&fmr, sizeof(fmr)) == -1)
err(1, "join lldp multicast group");
for (;;) {
socklen_t sfrmlen = sizeof(sfrm);
uint8_t frame[2048];
ssize_t rv;
rv = recvfrom(sock, frame, sizeof(frame), 0,
(struct sockaddr *)&sfrm, &sfrmlen);
if (rv == -1)
err(1, "lldp recv");
printf("received %zd bytes from %s", rv,
ether_ntoa((struct ether_addr *)sfrm.sfrm_addr));
}
π SEE ALSO π
π HISTORY π
frame domain sockets appeared in OpenBSD 7.7. Iconic.
π AUTHORS π
David Gwynne <dlg@openbsd.org>. π«Ά
Okay bestie, this page came from the Debian May 16, 2025 build of FRAME(4) β mwah π
π¦ where this page comes from
- nixpkgs unstable: cvs-export
- Copyright (c) 2024 David Gwynne <dlg@openbsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms