xref: /openbsd-src/share/man/man4/frame.4 (revision 825a12c4e5f1d0787f98f9d8f827217eb881fbf5)
1.\" $OpenBSD: frame.4,v 1.2 2024/12/16 21:39:29 jmc Exp $
2.\"
3.\" Copyright (c) 2024 David Gwynne <dlg@openbsd.org>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: December 16 2024 $
18.Dt FRAME 4
19.Os
20.Sh NAME
21.Nm frame
22.Nd frame protocol family
23.Sh SYNOPSIS
24.Cd "pseudo-device af_frame"
25.Pp
26.In sys/types.h
27.In net/frame.h
28.Sh DESCRIPTION
29The
30.Nm
31protocol family provides an interface for sending and receiving low
32level network interface frames through the normal
33.Xr socket 2
34mechanisms.
35.Pp
36The
37.Nm
38protocol family supports the
39.Dv SOCK_DGRAM
40socket type.
41Only root may create
42.Nm
43protocol family sockets.
44.Pp
45.Nm
46protocol family sockets are designed as an alternative to
47.Xr bpf 4
48for handling low data and packet rate communication protocols.
49Rather than filtering every frame entering the system before the
50network stack, like
51.Xr bpf 4 ,
52processing of the
53.Nm
54protocol family runs after the built in protocol handlers in the kernel,
55thus avoiding the overhead.
56For this reason, it is not possible to handle IPv4 or IPv6 packets
57with
58.Nm
59protocol sockets because the kernel network stack consumes them
60before the receive handling for
61.Nm
62sockets is run.
63.Pp
64Sockets can be created in the
65.Nm
66protocol family by using
67.Dv AF_FRAME
68as the
69.Fa domain
70argument to
71.Xr socket 2 .
72The type of interface, as per
73.In net/if_types.h ,
74is specified as the socket
75.Fa protocol .
76Currently only Ethernet interfaces are supported.
77.Pp
78Sockets bound to the
79.Nm
80family use the following address structure:
81.Bd -literal -offset indent
82#define FRAME_ADDRLEN	8
83#define FRAME_DATALEN	32
84
85struct sockaddr_frame {
86	uint8_t		sfrm_len;
87	uint8_t		sfrm_family;
88	uint16_t	sfrm_proto;
89	unsigned int	sfrm_ifindex;
90	uint8_t		sfrm_addr[FRAME_ADDRLEN];
91	char		sfrm_ifname[IFNAMSIZ];
92	uint8_t		sfrm_data[FRAME_DATALEN];
93};
94.Ed
95.Pp
96The interface used for transmitting or receiving frames with a
97.Nm
98domain socket may be specified by using an interface index with
99.Fa sfrm_ifindex ,
100or by name with
101.Fa sfrm_ifname .
102The use of other
103.Vt struct sockaddr_frame
104fields depends on the type of interface.
105.Ss Ethernet frame sockets
106A
107.Nm
108socket for use with Ethernet interfaces can be created using
109.Dv IFT_ETHER
110as the
111.Fa protocol
112argument to
113.Xr socket 2 :
114.Bd -literal -offset indent
115int sock = socket(AF_FRAME, SOCK_DGRAM, IFT_ETHER);
116.Ed
117.Pp
118The Ethernet protocol is specified with
119.Fa sfrm_proto
120in network byte order.
121Ethernet addresses are specified using the first 6 bytes of
122.Fa sfrm_addr .
123.Pp
124Ethernet
125.Nm
126sockets may receive frames on all interfaces by specifying 0 for
127.Va sfrm_ifindex
128when using
129.Xr bind 2 .
130Similarly, a
131.Dq wildcard
132local address of all zeros can be specified in
133.Fa sfrm_addr .
134.Pp
135An interface and address must be specified when sending Ethernet frames.
136.Pp
137Ethernet sockets support the following
138.Nm
139socket options
140using
141.Dv IFT_ETHER
142as the
143.Fa level
144argument with
145.Xr setsockopt 2
146and
147.Xr getsockopt 2 :
148.Bl -tag -width Ds
149.It Dv FRAME_RECVDSTADDR Ft int
150Enable or disable the reception of the Ethernet destination address as a
151.Vt struct ether_addr
152control message for frames received with
153.Xr recvmsg 2 .
154.It Dv FRAME_RECVPRIO Ft int
155Enable or disable the reception of the mbuf packet priority field as an
156.Vt int
157sized control message for frames received with
158.Xr recvmsg 2 .
159.It Dv FRAME_ADD_MEMBERSHIP Ft struct frame_mreq
160Configure an Ethernet interface to enable reception of
161frames destined to the specified multicast Ethernet address.
162.Bd -literal -offset indent
163struct frame_mreq {
164	unsigned int	fmr_ifindex;
165	uint8_t		fmr_addr[FRAME_ADDRLEN];
166	char		fmr_ifname[IFNAMSIZ];
167};
168.Ed
169.Pp
170An interface must be specified using either
171.Fa fmr_ifindex
172or
173.Fa fmr_ifname .
174The multicast Ethernet address is specified in the first 6 bytes of
175.Fa fmr_addr .
176.It Dv FRAME_DEL_MEMBERSHIP Ft struct frame_mreq
177Configure an Ethernet interface to disable reception of frames destined
178to the specified multicast Ethernet address.
179.It Dv FRAME_SENDPRIO Ft int
180Specify an mbuf priority value between
181.Dv IF_HDRPRIO_MIN
182.Pq 0
183and
184.Dv IF_HDRPRIO_MAX
185.Pq 7
186for frames sent with the Ethernet
187.Nm
188socket, or
189.Dv IF_HDRPRIO_PACKET
190to use the existing mbuf priority value.
191The default is
192.Dv IF_HDRPRIO_PACKET .
193.El
194.Sh EXAMPLES
195To receive LLDP frames on the em0 Ethernet interface:
196.Bd -literal -offset indent
197struct sockaddr_frame sfrm = {
198	.sfrm_family = AF_FRAME,
199	.sfrm_ifname = "em0",
200	.sfrm_proto = htons(ETHERTYPE_LLDP),
201};
202struct frame_mreq fmr = {
203	.fmr_ifname = "em0",
204	.fmr_addr = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e },
205};
206int sock;
207
208sock = socket(AF_FRAME, SOCK_DGRAM, IFT_ETHER);
209if (sock == -1)
210	err(1, "ethernet frame socket");
211if (bind(sock, (struct addrinfo *)&sfrm, sizeof(sfrm)) == -1)
212	err(1, "bind");
213if (setsockopt(sock, IFT_ETHER, FRAME_ADD_MEMBERSHIP,
214    &fmr, sizeof(fmr)) == -1)
215	err(1, "join lldp multicast group");
216
217for (;;) {
218	socklen_t sfrmlen = sizeof(sfrm);
219	uint8_t frame[2048];
220	ssize_t rv;
221
222	rv = recvfrom(sock, frame, sizeof(frame), 0,
223	    (struct sockaddr *)&sfrm, &sfrmlen);
224	if (rv == -1)
225		err(1, "lldp recv");
226	printf("received %zd bytes from %s", rv,
227	    ether_ntoa((struct ether_addr *)sfrm->sfrm_addr));
228}
229.Ed
230.Sh SEE ALSO
231.Xr socket 2 ,
232.Xr netintro 4
233.Sh HISTORY
234.Nm
235domain sockets appeared in
236.Ox 7.7 .
237.\" The
238.\" .Ox
239.\" implementation was influenced by the Linux
240.\" .Dv AF_PACKET
241.\" .Dq packet interface on device level
242.\" socket interface, but is not compatible with it.
243.Sh AUTHORS
244.An David Gwynne Aq Mt dlg@openbsd.org .
245