rustix/net/
types.rs

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