rustix/net/
types.rs

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