Skip to main content

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(target_os = "macos")]
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, linux_kernel, 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.
1119#[cfg(target_os = "macos")]
1120pub mod sysproto {
1121    #[cfg(apple)]
1122    use {
1123        super::{new_raw_protocol, Protocol},
1124        crate::backend::c,
1125    };
1126
1127    /// `SYSPROTO_EVENT`
1128    pub const EVENT: Protocol = Protocol(new_raw_protocol(c::SYSPROTO_EVENT as _));
1129
1130    /// `SYSPROTO_CONTROL`
1131    pub const CONTROL: Protocol = Protocol(new_raw_protocol(c::SYSPROTO_CONTROL as _));
1132}
1133
1134/// `NETLINK_*` constants.
1135///
1136/// For `NETLINK_ROUTE`, pass `None` as the `protocol` argument.
1137pub mod netlink {
1138    #[cfg(linux_kernel)]
1139    use {
1140        super::{new_raw_protocol, Protocol},
1141        crate::backend::c,
1142        crate::backend::net::read_sockaddr::read_sockaddr_netlink,
1143        crate::net::{
1144            addr::{call_with_sockaddr, SocketAddrArg, SocketAddrLen, SocketAddrOpaque},
1145            SocketAddrAny,
1146        },
1147        core::mem,
1148    };
1149
1150    /// `NETLINK_UNUSED`
1151    #[cfg(linux_kernel)]
1152    pub const UNUSED: Protocol = Protocol(new_raw_protocol(c::NETLINK_UNUSED as _));
1153    /// `NETLINK_USERSOCK`
1154    #[cfg(linux_kernel)]
1155    pub const USERSOCK: Protocol = Protocol(new_raw_protocol(c::NETLINK_USERSOCK as _));
1156    /// `NETLINK_FIREWALL`
1157    #[cfg(linux_kernel)]
1158    pub const FIREWALL: Protocol = Protocol(new_raw_protocol(c::NETLINK_FIREWALL as _));
1159    /// `NETLINK_SOCK_DIAG`
1160    #[cfg(linux_kernel)]
1161    pub const SOCK_DIAG: Protocol = Protocol(new_raw_protocol(c::NETLINK_SOCK_DIAG as _));
1162    /// `NETLINK_NFLOG`
1163    #[cfg(linux_kernel)]
1164    pub const NFLOG: Protocol = Protocol(new_raw_protocol(c::NETLINK_NFLOG as _));
1165    /// `NETLINK_XFRM`
1166    #[cfg(linux_kernel)]
1167    pub const XFRM: Protocol = Protocol(new_raw_protocol(c::NETLINK_XFRM as _));
1168    /// `NETLINK_SELINUX`
1169    #[cfg(linux_kernel)]
1170    pub const SELINUX: Protocol = Protocol(new_raw_protocol(c::NETLINK_SELINUX as _));
1171    /// `NETLINK_ISCSI`
1172    #[cfg(linux_kernel)]
1173    pub const ISCSI: Protocol = Protocol(new_raw_protocol(c::NETLINK_ISCSI as _));
1174    /// `NETLINK_AUDIT`
1175    #[cfg(linux_kernel)]
1176    pub const AUDIT: Protocol = Protocol(new_raw_protocol(c::NETLINK_AUDIT as _));
1177    /// `NETLINK_FIB_LOOKUP`
1178    #[cfg(linux_kernel)]
1179    pub const FIB_LOOKUP: Protocol = Protocol(new_raw_protocol(c::NETLINK_FIB_LOOKUP as _));
1180    /// `NETLINK_CONNECTOR`
1181    #[cfg(linux_kernel)]
1182    pub const CONNECTOR: Protocol = Protocol(new_raw_protocol(c::NETLINK_CONNECTOR as _));
1183    /// `NETLINK_NETFILTER`
1184    #[cfg(linux_kernel)]
1185    pub const NETFILTER: Protocol = Protocol(new_raw_protocol(c::NETLINK_NETFILTER as _));
1186    /// `NETLINK_IP6_FW`
1187    #[cfg(linux_kernel)]
1188    pub const IP6_FW: Protocol = Protocol(new_raw_protocol(c::NETLINK_IP6_FW as _));
1189    /// `NETLINK_DNRTMSG`
1190    #[cfg(linux_kernel)]
1191    pub const DNRTMSG: Protocol = Protocol(new_raw_protocol(c::NETLINK_DNRTMSG as _));
1192    /// `NETLINK_KOBJECT_UEVENT`
1193    #[cfg(linux_kernel)]
1194    pub const KOBJECT_UEVENT: Protocol = Protocol(new_raw_protocol(c::NETLINK_KOBJECT_UEVENT as _));
1195    /// `NETLINK_GENERIC`
1196    // This is defined on FreeBSD too, but it has the value 0, so it doesn't
1197    // fit in or `NonZeroU32`. It's unclear whether FreeBSD intends
1198    // `NETLINK_GENERIC` to be the default when Linux has `NETLINK_ROUTE` as
1199    // the default.
1200    #[cfg(linux_kernel)]
1201    pub const GENERIC: Protocol = Protocol(new_raw_protocol(c::NETLINK_GENERIC as _));
1202    /// `NETLINK_SCSITRANSPORT`
1203    #[cfg(linux_kernel)]
1204    pub const SCSITRANSPORT: Protocol = Protocol(new_raw_protocol(c::NETLINK_SCSITRANSPORT as _));
1205    /// `NETLINK_ECRYPTFS`
1206    #[cfg(linux_kernel)]
1207    pub const ECRYPTFS: Protocol = Protocol(new_raw_protocol(c::NETLINK_ECRYPTFS as _));
1208    /// `NETLINK_RDMA`
1209    #[cfg(linux_kernel)]
1210    pub const RDMA: Protocol = Protocol(new_raw_protocol(c::NETLINK_RDMA as _));
1211    /// `NETLINK_CRYPTO`
1212    #[cfg(linux_kernel)]
1213    pub const CRYPTO: Protocol = Protocol(new_raw_protocol(c::NETLINK_CRYPTO as _));
1214    /// `NETLINK_INET_DIAG`
1215    #[cfg(linux_kernel)]
1216    pub const INET_DIAG: Protocol = Protocol(new_raw_protocol(c::NETLINK_INET_DIAG as _));
1217
1218    /// A Netlink socket address.
1219    ///
1220    /// Used to bind to a Netlink socket.
1221    ///
1222    /// Not ABI compatible with `struct sockaddr_nl`
1223    #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
1224    #[cfg(linux_kernel)]
1225    pub struct SocketAddrNetlink {
1226        /// Port ID
1227        pid: u32,
1228
1229        /// Multicast groups mask
1230        groups: u32,
1231    }
1232
1233    #[cfg(linux_kernel)]
1234    impl SocketAddrNetlink {
1235        /// Construct a netlink address
1236        #[inline]
1237        pub const fn new(pid: u32, groups: u32) -> Self {
1238            Self { pid, groups }
1239        }
1240
1241        /// Return port id.
1242        #[inline]
1243        pub const fn pid(&self) -> u32 {
1244            self.pid
1245        }
1246
1247        /// Set port id.
1248        #[inline]
1249        pub fn set_pid(&mut self, pid: u32) {
1250            self.pid = pid;
1251        }
1252
1253        /// Return multicast groups mask.
1254        #[inline]
1255        pub const fn groups(&self) -> u32 {
1256            self.groups
1257        }
1258
1259        /// Set multicast groups mask.
1260        #[inline]
1261        pub fn set_groups(&mut self, groups: u32) {
1262            self.groups = groups;
1263        }
1264    }
1265
1266    #[cfg(linux_kernel)]
1267    #[allow(unsafe_code)]
1268    // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which
1269    // handles calling `f` with the needed preconditions.
1270    unsafe impl SocketAddrArg for SocketAddrNetlink {
1271        unsafe fn with_sockaddr<R>(
1272            &self,
1273            f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R,
1274        ) -> R {
1275            let mut addr: c::sockaddr_nl = mem::zeroed();
1276            addr.nl_family = c::AF_NETLINK as _;
1277            addr.nl_pid = self.pid;
1278            addr.nl_groups = self.groups;
1279            call_with_sockaddr(&addr, f)
1280        }
1281    }
1282
1283    #[cfg(linux_kernel)]
1284    impl From<SocketAddrNetlink> for SocketAddrAny {
1285        #[inline]
1286        fn from(from: SocketAddrNetlink) -> Self {
1287            from.as_any()
1288        }
1289    }
1290
1291    #[cfg(linux_kernel)]
1292    impl TryFrom<SocketAddrAny> for SocketAddrNetlink {
1293        type Error = crate::io::Errno;
1294
1295        fn try_from(addr: SocketAddrAny) -> Result<Self, Self::Error> {
1296            read_sockaddr_netlink(&addr)
1297        }
1298    }
1299}
1300
1301/// `ETH_P_*` constants.
1302// These are translated into 16-bit big-endian form because that's what the
1303// [`AddressFamily::PACKET`] address family [expects].
1304//
1305// [expects]: https://man7.org/linux/man-pages/man7/packet.7.html
1306pub mod eth {
1307    #[cfg(linux_kernel)]
1308    use {
1309        super::{new_raw_protocol, Protocol},
1310        crate::backend::c,
1311    };
1312
1313    /// `ETH_P_LOOP`
1314    #[cfg(linux_kernel)]
1315    pub const LOOP: Protocol = Protocol(new_raw_protocol((c::ETH_P_LOOP as u16).to_be() as u32));
1316    /// `ETH_P_PUP`
1317    #[cfg(linux_kernel)]
1318    pub const PUP: Protocol = Protocol(new_raw_protocol((c::ETH_P_PUP as u16).to_be() as u32));
1319    /// `ETH_P_PUPAT`
1320    #[cfg(linux_kernel)]
1321    pub const PUPAT: Protocol = Protocol(new_raw_protocol((c::ETH_P_PUPAT as u16).to_be() as u32));
1322    /// `ETH_P_TSN`
1323    #[cfg(linux_raw_dep)]
1324    pub const TSN: Protocol = Protocol(new_raw_protocol((c::ETH_P_TSN as u16).to_be() as u32));
1325    /// `ETH_P_ERSPAN2`
1326    #[cfg(linux_raw_dep)]
1327    pub const ERSPAN2: Protocol =
1328        Protocol(new_raw_protocol((c::ETH_P_ERSPAN2 as u16).to_be() as u32));
1329    /// `ETH_P_IP`
1330    #[cfg(linux_kernel)]
1331    pub const IP: Protocol = Protocol(new_raw_protocol((c::ETH_P_IP as u16).to_be() as u32));
1332    /// `ETH_P_X25`
1333    #[cfg(linux_kernel)]
1334    pub const X25: Protocol = Protocol(new_raw_protocol((c::ETH_P_X25 as u16).to_be() as u32));
1335    /// `ETH_P_ARP`
1336    #[cfg(linux_kernel)]
1337    pub const ARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_ARP as u16).to_be() as u32));
1338    /// `ETH_P_BPQ`
1339    #[cfg(linux_kernel)]
1340    pub const BPQ: Protocol = Protocol(new_raw_protocol((c::ETH_P_BPQ as u16).to_be() as u32));
1341    /// `ETH_P_IEEEPUP`
1342    #[cfg(linux_kernel)]
1343    pub const IEEEPUP: Protocol =
1344        Protocol(new_raw_protocol((c::ETH_P_IEEEPUP as u16).to_be() as u32));
1345    /// `ETH_P_IEEEPUPAT`
1346    #[cfg(linux_kernel)]
1347    pub const IEEEPUPAT: Protocol =
1348        Protocol(new_raw_protocol((c::ETH_P_IEEEPUPAT as u16).to_be() as u32));
1349    /// `ETH_P_BATMAN`
1350    #[cfg(linux_kernel)]
1351    pub const BATMAN: Protocol =
1352        Protocol(new_raw_protocol((c::ETH_P_BATMAN as u16).to_be() as u32));
1353    /// `ETH_P_DEC`
1354    #[cfg(linux_kernel)]
1355    pub const DEC: Protocol = Protocol(new_raw_protocol((c::ETH_P_DEC as u16).to_be() as u32));
1356    /// `ETH_P_DNA_DL`
1357    #[cfg(linux_kernel)]
1358    pub const DNA_DL: Protocol =
1359        Protocol(new_raw_protocol((c::ETH_P_DNA_DL as u16).to_be() as u32));
1360    /// `ETH_P_DNA_RC`
1361    #[cfg(linux_kernel)]
1362    pub const DNA_RC: Protocol =
1363        Protocol(new_raw_protocol((c::ETH_P_DNA_RC as u16).to_be() as u32));
1364    /// `ETH_P_DNA_RT`
1365    #[cfg(linux_kernel)]
1366    pub const DNA_RT: Protocol =
1367        Protocol(new_raw_protocol((c::ETH_P_DNA_RT as u16).to_be() as u32));
1368    /// `ETH_P_LAT`
1369    #[cfg(linux_kernel)]
1370    pub const LAT: Protocol = Protocol(new_raw_protocol((c::ETH_P_LAT as u16).to_be() as u32));
1371    /// `ETH_P_DIAG`
1372    #[cfg(linux_kernel)]
1373    pub const DIAG: Protocol = Protocol(new_raw_protocol((c::ETH_P_DIAG as u16).to_be() as u32));
1374    /// `ETH_P_CUST`
1375    #[cfg(linux_kernel)]
1376    pub const CUST: Protocol = Protocol(new_raw_protocol((c::ETH_P_CUST as u16).to_be() as u32));
1377    /// `ETH_P_SCA`
1378    #[cfg(linux_kernel)]
1379    pub const SCA: Protocol = Protocol(new_raw_protocol((c::ETH_P_SCA as u16).to_be() as u32));
1380    /// `ETH_P_TEB`
1381    #[cfg(linux_kernel)]
1382    pub const TEB: Protocol = Protocol(new_raw_protocol((c::ETH_P_TEB as u16).to_be() as u32));
1383    /// `ETH_P_RARP`
1384    #[cfg(linux_kernel)]
1385    pub const RARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_RARP as u16).to_be() as u32));
1386    /// `ETH_P_ATALK`
1387    #[cfg(linux_kernel)]
1388    pub const ATALK: Protocol = Protocol(new_raw_protocol((c::ETH_P_ATALK as u16).to_be() as u32));
1389    /// `ETH_P_AARP`
1390    #[cfg(linux_kernel)]
1391    pub const AARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_AARP as u16).to_be() as u32));
1392    /// `ETH_P_8021Q`
1393    #[cfg(linux_kernel)]
1394    pub const P_8021Q: Protocol =
1395        Protocol(new_raw_protocol((c::ETH_P_8021Q as u16).to_be() as u32));
1396    /// `ETH_P_ERSPAN`
1397    #[cfg(linux_raw_dep)]
1398    pub const ERSPAN: Protocol =
1399        Protocol(new_raw_protocol((c::ETH_P_ERSPAN as u16).to_be() as u32));
1400    /// `ETH_P_IPX`
1401    #[cfg(linux_kernel)]
1402    pub const IPX: Protocol = Protocol(new_raw_protocol((c::ETH_P_IPX as u16).to_be() as u32));
1403    /// `ETH_P_IPV6`
1404    #[cfg(linux_kernel)]
1405    pub const IPV6: Protocol = Protocol(new_raw_protocol((c::ETH_P_IPV6 as u16).to_be() as u32));
1406    /// `ETH_P_PAUSE`
1407    #[cfg(linux_kernel)]
1408    pub const PAUSE: Protocol = Protocol(new_raw_protocol((c::ETH_P_PAUSE as u16).to_be() as u32));
1409    /// `ETH_P_SLOW`
1410    #[cfg(linux_kernel)]
1411    pub const SLOW: Protocol = Protocol(new_raw_protocol((c::ETH_P_SLOW as u16).to_be() as u32));
1412    /// `ETH_P_WCCP`
1413    #[cfg(linux_kernel)]
1414    pub const WCCP: Protocol = Protocol(new_raw_protocol((c::ETH_P_WCCP as u16).to_be() as u32));
1415    /// `ETH_P_MPLS_UC`
1416    #[cfg(linux_kernel)]
1417    pub const MPLS_UC: Protocol =
1418        Protocol(new_raw_protocol((c::ETH_P_MPLS_UC as u16).to_be() as u32));
1419    /// `ETH_P_MPLS_MC`
1420    #[cfg(linux_kernel)]
1421    pub const MPLS_MC: Protocol =
1422        Protocol(new_raw_protocol((c::ETH_P_MPLS_MC as u16).to_be() as u32));
1423    /// `ETH_P_ATMMPOA`
1424    #[cfg(linux_kernel)]
1425    pub const ATMMPOA: Protocol =
1426        Protocol(new_raw_protocol((c::ETH_P_ATMMPOA as u16).to_be() as u32));
1427    /// `ETH_P_PPP_DISC`
1428    #[cfg(linux_kernel)]
1429    pub const PPP_DISC: Protocol =
1430        Protocol(new_raw_protocol((c::ETH_P_PPP_DISC as u16).to_be() as u32));
1431    /// `ETH_P_PPP_SES`
1432    #[cfg(linux_kernel)]
1433    pub const PPP_SES: Protocol =
1434        Protocol(new_raw_protocol((c::ETH_P_PPP_SES as u16).to_be() as u32));
1435    /// `ETH_P_LINK_CTL`
1436    #[cfg(linux_kernel)]
1437    pub const LINK_CTL: Protocol =
1438        Protocol(new_raw_protocol((c::ETH_P_LINK_CTL as u16).to_be() as u32));
1439    /// `ETH_P_ATMFATE`
1440    #[cfg(linux_kernel)]
1441    pub const ATMFATE: Protocol =
1442        Protocol(new_raw_protocol((c::ETH_P_ATMFATE as u16).to_be() as u32));
1443    /// `ETH_P_PAE`
1444    #[cfg(linux_kernel)]
1445    pub const PAE: Protocol = Protocol(new_raw_protocol((c::ETH_P_PAE as u16).to_be() as u32));
1446    /// `ETH_P_PROFINET`
1447    #[cfg(linux_raw_dep)]
1448    pub const PROFINET: Protocol =
1449        Protocol(new_raw_protocol((c::ETH_P_PROFINET as u16).to_be() as u32));
1450    /// `ETH_P_REALTEK`
1451    #[cfg(linux_raw_dep)]
1452    pub const REALTEK: Protocol =
1453        Protocol(new_raw_protocol((c::ETH_P_REALTEK as u16).to_be() as u32));
1454    /// `ETH_P_AOE`
1455    #[cfg(linux_kernel)]
1456    pub const AOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_AOE as u16).to_be() as u32));
1457    /// `ETH_P_ETHERCAT`
1458    #[cfg(linux_raw_dep)]
1459    pub const ETHERCAT: Protocol =
1460        Protocol(new_raw_protocol((c::ETH_P_ETHERCAT as u16).to_be() as u32));
1461    /// `ETH_P_8021AD`
1462    #[cfg(linux_kernel)]
1463    pub const P_8021AD: Protocol =
1464        Protocol(new_raw_protocol((c::ETH_P_8021AD as u16).to_be() as u32));
1465    /// `ETH_P_802_EX1`
1466    #[cfg(linux_kernel)]
1467    pub const P_802_EX1: Protocol =
1468        Protocol(new_raw_protocol((c::ETH_P_802_EX1 as u16).to_be() as u32));
1469    /// `ETH_P_PREAUTH`
1470    #[cfg(linux_raw_dep)]
1471    pub const PREAUTH: Protocol =
1472        Protocol(new_raw_protocol((c::ETH_P_PREAUTH as u16).to_be() as u32));
1473    /// `ETH_P_TIPC`
1474    #[cfg(linux_kernel)]
1475    pub const TIPC: Protocol = Protocol(new_raw_protocol((c::ETH_P_TIPC as u16).to_be() as u32));
1476    /// `ETH_P_LLDP`
1477    #[cfg(linux_raw_dep)]
1478    pub const LLDP: Protocol = Protocol(new_raw_protocol((c::ETH_P_LLDP as u16).to_be() as u32));
1479    /// `ETH_P_MRP`
1480    #[cfg(linux_raw_dep)]
1481    pub const MRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MRP as u16).to_be() as u32));
1482    /// `ETH_P_MACSEC`
1483    #[cfg(linux_kernel)]
1484    pub const MACSEC: Protocol =
1485        Protocol(new_raw_protocol((c::ETH_P_MACSEC as u16).to_be() as u32));
1486    /// `ETH_P_8021AH`
1487    #[cfg(linux_kernel)]
1488    pub const P_8021AH: Protocol =
1489        Protocol(new_raw_protocol((c::ETH_P_8021AH as u16).to_be() as u32));
1490    /// `ETH_P_MVRP`
1491    #[cfg(linux_kernel)]
1492    pub const MVRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MVRP as u16).to_be() as u32));
1493    /// `ETH_P_1588`
1494    #[cfg(linux_kernel)]
1495    pub const P_1588: Protocol = Protocol(new_raw_protocol((c::ETH_P_1588 as u16).to_be() as u32));
1496    /// `ETH_P_NCSI`
1497    #[cfg(linux_raw_dep)]
1498    pub const NCSI: Protocol = Protocol(new_raw_protocol((c::ETH_P_NCSI as u16).to_be() as u32));
1499    /// `ETH_P_PRP`
1500    #[cfg(linux_kernel)]
1501    pub const PRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_PRP as u16).to_be() as u32));
1502    /// `ETH_P_CFM`
1503    #[cfg(linux_raw_dep)]
1504    pub const CFM: Protocol = Protocol(new_raw_protocol((c::ETH_P_CFM as u16).to_be() as u32));
1505    /// `ETH_P_FCOE`
1506    #[cfg(linux_kernel)]
1507    pub const FCOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_FCOE as u16).to_be() as u32));
1508    /// `ETH_P_IBOE`
1509    #[cfg(linux_raw_dep)]
1510    pub const IBOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_IBOE as u16).to_be() as u32));
1511    /// `ETH_P_TDLS`
1512    #[cfg(linux_kernel)]
1513    pub const TDLS: Protocol = Protocol(new_raw_protocol((c::ETH_P_TDLS as u16).to_be() as u32));
1514    /// `ETH_P_FIP`
1515    #[cfg(linux_kernel)]
1516    pub const FIP: Protocol = Protocol(new_raw_protocol((c::ETH_P_FIP as u16).to_be() as u32));
1517    /// `ETH_P_80221`
1518    #[cfg(linux_kernel)]
1519    pub const P_80221: Protocol =
1520        Protocol(new_raw_protocol((c::ETH_P_80221 as u16).to_be() as u32));
1521    /// `ETH_P_HSR`
1522    #[cfg(linux_raw_dep)]
1523    pub const HSR: Protocol = Protocol(new_raw_protocol((c::ETH_P_HSR as u16).to_be() as u32));
1524    /// `ETH_P_NSH`
1525    #[cfg(linux_raw_dep)]
1526    pub const NSH: Protocol = Protocol(new_raw_protocol((c::ETH_P_NSH as u16).to_be() as u32));
1527    /// `ETH_P_LOOPBACK`
1528    #[cfg(linux_kernel)]
1529    pub const LOOPBACK: Protocol =
1530        Protocol(new_raw_protocol((c::ETH_P_LOOPBACK as u16).to_be() as u32));
1531    /// `ETH_P_QINQ1`
1532    #[cfg(linux_kernel)]
1533    pub const QINQ1: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ1 as u16).to_be() as u32));
1534    /// `ETH_P_QINQ2`
1535    #[cfg(linux_kernel)]
1536    pub const QINQ2: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ2 as u16).to_be() as u32));
1537    /// `ETH_P_QINQ3`
1538    #[cfg(linux_kernel)]
1539    pub const QINQ3: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ3 as u16).to_be() as u32));
1540    /// `ETH_P_EDSA`
1541    #[cfg(linux_kernel)]
1542    pub const EDSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_EDSA as u16).to_be() as u32));
1543    /// `ETH_P_DSA_8021Q`
1544    #[cfg(linux_raw_dep)]
1545    pub const DSA_8021Q: Protocol =
1546        Protocol(new_raw_protocol((c::ETH_P_DSA_8021Q as u16).to_be() as u32));
1547    /// `ETH_P_DSA_A5PSW`
1548    #[cfg(linux_raw_dep)]
1549    pub const DSA_A5PSW: Protocol =
1550        Protocol(new_raw_protocol((c::ETH_P_DSA_A5PSW as u16).to_be() as u32));
1551    /// `ETH_P_IFE`
1552    #[cfg(linux_raw_dep)]
1553    pub const IFE: Protocol = Protocol(new_raw_protocol((c::ETH_P_IFE as u16).to_be() as u32));
1554    /// `ETH_P_AF_IUCV`
1555    #[cfg(linux_kernel)]
1556    pub const AF_IUCV: Protocol =
1557        Protocol(new_raw_protocol((c::ETH_P_AF_IUCV as u16).to_be() as u32));
1558    /// `ETH_P_802_3_MIN`
1559    #[cfg(linux_kernel)]
1560    pub const P_802_3_MIN: Protocol =
1561        Protocol(new_raw_protocol((c::ETH_P_802_3_MIN as u16).to_be() as u32));
1562    /// `ETH_P_802_3`
1563    #[cfg(linux_kernel)]
1564    pub const P_802_3: Protocol =
1565        Protocol(new_raw_protocol((c::ETH_P_802_3 as u16).to_be() as u32));
1566    /// `ETH_P_AX25`
1567    #[cfg(linux_kernel)]
1568    pub const AX25: Protocol = Protocol(new_raw_protocol((c::ETH_P_AX25 as u16).to_be() as u32));
1569    /// `ETH_P_ALL`
1570    #[cfg(linux_raw_dep)]
1571    pub const ALL: Protocol = Protocol(new_raw_protocol((c::ETH_P_ALL as u16).to_be() as u32));
1572    /// `ETH_P_802_2`
1573    #[cfg(linux_kernel)]
1574    pub const P_802_2: Protocol =
1575        Protocol(new_raw_protocol((c::ETH_P_802_2 as u16).to_be() as u32));
1576    /// `ETH_P_SNAP`
1577    #[cfg(linux_kernel)]
1578    pub const SNAP: Protocol = Protocol(new_raw_protocol((c::ETH_P_SNAP as u16).to_be() as u32));
1579    /// `ETH_P_DDCMP`
1580    #[cfg(linux_kernel)]
1581    pub const DDCMP: Protocol = Protocol(new_raw_protocol((c::ETH_P_DDCMP as u16).to_be() as u32));
1582    /// `ETH_P_WAN_PPP`
1583    #[cfg(linux_kernel)]
1584    pub const WAN_PPP: Protocol =
1585        Protocol(new_raw_protocol((c::ETH_P_WAN_PPP as u16).to_be() as u32));
1586    /// `ETH_P_PPP_MP`
1587    #[cfg(linux_kernel)]
1588    pub const PPP_MP: Protocol =
1589        Protocol(new_raw_protocol((c::ETH_P_PPP_MP as u16).to_be() as u32));
1590    /// `ETH_P_LOCALTALK`
1591    #[cfg(linux_kernel)]
1592    pub const LOCALTALK: Protocol =
1593        Protocol(new_raw_protocol((c::ETH_P_LOCALTALK as u16).to_be() as u32));
1594    /// `ETH_P_CAN`
1595    #[cfg(linux_raw_dep)]
1596    pub const CAN: Protocol = Protocol(new_raw_protocol((c::ETH_P_CAN as u16).to_be() as u32));
1597    /// `ETH_P_CANFD`
1598    #[cfg(linux_kernel)]
1599    pub const CANFD: Protocol = Protocol(new_raw_protocol((c::ETH_P_CANFD as u16).to_be() as u32));
1600    /// `ETH_P_CANXL`
1601    #[cfg(linux_raw_dep)]
1602    pub const CANXL: Protocol = Protocol(new_raw_protocol((c::ETH_P_CANXL as u16).to_be() as u32));
1603    /// `ETH_P_PPPTALK`
1604    #[cfg(linux_kernel)]
1605    pub const PPPTALK: Protocol =
1606        Protocol(new_raw_protocol((c::ETH_P_PPPTALK as u16).to_be() as u32));
1607    /// `ETH_P_TR_802_2`
1608    #[cfg(linux_kernel)]
1609    pub const TR_802_2: Protocol =
1610        Protocol(new_raw_protocol((c::ETH_P_TR_802_2 as u16).to_be() as u32));
1611    /// `ETH_P_MOBITEX`
1612    #[cfg(linux_kernel)]
1613    pub const MOBITEX: Protocol =
1614        Protocol(new_raw_protocol((c::ETH_P_MOBITEX as u16).to_be() as u32));
1615    /// `ETH_P_CONTROL`
1616    #[cfg(linux_kernel)]
1617    pub const CONTROL: Protocol =
1618        Protocol(new_raw_protocol((c::ETH_P_CONTROL as u16).to_be() as u32));
1619    /// `ETH_P_IRDA`
1620    #[cfg(linux_kernel)]
1621    pub const IRDA: Protocol = Protocol(new_raw_protocol((c::ETH_P_IRDA as u16).to_be() as u32));
1622    /// `ETH_P_ECONET`
1623    #[cfg(linux_kernel)]
1624    pub const ECONET: Protocol =
1625        Protocol(new_raw_protocol((c::ETH_P_ECONET as u16).to_be() as u32));
1626    /// `ETH_P_HDLC`
1627    #[cfg(linux_kernel)]
1628    pub const HDLC: Protocol = Protocol(new_raw_protocol((c::ETH_P_HDLC as u16).to_be() as u32));
1629    /// `ETH_P_ARCNET`
1630    #[cfg(linux_kernel)]
1631    pub const ARCNET: Protocol =
1632        Protocol(new_raw_protocol((c::ETH_P_ARCNET as u16).to_be() as u32));
1633    /// `ETH_P_DSA`
1634    #[cfg(linux_raw_dep)]
1635    pub const DSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_DSA as u16).to_be() as u32));
1636    /// `ETH_P_TRAILER`
1637    #[cfg(linux_kernel)]
1638    pub const TRAILER: Protocol =
1639        Protocol(new_raw_protocol((c::ETH_P_TRAILER as u16).to_be() as u32));
1640    /// `ETH_P_PHONET`
1641    #[cfg(linux_kernel)]
1642    pub const PHONET: Protocol =
1643        Protocol(new_raw_protocol((c::ETH_P_PHONET as u16).to_be() as u32));
1644    /// `ETH_P_IEEE802154`
1645    #[cfg(linux_kernel)]
1646    pub const IEEE802154: Protocol =
1647        Protocol(new_raw_protocol((c::ETH_P_IEEE802154 as u16).to_be() as u32));
1648    /// `ETH_P_CAIF`
1649    #[cfg(linux_kernel)]
1650    pub const CAIF: Protocol = Protocol(new_raw_protocol((c::ETH_P_CAIF as u16).to_be() as u32));
1651    /// `ETH_P_XDSA`
1652    #[cfg(linux_raw_dep)]
1653    pub const XDSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_XDSA as u16).to_be() as u32));
1654    /// `ETH_P_MAP`
1655    #[cfg(linux_raw_dep)]
1656    pub const MAP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MAP as u16).to_be() as u32));
1657    /// `ETH_P_MCTP`
1658    #[cfg(linux_raw_dep)]
1659    pub const MCTP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MCTP as u16).to_be() as u32));
1660}
1661
1662#[rustfmt::skip]
1663impl Protocol {
1664    /// Constructs a `Protocol` from a raw integer.
1665    #[inline]
1666    pub const fn from_raw(raw: RawProtocol) -> Self {
1667        Self(raw)
1668    }
1669
1670    /// Returns the raw integer for this `Protocol`.
1671    #[inline]
1672    pub const fn as_raw(self) -> RawProtocol {
1673        self.0
1674    }
1675}
1676
1677/// `SHUT_*` constants for use with [`shutdown`].
1678///
1679/// [`shutdown`]: crate::net::shutdown
1680#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
1681#[repr(u32)]
1682pub enum Shutdown {
1683    /// `SHUT_RD`—Disable further read operations.
1684    Read = c::SHUT_RD as _,
1685    /// `SHUT_WR`—Disable further write operations.
1686    Write = c::SHUT_WR as _,
1687    /// `SHUT_RDWR`—Disable further read and write operations.
1688    Both = c::SHUT_RDWR as _,
1689}
1690
1691bitflags! {
1692    /// `SOCK_*` constants for use with [`socket_with`], [`accept_with`] and
1693    /// [`acceptfrom_with`].
1694    ///
1695    /// [`socket_with`]: crate::net::socket_with
1696    /// [`accept_with`]: crate::net::accept_with
1697    /// [`acceptfrom_with`]: crate::net::acceptfrom_with
1698    #[repr(transparent)]
1699    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1700    pub struct SocketFlags: ffi::c_uint {
1701        /// `SOCK_NONBLOCK`
1702        #[cfg(not(any(
1703            apple,
1704            windows,
1705            target_os = "aix",
1706            target_os = "espidf",
1707            target_os = "haiku",
1708            target_os = "horizon",
1709            target_os = "nto",
1710            target_os = "vita",
1711        )))]
1712        const NONBLOCK = bitcast!(c::SOCK_NONBLOCK);
1713
1714        /// `SOCK_CLOEXEC`
1715        #[cfg(not(any(apple, windows, target_os = "aix", target_os = "haiku")))]
1716        const CLOEXEC = bitcast!(c::SOCK_CLOEXEC);
1717
1718        // This deliberately lacks a `const _ = !0`, so that users can use
1719        // `from_bits_truncate` to extract the `SocketFlags` from a flags
1720        // value that also includes a `SocketType`.
1721    }
1722}
1723
1724#[cfg(all(target_os = "linux", feature = "time"))]
1725bitflags! {
1726    /// Flags for use with [`set_txtime`].
1727    ///
1728    /// [`set_txtime`]: crate::net::sockopt::set_txtime
1729    #[repr(transparent)]
1730    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1731    pub struct TxTimeFlags: u32 {
1732        /// `SOF_TXTIME_DEADLINE_MODE`
1733        const DEADLINE_MODE = bitcast!(c::SOF_TXTIME_DEADLINE_MODE);
1734        /// `SOF_TXTIME_REPORT_ERRORS`
1735        const REPORT_ERRORS = bitcast!(c::SOF_TXTIME_REPORT_ERRORS);
1736    }
1737}
1738
1739/// `AF_XDP` related types and constants.
1740#[cfg(target_os = "linux")]
1741pub mod xdp {
1742    use crate::backend::net::read_sockaddr::read_sockaddr_xdp;
1743    use crate::fd::{AsRawFd, BorrowedFd};
1744    use crate::net::addr::{call_with_sockaddr, SocketAddrArg, SocketAddrLen, SocketAddrOpaque};
1745    use crate::net::SocketAddrAny;
1746
1747    use super::{bitflags, c};
1748
1749    bitflags! {
1750        /// `XDP_OPTIONS_*` constants returned by [`get_xdp_options`].
1751        ///
1752        /// [`get_xdp_options`]: crate::net::sockopt::get_xdp_options
1753        #[repr(transparent)]
1754        #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1755        pub struct XdpOptionsFlags: u32 {
1756            /// `XDP_OPTIONS_ZEROCOPY`
1757            const XDP_OPTIONS_ZEROCOPY = bitcast!(c::XDP_OPTIONS_ZEROCOPY);
1758        }
1759    }
1760
1761    // Constant needs to be cast because bindgen does generate a `u32` but the
1762    // struct expects a `u16`.
1763    // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n15>
1764    bitflags! {
1765        /// `XDP_*` constants for use in [`SocketAddrXdp`].
1766        #[repr(transparent)]
1767        #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
1768        pub struct SocketAddrXdpFlags: u16 {
1769            /// `XDP_SHARED_UMEM`
1770            const XDP_SHARED_UMEM = bitcast!(c::XDP_SHARED_UMEM as u16);
1771            /// `XDP_COPY`
1772            const XDP_COPY = bitcast!(c::XDP_COPY  as u16);
1773            /// `XDP_COPY`
1774            const XDP_ZEROCOPY = bitcast!(c::XDP_ZEROCOPY as u16);
1775            /// `XDP_USE_NEED_WAKEUP`
1776            const XDP_USE_NEED_WAKEUP = bitcast!(c::XDP_USE_NEED_WAKEUP as u16);
1777            // requires kernel 6.6
1778            /// `XDP_USE_SG`
1779            const XDP_USE_SG = bitcast!(c::XDP_USE_SG as u16);
1780        }
1781    }
1782
1783    bitflags! {
1784        /// `XDP_RING_*` constants for use in fill and/or Tx ring.
1785        #[repr(transparent)]
1786        #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1787        pub struct XdpRingFlags: u32 {
1788            /// `XDP_RING_NEED_WAKEUP`
1789            const XDP_RING_NEED_WAKEUP = bitcast!(c::XDP_RING_NEED_WAKEUP);
1790        }
1791    }
1792
1793    bitflags! {
1794        /// `XDP_UMEM_*` constants for use in [`XdpUmemReg`].
1795        #[repr(transparent)]
1796        #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1797        pub struct XdpUmemRegFlags: u32 {
1798            /// `XDP_UMEM_UNALIGNED_CHUNK_FLAG`
1799            const XDP_UMEM_UNALIGNED_CHUNK_FLAG = bitcast!(c::XDP_UMEM_UNALIGNED_CHUNK_FLAG);
1800        }
1801    }
1802
1803    /// A XDP socket address.
1804    ///
1805    /// Used to bind to XDP socket.
1806    ///
1807    /// Not ABI compatible with `struct sockaddr_xdp`.
1808    ///
1809    /// To add a shared UMEM file descriptor, use
1810    /// [`SocketAddrXdpWithSharedUmem`].
1811    // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n48>
1812    #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
1813    pub struct SocketAddrXdp {
1814        /// Flags.
1815        sxdp_flags: SocketAddrXdpFlags,
1816        /// Interface index.
1817        sxdp_ifindex: u32,
1818        /// Queue ID.
1819        sxdp_queue_id: u32,
1820    }
1821
1822    impl SocketAddrXdp {
1823        /// Construct a new XDP address.
1824        #[inline]
1825        pub const fn new(flags: SocketAddrXdpFlags, interface_index: u32, queue_id: u32) -> Self {
1826            Self {
1827                sxdp_flags: flags,
1828                sxdp_ifindex: interface_index,
1829                sxdp_queue_id: queue_id,
1830            }
1831        }
1832
1833        /// Return flags.
1834        #[inline]
1835        pub fn flags(&self) -> SocketAddrXdpFlags {
1836            self.sxdp_flags
1837        }
1838
1839        /// Set flags.
1840        #[inline]
1841        pub fn set_flags(&mut self, flags: SocketAddrXdpFlags) {
1842            self.sxdp_flags = flags;
1843        }
1844
1845        /// Return interface index.
1846        #[inline]
1847        pub fn interface_index(&self) -> u32 {
1848            self.sxdp_ifindex
1849        }
1850
1851        /// Set interface index.
1852        #[inline]
1853        pub fn set_interface_index(&mut self, interface_index: u32) {
1854            self.sxdp_ifindex = interface_index;
1855        }
1856
1857        /// Return queue ID.
1858        #[inline]
1859        pub fn queue_id(&self) -> u32 {
1860            self.sxdp_queue_id
1861        }
1862
1863        /// Set queue ID.
1864        #[inline]
1865        pub fn set_queue_id(&mut self, queue_id: u32) {
1866            self.sxdp_queue_id = queue_id;
1867        }
1868    }
1869
1870    #[allow(unsafe_code)]
1871    // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which
1872    // handles calling `f` with the needed preconditions.
1873    unsafe impl SocketAddrArg for SocketAddrXdp {
1874        unsafe fn with_sockaddr<R>(
1875            &self,
1876            f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R,
1877        ) -> R {
1878            let addr = c::sockaddr_xdp {
1879                sxdp_family: c::AF_XDP as _,
1880                sxdp_flags: self.flags().bits(),
1881                sxdp_ifindex: self.interface_index(),
1882                sxdp_queue_id: self.queue_id(),
1883                sxdp_shared_umem_fd: !0,
1884            };
1885
1886            call_with_sockaddr(&addr, f)
1887        }
1888    }
1889
1890    impl From<SocketAddrXdp> for SocketAddrAny {
1891        #[inline]
1892        fn from(from: SocketAddrXdp) -> Self {
1893            from.as_any()
1894        }
1895    }
1896
1897    impl TryFrom<SocketAddrAny> for SocketAddrXdp {
1898        type Error = crate::io::Errno;
1899
1900        fn try_from(addr: SocketAddrAny) -> Result<Self, Self::Error> {
1901            read_sockaddr_xdp(&addr)
1902        }
1903    }
1904
1905    /// An XDP socket address with a shared UMEM file descriptor.
1906    ///
1907    /// This implements `SocketAddrArg` so that it can be passed to [`bind`].
1908    ///
1909    /// [`bind`]: crate::net::bind
1910    #[derive(Debug)]
1911    pub struct SocketAddrXdpWithSharedUmem<'a> {
1912        /// XDP address.
1913        pub addr: SocketAddrXdp,
1914        /// Shared UMEM file descriptor.
1915        pub shared_umem_fd: BorrowedFd<'a>,
1916    }
1917
1918    #[allow(unsafe_code)]
1919    // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which
1920    // handles calling `f` with the needed preconditions.
1921    unsafe impl<'a> SocketAddrArg for SocketAddrXdpWithSharedUmem<'a> {
1922        unsafe fn with_sockaddr<R>(
1923            &self,
1924            f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R,
1925        ) -> R {
1926            let addr = c::sockaddr_xdp {
1927                sxdp_family: c::AF_XDP as _,
1928                sxdp_flags: self.addr.flags().bits(),
1929                sxdp_ifindex: self.addr.interface_index(),
1930                sxdp_queue_id: self.addr.queue_id(),
1931                sxdp_shared_umem_fd: self.shared_umem_fd.as_raw_fd() as u32,
1932            };
1933
1934            call_with_sockaddr(&addr, f)
1935        }
1936    }
1937
1938    /// XDP ring offset.
1939    ///
1940    /// Used to mmap rings from kernel.
1941    ///
1942    /// Not ABI compatible with `struct xdp_ring_offset`.
1943    // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n59>
1944    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1945    pub struct XdpRingOffset {
1946        /// Producer offset.
1947        pub producer: u64,
1948        /// Consumer offset.
1949        pub consumer: u64,
1950        /// Descriptors offset.
1951        pub desc: u64,
1952        /// Flags offset.
1953        ///
1954        /// Is `None` if the kernel version (<5.4) does not yet support flags.
1955        pub flags: Option<u64>,
1956    }
1957
1958    /// XDP mmap offsets.
1959    ///
1960    /// Not ABI compatible with `struct xdp_mmap_offsets`
1961    // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n66>
1962    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1963    pub struct XdpMmapOffsets {
1964        /// Rx ring offsets.
1965        pub rx: XdpRingOffset,
1966        /// Tx ring offsets.
1967        pub tx: XdpRingOffset,
1968        /// Fill ring offsets.
1969        pub fr: XdpRingOffset,
1970        /// Completion ring offsets.
1971        pub cr: XdpRingOffset,
1972    }
1973
1974    /// XDP umem registration.
1975    ///
1976    /// `struct xdp_umem_reg`
1977    // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n79>
1978    #[repr(C)]
1979    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
1980    pub struct XdpUmemReg {
1981        /// Start address of UMEM.
1982        pub addr: u64,
1983        /// Umem length in bytes.
1984        pub len: u64,
1985        /// Chunk size in bytes.
1986        pub chunk_size: u32,
1987        /// Headroom in bytes.
1988        pub headroom: u32,
1989        /// Flags.
1990        ///
1991        /// Requires kernel version 5.4.
1992        pub flags: XdpUmemRegFlags,
1993        /// `AF_XDP` TX metadata length
1994        ///
1995        /// Requires kernel version 6.8.
1996        pub tx_metadata_len: u32,
1997    }
1998
1999    /// XDP statistics.
2000    ///
2001    /// Not ABI compatible with `struct xdp_statistics`
2002    // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n92>
2003    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
2004    pub struct XdpStatistics {
2005        /// Rx dropped.
2006        pub rx_dropped: u64,
2007        /// Rx invalid descriptors.
2008        pub rx_invalid_descs: u64,
2009        /// Tx invalid descriptors.
2010        pub tx_invalid_descs: u64,
2011        /// Rx ring full.
2012        ///
2013        /// Is `None` if the kernel version (<5.9) does not yet support flags.
2014        pub rx_ring_full: Option<u64>,
2015        /// Rx fill ring empty descriptors.
2016        ///
2017        /// Is `None` if the kernel version (<5.9) does not yet support flags.
2018        pub rx_fill_ring_empty_descs: Option<u64>,
2019        /// Tx ring empty descriptors.
2020        ///
2021        /// Is `None` if the kernel version (<5.9) does not yet support flags.
2022        pub tx_ring_empty_descs: Option<u64>,
2023    }
2024
2025    /// XDP options.
2026    ///
2027    /// Requires kernel version 5.3.
2028    /// `struct xdp_options`
2029    // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n101>
2030    #[repr(C)]
2031    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
2032    pub struct XdpOptions {
2033        /// Flags.
2034        pub flags: XdpOptionsFlags,
2035    }
2036
2037    /// XDP rx/tx frame descriptor.
2038    ///
2039    /// `struct xdp_desc`
2040    // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n154>
2041    #[repr(C)]
2042    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
2043    pub struct XdpDesc {
2044        /// Offset from the start of the UMEM.
2045        pub addr: u64,
2046        /// Length of packet in bytes.
2047        pub len: u32,
2048        /// Options.
2049        pub options: XdpDescOptions,
2050    }
2051
2052    #[cfg(target_os = "linux")]
2053    bitflags! {
2054        /// `XDP_*` constants for use in [`XdpDesc`].
2055        ///
2056        /// Requires kernel version 6.6.
2057        #[repr(transparent)]
2058        #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
2059        pub struct XdpDescOptions: u32 {
2060            /// `XDP_PKT_CONTD`
2061            const XDP_PKT_CONTD = bitcast!(c::XDP_PKT_CONTD);
2062        }
2063    }
2064
2065    /// Offset for mmapping rx ring.
2066    pub const XDP_PGOFF_RX_RING: u64 = c::XDP_PGOFF_RX_RING as u64;
2067    /// Offset for mmapping tx ring.
2068    pub const XDP_PGOFF_TX_RING: u64 = c::XDP_PGOFF_TX_RING as u64;
2069    /// Offset for mmapping fill ring.
2070    pub const XDP_UMEM_PGOFF_FILL_RING: u64 = c::XDP_UMEM_PGOFF_FILL_RING;
2071    /// Offset for mmapping completion ring.
2072    pub const XDP_UMEM_PGOFF_COMPLETION_RING: u64 = c::XDP_UMEM_PGOFF_COMPLETION_RING;
2073
2074    /// Offset used to shift the [`XdpDesc`] addr to the right to extract the
2075    /// address offset in unaligned mode.
2076    pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: u64 = c::XSK_UNALIGNED_BUF_OFFSET_SHIFT as u64;
2077    /// Mask used to binary `and` the [`XdpDesc`] addr to extract the address
2078    /// without the offset carried in the upper 16 bits of the address in
2079    /// unaligned mode.
2080    pub const XSK_UNALIGNED_BUF_ADDR_MASK: u64 = c::XSK_UNALIGNED_BUF_ADDR_MASK;
2081}
2082
2083/// UNIX credentials of socket peer, for use with [`get_socket_peercred`]
2084/// [`SendAncillaryMessage::ScmCredentials`] and
2085/// [`RecvAncillaryMessage::ScmCredentials`].
2086///
2087/// [`get_socket_peercred`]: crate::net::sockopt::socket_peercred
2088/// [`SendAncillaryMessage::ScmCredentials`]: crate::net::SendAncillaryMessage::ScmCredentials
2089/// [`RecvAncillaryMessage::ScmCredentials`]: crate::net::RecvAncillaryMessage::ScmCredentials
2090#[cfg(linux_kernel)]
2091#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
2092#[repr(C)]
2093pub struct UCred {
2094    /// Process ID of peer
2095    pub pid: crate::pid::Pid,
2096    /// User ID of peer
2097    pub uid: crate::ugid::Uid,
2098    /// Group ID of peer
2099    pub gid: crate::ugid::Gid,
2100}
2101
2102#[cfg(test)]
2103mod tests {
2104    use super::*;
2105
2106    #[test]
2107    fn test_sizes() {
2108        #[cfg(target_os = "linux")]
2109        use crate::backend::c;
2110        use crate::ffi::c_int;
2111        use crate::net::addr::SocketAddrStorage;
2112        use core::mem::transmute;
2113
2114        // Backend code needs to cast these to `c_int` so make sure that cast isn't
2115        // lossy.
2116        static_assertions::assert_eq_size!(RawProtocol, c_int);
2117        static_assertions::assert_eq_size!(Protocol, c_int);
2118        static_assertions::assert_eq_size!(Option<RawProtocol>, c_int);
2119        static_assertions::assert_eq_size!(Option<Protocol>, c_int);
2120        static_assertions::assert_eq_size!(RawSocketType, c_int);
2121        static_assertions::assert_eq_size!(SocketType, c_int);
2122        static_assertions::assert_eq_size!(SocketFlags, c_int);
2123        static_assertions::assert_eq_size!(SocketAddrStorage, c::sockaddr_storage);
2124
2125        // Rustix doesn't depend on `Option<Protocol>` matching the ABI of a raw
2126        // integer for correctness, but it should work nonetheless.
2127        #[allow(unsafe_code)]
2128        unsafe {
2129            let t: Option<Protocol> = None;
2130            assert_eq!(0_u32, transmute::<Option<Protocol>, u32>(t));
2131
2132            let t: Option<Protocol> = Some(Protocol::from_raw(RawProtocol::new(4567).unwrap()));
2133            assert_eq!(4567_u32, transmute::<Option<Protocol>, u32>(t));
2134        }
2135
2136        #[cfg(linux_kernel)]
2137        static_assertions::assert_eq_size!(UCred, libc::ucred);
2138
2139        #[cfg(target_os = "linux")]
2140        static_assertions::assert_eq_size!(super::xdp::XdpUmemReg, c::xdp_umem_reg);
2141        #[cfg(target_os = "linux")]
2142        static_assertions::assert_eq_size!(super::xdp::XdpOptions, c::xdp_options);
2143        #[cfg(target_os = "linux")]
2144        static_assertions::assert_eq_size!(super::xdp::XdpDesc, c::xdp_desc);
2145    }
2146}