1 //! Types and constants for `rustix::net`.
2 
3 use crate::backend::c;
4 use bitflags::bitflags;
5 
6 /// A type for holding raw integer socket types.
7 pub type RawSocketType = u32;
8 
9 /// `SOCK_*` constants for use with [`socket`].
10 ///
11 /// [`socket`]: crate::net::socket()
12 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
13 #[repr(transparent)]
14 pub struct SocketType(pub(crate) RawSocketType);
15 
16 #[rustfmt::skip]
17 impl SocketType {
18     /// `SOCK_STREAM`
19     pub const STREAM: Self = Self(c::SOCK_STREAM as _);
20 
21     /// `SOCK_DGRAM`
22     pub const DGRAM: Self = Self(c::SOCK_DGRAM as _);
23 
24     /// `SOCK_SEQPACKET`
25     #[cfg(not(target_os = "espidf"))]
26     pub const SEQPACKET: Self = Self(c::SOCK_SEQPACKET as _);
27 
28     /// `SOCK_RAW`
29     #[cfg(not(target_os = "espidf"))]
30     pub const RAW: Self = Self(c::SOCK_RAW as _);
31 
32     /// `SOCK_RDM`
33     #[cfg(not(any(target_os = "espidf", target_os = "haiku")))]
34     pub const RDM: Self = Self(c::SOCK_RDM as _);
35 
36     /// Constructs a `SocketType` from a raw integer.
37     #[inline]
from_raw(raw: RawSocketType) -> Self38     pub const fn from_raw(raw: RawSocketType) -> Self {
39         Self(raw)
40     }
41 
42     /// Returns the raw integer for this `SocketType`.
43     #[inline]
as_raw(self) -> RawSocketType44     pub const fn as_raw(self) -> RawSocketType {
45         self.0
46     }
47 }
48 
49 /// A type for holding raw integer address families.
50 pub type RawAddressFamily = c::sa_family_t;
51 
52 /// `AF_*` constants for use with [`socket`], [`socket_with`], and
53 /// [`socketpair`].
54 ///
55 /// [`socket`]: crate::net::socket()
56 /// [`socket_with`]: crate::net::socket_with
57 /// [`socketpair`]: crate::net::socketpair()
58 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
59 #[repr(transparent)]
60 pub struct AddressFamily(pub(crate) RawAddressFamily);
61 
62 #[rustfmt::skip]
63 #[allow(non_upper_case_globals)]
64 impl AddressFamily {
65     /// `AF_UNSPEC`
66     pub const UNSPEC: Self = Self(c::AF_UNSPEC as _);
67     /// `AF_INET`
68     ///
69     /// # References
70     ///  - [Linux]
71     ///
72     /// [Linux]: https://man7.org/linux/man-pages/man7/ip.7.html
73     pub const INET: Self = Self(c::AF_INET as _);
74     /// `AF_INET6`
75     ///
76     /// # References
77     ///  - [Linux]
78     ///
79     /// [Linux]: https://man7.org/linux/man-pages/man7/ipv6.7.html
80     pub const INET6: Self = Self(c::AF_INET6 as _);
81     /// `AF_NETLINK`
82     ///
83     /// # References
84     ///  - [Linux]
85     ///
86     /// [Linux]: https://man7.org/linux/man-pages/man7/netlink.7.html
87     #[cfg(not(any(
88         bsd,
89         solarish,
90         windows,
91         target_os = "aix",
92         target_os = "espidf",
93         target_os = "haiku",
94         target_os = "nto",
95         target_os = "vita",
96     )))]
97     pub const NETLINK: Self = Self(c::AF_NETLINK as _);
98     /// `AF_UNIX`, aka `AF_LOCAL`
99     #[doc(alias = "LOCAL")]
100     pub const UNIX: Self = Self(c::AF_UNIX as _);
101     /// `AF_AX25`
102     #[cfg(not(any(
103         bsd,
104         solarish,
105         windows,
106         target_os = "aix",
107         target_os = "espidf",
108         target_os = "haiku",
109         target_os = "nto",
110         target_os = "vita",
111     )))]
112     pub const AX25: Self = Self(c::AF_AX25 as _);
113     /// `AF_IPX`
114     #[cfg(not(any(
115         target_os = "aix",
116         target_os = "espidf",
117         target_os = "vita",
118     )))]
119     pub const IPX: Self = Self(c::AF_IPX as _);
120     /// `AF_APPLETALK`
121     #[cfg(not(any(target_os = "espidf", target_os = "vita")))]
122     pub const APPLETALK: Self = Self(c::AF_APPLETALK as _);
123     /// `AF_NETROM`
124     #[cfg(not(any(
125         bsd,
126         solarish,
127         windows,
128         target_os = "aix",
129         target_os = "espidf",
130         target_os = "haiku",
131         target_os = "nto",
132         target_os = "vita",
133     )))]
134     pub const NETROM: Self = Self(c::AF_NETROM as _);
135     /// `AF_BRIDGE`
136     #[cfg(not(any(
137         bsd,
138         solarish,
139         windows,
140         target_os = "aix",
141         target_os = "espidf",
142         target_os = "haiku",
143         target_os = "nto",
144         target_os = "vita",
145     )))]
146     pub const BRIDGE: Self = Self(c::AF_BRIDGE as _);
147     /// `AF_ATMPVC`
148     #[cfg(not(any(
149         bsd,
150         solarish,
151         windows,
152         target_os = "aix",
153         target_os = "espidf",
154         target_os = "haiku",
155         target_os = "nto",
156         target_os = "vita",
157     )))]
158     pub const ATMPVC: Self = Self(c::AF_ATMPVC as _);
159     /// `AF_X25`
160     #[cfg(not(any(
161         bsd,
162         windows,
163         target_os = "aix",
164         target_os = "espidf",
165         target_os = "haiku",
166         target_os = "nto",
167         target_os = "vita",
168     )))]
169     pub const X25: Self = Self(c::AF_X25 as _);
170     /// `AF_ROSE`
171     #[cfg(not(any(
172         bsd,
173         solarish,
174         windows,
175         target_os = "aix",
176         target_os = "espidf",
177         target_os = "haiku",
178         target_os = "nto",
179         target_os = "vita",
180     )))]
181     pub const ROSE: Self = Self(c::AF_ROSE as _);
182     /// `AF_DECnet`
183     #[cfg(not(any(target_os = "espidf", target_os = "haiku", target_os = "vita")))]
184     pub const DECnet: Self = Self(c::AF_DECnet as _);
185     /// `AF_NETBEUI`
186     #[cfg(not(any(
187         bsd,
188         solarish,
189         windows,
190         target_os = "aix",
191         target_os = "espidf",
192         target_os = "haiku",
193         target_os = "nto",
194         target_os = "vita",
195     )))]
196     pub const NETBEUI: Self = Self(c::AF_NETBEUI as _);
197     /// `AF_SECURITY`
198     #[cfg(not(any(
199         bsd,
200         solarish,
201         windows,
202         target_os = "aix",
203         target_os = "espidf",
204         target_os = "haiku",
205         target_os = "nto",
206         target_os = "vita",
207     )))]
208     pub const SECURITY: Self = Self(c::AF_SECURITY as _);
209     /// `AF_KEY`
210     #[cfg(not(any(
211         bsd,
212         windows,
213         target_os = "aix",
214         target_os = "espidf",
215         target_os = "haiku",
216         target_os = "nto",
217         target_os = "vita",
218     )))]
219     pub const KEY: Self = Self(c::AF_KEY as _);
220     /// `AF_PACKET`
221     ///
222     /// # References
223     ///  - [Linux]
224     ///
225     /// [Linux]: https://man7.org/linux/man-pages/man7/packet.7.html
226     #[cfg(not(any(
227         bsd,
228         windows,
229         target_os = "aix",
230         target_os = "espidf",
231         target_os = "haiku",
232         target_os = "nto",
233         target_os = "vita",
234     )))]
235     pub const PACKET: Self = Self(c::AF_PACKET as _);
236     /// `AF_ASH`
237     #[cfg(not(any(
238         bsd,
239         solarish,
240         windows,
241         target_os = "aix",
242         target_os = "espidf",
243         target_os = "haiku",
244         target_os = "nto",
245         target_os = "vita",
246     )))]
247     pub const ASH: Self = Self(c::AF_ASH as _);
248     /// `AF_ECONET`
249     #[cfg(not(any(
250         bsd,
251         solarish,
252         windows,
253         target_os = "aix",
254         target_os = "espidf",
255         target_os = "haiku",
256         target_os = "nto",
257         target_os = "vita",
258     )))]
259     pub const ECONET: Self = Self(c::AF_ECONET as _);
260     /// `AF_ATMSVC`
261     #[cfg(not(any(
262         bsd,
263         solarish,
264         windows,
265         target_os = "aix",
266         target_os = "espidf",
267         target_os = "haiku",
268         target_os = "nto",
269         target_os = "vita",
270     )))]
271     pub const ATMSVC: Self = Self(c::AF_ATMSVC as _);
272     /// `AF_RDS`
273     #[cfg(not(any(
274         bsd,
275         solarish,
276         windows,
277         target_os = "aix",
278         target_os = "espidf",
279         target_os = "haiku",
280         target_os = "nto",
281         target_os = "vita",
282     )))]
283     pub const RDS: Self = Self(c::AF_RDS as _);
284     /// `AF_SNA`
285     #[cfg(not(any(target_os = "espidf", target_os = "haiku", target_os = "vita")))]
286     pub const SNA: Self = Self(c::AF_SNA as _);
287     /// `AF_IRDA`
288     #[cfg(not(any(
289         bsd,
290         solarish,
291         target_os = "aix",
292         target_os = "espidf",
293         target_os = "haiku",
294         target_os = "nto",
295         target_os = "vita",
296     )))]
297     pub const IRDA: Self = Self(c::AF_IRDA as _);
298     /// `AF_PPPOX`
299     #[cfg(not(any(
300         bsd,
301         solarish,
302         windows,
303         target_os = "aix",
304         target_os = "espidf",
305         target_os = "haiku",
306         target_os = "nto",
307         target_os = "vita",
308     )))]
309     pub const PPPOX: Self = Self(c::AF_PPPOX as _);
310     /// `AF_WANPIPE`
311     #[cfg(not(any(
312         bsd,
313         solarish,
314         windows,
315         target_os = "aix",
316         target_os = "espidf",
317         target_os = "haiku",
318         target_os = "nto",
319         target_os = "vita",
320     )))]
321     pub const WANPIPE: Self = Self(c::AF_WANPIPE as _);
322     /// `AF_LLC`
323     #[cfg(not(any(
324         bsd,
325         solarish,
326         windows,
327         target_os = "aix",
328         target_os = "espidf",
329         target_os = "haiku",
330         target_os = "nto",
331         target_os = "vita",
332     )))]
333     pub const LLC: Self = Self(c::AF_LLC as _);
334     /// `AF_CAN`
335     #[cfg(not(any(
336         bsd,
337         solarish,
338         windows,
339         target_os = "aix",
340         target_os = "espidf",
341         target_os = "haiku",
342         target_os = "nto",
343         target_os = "vita",
344     )))]
345     pub const CAN: Self = Self(c::AF_CAN as _);
346     /// `AF_TIPC`
347     #[cfg(not(any(
348         bsd,
349         solarish,
350         windows,
351         target_os = "aix",
352         target_os = "espidf",
353         target_os = "haiku",
354         target_os = "nto",
355         target_os = "vita",
356     )))]
357     pub const TIPC: Self = Self(c::AF_TIPC as _);
358     /// `AF_BLUETOOTH`
359     #[cfg(not(any(
360         apple,
361         solarish,
362         windows,
363         target_os = "aix",
364         target_os = "espidf",
365         target_os = "vita",
366     )))]
367     pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _);
368     /// `AF_IUCV`
369     #[cfg(not(any(
370         bsd,
371         solarish,
372         windows,
373         target_os = "aix",
374         target_os = "espidf",
375         target_os = "haiku",
376         target_os = "nto",
377         target_os = "vita",
378     )))]
379     pub const IUCV: Self = Self(c::AF_IUCV as _);
380     /// `AF_RXRPC`
381     #[cfg(not(any(
382         bsd,
383         solarish,
384         windows,
385         target_os = "aix",
386         target_os = "espidf",
387         target_os = "haiku",
388         target_os = "nto",
389         target_os = "vita",
390     )))]
391     pub const RXRPC: Self = Self(c::AF_RXRPC as _);
392     /// `AF_ISDN`
393     #[cfg(not(any(
394         solarish,
395         windows,
396         target_os = "aix",
397         target_os = "espidf",
398         target_os = "haiku",
399         target_os = "vita",
400     )))]
401     pub const ISDN: Self = Self(c::AF_ISDN as _);
402     /// `AF_PHONET`
403     #[cfg(not(any(
404         bsd,
405         solarish,
406         windows,
407         target_os = "aix",
408         target_os = "espidf",
409         target_os = "haiku",
410         target_os = "nto",
411         target_os = "vita",
412     )))]
413     pub const PHONET: Self = Self(c::AF_PHONET as _);
414     /// `AF_IEEE802154`
415     #[cfg(not(any(
416         bsd,
417         solarish,
418         windows,
419         target_os = "aix",
420         target_os = "espidf",
421         target_os = "haiku",
422         target_os = "nto",
423         target_os = "vita",
424     )))]
425     pub const IEEE802154: Self = Self(c::AF_IEEE802154 as _);
426     /// `AF_802`
427     #[cfg(solarish)]
428     pub const EIGHT_ZERO_TWO: Self = Self(c::AF_802 as _);
429     #[cfg(target_os = "fuchsia")]
430     /// `AF_ALG`
431     pub const ALG: Self = Self(c::AF_ALG as _);
432     #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "nto"))]
433     /// `AF_ARP`
434     pub const ARP: Self = Self(c::AF_ARP as _);
435     /// `AF_ATM`
436     #[cfg(freebsdlike)]
437     pub const ATM: Self = Self(c::AF_ATM as _);
438     /// `AF_CAIF`
439     #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia"))]
440     pub const CAIF: Self = Self(c::AF_CAIF as _);
441     /// `AF_CCITT`
442     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))]
443     pub const CCITT: Self = Self(c::AF_CCITT as _);
444     /// `AF_CHAOS`
445     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))]
446     pub const CHAOS: Self = Self(c::AF_CHAOS as _);
447     /// `AF_CNT`
448     #[cfg(any(bsd, target_os = "nto"))]
449     pub const CNT: Self = Self(c::AF_CNT as _);
450     /// `AF_COIP`
451     #[cfg(any(bsd, target_os = "nto"))]
452     pub const COIP: Self = Self(c::AF_COIP as _);
453     /// `AF_DATAKIT`
454     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))]
455     pub const DATAKIT: Self = Self(c::AF_DATAKIT as _);
456     /// `AF_DLI`
457     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "haiku", target_os = "nto"))]
458     pub const DLI: Self = Self(c::AF_DLI as _);
459     /// `AF_E164`
460     #[cfg(any(bsd, target_os = "nto"))]
461     pub const E164: Self = Self(c::AF_E164 as _);
462     /// `AF_ECMA`
463     #[cfg(any(apple, freebsdlike, solarish, target_os = "aix", target_os = "nto", target_os = "openbsd"))]
464     pub const ECMA: Self = Self(c::AF_ECMA as _);
465     /// `AF_ENCAP`
466     #[cfg(target_os = "openbsd")]
467     pub const ENCAP: Self = Self(c::AF_ENCAP as _);
468     /// `AF_FILE`
469     #[cfg(solarish)]
470     pub const FILE: Self = Self(c::AF_FILE as _);
471     /// `AF_GOSIP`
472     #[cfg(solarish)]
473     pub const GOSIP: Self = Self(c::AF_GOSIP as _);
474     /// `AF_HYLINK`
475     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))]
476     pub const HYLINK: Self = Self(c::AF_HYLINK as _);
477     /// `AF_IB`
478     #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))]
479     pub const IB: Self = Self(c::AF_IB as _);
480     /// `AF_IMPLINK`
481     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))]
482     pub const IMPLINK: Self = Self(c::AF_IMPLINK as _);
483     /// `AF_IEEE80211`
484     #[cfg(any(apple, freebsdlike, target_os = "netbsd"))]
485     pub const IEEE80211: Self = Self(c::AF_IEEE80211 as _);
486     /// `AF_INET6_SDP`
487     #[cfg(target_os = "freebsd")]
488     pub const INET6_SDP: Self = Self(c::AF_INET6_SDP as _);
489     /// `AF_INET_OFFLOAD`
490     #[cfg(solarish)]
491     pub const INET_OFFLOAD: Self = Self(c::AF_INET_OFFLOAD as _);
492     /// `AF_INET_SDP`
493     #[cfg(target_os = "freebsd")]
494     pub const INET_SDP: Self = Self(c::AF_INET_SDP as _);
495     /// `AF_INTF`
496     #[cfg(target_os = "aix")]
497     pub const INTF: Self = Self(c::AF_INTF as _);
498     /// `AF_ISO`
499     #[cfg(any(bsd, target_os = "aix", target_os = "nto"))]
500     pub const ISO: Self = Self(c::AF_ISO as _);
501     /// `AF_LAT`
502     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))]
503     pub const LAT: Self = Self(c::AF_LAT as _);
504     /// `AF_LINK`
505     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "haiku", target_os = "nto"))]
506     pub const LINK: Self = Self(c::AF_LINK as _);
507     /// `AF_MPLS`
508     #[cfg(any(netbsdlike, target_os = "dragonfly", target_os = "emscripten", target_os = "fuchsia"))]
509     pub const MPLS: Self = Self(c::AF_MPLS as _);
510     /// `AF_NATM`
511     #[cfg(any(bsd, target_os = "nto"))]
512     pub const NATM: Self = Self(c::AF_NATM as _);
513     /// `AF_NBS`
514     #[cfg(solarish)]
515     pub const NBS: Self = Self(c::AF_NBS as _);
516     /// `AF_NCA`
517     #[cfg(solarish)]
518     pub const NCA: Self = Self(c::AF_NCA as _);
519     /// `AF_NDD`
520     #[cfg(target_os = "aix")]
521     pub const NDD: Self = Self(c::AF_NDD as _);
522     /// `AF_NDRV`
523     #[cfg(apple)]
524     pub const NDRV: Self = Self(c::AF_NDRV as _);
525     /// `AF_NETBIOS`
526     #[cfg(any(apple, freebsdlike))]
527     pub const NETBIOS: Self = Self(c::AF_NETBIOS as _);
528     /// `AF_NETGRAPH`
529     #[cfg(freebsdlike)]
530     pub const NETGRAPH: Self = Self(c::AF_NETGRAPH as _);
531     /// `AF_NIT`
532     #[cfg(solarish)]
533     pub const NIT: Self = Self(c::AF_NIT as _);
534     /// `AF_NOTIFY`
535     #[cfg(target_os = "haiku")]
536     pub const NOTIFY: Self = Self(c::AF_NOTIFY as _);
537     /// `AF_NFC`
538     #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))]
539     pub const NFC: Self = Self(c::AF_NFC as _);
540     /// `AF_NS`
541     #[cfg(any(apple, solarish, netbsdlike, target_os = "aix", target_os = "nto"))]
542     pub const NS: Self = Self(c::AF_NS as _);
543     /// `AF_OROUTE`
544     #[cfg(target_os = "netbsd")]
545     pub const OROUTE: Self = Self(c::AF_OROUTE as _);
546     /// `AF_OSI`
547     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))]
548     pub const OSI: Self = Self(c::AF_OSI as _);
549     /// `AF_OSINET`
550     #[cfg(solarish)]
551     pub const OSINET: Self = Self(c::AF_OSINET as _);
552     /// `AF_POLICY`
553     #[cfg(solarish)]
554     pub const POLICY: Self = Self(c::AF_POLICY as _);
555     /// `AF_PPP`
556     #[cfg(apple)]
557     pub const PPP: Self = Self(c::AF_PPP as _);
558     /// `AF_PUP`
559     #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))]
560     pub const PUP: Self = Self(c::AF_PUP as _);
561     /// `AF_RIF`
562     #[cfg(target_os = "aix")]
563     pub const RIF: Self = Self(c::AF_RIF as _);
564     /// `AF_ROUTE`
565     #[cfg(any(bsd, solarish, target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "haiku", target_os = "nto"))]
566     pub const ROUTE: Self = Self(c::AF_ROUTE as _);
567     /// `AF_SCLUSTER`
568     #[cfg(target_os = "freebsd")]
569     pub const SCLUSTER: Self = Self(c::AF_SCLUSTER as _);
570     /// `AF_SIP`
571     #[cfg(any(apple, target_os = "freebsd", target_os = "openbsd"))]
572     pub const SIP: Self = Self(c::AF_SIP as _);
573     /// `AF_SLOW`
574     #[cfg(target_os = "freebsd")]
575     pub const SLOW: Self = Self(c::AF_SLOW as _);
576     /// `AF_SYS_CONTROL`
577     #[cfg(apple)]
578     pub const SYS_CONTROL: Self = Self(c::AF_SYS_CONTROL as _);
579     /// `AF_SYSTEM`
580     #[cfg(apple)]
581     pub const SYSTEM: Self = Self(c::AF_SYSTEM as _);
582     /// `AF_TRILL`
583     #[cfg(solarish)]
584     pub const TRILL: Self = Self(c::AF_TRILL as _);
585     /// `AF_UTUN`
586     #[cfg(apple)]
587     pub const UTUN: Self = Self(c::AF_UTUN as _);
588     /// `AF_VSOCK`
589     #[cfg(any(apple, target_os = "emscripten", target_os = "fuchsia"))]
590     pub const VSOCK: Self = Self(c::AF_VSOCK as _);
591     /// `AF_XDP`
592     #[cfg(target_os = "linux")]
593     pub const XDP: Self = Self(c::AF_XDP as _);
594 
595     /// Constructs a `AddressFamily` from a raw integer.
596     #[inline]
from_raw(raw: RawAddressFamily) -> Self597     pub const fn from_raw(raw: RawAddressFamily) -> Self {
598         Self(raw)
599     }
600 
601     /// Returns the raw integer for this `AddressFamily`.
602     #[inline]
as_raw(self) -> RawAddressFamily603     pub const fn as_raw(self) -> RawAddressFamily {
604         self.0
605     }
606 }
607 
608 /// A type for holding raw integer protocols.
609 pub type RawProtocol = core::num::NonZeroU32;
610 
new_raw_protocol(u: u32) -> RawProtocol611 const fn new_raw_protocol(u: u32) -> RawProtocol {
612     match RawProtocol::new(u) {
613         Some(p) => p,
614         None => panic!("new_raw_protocol: protocol must be non-zero"),
615     }
616 }
617 
618 /// `IPPROTO_*` and other constants for use with [`socket`], [`socket_with`],
619 /// and [`socketpair`] when a nondefault value is desired. See the [`ipproto`],
620 /// [`sysproto`], and [`netlink`] modules for possible values.
621 ///
622 /// For the default values, such as `IPPROTO_IP` or `NETLINK_ROUTE`, pass
623 /// `None` as the `protocol` argument in these functions.
624 ///
625 /// [`socket`]: crate::net::socket()
626 /// [`socket_with`]: crate::net::socket_with
627 /// [`socketpair`]: crate::net::socketpair()
628 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
629 #[repr(transparent)]
630 #[doc(alias = "IPPROTO_IP")]
631 #[doc(alias = "NETLINK_ROUTE")]
632 pub struct Protocol(pub(crate) RawProtocol);
633 
634 /// `IPPROTO_*` constants.
635 ///
636 /// For `IPPROTO_IP`, pass `None` as the `protocol` argument.
637 pub mod ipproto {
638     use super::{new_raw_protocol, Protocol};
639     use crate::backend::c;
640 
641     /// `IPPROTO_ICMP`
642     pub const ICMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ICMP as _));
643     /// `IPPROTO_IGMP`
644     #[cfg(not(any(
645         solarish,
646         target_os = "espidf",
647         target_os = "haiku",
648         target_os = "vita"
649     )))]
650     pub const IGMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IGMP as _));
651     /// `IPPROTO_IPIP`
652     #[cfg(not(any(
653         solarish,
654         windows,
655         target_os = "espidf",
656         target_os = "haiku",
657         target_os = "vita"
658     )))]
659     pub const IPIP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IPIP as _));
660     /// `IPPROTO_TCP`
661     pub const TCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_TCP as _));
662     /// `IPPROTO_EGP`
663     #[cfg(not(any(
664         solarish,
665         target_os = "espidf",
666         target_os = "haiku",
667         target_os = "vita"
668     )))]
669     pub const EGP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_EGP as _));
670     /// `IPPROTO_PUP`
671     #[cfg(not(any(
672         solarish,
673         target_os = "espidf",
674         target_os = "haiku",
675         target_os = "vita"
676     )))]
677     pub const PUP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_PUP as _));
678     /// `IPPROTO_UDP`
679     pub const UDP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_UDP as _));
680     /// `IPPROTO_IDP`
681     #[cfg(not(any(
682         solarish,
683         target_os = "espidf",
684         target_os = "haiku",
685         target_os = "vita"
686     )))]
687     pub const IDP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IDP as _));
688     /// `IPPROTO_TP`
689     #[cfg(not(any(
690         solarish,
691         windows,
692         target_os = "espidf",
693         target_os = "haiku",
694         target_os = "vita"
695     )))]
696     pub const TP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_TP as _));
697     /// `IPPROTO_DCCP`
698     #[cfg(not(any(
699         apple,
700         solarish,
701         windows,
702         target_os = "aix",
703         target_os = "dragonfly",
704         target_os = "espidf",
705         target_os = "haiku",
706         target_os = "nto",
707         target_os = "openbsd",
708         target_os = "vita",
709     )))]
710     pub const DCCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_DCCP as _));
711     /// `IPPROTO_IPV6`
712     pub const IPV6: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IPV6 as _));
713     /// `IPPROTO_RSVP`
714     #[cfg(not(any(
715         solarish,
716         windows,
717         target_os = "espidf",
718         target_os = "haiku",
719         target_os = "vita"
720     )))]
721     pub const RSVP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_RSVP as _));
722     /// `IPPROTO_GRE`
723     #[cfg(not(any(
724         solarish,
725         windows,
726         target_os = "espidf",
727         target_os = "haiku",
728         target_os = "vita"
729     )))]
730     pub const GRE: Protocol = Protocol(new_raw_protocol(c::IPPROTO_GRE as _));
731     /// `IPPROTO_ESP`
732     #[cfg(not(any(
733         solarish,
734         target_os = "espidf",
735         target_os = "haiku",
736         target_os = "vita"
737     )))]
738     pub const ESP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ESP as _));
739     /// `IPPROTO_AH`
740     #[cfg(not(any(
741         solarish,
742         target_os = "espidf",
743         target_os = "haiku",
744         target_os = "vita"
745     )))]
746     pub const AH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_AH as _));
747     /// `IPPROTO_MTP`
748     #[cfg(not(any(
749         solarish,
750         netbsdlike,
751         windows,
752         target_os = "aix",
753         target_os = "espidf",
754         target_os = "haiku",
755         target_os = "nto",
756         target_os = "vita",
757     )))]
758     pub const MTP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MTP as _));
759     /// `IPPROTO_BEETPH`
760     #[cfg(not(any(
761         bsd,
762         solarish,
763         windows,
764         target_os = "aix",
765         target_os = "espidf",
766         target_os = "haiku",
767         target_os = "nto",
768         target_os = "vita",
769     )))]
770     pub const BEETPH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_BEETPH as _));
771     /// `IPPROTO_ENCAP`
772     #[cfg(not(any(
773         solarish,
774         windows,
775         target_os = "aix",
776         target_os = "espidf",
777         target_os = "haiku",
778         target_os = "vita",
779     )))]
780     pub const ENCAP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ENCAP as _));
781     /// `IPPROTO_PIM`
782     #[cfg(not(any(
783         solarish,
784         target_os = "aix",
785         target_os = "espidf",
786         target_os = "haiku",
787         target_os = "vita"
788     )))]
789     pub const PIM: Protocol = Protocol(new_raw_protocol(c::IPPROTO_PIM as _));
790     /// `IPPROTO_COMP`
791     #[cfg(not(any(
792         bsd,
793         solarish,
794         windows,
795         target_os = "aix",
796         target_os = "espidf",
797         target_os = "haiku",
798         target_os = "nto",
799         target_os = "vita",
800     )))]
801     pub const COMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_COMP as _));
802     /// `IPPROTO_SCTP`
803     #[cfg(not(any(
804         solarish,
805         target_os = "dragonfly",
806         target_os = "espidf",
807         target_os = "haiku",
808         target_os = "openbsd",
809         target_os = "vita",
810     )))]
811     pub const SCTP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_SCTP as _));
812     /// `IPPROTO_UDPLITE`
813     #[cfg(not(any(
814         apple,
815         netbsdlike,
816         solarish,
817         windows,
818         target_os = "aix",
819         target_os = "dragonfly",
820         target_os = "espidf",
821         target_os = "haiku",
822         target_os = "nto",
823         target_os = "vita",
824     )))]
825     pub const UDPLITE: Protocol = Protocol(new_raw_protocol(c::IPPROTO_UDPLITE as _));
826     /// `IPPROTO_MPLS`
827     #[cfg(not(any(
828         apple,
829         solarish,
830         windows,
831         target_os = "aix",
832         target_os = "dragonfly",
833         target_os = "espidf",
834         target_os = "haiku",
835         target_os = "netbsd",
836         target_os = "nto",
837         target_os = "vita",
838     )))]
839     pub const MPLS: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MPLS as _));
840     /// `IPPROTO_ETHERNET`
841     #[cfg(linux_kernel)]
842     pub const ETHERNET: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ETHERNET as _));
843     /// `IPPROTO_RAW`
844     #[cfg(not(any(target_os = "espidf", target_os = "vita")))]
845     pub const RAW: Protocol = Protocol(new_raw_protocol(c::IPPROTO_RAW as _));
846     /// `IPPROTO_MPTCP`
847     #[cfg(not(any(
848         bsd,
849         solarish,
850         windows,
851         target_os = "aix",
852         target_os = "emscripten",
853         target_os = "espidf",
854         target_os = "fuchsia",
855         target_os = "haiku",
856         target_os = "nto",
857         target_os = "vita",
858     )))]
859     pub const MPTCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MPTCP as _));
860     /// `IPPROTO_FRAGMENT`
861     #[cfg(not(any(
862         solarish,
863         target_os = "espidf",
864         target_os = "haiku",
865         target_os = "vita"
866     )))]
867     pub const FRAGMENT: Protocol = Protocol(new_raw_protocol(c::IPPROTO_FRAGMENT as _));
868     /// `IPPROTO_ICMPV6`
869     pub const ICMPV6: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ICMPV6 as _));
870     /// `IPPROTO_MH`
871     #[cfg(not(any(
872         apple,
873         netbsdlike,
874         solarish,
875         windows,
876         target_os = "dragonfly",
877         target_os = "espidf",
878         target_os = "haiku",
879         target_os = "nto",
880         target_os = "vita",
881     )))]
882     pub const MH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MH as _));
883     /// `IPPROTO_ROUTING`
884     #[cfg(not(any(
885         solarish,
886         target_os = "espidf",
887         target_os = "haiku",
888         target_os = "vita"
889     )))]
890     pub const ROUTING: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ROUTING as _));
891 }
892 
893 /// `SYSPROTO_*` constants.
894 pub mod sysproto {
895     #[cfg(apple)]
896     use {
897         super::{new_raw_protocol, Protocol},
898         crate::backend::c,
899     };
900 
901     /// `SYSPROTO_EVENT`
902     #[cfg(apple)]
903     pub const EVENT: Protocol = Protocol(new_raw_protocol(c::SYSPROTO_EVENT as _));
904 
905     /// `SYSPROTO_CONTROL`
906     #[cfg(apple)]
907     pub const CONTROL: Protocol = Protocol(new_raw_protocol(c::SYSPROTO_CONTROL as _));
908 }
909 
910 /// `NETLINK_*` constants.
911 ///
912 /// For `NETLINK_ROUTE`, pass `None` as the `protocol` argument.
913 pub mod netlink {
914     #[cfg(linux_kernel)]
915     use {
916         super::{new_raw_protocol, Protocol},
917         crate::backend::c,
918     };
919 
920     /// `NETLINK_UNUSED`
921     #[cfg(linux_kernel)]
922     pub const UNUSED: Protocol = Protocol(new_raw_protocol(c::NETLINK_UNUSED as _));
923     /// `NETLINK_USERSOCK`
924     #[cfg(linux_kernel)]
925     pub const USERSOCK: Protocol = Protocol(new_raw_protocol(c::NETLINK_USERSOCK as _));
926     /// `NETLINK_FIREWALL`
927     #[cfg(linux_kernel)]
928     pub const FIREWALL: Protocol = Protocol(new_raw_protocol(c::NETLINK_FIREWALL as _));
929     /// `NETLINK_SOCK_DIAG`
930     #[cfg(linux_kernel)]
931     pub const SOCK_DIAG: Protocol = Protocol(new_raw_protocol(c::NETLINK_SOCK_DIAG as _));
932     /// `NETLINK_NFLOG`
933     #[cfg(linux_kernel)]
934     pub const NFLOG: Protocol = Protocol(new_raw_protocol(c::NETLINK_NFLOG as _));
935     /// `NETLINK_XFRM`
936     #[cfg(linux_kernel)]
937     pub const XFRM: Protocol = Protocol(new_raw_protocol(c::NETLINK_XFRM as _));
938     /// `NETLINK_SELINUX`
939     #[cfg(linux_kernel)]
940     pub const SELINUX: Protocol = Protocol(new_raw_protocol(c::NETLINK_SELINUX as _));
941     /// `NETLINK_ISCSI`
942     #[cfg(linux_kernel)]
943     pub const ISCSI: Protocol = Protocol(new_raw_protocol(c::NETLINK_ISCSI as _));
944     /// `NETLINK_AUDIT`
945     #[cfg(linux_kernel)]
946     pub const AUDIT: Protocol = Protocol(new_raw_protocol(c::NETLINK_AUDIT as _));
947     /// `NETLINK_FIB_LOOKUP`
948     #[cfg(linux_kernel)]
949     pub const FIB_LOOKUP: Protocol = Protocol(new_raw_protocol(c::NETLINK_FIB_LOOKUP as _));
950     /// `NETLINK_CONNECTOR`
951     #[cfg(linux_kernel)]
952     pub const CONNECTOR: Protocol = Protocol(new_raw_protocol(c::NETLINK_CONNECTOR as _));
953     /// `NETLINK_NETFILTER`
954     #[cfg(linux_kernel)]
955     pub const NETFILTER: Protocol = Protocol(new_raw_protocol(c::NETLINK_NETFILTER as _));
956     /// `NETLINK_IP6_FW`
957     #[cfg(linux_kernel)]
958     pub const IP6_FW: Protocol = Protocol(new_raw_protocol(c::NETLINK_IP6_FW as _));
959     /// `NETLINK_DNRTMSG`
960     #[cfg(linux_kernel)]
961     pub const DNRTMSG: Protocol = Protocol(new_raw_protocol(c::NETLINK_DNRTMSG as _));
962     /// `NETLINK_KOBJECT_UEVENT`
963     #[cfg(linux_kernel)]
964     pub const KOBJECT_UEVENT: Protocol = Protocol(new_raw_protocol(c::NETLINK_KOBJECT_UEVENT as _));
965     /// `NETLINK_GENERIC`
966     // This is defined on FreeBSD too, but it has the value 0, so it doesn't
967     // fit in or `NonZeroU32`. It's unclear whether FreeBSD intends
968     // `NETLINK_GENERIC` to be the default when Linux has `NETLINK_ROUTE`
969     // as the default.
970     #[cfg(linux_kernel)]
971     pub const GENERIC: Protocol = Protocol(new_raw_protocol(c::NETLINK_GENERIC as _));
972     /// `NETLINK_SCSITRANSPORT`
973     #[cfg(linux_kernel)]
974     pub const SCSITRANSPORT: Protocol = Protocol(new_raw_protocol(c::NETLINK_SCSITRANSPORT as _));
975     /// `NETLINK_ECRYPTFS`
976     #[cfg(linux_kernel)]
977     pub const ECRYPTFS: Protocol = Protocol(new_raw_protocol(c::NETLINK_ECRYPTFS as _));
978     /// `NETLINK_RDMA`
979     #[cfg(linux_kernel)]
980     pub const RDMA: Protocol = Protocol(new_raw_protocol(c::NETLINK_RDMA as _));
981     /// `NETLINK_CRYPTO`
982     #[cfg(linux_kernel)]
983     pub const CRYPTO: Protocol = Protocol(new_raw_protocol(c::NETLINK_CRYPTO as _));
984     /// `NETLINK_INET_DIAG`
985     #[cfg(linux_kernel)]
986     pub const INET_DIAG: Protocol = Protocol(new_raw_protocol(c::NETLINK_INET_DIAG as _));
987     /// `NETLINK_ADD_MEMBERSHIP`
988     #[cfg(linux_kernel)]
989     pub const ADD_MEMBERSHIP: Protocol = Protocol(new_raw_protocol(c::NETLINK_ADD_MEMBERSHIP as _));
990     /// `NETLINK_DROP_MEMBERSHIP`
991     #[cfg(linux_kernel)]
992     pub const DROP_MEMBERSHIP: Protocol =
993         Protocol(new_raw_protocol(c::NETLINK_DROP_MEMBERSHIP as _));
994     /// `NETLINK_PKTINFO`
995     #[cfg(linux_kernel)]
996     pub const PKTINFO: Protocol = Protocol(new_raw_protocol(c::NETLINK_PKTINFO as _));
997     /// `NETLINK_BROADCAST_ERROR`
998     #[cfg(linux_kernel)]
999     pub const BROADCAST_ERROR: Protocol =
1000         Protocol(new_raw_protocol(c::NETLINK_BROADCAST_ERROR as _));
1001     /// `NETLINK_NO_ENOBUFS`
1002     #[cfg(linux_kernel)]
1003     pub const NO_ENOBUFS: Protocol = Protocol(new_raw_protocol(c::NETLINK_NO_ENOBUFS as _));
1004     /// `NETLINK_RX_RING`
1005     #[cfg(linux_kernel)]
1006     pub const RX_RING: Protocol = Protocol(new_raw_protocol(c::NETLINK_RX_RING as _));
1007     /// `NETLINK_TX_RING`
1008     #[cfg(linux_kernel)]
1009     pub const TX_RING: Protocol = Protocol(new_raw_protocol(c::NETLINK_TX_RING as _));
1010     /// `NETLINK_LISTEN_ALL_NSID`
1011     #[cfg(linux_kernel)]
1012     pub const LISTEN_ALL_NSID: Protocol =
1013         Protocol(new_raw_protocol(c::NETLINK_LISTEN_ALL_NSID as _));
1014     /// `NETLINK_LIST_MEMBERSHIPS`
1015     #[cfg(linux_kernel)]
1016     pub const LIST_MEMBERSHIPS: Protocol =
1017         Protocol(new_raw_protocol(c::NETLINK_LIST_MEMBERSHIPS as _));
1018     /// `NETLINK_CAP_ACK`
1019     #[cfg(linux_kernel)]
1020     pub const CAP_ACK: Protocol = Protocol(new_raw_protocol(c::NETLINK_CAP_ACK as _));
1021     /// `NETLINK_EXT_ACK`
1022     #[cfg(linux_kernel)]
1023     pub const EXT_ACK: Protocol = Protocol(new_raw_protocol(c::NETLINK_EXT_ACK as _));
1024     /// `NETLINK_GET_STRICT_CHK`
1025     #[cfg(linux_kernel)]
1026     pub const GET_STRICT_CHK: Protocol = Protocol(new_raw_protocol(c::NETLINK_GET_STRICT_CHK as _));
1027 }
1028 
1029 /// `ETH_P_*` constants.
1030 // These are translated into 16-bit big-endian form because that's what the
1031 // [`AddressFamily::PACKET`] address family [expects].
1032 //
1033 // [expects]: https://man7.org/linux/man-pages/man7/packet.7.html
1034 pub mod eth {
1035     #[cfg(linux_kernel)]
1036     use {
1037         super::{new_raw_protocol, Protocol},
1038         crate::backend::c,
1039     };
1040 
1041     /// `ETH_P_LOOP`
1042     #[cfg(linux_kernel)]
1043     pub const LOOP: Protocol = Protocol(new_raw_protocol((c::ETH_P_LOOP as u16).to_be() as u32));
1044     /// `ETH_P_PUP`
1045     #[cfg(linux_kernel)]
1046     pub const PUP: Protocol = Protocol(new_raw_protocol((c::ETH_P_PUP as u16).to_be() as u32));
1047     /// `ETH_P_PUPAT`
1048     #[cfg(linux_kernel)]
1049     pub const PUPAT: Protocol = Protocol(new_raw_protocol((c::ETH_P_PUPAT as u16).to_be() as u32));
1050     /// `ETH_P_TSN`
1051     #[cfg(linux_kernel)]
1052     pub const TSN: Protocol = Protocol(new_raw_protocol((c::ETH_P_TSN as u16).to_be() as u32));
1053     /// `ETH_P_ERSPAN2`
1054     #[cfg(linux_kernel)]
1055     pub const ERSPAN2: Protocol =
1056         Protocol(new_raw_protocol((c::ETH_P_ERSPAN2 as u16).to_be() as u32));
1057     /// `ETH_P_IP`
1058     #[cfg(linux_kernel)]
1059     pub const IP: Protocol = Protocol(new_raw_protocol((c::ETH_P_IP as u16).to_be() as u32));
1060     /// `ETH_P_X25`
1061     #[cfg(linux_kernel)]
1062     pub const X25: Protocol = Protocol(new_raw_protocol((c::ETH_P_X25 as u16).to_be() as u32));
1063     /// `ETH_P_ARP`
1064     #[cfg(linux_kernel)]
1065     pub const ARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_ARP as u16).to_be() as u32));
1066     /// `ETH_P_BPQ`
1067     #[cfg(linux_kernel)]
1068     pub const BPQ: Protocol = Protocol(new_raw_protocol((c::ETH_P_BPQ as u16).to_be() as u32));
1069     /// `ETH_P_IEEEPUP`
1070     #[cfg(linux_kernel)]
1071     pub const IEEEPUP: Protocol =
1072         Protocol(new_raw_protocol((c::ETH_P_IEEEPUP as u16).to_be() as u32));
1073     /// `ETH_P_IEEEPUPAT`
1074     #[cfg(linux_kernel)]
1075     pub const IEEEPUPAT: Protocol =
1076         Protocol(new_raw_protocol((c::ETH_P_IEEEPUPAT as u16).to_be() as u32));
1077     /// `ETH_P_BATMAN`
1078     #[cfg(linux_kernel)]
1079     pub const BATMAN: Protocol =
1080         Protocol(new_raw_protocol((c::ETH_P_BATMAN as u16).to_be() as u32));
1081     /// `ETH_P_DEC`
1082     #[cfg(linux_kernel)]
1083     pub const DEC: Protocol = Protocol(new_raw_protocol((c::ETH_P_DEC as u16).to_be() as u32));
1084     /// `ETH_P_DNA_DL`
1085     #[cfg(linux_kernel)]
1086     pub const DNA_DL: Protocol =
1087         Protocol(new_raw_protocol((c::ETH_P_DNA_DL as u16).to_be() as u32));
1088     /// `ETH_P_DNA_RC`
1089     #[cfg(linux_kernel)]
1090     pub const DNA_RC: Protocol =
1091         Protocol(new_raw_protocol((c::ETH_P_DNA_RC as u16).to_be() as u32));
1092     /// `ETH_P_DNA_RT`
1093     #[cfg(linux_kernel)]
1094     pub const DNA_RT: Protocol =
1095         Protocol(new_raw_protocol((c::ETH_P_DNA_RT as u16).to_be() as u32));
1096     /// `ETH_P_LAT`
1097     #[cfg(linux_kernel)]
1098     pub const LAT: Protocol = Protocol(new_raw_protocol((c::ETH_P_LAT as u16).to_be() as u32));
1099     /// `ETH_P_DIAG`
1100     #[cfg(linux_kernel)]
1101     pub const DIAG: Protocol = Protocol(new_raw_protocol((c::ETH_P_DIAG as u16).to_be() as u32));
1102     /// `ETH_P_CUST`
1103     #[cfg(linux_kernel)]
1104     pub const CUST: Protocol = Protocol(new_raw_protocol((c::ETH_P_CUST as u16).to_be() as u32));
1105     /// `ETH_P_SCA`
1106     #[cfg(linux_kernel)]
1107     pub const SCA: Protocol = Protocol(new_raw_protocol((c::ETH_P_SCA as u16).to_be() as u32));
1108     /// `ETH_P_TEB`
1109     #[cfg(linux_kernel)]
1110     pub const TEB: Protocol = Protocol(new_raw_protocol((c::ETH_P_TEB as u16).to_be() as u32));
1111     /// `ETH_P_RARP`
1112     #[cfg(linux_kernel)]
1113     pub const RARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_RARP as u16).to_be() as u32));
1114     /// `ETH_P_ATALK`
1115     #[cfg(linux_kernel)]
1116     pub const ATALK: Protocol = Protocol(new_raw_protocol((c::ETH_P_ATALK as u16).to_be() as u32));
1117     /// `ETH_P_AARP`
1118     #[cfg(linux_kernel)]
1119     pub const AARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_AARP as u16).to_be() as u32));
1120     /// `ETH_P_8021Q`
1121     #[cfg(linux_kernel)]
1122     pub const P_8021Q: Protocol =
1123         Protocol(new_raw_protocol((c::ETH_P_8021Q as u16).to_be() as u32));
1124     /// `ETH_P_ERSPAN`
1125     #[cfg(linux_kernel)]
1126     pub const ERSPAN: Protocol =
1127         Protocol(new_raw_protocol((c::ETH_P_ERSPAN as u16).to_be() as u32));
1128     /// `ETH_P_IPX`
1129     #[cfg(linux_kernel)]
1130     pub const IPX: Protocol = Protocol(new_raw_protocol((c::ETH_P_IPX as u16).to_be() as u32));
1131     /// `ETH_P_IPV6`
1132     #[cfg(linux_kernel)]
1133     pub const IPV6: Protocol = Protocol(new_raw_protocol((c::ETH_P_IPV6 as u16).to_be() as u32));
1134     /// `ETH_P_PAUSE`
1135     #[cfg(linux_kernel)]
1136     pub const PAUSE: Protocol = Protocol(new_raw_protocol((c::ETH_P_PAUSE as u16).to_be() as u32));
1137     /// `ETH_P_SLOW`
1138     #[cfg(linux_kernel)]
1139     pub const SLOW: Protocol = Protocol(new_raw_protocol((c::ETH_P_SLOW as u16).to_be() as u32));
1140     /// `ETH_P_WCCP`
1141     #[cfg(linux_kernel)]
1142     pub const WCCP: Protocol = Protocol(new_raw_protocol((c::ETH_P_WCCP as u16).to_be() as u32));
1143     /// `ETH_P_MPLS_UC`
1144     #[cfg(linux_kernel)]
1145     pub const MPLS_UC: Protocol =
1146         Protocol(new_raw_protocol((c::ETH_P_MPLS_UC as u16).to_be() as u32));
1147     /// `ETH_P_MPLS_MC`
1148     #[cfg(linux_kernel)]
1149     pub const MPLS_MC: Protocol =
1150         Protocol(new_raw_protocol((c::ETH_P_MPLS_MC as u16).to_be() as u32));
1151     /// `ETH_P_ATMMPOA`
1152     #[cfg(linux_kernel)]
1153     pub const ATMMPOA: Protocol =
1154         Protocol(new_raw_protocol((c::ETH_P_ATMMPOA as u16).to_be() as u32));
1155     /// `ETH_P_PPP_DISC`
1156     #[cfg(linux_kernel)]
1157     pub const PPP_DISC: Protocol =
1158         Protocol(new_raw_protocol((c::ETH_P_PPP_DISC as u16).to_be() as u32));
1159     /// `ETH_P_PPP_SES`
1160     #[cfg(linux_kernel)]
1161     pub const PPP_SES: Protocol =
1162         Protocol(new_raw_protocol((c::ETH_P_PPP_SES as u16).to_be() as u32));
1163     /// `ETH_P_LINK_CTL`
1164     #[cfg(linux_kernel)]
1165     pub const LINK_CTL: Protocol =
1166         Protocol(new_raw_protocol((c::ETH_P_LINK_CTL as u16).to_be() as u32));
1167     /// `ETH_P_ATMFATE`
1168     #[cfg(linux_kernel)]
1169     pub const ATMFATE: Protocol =
1170         Protocol(new_raw_protocol((c::ETH_P_ATMFATE as u16).to_be() as u32));
1171     /// `ETH_P_PAE`
1172     #[cfg(linux_kernel)]
1173     pub const PAE: Protocol = Protocol(new_raw_protocol((c::ETH_P_PAE as u16).to_be() as u32));
1174     /// `ETH_P_PROFINET`
1175     #[cfg(linux_kernel)]
1176     pub const PROFINET: Protocol =
1177         Protocol(new_raw_protocol((c::ETH_P_PROFINET as u16).to_be() as u32));
1178     /// `ETH_P_REALTEK`
1179     #[cfg(linux_kernel)]
1180     pub const REALTEK: Protocol =
1181         Protocol(new_raw_protocol((c::ETH_P_REALTEK as u16).to_be() as u32));
1182     /// `ETH_P_AOE`
1183     #[cfg(linux_kernel)]
1184     pub const AOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_AOE as u16).to_be() as u32));
1185     /// `ETH_P_ETHERCAT`
1186     #[cfg(linux_kernel)]
1187     pub const ETHERCAT: Protocol =
1188         Protocol(new_raw_protocol((c::ETH_P_ETHERCAT as u16).to_be() as u32));
1189     /// `ETH_P_8021AD`
1190     #[cfg(linux_kernel)]
1191     pub const P_8021AD: Protocol =
1192         Protocol(new_raw_protocol((c::ETH_P_8021AD as u16).to_be() as u32));
1193     /// `ETH_P_802_EX1`
1194     #[cfg(linux_kernel)]
1195     pub const P_802_EX1: Protocol =
1196         Protocol(new_raw_protocol((c::ETH_P_802_EX1 as u16).to_be() as u32));
1197     /// `ETH_P_PREAUTH`
1198     #[cfg(linux_kernel)]
1199     pub const PREAUTH: Protocol =
1200         Protocol(new_raw_protocol((c::ETH_P_PREAUTH as u16).to_be() as u32));
1201     /// `ETH_P_TIPC`
1202     #[cfg(linux_kernel)]
1203     pub const TIPC: Protocol = Protocol(new_raw_protocol((c::ETH_P_TIPC as u16).to_be() as u32));
1204     /// `ETH_P_LLDP`
1205     #[cfg(linux_kernel)]
1206     pub const LLDP: Protocol = Protocol(new_raw_protocol((c::ETH_P_LLDP as u16).to_be() as u32));
1207     /// `ETH_P_MRP`
1208     #[cfg(linux_kernel)]
1209     pub const MRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MRP as u16).to_be() as u32));
1210     /// `ETH_P_MACSEC`
1211     #[cfg(linux_kernel)]
1212     pub const MACSEC: Protocol =
1213         Protocol(new_raw_protocol((c::ETH_P_MACSEC as u16).to_be() as u32));
1214     /// `ETH_P_8021AH`
1215     #[cfg(linux_kernel)]
1216     pub const P_8021AH: Protocol =
1217         Protocol(new_raw_protocol((c::ETH_P_8021AH as u16).to_be() as u32));
1218     /// `ETH_P_MVRP`
1219     #[cfg(linux_kernel)]
1220     pub const MVRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MVRP as u16).to_be() as u32));
1221     /// `ETH_P_1588`
1222     #[cfg(linux_kernel)]
1223     pub const P_1588: Protocol = Protocol(new_raw_protocol((c::ETH_P_1588 as u16).to_be() as u32));
1224     /// `ETH_P_NCSI`
1225     #[cfg(linux_kernel)]
1226     pub const NCSI: Protocol = Protocol(new_raw_protocol((c::ETH_P_NCSI as u16).to_be() as u32));
1227     /// `ETH_P_PRP`
1228     #[cfg(linux_kernel)]
1229     pub const PRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_PRP as u16).to_be() as u32));
1230     /// `ETH_P_CFM`
1231     #[cfg(linux_kernel)]
1232     pub const CFM: Protocol = Protocol(new_raw_protocol((c::ETH_P_CFM as u16).to_be() as u32));
1233     /// `ETH_P_FCOE`
1234     #[cfg(linux_kernel)]
1235     pub const FCOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_FCOE as u16).to_be() as u32));
1236     /// `ETH_P_IBOE`
1237     #[cfg(linux_kernel)]
1238     pub const IBOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_IBOE as u16).to_be() as u32));
1239     /// `ETH_P_TDLS`
1240     #[cfg(linux_kernel)]
1241     pub const TDLS: Protocol = Protocol(new_raw_protocol((c::ETH_P_TDLS as u16).to_be() as u32));
1242     /// `ETH_P_FIP`
1243     #[cfg(linux_kernel)]
1244     pub const FIP: Protocol = Protocol(new_raw_protocol((c::ETH_P_FIP as u16).to_be() as u32));
1245     /// `ETH_P_80221`
1246     #[cfg(linux_kernel)]
1247     pub const P_80221: Protocol =
1248         Protocol(new_raw_protocol((c::ETH_P_80221 as u16).to_be() as u32));
1249     /// `ETH_P_HSR`
1250     #[cfg(linux_kernel)]
1251     pub const HSR: Protocol = Protocol(new_raw_protocol((c::ETH_P_HSR as u16).to_be() as u32));
1252     /// `ETH_P_NSH`
1253     #[cfg(linux_kernel)]
1254     pub const NSH: Protocol = Protocol(new_raw_protocol((c::ETH_P_NSH as u16).to_be() as u32));
1255     /// `ETH_P_LOOPBACK`
1256     #[cfg(linux_kernel)]
1257     pub const LOOPBACK: Protocol =
1258         Protocol(new_raw_protocol((c::ETH_P_LOOPBACK as u16).to_be() as u32));
1259     /// `ETH_P_QINQ1`
1260     #[cfg(linux_kernel)]
1261     pub const QINQ1: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ1 as u16).to_be() as u32));
1262     /// `ETH_P_QINQ2`
1263     #[cfg(linux_kernel)]
1264     pub const QINQ2: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ2 as u16).to_be() as u32));
1265     /// `ETH_P_QINQ3`
1266     #[cfg(linux_kernel)]
1267     pub const QINQ3: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ3 as u16).to_be() as u32));
1268     /// `ETH_P_EDSA`
1269     #[cfg(linux_kernel)]
1270     pub const EDSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_EDSA as u16).to_be() as u32));
1271     /// `ETH_P_DSA_8021Q`
1272     #[cfg(linux_kernel)]
1273     pub const DSA_8021Q: Protocol =
1274         Protocol(new_raw_protocol((c::ETH_P_DSA_8021Q as u16).to_be() as u32));
1275     /// `ETH_P_DSA_A5PSW`
1276     #[cfg(linux_kernel)]
1277     pub const DSA_A5PSW: Protocol =
1278         Protocol(new_raw_protocol((c::ETH_P_DSA_A5PSW as u16).to_be() as u32));
1279     /// `ETH_P_IFE`
1280     #[cfg(linux_kernel)]
1281     pub const IFE: Protocol = Protocol(new_raw_protocol((c::ETH_P_IFE as u16).to_be() as u32));
1282     /// `ETH_P_AF_IUCV`
1283     #[cfg(linux_kernel)]
1284     pub const AF_IUCV: Protocol =
1285         Protocol(new_raw_protocol((c::ETH_P_AF_IUCV as u16).to_be() as u32));
1286     /// `ETH_P_802_3_MIN`
1287     #[cfg(linux_kernel)]
1288     pub const P_802_3_MIN: Protocol =
1289         Protocol(new_raw_protocol((c::ETH_P_802_3_MIN as u16).to_be() as u32));
1290     /// `ETH_P_802_3`
1291     #[cfg(linux_kernel)]
1292     pub const P_802_3: Protocol =
1293         Protocol(new_raw_protocol((c::ETH_P_802_3 as u16).to_be() as u32));
1294     /// `ETH_P_AX25`
1295     #[cfg(linux_kernel)]
1296     pub const AX25: Protocol = Protocol(new_raw_protocol((c::ETH_P_AX25 as u16).to_be() as u32));
1297     /// `ETH_P_ALL`
1298     #[cfg(linux_kernel)]
1299     pub const ALL: Protocol = Protocol(new_raw_protocol((c::ETH_P_ALL as u16).to_be() as u32));
1300     /// `ETH_P_802_2`
1301     #[cfg(linux_kernel)]
1302     pub const P_802_2: Protocol =
1303         Protocol(new_raw_protocol((c::ETH_P_802_2 as u16).to_be() as u32));
1304     /// `ETH_P_SNAP`
1305     #[cfg(linux_kernel)]
1306     pub const SNAP: Protocol = Protocol(new_raw_protocol((c::ETH_P_SNAP as u16).to_be() as u32));
1307     /// `ETH_P_DDCMP`
1308     #[cfg(linux_kernel)]
1309     pub const DDCMP: Protocol = Protocol(new_raw_protocol((c::ETH_P_DDCMP as u16).to_be() as u32));
1310     /// `ETH_P_WAN_PPP`
1311     #[cfg(linux_kernel)]
1312     pub const WAN_PPP: Protocol =
1313         Protocol(new_raw_protocol((c::ETH_P_WAN_PPP as u16).to_be() as u32));
1314     /// `ETH_P_PPP_MP`
1315     #[cfg(linux_kernel)]
1316     pub const PPP_MP: Protocol =
1317         Protocol(new_raw_protocol((c::ETH_P_PPP_MP as u16).to_be() as u32));
1318     /// `ETH_P_LOCALTALK`
1319     #[cfg(linux_kernel)]
1320     pub const LOCALTALK: Protocol =
1321         Protocol(new_raw_protocol((c::ETH_P_LOCALTALK as u16).to_be() as u32));
1322     /// `ETH_P_CAN`
1323     #[cfg(linux_kernel)]
1324     pub const CAN: Protocol = Protocol(new_raw_protocol((c::ETH_P_CAN as u16).to_be() as u32));
1325     /// `ETH_P_CANFD`
1326     #[cfg(linux_kernel)]
1327     pub const CANFD: Protocol = Protocol(new_raw_protocol((c::ETH_P_CANFD as u16).to_be() as u32));
1328     /// `ETH_P_CANXL`
1329     #[cfg(linux_kernel)]
1330     pub const CANXL: Protocol = Protocol(new_raw_protocol((c::ETH_P_CANXL as u16).to_be() as u32));
1331     /// `ETH_P_PPPTALK`
1332     #[cfg(linux_kernel)]
1333     pub const PPPTALK: Protocol =
1334         Protocol(new_raw_protocol((c::ETH_P_PPPTALK as u16).to_be() as u32));
1335     /// `ETH_P_TR_802_2`
1336     #[cfg(linux_kernel)]
1337     pub const TR_802_2: Protocol =
1338         Protocol(new_raw_protocol((c::ETH_P_TR_802_2 as u16).to_be() as u32));
1339     /// `ETH_P_MOBITEX`
1340     #[cfg(linux_kernel)]
1341     pub const MOBITEX: Protocol =
1342         Protocol(new_raw_protocol((c::ETH_P_MOBITEX as u16).to_be() as u32));
1343     /// `ETH_P_CONTROL`
1344     #[cfg(linux_kernel)]
1345     pub const CONTROL: Protocol =
1346         Protocol(new_raw_protocol((c::ETH_P_CONTROL as u16).to_be() as u32));
1347     /// `ETH_P_IRDA`
1348     #[cfg(linux_kernel)]
1349     pub const IRDA: Protocol = Protocol(new_raw_protocol((c::ETH_P_IRDA as u16).to_be() as u32));
1350     /// `ETH_P_ECONET`
1351     #[cfg(linux_kernel)]
1352     pub const ECONET: Protocol =
1353         Protocol(new_raw_protocol((c::ETH_P_ECONET as u16).to_be() as u32));
1354     /// `ETH_P_HDLC`
1355     #[cfg(linux_kernel)]
1356     pub const HDLC: Protocol = Protocol(new_raw_protocol((c::ETH_P_HDLC as u16).to_be() as u32));
1357     /// `ETH_P_ARCNET`
1358     #[cfg(linux_kernel)]
1359     pub const ARCNET: Protocol =
1360         Protocol(new_raw_protocol((c::ETH_P_ARCNET as u16).to_be() as u32));
1361     /// `ETH_P_DSA`
1362     #[cfg(linux_kernel)]
1363     pub const DSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_DSA as u16).to_be() as u32));
1364     /// `ETH_P_TRAILER`
1365     #[cfg(linux_kernel)]
1366     pub const TRAILER: Protocol =
1367         Protocol(new_raw_protocol((c::ETH_P_TRAILER as u16).to_be() as u32));
1368     /// `ETH_P_PHONET`
1369     #[cfg(linux_kernel)]
1370     pub const PHONET: Protocol =
1371         Protocol(new_raw_protocol((c::ETH_P_PHONET as u16).to_be() as u32));
1372     /// `ETH_P_IEEE802154`
1373     #[cfg(linux_kernel)]
1374     pub const IEEE802154: Protocol =
1375         Protocol(new_raw_protocol((c::ETH_P_IEEE802154 as u16).to_be() as u32));
1376     /// `ETH_P_CAIF`
1377     #[cfg(linux_kernel)]
1378     pub const CAIF: Protocol = Protocol(new_raw_protocol((c::ETH_P_CAIF as u16).to_be() as u32));
1379     /// `ETH_P_XDSA`
1380     #[cfg(linux_kernel)]
1381     pub const XDSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_XDSA as u16).to_be() as u32));
1382     /// `ETH_P_MAP`
1383     #[cfg(linux_kernel)]
1384     pub const MAP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MAP as u16).to_be() as u32));
1385     /// `ETH_P_MCTP`
1386     #[cfg(linux_kernel)]
1387     pub const MCTP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MCTP as u16).to_be() as u32));
1388 }
1389 
1390 #[rustfmt::skip]
1391 impl Protocol {
1392     /// Constructs a `Protocol` from a raw integer.
1393     #[inline]
from_raw(raw: RawProtocol) -> Self1394     pub const fn from_raw(raw: RawProtocol) -> Self {
1395         Self(raw)
1396     }
1397 
1398     /// Returns the raw integer for this `Protocol`.
1399     #[inline]
as_raw(self) -> RawProtocol1400     pub const fn as_raw(self) -> RawProtocol {
1401         self.0
1402     }
1403 }
1404 
1405 /// `SHUT_*` constants for use with [`shutdown`].
1406 ///
1407 /// [`shutdown`]: crate::net::shutdown
1408 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
1409 #[repr(u32)]
1410 pub enum Shutdown {
1411     /// `SHUT_RD`—Disable further read operations.
1412     Read = c::SHUT_RD as _,
1413     /// `SHUT_WR`—Disable further write operations.
1414     Write = c::SHUT_WR as _,
1415     /// `SHUT_RDWR`—Disable further read and write operations.
1416     ReadWrite = c::SHUT_RDWR as _,
1417 }
1418 
1419 bitflags! {
1420     /// `SOCK_*` constants for use with [`socket_with`], [`accept_with`] and
1421     /// [`acceptfrom_with`].
1422     ///
1423     /// [`socket_with`]: crate::net::socket_with
1424     /// [`accept_with`]: crate::net::accept_with
1425     /// [`acceptfrom_with`]: crate::net::acceptfrom_with
1426     #[repr(transparent)]
1427     #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1428     pub struct SocketFlags: c::c_uint {
1429         /// `SOCK_NONBLOCK`
1430         #[cfg(not(any(
1431             apple,
1432             windows,
1433             target_os = "aix",
1434             target_os = "espidf",
1435             target_os = "haiku",
1436             target_os = "nto",
1437             target_os = "vita",
1438         )))]
1439         const NONBLOCK = bitcast!(c::SOCK_NONBLOCK);
1440 
1441         /// `SOCK_CLOEXEC`
1442         #[cfg(not(any(apple, windows, target_os = "aix", target_os = "haiku")))]
1443         const CLOEXEC = bitcast!(c::SOCK_CLOEXEC);
1444 
1445         // This deliberately lacks a `const _ = !0`, so that users can use
1446         // `from_bits_truncate` to extract the `SocketFlags` from a flags
1447         // value that also includes a `SocketType`.
1448     }
1449 }
1450 
1451 /// `AF_XDP` related types and constants.
1452 #[cfg(target_os = "linux")]
1453 pub mod xdp {
1454     use super::{bitflags, c};
1455 
1456     bitflags! {
1457         /// `XDP_OPTIONS_*` constants returned by [`get_xdp_options`].
1458         ///
1459         /// [`get_xdp_options`]: crate::net::sockopt::get_xdp_options
1460         #[repr(transparent)]
1461         #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1462         pub struct XdpOptionsFlags: u32 {
1463             /// `XDP_OPTIONS_ZEROCOPY`
1464             const XDP_OPTIONS_ZEROCOPY = bitcast!(c::XDP_OPTIONS_ZEROCOPY);
1465         }
1466     }
1467 
1468     // Constant needs to be cast because bindgen does generate a u32 but the struct expects a u16.
1469     // https://github.com/torvalds/linux/blob/v6.6/include/uapi/linux/if_xdp.h#L15-L44
1470     bitflags! {
1471         /// `XDP_*` constants for use in [`SockaddrXdp`].
1472         #[repr(transparent)]
1473         #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
1474         pub struct SockaddrXdpFlags: u16 {
1475             /// `XDP_SHARED_UMEM`
1476             const XDP_SHARED_UMEM = bitcast!(c::XDP_SHARED_UMEM as u16);
1477             /// `XDP_COPY`
1478             const XDP_COPY = bitcast!(c::XDP_COPY  as u16);
1479             /// `XDP_COPY`
1480             const XDP_ZEROCOPY = bitcast!(c::XDP_ZEROCOPY as u16);
1481             /// `XDP_USE_NEED_WAKEUP`
1482             const XDP_USE_NEED_WAKEUP = bitcast!(c::XDP_USE_NEED_WAKEUP as u16);
1483             // requires kernel 6.6
1484             /// `XDP_USE_SG`
1485             const XDP_USE_SG = bitcast!(c::XDP_USE_SG as u16);
1486         }
1487     }
1488 
1489     bitflags! {
1490         /// `XDP_RING_*` constants for use in fill and/or Tx ring.
1491         #[repr(transparent)]
1492         #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1493         pub struct XdpRingFlags: u32 {
1494             /// `XDP_RING_NEED_WAKEUP`
1495             const XDP_RING_NEED_WAKEUP = bitcast!(c::XDP_RING_NEED_WAKEUP);
1496         }
1497     }
1498 
1499     bitflags! {
1500         /// `XDP_UMEM_*` constants for use in [`XdpUmemReg`].
1501         #[repr(transparent)]
1502         #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1503         pub struct XdpUmemRegFlags: u32 {
1504             /// `XDP_UMEM_UNALIGNED_CHUNK_FLAG`
1505             const XDP_UMEM_UNALIGNED_CHUNK_FLAG = bitcast!(c::XDP_UMEM_UNALIGNED_CHUNK_FLAG);
1506         }
1507     }
1508 
1509     /// A XDP socket address.
1510     ///
1511     /// Used to bind to XDP socket.
1512     ///
1513     /// Not ABI compatible with `struct sockaddr_xdp`
1514     // https://github.com/torvalds/linux/blob/v6.6/include/uapi/linux/if_xdp.h#L38-L44
1515     #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
1516     pub struct SocketAddrXdp {
1517         /// Flags.
1518         sxdp_flags: SockaddrXdpFlags,
1519         /// Interface index.
1520         sxdp_ifindex: u32,
1521         /// Queue ID.
1522         sxdp_queue_id: u32,
1523         /// Shared UMEM file descriptor.
1524         sxdp_shared_umem_fd: u32,
1525     }
1526 
1527     impl SocketAddrXdp {
1528         /// Construct a new XDP address.
1529         #[inline]
new( flags: SockaddrXdpFlags, interface_index: u32, queue_id: u32, share_umem_fd: u32, ) -> Self1530         pub fn new(
1531             flags: SockaddrXdpFlags,
1532             interface_index: u32,
1533             queue_id: u32,
1534             share_umem_fd: u32,
1535         ) -> Self {
1536             Self {
1537                 sxdp_flags: flags,
1538                 sxdp_ifindex: interface_index,
1539                 sxdp_queue_id: queue_id,
1540                 sxdp_shared_umem_fd: share_umem_fd,
1541             }
1542         }
1543 
1544         /// Return flags.
1545         #[inline]
flags(&self) -> SockaddrXdpFlags1546         pub fn flags(&self) -> SockaddrXdpFlags {
1547             self.sxdp_flags
1548         }
1549 
1550         /// Set flags.
1551         #[inline]
set_flags(&mut self, flags: SockaddrXdpFlags)1552         pub fn set_flags(&mut self, flags: SockaddrXdpFlags) {
1553             self.sxdp_flags = flags;
1554         }
1555 
1556         /// Return interface index.
1557         #[inline]
interface_index(&self) -> u321558         pub fn interface_index(&self) -> u32 {
1559             self.sxdp_ifindex
1560         }
1561 
1562         /// Set interface index.
1563         #[inline]
set_interface_index(&mut self, interface_index: u32)1564         pub fn set_interface_index(&mut self, interface_index: u32) {
1565             self.sxdp_ifindex = interface_index;
1566         }
1567 
1568         /// Return queue ID.
1569         #[inline]
queue_id(&self) -> u321570         pub fn queue_id(&self) -> u32 {
1571             self.sxdp_queue_id
1572         }
1573 
1574         /// Set queue ID.
1575         #[inline]
set_queue_id(&mut self, queue_id: u32)1576         pub fn set_queue_id(&mut self, queue_id: u32) {
1577             self.sxdp_queue_id = queue_id;
1578         }
1579 
1580         /// Return shared UMEM file descriptor.
1581         #[inline]
shared_umem_fd(&self) -> u321582         pub fn shared_umem_fd(&self) -> u32 {
1583             self.sxdp_shared_umem_fd
1584         }
1585 
1586         /// Set shared UMEM file descriptor.
1587         #[inline]
set_shared_umem_fd(&mut self, shared_umem_fd: u32)1588         pub fn set_shared_umem_fd(&mut self, shared_umem_fd: u32) {
1589             self.sxdp_shared_umem_fd = shared_umem_fd;
1590         }
1591     }
1592 
1593     /// XDP ring offset.
1594     ///
1595     /// Used to mmap rings from kernel.
1596     ///
1597     /// Not ABI compatible with `struct xdp_ring_offset`.
1598     // https://github.com/torvalds/linux/blob/v6.6/include/uapi/linux/if_xdp.h#L49-L54
1599     #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1600     pub struct XdpRingOffset {
1601         /// Producer offset.
1602         pub producer: u64,
1603         /// Consumer offset.
1604         pub consumer: u64,
1605         /// Descriptors offset.
1606         pub desc: u64,
1607         /// Flags offset.
1608         ///
1609         /// Is `None` if the kernel version (<5.4) does not yet support flags.
1610         pub flags: Option<u64>,
1611     }
1612 
1613     /// XDP mmap offsets.
1614     ///
1615     /// Not ABI compatible with `struct xdp_mmap_offsets`
1616     // https://github.com/torvalds/linux/blob/v6.6/include/uapi/linux/if_xdp.h#L56-L61
1617     #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1618     pub struct XdpMmapOffsets {
1619         /// Rx ring offsets.
1620         pub rx: XdpRingOffset,
1621         /// Tx ring offsets.
1622         pub tx: XdpRingOffset,
1623         /// Fill ring offsets.
1624         pub fr: XdpRingOffset,
1625         /// Completion ring offsets.
1626         pub cr: XdpRingOffset,
1627     }
1628 
1629     /// XDP umem registration.
1630     ///
1631     /// `struct xdp_umem_reg`
1632     // https://github.com/torvalds/linux/blob/v6.6/include/uapi/linux/if_xdp.h#L73-L79
1633     #[repr(C)]
1634     #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1635     pub struct XdpUmemReg {
1636         /// Start address of UMEM.
1637         pub addr: u64,
1638         /// Umem length in bytes.
1639         pub len: u64,
1640         /// Chunk size in bytes.
1641         pub chunk_size: u32,
1642         /// Headroom in bytes.
1643         pub headroom: u32,
1644         /// Flags.
1645         ///
1646         /// Requires kernel version 5.4.
1647         pub flags: XdpUmemRegFlags,
1648     }
1649 
1650     /// XDP statistics.
1651     ///
1652     /// Not ABI compatible with `struct xdp_statistics`
1653     // https://github.com/torvalds/linux/blob/v6.6/include/uapi/linux/if_xdp.h#L81-L88
1654     #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1655     pub struct XdpStatistics {
1656         /// Rx dropped.
1657         pub rx_dropped: u64,
1658         /// Rx invalid descriptors.
1659         pub rx_invalid_descs: u64,
1660         /// Tx invalid descriptors.
1661         pub tx_invalid_descs: u64,
1662         /// Rx ring full.
1663         ///
1664         /// Is `None` if the kernel version (<5.9) does not yet support flags.
1665         pub rx_ring_full: Option<u64>,
1666         /// Rx fill ring empty descriptors.
1667         ///
1668         /// Is `None` if the kernel version (<5.9) does not yet support flags.
1669         pub rx_fill_ring_empty_descs: Option<u64>,
1670         /// Tx ring empty descriptors.
1671         ///
1672         /// Is `None` if the kernel version (<5.9) does not yet support flags.
1673         pub tx_ring_empty_descs: Option<u64>,
1674     }
1675 
1676     /// XDP options.
1677     ///
1678     /// Requires kernel version 5.3.
1679     /// `struct xdp_options`
1680     // https://github.com/torvalds/linux/blob/v6.6/include/uapi/linux/if_xdp.h#L90-L92
1681     #[repr(C)]
1682     #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1683     pub struct XdpOptions {
1684         /// Flags.
1685         pub flags: XdpOptionsFlags,
1686     }
1687 
1688     /// XDP rx/tx frame descriptor.
1689     ///
1690     /// `struct xdp_desc`
1691     // https://github.com/torvalds/linux/blob/v6.6/include/uapi/linux/if_xdp.h#L109-L113
1692     #[repr(C)]
1693     #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1694     pub struct XdpDesc {
1695         /// Offset from the start of the UMEM.
1696         pub addr: u64,
1697         /// Length of packet in bytes.
1698         pub len: u32,
1699         /// Options.
1700         pub options: XdpDescOptions,
1701     }
1702 
1703     #[cfg(target_os = "linux")]
1704     bitflags! {
1705         #[repr(transparent)]
1706         #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1707         /// `XDP_*` constants for use in [`XdpDesc`].
1708         ///
1709         /// Requires kernel version 6.6.
1710         pub struct XdpDescOptions: u32 {
1711             /// `XDP_PKT_CONTD`
1712             const XDP_PKT_CONTD = bitcast!(c::XDP_PKT_CONTD);
1713         }
1714     }
1715 
1716     /// Offset for mmapping rx ring.
1717     pub const XDP_PGOFF_RX_RING: u64 = c::XDP_PGOFF_RX_RING as u64;
1718     /// Offset for mmapping tx ring.
1719     pub const XDP_PGOFF_TX_RING: u64 = c::XDP_PGOFF_TX_RING as u64;
1720     /// Offset for mmapping fill ring.
1721     pub const XDP_UMEM_PGOFF_FILL_RING: u64 = c::XDP_UMEM_PGOFF_FILL_RING;
1722     /// Offset for mmapping completion ring.
1723     pub const XDP_UMEM_PGOFF_COMPLETION_RING: u64 = c::XDP_UMEM_PGOFF_COMPLETION_RING;
1724 
1725     /// Offset used to shift the [`XdpDesc`] addr to the right to extract the address offset in
1726     /// unaligned mode.
1727     pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: u64 = c::XSK_UNALIGNED_BUF_OFFSET_SHIFT as u64;
1728     /// Mask used to binary `and` the [`XdpDesc`] addr to extract the address without the offset
1729     /// carried in the upper 16 bits of the address in unaligned mode.
1730     pub const XSK_UNALIGNED_BUF_ADDR_MASK: u64 = c::XSK_UNALIGNED_BUF_ADDR_MASK;
1731 }
1732 
1733 /// UNIX credentials of socket peer, for use with [`get_socket_peercred`]
1734 /// [`SendAncillaryMessage::ScmCredentials`] and
1735 /// [`RecvAncillaryMessage::ScmCredentials`].
1736 ///
1737 /// [`get_socket_peercred`]: crate::net::sockopt::get_socket_peercred
1738 /// [`SendAncillaryMessage::ScmCredentials`]: crate::net::SendAncillaryMessage::ScmCredentials
1739 /// [`RecvAncillaryMessage::ScmCredentials`]: crate::net::RecvAncillaryMessage::ScmCredentials
1740 #[cfg(linux_kernel)]
1741 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
1742 #[repr(C)]
1743 pub struct UCred {
1744     /// Process ID of peer
1745     pub pid: crate::pid::Pid,
1746     /// User ID of peer
1747     pub uid: crate::ugid::Uid,
1748     /// Group ID of peer
1749     pub gid: crate::ugid::Gid,
1750 }
1751 
1752 #[test]
test_sizes()1753 fn test_sizes() {
1754     use crate::backend::c;
1755     use c::c_int;
1756     use core::mem::transmute;
1757 
1758     // Backend code needs to cast these to `c_int` so make sure that cast isn't
1759     // lossy.
1760     assert_eq_size!(RawProtocol, c_int);
1761     assert_eq_size!(Protocol, c_int);
1762     assert_eq_size!(Option<RawProtocol>, c_int);
1763     assert_eq_size!(Option<Protocol>, c_int);
1764     assert_eq_size!(RawSocketType, c_int);
1765     assert_eq_size!(SocketType, c_int);
1766     assert_eq_size!(SocketFlags, c_int);
1767 
1768     // Rustix doesn't depend on `Option<Protocol>` matching the ABI of a raw
1769     // integer for correctness, but it should work nonetheless.
1770     #[allow(unsafe_code)]
1771     unsafe {
1772         let t: Option<Protocol> = None;
1773         assert_eq!(0_u32, transmute::<Option<Protocol>, u32>(t));
1774 
1775         let t: Option<Protocol> = Some(Protocol::from_raw(RawProtocol::new(4567).unwrap()));
1776         assert_eq!(4567_u32, transmute::<Option<Protocol>, u32>(t));
1777     }
1778 
1779     #[cfg(linux_kernel)]
1780     assert_eq_size!(UCred, libc::ucred);
1781 
1782     #[cfg(target_os = "linux")]
1783     assert_eq_size!(super::xdp::XdpUmemReg, c::xdp_umem_reg);
1784     #[cfg(target_os = "linux")]
1785     assert_eq_size!(super::xdp::XdpOptions, c::xdp_options);
1786     #[cfg(target_os = "linux")]
1787     assert_eq_size!(super::xdp::XdpDesc, c::xdp_desc);
1788 }
1789