Skip to main content

netlink_bindings/rt-addr/
mod.rs

1#![doc = "Address configuration over rtnetlink."]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{PushBuiltinBitfield32, PushBuiltinNfgenmsg, PushDummy, PushNlmsghdr};
11use crate::{
12    consts,
13    traits::{NetlinkRequest, Protocol},
14    utils::*,
15};
16pub const PROTONAME: &CStr = c"rt-addr";
17pub const PROTONUM: u16 = 0u16;
18#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
19#[derive(Debug, Clone, Copy)]
20pub enum IfaFlags {
21    Secondary = 1 << 0,
22    Nodad = 1 << 1,
23    Optimistic = 1 << 2,
24    Dadfailed = 1 << 3,
25    Homeaddress = 1 << 4,
26    Deprecated = 1 << 5,
27    Tentative = 1 << 6,
28    Permanent = 1 << 7,
29    Managetempaddr = 1 << 8,
30    Noprefixroute = 1 << 9,
31    Mcautojoin = 1 << 10,
32    StablePrivacy = 1 << 11,
33}
34impl IfaFlags {
35    pub fn from_value(value: u64) -> Option<Self> {
36        Some(match value {
37            n if n == 1 << 0 => Self::Secondary,
38            n if n == 1 << 1 => Self::Nodad,
39            n if n == 1 << 2 => Self::Optimistic,
40            n if n == 1 << 3 => Self::Dadfailed,
41            n if n == 1 << 4 => Self::Homeaddress,
42            n if n == 1 << 5 => Self::Deprecated,
43            n if n == 1 << 6 => Self::Tentative,
44            n if n == 1 << 7 => Self::Permanent,
45            n if n == 1 << 8 => Self::Managetempaddr,
46            n if n == 1 << 9 => Self::Noprefixroute,
47            n if n == 1 << 10 => Self::Mcautojoin,
48            n if n == 1 << 11 => Self::StablePrivacy,
49            _ => return None,
50        })
51    }
52}
53#[derive(Clone)]
54pub enum AddrAttrs<'a> {
55    Address(std::net::IpAddr),
56    Local(std::net::IpAddr),
57    Label(&'a CStr),
58    Broadcast(std::net::IpAddr),
59    Anycast(&'a [u8]),
60    Cacheinfo(PushIfaCacheinfo),
61    Multicast(&'a [u8]),
62    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
63    Flags(u32),
64    RtPriority(u32),
65    TargetNetnsid(&'a [u8]),
66    Proto(u8),
67}
68impl<'a> IterableAddrAttrs<'a> {
69    pub fn get_address(&self) -> Result<std::net::IpAddr, ErrorContext> {
70        let mut iter = self.clone();
71        iter.pos = 0;
72        for attr in iter {
73            if let AddrAttrs::Address(val) = attr? {
74                return Ok(val);
75            }
76        }
77        Err(ErrorContext::new_missing(
78            "AddrAttrs",
79            "Address",
80            self.orig_loc,
81            self.buf.as_ptr() as usize,
82        ))
83    }
84    pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
85        let mut iter = self.clone();
86        iter.pos = 0;
87        for attr in iter {
88            if let AddrAttrs::Local(val) = attr? {
89                return Ok(val);
90            }
91        }
92        Err(ErrorContext::new_missing(
93            "AddrAttrs",
94            "Local",
95            self.orig_loc,
96            self.buf.as_ptr() as usize,
97        ))
98    }
99    pub fn get_label(&self) -> Result<&'a CStr, ErrorContext> {
100        let mut iter = self.clone();
101        iter.pos = 0;
102        for attr in iter {
103            if let AddrAttrs::Label(val) = attr? {
104                return Ok(val);
105            }
106        }
107        Err(ErrorContext::new_missing(
108            "AddrAttrs",
109            "Label",
110            self.orig_loc,
111            self.buf.as_ptr() as usize,
112        ))
113    }
114    pub fn get_broadcast(&self) -> Result<std::net::IpAddr, ErrorContext> {
115        let mut iter = self.clone();
116        iter.pos = 0;
117        for attr in iter {
118            if let AddrAttrs::Broadcast(val) = attr? {
119                return Ok(val);
120            }
121        }
122        Err(ErrorContext::new_missing(
123            "AddrAttrs",
124            "Broadcast",
125            self.orig_loc,
126            self.buf.as_ptr() as usize,
127        ))
128    }
129    pub fn get_anycast(&self) -> Result<&'a [u8], ErrorContext> {
130        let mut iter = self.clone();
131        iter.pos = 0;
132        for attr in iter {
133            if let AddrAttrs::Anycast(val) = attr? {
134                return Ok(val);
135            }
136        }
137        Err(ErrorContext::new_missing(
138            "AddrAttrs",
139            "Anycast",
140            self.orig_loc,
141            self.buf.as_ptr() as usize,
142        ))
143    }
144    pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
145        let mut iter = self.clone();
146        iter.pos = 0;
147        for attr in iter {
148            if let AddrAttrs::Cacheinfo(val) = attr? {
149                return Ok(val);
150            }
151        }
152        Err(ErrorContext::new_missing(
153            "AddrAttrs",
154            "Cacheinfo",
155            self.orig_loc,
156            self.buf.as_ptr() as usize,
157        ))
158    }
159    pub fn get_multicast(&self) -> Result<&'a [u8], ErrorContext> {
160        let mut iter = self.clone();
161        iter.pos = 0;
162        for attr in iter {
163            if let AddrAttrs::Multicast(val) = attr? {
164                return Ok(val);
165            }
166        }
167        Err(ErrorContext::new_missing(
168            "AddrAttrs",
169            "Multicast",
170            self.orig_loc,
171            self.buf.as_ptr() as usize,
172        ))
173    }
174    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
175    pub fn get_flags(&self) -> Result<u32, ErrorContext> {
176        let mut iter = self.clone();
177        iter.pos = 0;
178        for attr in iter {
179            if let AddrAttrs::Flags(val) = attr? {
180                return Ok(val);
181            }
182        }
183        Err(ErrorContext::new_missing(
184            "AddrAttrs",
185            "Flags",
186            self.orig_loc,
187            self.buf.as_ptr() as usize,
188        ))
189    }
190    pub fn get_rt_priority(&self) -> Result<u32, ErrorContext> {
191        let mut iter = self.clone();
192        iter.pos = 0;
193        for attr in iter {
194            if let AddrAttrs::RtPriority(val) = attr? {
195                return Ok(val);
196            }
197        }
198        Err(ErrorContext::new_missing(
199            "AddrAttrs",
200            "RtPriority",
201            self.orig_loc,
202            self.buf.as_ptr() as usize,
203        ))
204    }
205    pub fn get_target_netnsid(&self) -> Result<&'a [u8], ErrorContext> {
206        let mut iter = self.clone();
207        iter.pos = 0;
208        for attr in iter {
209            if let AddrAttrs::TargetNetnsid(val) = attr? {
210                return Ok(val);
211            }
212        }
213        Err(ErrorContext::new_missing(
214            "AddrAttrs",
215            "TargetNetnsid",
216            self.orig_loc,
217            self.buf.as_ptr() as usize,
218        ))
219    }
220    pub fn get_proto(&self) -> Result<u8, ErrorContext> {
221        let mut iter = self.clone();
222        iter.pos = 0;
223        for attr in iter {
224            if let AddrAttrs::Proto(val) = attr? {
225                return Ok(val);
226            }
227        }
228        Err(ErrorContext::new_missing(
229            "AddrAttrs",
230            "Proto",
231            self.orig_loc,
232            self.buf.as_ptr() as usize,
233        ))
234    }
235}
236impl AddrAttrs<'_> {
237    pub fn new<'a>(buf: &'a [u8]) -> IterableAddrAttrs<'a> {
238        IterableAddrAttrs::with_loc(buf, buf.as_ptr() as usize)
239    }
240    fn attr_from_type(r#type: u16) -> Option<&'static str> {
241        let res = match r#type {
242            1u16 => "Address",
243            2u16 => "Local",
244            3u16 => "Label",
245            4u16 => "Broadcast",
246            5u16 => "Anycast",
247            6u16 => "Cacheinfo",
248            7u16 => "Multicast",
249            8u16 => "Flags",
250            9u16 => "RtPriority",
251            10u16 => "TargetNetnsid",
252            11u16 => "Proto",
253            _ => return None,
254        };
255        Some(res)
256    }
257}
258#[derive(Clone, Copy, Default)]
259pub struct IterableAddrAttrs<'a> {
260    buf: &'a [u8],
261    pos: usize,
262    orig_loc: usize,
263}
264impl<'a> IterableAddrAttrs<'a> {
265    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
266        Self {
267            buf,
268            pos: 0,
269            orig_loc,
270        }
271    }
272    pub fn get_buf(&self) -> &'a [u8] {
273        self.buf
274    }
275}
276impl<'a> Iterator for IterableAddrAttrs<'a> {
277    type Item = Result<AddrAttrs<'a>, ErrorContext>;
278    fn next(&mut self) -> Option<Self::Item> {
279        let pos = self.pos;
280        let mut r#type;
281        loop {
282            r#type = None;
283            if self.buf.len() == self.pos {
284                return None;
285            }
286            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
287                break;
288            };
289            r#type = Some(header.r#type);
290            let res = match header.r#type {
291                1u16 => AddrAttrs::Address({
292                    let res = parse_ip(next);
293                    let Some(val) = res else { break };
294                    val
295                }),
296                2u16 => AddrAttrs::Local({
297                    let res = parse_ip(next);
298                    let Some(val) = res else { break };
299                    val
300                }),
301                3u16 => AddrAttrs::Label({
302                    let res = CStr::from_bytes_with_nul(next).ok();
303                    let Some(val) = res else { break };
304                    val
305                }),
306                4u16 => AddrAttrs::Broadcast({
307                    let res = parse_ip(next);
308                    let Some(val) = res else { break };
309                    val
310                }),
311                5u16 => AddrAttrs::Anycast({
312                    let res = Some(next);
313                    let Some(val) = res else { break };
314                    val
315                }),
316                6u16 => AddrAttrs::Cacheinfo({
317                    let res = PushIfaCacheinfo::new_from_slice(next);
318                    let Some(val) = res else { break };
319                    val
320                }),
321                7u16 => AddrAttrs::Multicast({
322                    let res = Some(next);
323                    let Some(val) = res else { break };
324                    val
325                }),
326                8u16 => AddrAttrs::Flags({
327                    let res = parse_u32(next);
328                    let Some(val) = res else { break };
329                    val
330                }),
331                9u16 => AddrAttrs::RtPriority({
332                    let res = parse_u32(next);
333                    let Some(val) = res else { break };
334                    val
335                }),
336                10u16 => AddrAttrs::TargetNetnsid({
337                    let res = Some(next);
338                    let Some(val) = res else { break };
339                    val
340                }),
341                11u16 => AddrAttrs::Proto({
342                    let res = parse_u8(next);
343                    let Some(val) = res else { break };
344                    val
345                }),
346                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
347                n => continue,
348            };
349            return Some(Ok(res));
350        }
351        Some(Err(ErrorContext::new(
352            "AddrAttrs",
353            r#type.and_then(|t| AddrAttrs::attr_from_type(t)),
354            self.orig_loc,
355            self.buf.as_ptr().wrapping_add(pos) as usize,
356        )))
357    }
358}
359impl<'a> std::fmt::Debug for IterableAddrAttrs<'_> {
360    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
361        let mut fmt = f.debug_struct("AddrAttrs");
362        for attr in self.clone() {
363            let attr = match attr {
364                Ok(a) => a,
365                Err(err) => {
366                    fmt.finish()?;
367                    f.write_str("Err(")?;
368                    err.fmt(f)?;
369                    return f.write_str(")");
370                }
371            };
372            match attr {
373                AddrAttrs::Address(val) => fmt.field("Address", &val),
374                AddrAttrs::Local(val) => fmt.field("Local", &val),
375                AddrAttrs::Label(val) => fmt.field("Label", &val),
376                AddrAttrs::Broadcast(val) => fmt.field("Broadcast", &val),
377                AddrAttrs::Anycast(val) => fmt.field("Anycast", &val),
378                AddrAttrs::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
379                AddrAttrs::Multicast(val) => fmt.field("Multicast", &val),
380                AddrAttrs::Flags(val) => {
381                    fmt.field("Flags", &FormatFlags(val.into(), IfaFlags::from_value))
382                }
383                AddrAttrs::RtPriority(val) => fmt.field("RtPriority", &val),
384                AddrAttrs::TargetNetnsid(val) => fmt.field("TargetNetnsid", &val),
385                AddrAttrs::Proto(val) => fmt.field("Proto", &val),
386            };
387        }
388        fmt.finish()
389    }
390}
391impl IterableAddrAttrs<'_> {
392    pub fn lookup_attr(
393        &self,
394        offset: usize,
395        missing_type: Option<u16>,
396    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
397        let mut stack = Vec::new();
398        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
399        if cur == offset {
400            stack.push(("AddrAttrs", offset));
401            return (
402                stack,
403                missing_type.and_then(|t| AddrAttrs::attr_from_type(t)),
404            );
405        }
406        if cur > offset || cur + self.buf.len() < offset {
407            return (stack, None);
408        }
409        let mut attrs = self.clone();
410        let mut last_off = cur + attrs.pos;
411        while let Some(attr) = attrs.next() {
412            let Ok(attr) = attr else { break };
413            match attr {
414                AddrAttrs::Address(val) => {
415                    if last_off == offset {
416                        stack.push(("Address", last_off));
417                        break;
418                    }
419                }
420                AddrAttrs::Local(val) => {
421                    if last_off == offset {
422                        stack.push(("Local", last_off));
423                        break;
424                    }
425                }
426                AddrAttrs::Label(val) => {
427                    if last_off == offset {
428                        stack.push(("Label", last_off));
429                        break;
430                    }
431                }
432                AddrAttrs::Broadcast(val) => {
433                    if last_off == offset {
434                        stack.push(("Broadcast", last_off));
435                        break;
436                    }
437                }
438                AddrAttrs::Anycast(val) => {
439                    if last_off == offset {
440                        stack.push(("Anycast", last_off));
441                        break;
442                    }
443                }
444                AddrAttrs::Cacheinfo(val) => {
445                    if last_off == offset {
446                        stack.push(("Cacheinfo", last_off));
447                        break;
448                    }
449                }
450                AddrAttrs::Multicast(val) => {
451                    if last_off == offset {
452                        stack.push(("Multicast", last_off));
453                        break;
454                    }
455                }
456                AddrAttrs::Flags(val) => {
457                    if last_off == offset {
458                        stack.push(("Flags", last_off));
459                        break;
460                    }
461                }
462                AddrAttrs::RtPriority(val) => {
463                    if last_off == offset {
464                        stack.push(("RtPriority", last_off));
465                        break;
466                    }
467                }
468                AddrAttrs::TargetNetnsid(val) => {
469                    if last_off == offset {
470                        stack.push(("TargetNetnsid", last_off));
471                        break;
472                    }
473                }
474                AddrAttrs::Proto(val) => {
475                    if last_off == offset {
476                        stack.push(("Proto", last_off));
477                        break;
478                    }
479                }
480                _ => {}
481            };
482            last_off = cur + attrs.pos;
483        }
484        if !stack.is_empty() {
485            stack.push(("AddrAttrs", cur));
486        }
487        (stack, None)
488    }
489}
490pub struct PushAddrAttrs<Prev: Rec> {
491    pub(crate) prev: Option<Prev>,
492    pub(crate) header_offset: Option<usize>,
493}
494impl<Prev: Rec> Rec for PushAddrAttrs<Prev> {
495    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
496        self.prev.as_mut().unwrap().as_rec_mut()
497    }
498    fn as_rec(&self) -> &Vec<u8> {
499        self.prev.as_ref().unwrap().as_rec()
500    }
501}
502impl<Prev: Rec> PushAddrAttrs<Prev> {
503    pub fn new(prev: Prev) -> Self {
504        Self {
505            prev: Some(prev),
506            header_offset: None,
507        }
508    }
509    pub fn end_nested(mut self) -> Prev {
510        let mut prev = self.prev.take().unwrap();
511        if let Some(header_offset) = &self.header_offset {
512            finalize_nested_header(prev.as_rec_mut(), *header_offset);
513        }
514        prev
515    }
516    pub fn push_address(mut self, value: std::net::IpAddr) -> Self {
517        push_header(self.as_rec_mut(), 1u16, {
518            match &value {
519                IpAddr::V4(_) => 4,
520                IpAddr::V6(_) => 16,
521            }
522        } as u16);
523        encode_ip(self.as_rec_mut(), value);
524        self
525    }
526    pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
527        push_header(self.as_rec_mut(), 2u16, {
528            match &value {
529                IpAddr::V4(_) => 4,
530                IpAddr::V6(_) => 16,
531            }
532        } as u16);
533        encode_ip(self.as_rec_mut(), value);
534        self
535    }
536    pub fn push_label(mut self, value: &CStr) -> Self {
537        push_header(
538            self.as_rec_mut(),
539            3u16,
540            value.to_bytes_with_nul().len() as u16,
541        );
542        self.as_rec_mut().extend(value.to_bytes_with_nul());
543        self
544    }
545    pub fn push_label_bytes(mut self, value: &[u8]) -> Self {
546        push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
547        self.as_rec_mut().extend(value);
548        self.as_rec_mut().push(0);
549        self
550    }
551    pub fn push_broadcast(mut self, value: std::net::IpAddr) -> Self {
552        push_header(self.as_rec_mut(), 4u16, {
553            match &value {
554                IpAddr::V4(_) => 4,
555                IpAddr::V6(_) => 16,
556            }
557        } as u16);
558        encode_ip(self.as_rec_mut(), value);
559        self
560    }
561    pub fn push_anycast(mut self, value: &[u8]) -> Self {
562        push_header(self.as_rec_mut(), 5u16, value.len() as u16);
563        self.as_rec_mut().extend(value);
564        self
565    }
566    pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
567        push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
568        self.as_rec_mut().extend(value.as_slice());
569        self
570    }
571    pub fn push_multicast(mut self, value: &[u8]) -> Self {
572        push_header(self.as_rec_mut(), 7u16, value.len() as u16);
573        self.as_rec_mut().extend(value);
574        self
575    }
576    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
577    pub fn push_flags(mut self, value: u32) -> Self {
578        push_header(self.as_rec_mut(), 8u16, 4 as u16);
579        self.as_rec_mut().extend(value.to_ne_bytes());
580        self
581    }
582    pub fn push_rt_priority(mut self, value: u32) -> Self {
583        push_header(self.as_rec_mut(), 9u16, 4 as u16);
584        self.as_rec_mut().extend(value.to_ne_bytes());
585        self
586    }
587    pub fn push_target_netnsid(mut self, value: &[u8]) -> Self {
588        push_header(self.as_rec_mut(), 10u16, value.len() as u16);
589        self.as_rec_mut().extend(value);
590        self
591    }
592    pub fn push_proto(mut self, value: u8) -> Self {
593        push_header(self.as_rec_mut(), 11u16, 1 as u16);
594        self.as_rec_mut().extend(value.to_ne_bytes());
595        self
596    }
597}
598impl<Prev: Rec> Drop for PushAddrAttrs<Prev> {
599    fn drop(&mut self) {
600        if let Some(prev) = &mut self.prev {
601            if let Some(header_offset) = &self.header_offset {
602                finalize_nested_header(prev.as_rec_mut(), *header_offset);
603            }
604        }
605    }
606}
607#[derive(Clone)]
608pub struct PushIfaddrmsg {
609    pub(crate) buf: [u8; 8usize],
610}
611#[doc = "Create zero-initialized struct"]
612impl Default for PushIfaddrmsg {
613    fn default() -> Self {
614        Self { buf: [0u8; 8usize] }
615    }
616}
617impl PushIfaddrmsg {
618    #[doc = "Create zero-initialized struct"]
619    pub fn new() -> Self {
620        Default::default()
621    }
622    #[doc = "Copy from contents from other slice"]
623    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
624        if other.len() != Self::len() {
625            return None;
626        }
627        let mut buf = [0u8; Self::len()];
628        buf.clone_from_slice(other);
629        Some(Self { buf })
630    }
631    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
632    pub fn new_from_zeroed(other: &[u8]) -> Self {
633        let mut buf = [0u8; Self::len()];
634        let len = buf.len().min(other.len());
635        buf[..len].clone_from_slice(&other[..len]);
636        Self { buf }
637    }
638    pub fn as_slice(&self) -> &[u8] {
639        &self.buf
640    }
641    pub fn as_mut_slice(&mut self) -> &mut [u8] {
642        &mut self.buf
643    }
644    pub const fn len() -> usize {
645        8usize
646    }
647    pub fn ifa_family(&self) -> u8 {
648        parse_u8(&self.buf[0usize..1usize]).unwrap()
649    }
650    pub fn set_ifa_family(&mut self, value: u8) {
651        self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
652    }
653    pub fn ifa_prefixlen(&self) -> u8 {
654        parse_u8(&self.buf[1usize..2usize]).unwrap()
655    }
656    pub fn set_ifa_prefixlen(&mut self, value: u8) {
657        self.buf[1usize..2usize].copy_from_slice(&value.to_ne_bytes())
658    }
659    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
660    pub fn ifa_flags(&self) -> u8 {
661        parse_u8(&self.buf[2usize..3usize]).unwrap()
662    }
663    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
664    pub fn set_ifa_flags(&mut self, value: u8) {
665        self.buf[2usize..3usize].copy_from_slice(&value.to_ne_bytes())
666    }
667    pub fn ifa_scope(&self) -> u8 {
668        parse_u8(&self.buf[3usize..4usize]).unwrap()
669    }
670    pub fn set_ifa_scope(&mut self, value: u8) {
671        self.buf[3usize..4usize].copy_from_slice(&value.to_ne_bytes())
672    }
673    pub fn ifa_index(&self) -> u32 {
674        parse_u32(&self.buf[4usize..8usize]).unwrap()
675    }
676    pub fn set_ifa_index(&mut self, value: u32) {
677        self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
678    }
679}
680impl std::fmt::Debug for PushIfaddrmsg {
681    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
682        fmt.debug_struct("Ifaddrmsg")
683            .field("ifa_family", &self.ifa_family())
684            .field("ifa_prefixlen", &self.ifa_prefixlen())
685            .field(
686                "ifa_flags",
687                &FormatFlags(self.ifa_flags().into(), IfaFlags::from_value),
688            )
689            .field("ifa_scope", &self.ifa_scope())
690            .field("ifa_index", &self.ifa_index())
691            .finish()
692    }
693}
694#[derive(Clone)]
695pub struct PushIfaCacheinfo {
696    pub(crate) buf: [u8; 16usize],
697}
698#[doc = "Create zero-initialized struct"]
699impl Default for PushIfaCacheinfo {
700    fn default() -> Self {
701        Self {
702            buf: [0u8; 16usize],
703        }
704    }
705}
706impl PushIfaCacheinfo {
707    #[doc = "Create zero-initialized struct"]
708    pub fn new() -> Self {
709        Default::default()
710    }
711    #[doc = "Copy from contents from other slice"]
712    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
713        if other.len() != Self::len() {
714            return None;
715        }
716        let mut buf = [0u8; Self::len()];
717        buf.clone_from_slice(other);
718        Some(Self { buf })
719    }
720    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
721    pub fn new_from_zeroed(other: &[u8]) -> Self {
722        let mut buf = [0u8; Self::len()];
723        let len = buf.len().min(other.len());
724        buf[..len].clone_from_slice(&other[..len]);
725        Self { buf }
726    }
727    pub fn as_slice(&self) -> &[u8] {
728        &self.buf
729    }
730    pub fn as_mut_slice(&mut self) -> &mut [u8] {
731        &mut self.buf
732    }
733    pub const fn len() -> usize {
734        16usize
735    }
736    pub fn ifa_prefered(&self) -> u32 {
737        parse_u32(&self.buf[0usize..4usize]).unwrap()
738    }
739    pub fn set_ifa_prefered(&mut self, value: u32) {
740        self.buf[0usize..4usize].copy_from_slice(&value.to_ne_bytes())
741    }
742    pub fn ifa_valid(&self) -> u32 {
743        parse_u32(&self.buf[4usize..8usize]).unwrap()
744    }
745    pub fn set_ifa_valid(&mut self, value: u32) {
746        self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
747    }
748    pub fn cstamp(&self) -> u32 {
749        parse_u32(&self.buf[8usize..12usize]).unwrap()
750    }
751    pub fn set_cstamp(&mut self, value: u32) {
752        self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
753    }
754    pub fn tstamp(&self) -> u32 {
755        parse_u32(&self.buf[12usize..16usize]).unwrap()
756    }
757    pub fn set_tstamp(&mut self, value: u32) {
758        self.buf[12usize..16usize].copy_from_slice(&value.to_ne_bytes())
759    }
760}
761impl std::fmt::Debug for PushIfaCacheinfo {
762    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
763        fmt.debug_struct("IfaCacheinfo")
764            .field("ifa_prefered", &self.ifa_prefered())
765            .field("ifa_valid", &self.ifa_valid())
766            .field("cstamp", &self.cstamp())
767            .field("tstamp", &self.tstamp())
768            .finish()
769    }
770}
771#[doc = "Add new address"]
772pub struct PushOpNewaddrDoRequest<Prev: Rec> {
773    pub(crate) prev: Option<Prev>,
774    pub(crate) header_offset: Option<usize>,
775}
776impl<Prev: Rec> Rec for PushOpNewaddrDoRequest<Prev> {
777    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
778        self.prev.as_mut().unwrap().as_rec_mut()
779    }
780    fn as_rec(&self) -> &Vec<u8> {
781        self.prev.as_ref().unwrap().as_rec()
782    }
783}
784impl<Prev: Rec> PushOpNewaddrDoRequest<Prev> {
785    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
786        Self::write_header(&mut prev, header);
787        Self::new_without_header(prev)
788    }
789    fn new_without_header(prev: Prev) -> Self {
790        Self {
791            prev: Some(prev),
792            header_offset: None,
793        }
794    }
795    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
796        prev.as_rec_mut().extend(header.as_slice());
797    }
798    pub fn end_nested(mut self) -> Prev {
799        let mut prev = self.prev.take().unwrap();
800        if let Some(header_offset) = &self.header_offset {
801            finalize_nested_header(prev.as_rec_mut(), *header_offset);
802        }
803        prev
804    }
805    pub fn push_address(mut self, value: std::net::IpAddr) -> Self {
806        push_header(self.as_rec_mut(), 1u16, {
807            match &value {
808                IpAddr::V4(_) => 4,
809                IpAddr::V6(_) => 16,
810            }
811        } as u16);
812        encode_ip(self.as_rec_mut(), value);
813        self
814    }
815    pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
816        push_header(self.as_rec_mut(), 2u16, {
817            match &value {
818                IpAddr::V4(_) => 4,
819                IpAddr::V6(_) => 16,
820            }
821        } as u16);
822        encode_ip(self.as_rec_mut(), value);
823        self
824    }
825    pub fn push_label(mut self, value: &CStr) -> Self {
826        push_header(
827            self.as_rec_mut(),
828            3u16,
829            value.to_bytes_with_nul().len() as u16,
830        );
831        self.as_rec_mut().extend(value.to_bytes_with_nul());
832        self
833    }
834    pub fn push_label_bytes(mut self, value: &[u8]) -> Self {
835        push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
836        self.as_rec_mut().extend(value);
837        self.as_rec_mut().push(0);
838        self
839    }
840    pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
841        push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
842        self.as_rec_mut().extend(value.as_slice());
843        self
844    }
845    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
846    pub fn push_flags(mut self, value: u32) -> Self {
847        push_header(self.as_rec_mut(), 8u16, 4 as u16);
848        self.as_rec_mut().extend(value.to_ne_bytes());
849        self
850    }
851}
852impl<Prev: Rec> Drop for PushOpNewaddrDoRequest<Prev> {
853    fn drop(&mut self) {
854        if let Some(prev) = &mut self.prev {
855            if let Some(header_offset) = &self.header_offset {
856                finalize_nested_header(prev.as_rec_mut(), *header_offset);
857            }
858        }
859    }
860}
861#[doc = "Add new address"]
862#[derive(Clone)]
863pub enum OpNewaddrDoRequest<'a> {
864    Address(std::net::IpAddr),
865    Local(std::net::IpAddr),
866    Label(&'a CStr),
867    Cacheinfo(PushIfaCacheinfo),
868    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
869    Flags(u32),
870}
871impl<'a> IterableOpNewaddrDoRequest<'a> {
872    pub fn get_address(&self) -> Result<std::net::IpAddr, ErrorContext> {
873        let mut iter = self.clone();
874        iter.pos = 0;
875        for attr in iter {
876            if let OpNewaddrDoRequest::Address(val) = attr? {
877                return Ok(val);
878            }
879        }
880        Err(ErrorContext::new_missing(
881            "OpNewaddrDoRequest",
882            "Address",
883            self.orig_loc,
884            self.buf.as_ptr() as usize,
885        ))
886    }
887    pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
888        let mut iter = self.clone();
889        iter.pos = 0;
890        for attr in iter {
891            if let OpNewaddrDoRequest::Local(val) = attr? {
892                return Ok(val);
893            }
894        }
895        Err(ErrorContext::new_missing(
896            "OpNewaddrDoRequest",
897            "Local",
898            self.orig_loc,
899            self.buf.as_ptr() as usize,
900        ))
901    }
902    pub fn get_label(&self) -> Result<&'a CStr, ErrorContext> {
903        let mut iter = self.clone();
904        iter.pos = 0;
905        for attr in iter {
906            if let OpNewaddrDoRequest::Label(val) = attr? {
907                return Ok(val);
908            }
909        }
910        Err(ErrorContext::new_missing(
911            "OpNewaddrDoRequest",
912            "Label",
913            self.orig_loc,
914            self.buf.as_ptr() as usize,
915        ))
916    }
917    pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
918        let mut iter = self.clone();
919        iter.pos = 0;
920        for attr in iter {
921            if let OpNewaddrDoRequest::Cacheinfo(val) = attr? {
922                return Ok(val);
923            }
924        }
925        Err(ErrorContext::new_missing(
926            "OpNewaddrDoRequest",
927            "Cacheinfo",
928            self.orig_loc,
929            self.buf.as_ptr() as usize,
930        ))
931    }
932    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
933    pub fn get_flags(&self) -> Result<u32, ErrorContext> {
934        let mut iter = self.clone();
935        iter.pos = 0;
936        for attr in iter {
937            if let OpNewaddrDoRequest::Flags(val) = attr? {
938                return Ok(val);
939            }
940        }
941        Err(ErrorContext::new_missing(
942            "OpNewaddrDoRequest",
943            "Flags",
944            self.orig_loc,
945            self.buf.as_ptr() as usize,
946        ))
947    }
948}
949impl OpNewaddrDoRequest<'_> {
950    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpNewaddrDoRequest<'a>) {
951        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
952        (
953            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
954            IterableOpNewaddrDoRequest::with_loc(attrs, buf.as_ptr() as usize),
955        )
956    }
957    fn attr_from_type(r#type: u16) -> Option<&'static str> {
958        AddrAttrs::attr_from_type(r#type)
959    }
960}
961#[derive(Clone, Copy, Default)]
962pub struct IterableOpNewaddrDoRequest<'a> {
963    buf: &'a [u8],
964    pos: usize,
965    orig_loc: usize,
966}
967impl<'a> IterableOpNewaddrDoRequest<'a> {
968    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
969        Self {
970            buf,
971            pos: 0,
972            orig_loc,
973        }
974    }
975    pub fn get_buf(&self) -> &'a [u8] {
976        self.buf
977    }
978}
979impl<'a> Iterator for IterableOpNewaddrDoRequest<'a> {
980    type Item = Result<OpNewaddrDoRequest<'a>, ErrorContext>;
981    fn next(&mut self) -> Option<Self::Item> {
982        let pos = self.pos;
983        let mut r#type;
984        loop {
985            r#type = None;
986            if self.buf.len() == self.pos {
987                return None;
988            }
989            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
990                break;
991            };
992            r#type = Some(header.r#type);
993            let res = match header.r#type {
994                1u16 => OpNewaddrDoRequest::Address({
995                    let res = parse_ip(next);
996                    let Some(val) = res else { break };
997                    val
998                }),
999                2u16 => OpNewaddrDoRequest::Local({
1000                    let res = parse_ip(next);
1001                    let Some(val) = res else { break };
1002                    val
1003                }),
1004                3u16 => OpNewaddrDoRequest::Label({
1005                    let res = CStr::from_bytes_with_nul(next).ok();
1006                    let Some(val) = res else { break };
1007                    val
1008                }),
1009                6u16 => OpNewaddrDoRequest::Cacheinfo({
1010                    let res = PushIfaCacheinfo::new_from_slice(next);
1011                    let Some(val) = res else { break };
1012                    val
1013                }),
1014                8u16 => OpNewaddrDoRequest::Flags({
1015                    let res = parse_u32(next);
1016                    let Some(val) = res else { break };
1017                    val
1018                }),
1019                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1020                n => continue,
1021            };
1022            return Some(Ok(res));
1023        }
1024        Some(Err(ErrorContext::new(
1025            "OpNewaddrDoRequest",
1026            r#type.and_then(|t| OpNewaddrDoRequest::attr_from_type(t)),
1027            self.orig_loc,
1028            self.buf.as_ptr().wrapping_add(pos) as usize,
1029        )))
1030    }
1031}
1032impl<'a> std::fmt::Debug for IterableOpNewaddrDoRequest<'_> {
1033    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1034        let mut fmt = f.debug_struct("OpNewaddrDoRequest");
1035        for attr in self.clone() {
1036            let attr = match attr {
1037                Ok(a) => a,
1038                Err(err) => {
1039                    fmt.finish()?;
1040                    f.write_str("Err(")?;
1041                    err.fmt(f)?;
1042                    return f.write_str(")");
1043                }
1044            };
1045            match attr {
1046                OpNewaddrDoRequest::Address(val) => fmt.field("Address", &val),
1047                OpNewaddrDoRequest::Local(val) => fmt.field("Local", &val),
1048                OpNewaddrDoRequest::Label(val) => fmt.field("Label", &val),
1049                OpNewaddrDoRequest::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
1050                OpNewaddrDoRequest::Flags(val) => {
1051                    fmt.field("Flags", &FormatFlags(val.into(), IfaFlags::from_value))
1052                }
1053            };
1054        }
1055        fmt.finish()
1056    }
1057}
1058impl IterableOpNewaddrDoRequest<'_> {
1059    pub fn lookup_attr(
1060        &self,
1061        offset: usize,
1062        missing_type: Option<u16>,
1063    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1064        let mut stack = Vec::new();
1065        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1066        if cur == offset + PushIfaddrmsg::len() {
1067            stack.push(("OpNewaddrDoRequest", offset));
1068            return (
1069                stack,
1070                missing_type.and_then(|t| OpNewaddrDoRequest::attr_from_type(t)),
1071            );
1072        }
1073        if cur > offset || cur + self.buf.len() < offset {
1074            return (stack, None);
1075        }
1076        let mut attrs = self.clone();
1077        let mut last_off = cur + attrs.pos;
1078        while let Some(attr) = attrs.next() {
1079            let Ok(attr) = attr else { break };
1080            match attr {
1081                OpNewaddrDoRequest::Address(val) => {
1082                    if last_off == offset {
1083                        stack.push(("Address", last_off));
1084                        break;
1085                    }
1086                }
1087                OpNewaddrDoRequest::Local(val) => {
1088                    if last_off == offset {
1089                        stack.push(("Local", last_off));
1090                        break;
1091                    }
1092                }
1093                OpNewaddrDoRequest::Label(val) => {
1094                    if last_off == offset {
1095                        stack.push(("Label", last_off));
1096                        break;
1097                    }
1098                }
1099                OpNewaddrDoRequest::Cacheinfo(val) => {
1100                    if last_off == offset {
1101                        stack.push(("Cacheinfo", last_off));
1102                        break;
1103                    }
1104                }
1105                OpNewaddrDoRequest::Flags(val) => {
1106                    if last_off == offset {
1107                        stack.push(("Flags", last_off));
1108                        break;
1109                    }
1110                }
1111                _ => {}
1112            };
1113            last_off = cur + attrs.pos;
1114        }
1115        if !stack.is_empty() {
1116            stack.push(("OpNewaddrDoRequest", cur));
1117        }
1118        (stack, None)
1119    }
1120}
1121#[doc = "Add new address"]
1122pub struct PushOpNewaddrDoReply<Prev: Rec> {
1123    pub(crate) prev: Option<Prev>,
1124    pub(crate) header_offset: Option<usize>,
1125}
1126impl<Prev: Rec> Rec for PushOpNewaddrDoReply<Prev> {
1127    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1128        self.prev.as_mut().unwrap().as_rec_mut()
1129    }
1130    fn as_rec(&self) -> &Vec<u8> {
1131        self.prev.as_ref().unwrap().as_rec()
1132    }
1133}
1134impl<Prev: Rec> PushOpNewaddrDoReply<Prev> {
1135    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1136        Self::write_header(&mut prev, header);
1137        Self::new_without_header(prev)
1138    }
1139    fn new_without_header(prev: Prev) -> Self {
1140        Self {
1141            prev: Some(prev),
1142            header_offset: None,
1143        }
1144    }
1145    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1146        prev.as_rec_mut().extend(header.as_slice());
1147    }
1148    pub fn end_nested(mut self) -> Prev {
1149        let mut prev = self.prev.take().unwrap();
1150        if let Some(header_offset) = &self.header_offset {
1151            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1152        }
1153        prev
1154    }
1155}
1156impl<Prev: Rec> Drop for PushOpNewaddrDoReply<Prev> {
1157    fn drop(&mut self) {
1158        if let Some(prev) = &mut self.prev {
1159            if let Some(header_offset) = &self.header_offset {
1160                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1161            }
1162        }
1163    }
1164}
1165#[doc = "Add new address"]
1166#[derive(Clone)]
1167pub enum OpNewaddrDoReply {}
1168impl<'a> IterableOpNewaddrDoReply<'a> {}
1169impl OpNewaddrDoReply {
1170    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpNewaddrDoReply<'a>) {
1171        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
1172        (
1173            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
1174            IterableOpNewaddrDoReply::with_loc(attrs, buf.as_ptr() as usize),
1175        )
1176    }
1177    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1178        AddrAttrs::attr_from_type(r#type)
1179    }
1180}
1181#[derive(Clone, Copy, Default)]
1182pub struct IterableOpNewaddrDoReply<'a> {
1183    buf: &'a [u8],
1184    pos: usize,
1185    orig_loc: usize,
1186}
1187impl<'a> IterableOpNewaddrDoReply<'a> {
1188    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1189        Self {
1190            buf,
1191            pos: 0,
1192            orig_loc,
1193        }
1194    }
1195    pub fn get_buf(&self) -> &'a [u8] {
1196        self.buf
1197    }
1198}
1199impl<'a> Iterator for IterableOpNewaddrDoReply<'a> {
1200    type Item = Result<OpNewaddrDoReply, ErrorContext>;
1201    fn next(&mut self) -> Option<Self::Item> {
1202        let pos = self.pos;
1203        let mut r#type;
1204        loop {
1205            r#type = None;
1206            if self.buf.len() == self.pos {
1207                return None;
1208            }
1209            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1210                break;
1211            };
1212            r#type = Some(header.r#type);
1213            let res = match header.r#type {
1214                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1215                n => continue,
1216            };
1217            return Some(Ok(res));
1218        }
1219        Some(Err(ErrorContext::new(
1220            "OpNewaddrDoReply",
1221            r#type.and_then(|t| OpNewaddrDoReply::attr_from_type(t)),
1222            self.orig_loc,
1223            self.buf.as_ptr().wrapping_add(pos) as usize,
1224        )))
1225    }
1226}
1227impl std::fmt::Debug for IterableOpNewaddrDoReply<'_> {
1228    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1229        let mut fmt = f.debug_struct("OpNewaddrDoReply");
1230        for attr in self.clone() {
1231            let attr = match attr {
1232                Ok(a) => a,
1233                Err(err) => {
1234                    fmt.finish()?;
1235                    f.write_str("Err(")?;
1236                    err.fmt(f)?;
1237                    return f.write_str(")");
1238                }
1239            };
1240            match attr {};
1241        }
1242        fmt.finish()
1243    }
1244}
1245impl IterableOpNewaddrDoReply<'_> {
1246    pub fn lookup_attr(
1247        &self,
1248        offset: usize,
1249        missing_type: Option<u16>,
1250    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1251        let mut stack = Vec::new();
1252        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1253        if cur == offset + PushIfaddrmsg::len() {
1254            stack.push(("OpNewaddrDoReply", offset));
1255            return (
1256                stack,
1257                missing_type.and_then(|t| OpNewaddrDoReply::attr_from_type(t)),
1258            );
1259        }
1260        (stack, None)
1261    }
1262}
1263#[derive(Debug)]
1264pub struct RequestOpNewaddrDoRequest<'r> {
1265    request: Request<'r>,
1266}
1267impl<'r> RequestOpNewaddrDoRequest<'r> {
1268    pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
1269        PushOpNewaddrDoRequest::write_header(&mut request.buf_mut(), header);
1270        Self { request: request }
1271    }
1272    pub fn encode(&mut self) -> PushOpNewaddrDoRequest<&mut Vec<u8>> {
1273        PushOpNewaddrDoRequest::new_without_header(self.request.buf_mut())
1274    }
1275    pub fn into_encoder(self) -> PushOpNewaddrDoRequest<RequestBuf<'r>> {
1276        PushOpNewaddrDoRequest::new_without_header(self.request.buf)
1277    }
1278    pub fn decode_request<'buf>(
1279        buf: &'buf [u8],
1280    ) -> (PushIfaddrmsg, IterableOpNewaddrDoRequest<'buf>) {
1281        OpNewaddrDoRequest::new(buf)
1282    }
1283}
1284impl NetlinkRequest for RequestOpNewaddrDoRequest<'_> {
1285    fn protocol(&self) -> Protocol {
1286        Protocol::Raw {
1287            protonum: 0u16,
1288            request_type: 20u16,
1289        }
1290    }
1291    fn flags(&self) -> u16 {
1292        self.request.flags
1293    }
1294    fn payload(&self) -> &[u8] {
1295        self.request.buf()
1296    }
1297    type ReplyType<'buf> = (PushIfaddrmsg, IterableOpNewaddrDoReply<'buf>);
1298    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1299        OpNewaddrDoReply::new(buf)
1300    }
1301    fn lookup(
1302        buf: &[u8],
1303        offset: usize,
1304        missing_type: Option<u16>,
1305    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1306        OpNewaddrDoRequest::new(buf)
1307            .1
1308            .lookup_attr(offset, missing_type)
1309    }
1310}
1311#[doc = "Remove address"]
1312pub struct PushOpDeladdrDoRequest<Prev: Rec> {
1313    pub(crate) prev: Option<Prev>,
1314    pub(crate) header_offset: Option<usize>,
1315}
1316impl<Prev: Rec> Rec for PushOpDeladdrDoRequest<Prev> {
1317    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1318        self.prev.as_mut().unwrap().as_rec_mut()
1319    }
1320    fn as_rec(&self) -> &Vec<u8> {
1321        self.prev.as_ref().unwrap().as_rec()
1322    }
1323}
1324impl<Prev: Rec> PushOpDeladdrDoRequest<Prev> {
1325    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1326        Self::write_header(&mut prev, header);
1327        Self::new_without_header(prev)
1328    }
1329    fn new_without_header(prev: Prev) -> Self {
1330        Self {
1331            prev: Some(prev),
1332            header_offset: None,
1333        }
1334    }
1335    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1336        prev.as_rec_mut().extend(header.as_slice());
1337    }
1338    pub fn end_nested(mut self) -> Prev {
1339        let mut prev = self.prev.take().unwrap();
1340        if let Some(header_offset) = &self.header_offset {
1341            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1342        }
1343        prev
1344    }
1345    pub fn push_address(mut self, value: std::net::IpAddr) -> Self {
1346        push_header(self.as_rec_mut(), 1u16, {
1347            match &value {
1348                IpAddr::V4(_) => 4,
1349                IpAddr::V6(_) => 16,
1350            }
1351        } as u16);
1352        encode_ip(self.as_rec_mut(), value);
1353        self
1354    }
1355    pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
1356        push_header(self.as_rec_mut(), 2u16, {
1357            match &value {
1358                IpAddr::V4(_) => 4,
1359                IpAddr::V6(_) => 16,
1360            }
1361        } as u16);
1362        encode_ip(self.as_rec_mut(), value);
1363        self
1364    }
1365}
1366impl<Prev: Rec> Drop for PushOpDeladdrDoRequest<Prev> {
1367    fn drop(&mut self) {
1368        if let Some(prev) = &mut self.prev {
1369            if let Some(header_offset) = &self.header_offset {
1370                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1371            }
1372        }
1373    }
1374}
1375#[doc = "Remove address"]
1376#[derive(Clone)]
1377pub enum OpDeladdrDoRequest {
1378    Address(std::net::IpAddr),
1379    Local(std::net::IpAddr),
1380}
1381impl<'a> IterableOpDeladdrDoRequest<'a> {
1382    pub fn get_address(&self) -> Result<std::net::IpAddr, ErrorContext> {
1383        let mut iter = self.clone();
1384        iter.pos = 0;
1385        for attr in iter {
1386            if let OpDeladdrDoRequest::Address(val) = attr? {
1387                return Ok(val);
1388            }
1389        }
1390        Err(ErrorContext::new_missing(
1391            "OpDeladdrDoRequest",
1392            "Address",
1393            self.orig_loc,
1394            self.buf.as_ptr() as usize,
1395        ))
1396    }
1397    pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
1398        let mut iter = self.clone();
1399        iter.pos = 0;
1400        for attr in iter {
1401            if let OpDeladdrDoRequest::Local(val) = attr? {
1402                return Ok(val);
1403            }
1404        }
1405        Err(ErrorContext::new_missing(
1406            "OpDeladdrDoRequest",
1407            "Local",
1408            self.orig_loc,
1409            self.buf.as_ptr() as usize,
1410        ))
1411    }
1412}
1413impl OpDeladdrDoRequest {
1414    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpDeladdrDoRequest<'a>) {
1415        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
1416        (
1417            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
1418            IterableOpDeladdrDoRequest::with_loc(attrs, buf.as_ptr() as usize),
1419        )
1420    }
1421    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1422        AddrAttrs::attr_from_type(r#type)
1423    }
1424}
1425#[derive(Clone, Copy, Default)]
1426pub struct IterableOpDeladdrDoRequest<'a> {
1427    buf: &'a [u8],
1428    pos: usize,
1429    orig_loc: usize,
1430}
1431impl<'a> IterableOpDeladdrDoRequest<'a> {
1432    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1433        Self {
1434            buf,
1435            pos: 0,
1436            orig_loc,
1437        }
1438    }
1439    pub fn get_buf(&self) -> &'a [u8] {
1440        self.buf
1441    }
1442}
1443impl<'a> Iterator for IterableOpDeladdrDoRequest<'a> {
1444    type Item = Result<OpDeladdrDoRequest, ErrorContext>;
1445    fn next(&mut self) -> Option<Self::Item> {
1446        let pos = self.pos;
1447        let mut r#type;
1448        loop {
1449            r#type = None;
1450            if self.buf.len() == self.pos {
1451                return None;
1452            }
1453            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1454                break;
1455            };
1456            r#type = Some(header.r#type);
1457            let res = match header.r#type {
1458                1u16 => OpDeladdrDoRequest::Address({
1459                    let res = parse_ip(next);
1460                    let Some(val) = res else { break };
1461                    val
1462                }),
1463                2u16 => OpDeladdrDoRequest::Local({
1464                    let res = parse_ip(next);
1465                    let Some(val) = res else { break };
1466                    val
1467                }),
1468                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1469                n => continue,
1470            };
1471            return Some(Ok(res));
1472        }
1473        Some(Err(ErrorContext::new(
1474            "OpDeladdrDoRequest",
1475            r#type.and_then(|t| OpDeladdrDoRequest::attr_from_type(t)),
1476            self.orig_loc,
1477            self.buf.as_ptr().wrapping_add(pos) as usize,
1478        )))
1479    }
1480}
1481impl std::fmt::Debug for IterableOpDeladdrDoRequest<'_> {
1482    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1483        let mut fmt = f.debug_struct("OpDeladdrDoRequest");
1484        for attr in self.clone() {
1485            let attr = match attr {
1486                Ok(a) => a,
1487                Err(err) => {
1488                    fmt.finish()?;
1489                    f.write_str("Err(")?;
1490                    err.fmt(f)?;
1491                    return f.write_str(")");
1492                }
1493            };
1494            match attr {
1495                OpDeladdrDoRequest::Address(val) => fmt.field("Address", &val),
1496                OpDeladdrDoRequest::Local(val) => fmt.field("Local", &val),
1497            };
1498        }
1499        fmt.finish()
1500    }
1501}
1502impl IterableOpDeladdrDoRequest<'_> {
1503    pub fn lookup_attr(
1504        &self,
1505        offset: usize,
1506        missing_type: Option<u16>,
1507    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1508        let mut stack = Vec::new();
1509        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1510        if cur == offset + PushIfaddrmsg::len() {
1511            stack.push(("OpDeladdrDoRequest", offset));
1512            return (
1513                stack,
1514                missing_type.and_then(|t| OpDeladdrDoRequest::attr_from_type(t)),
1515            );
1516        }
1517        if cur > offset || cur + self.buf.len() < offset {
1518            return (stack, None);
1519        }
1520        let mut attrs = self.clone();
1521        let mut last_off = cur + attrs.pos;
1522        while let Some(attr) = attrs.next() {
1523            let Ok(attr) = attr else { break };
1524            match attr {
1525                OpDeladdrDoRequest::Address(val) => {
1526                    if last_off == offset {
1527                        stack.push(("Address", last_off));
1528                        break;
1529                    }
1530                }
1531                OpDeladdrDoRequest::Local(val) => {
1532                    if last_off == offset {
1533                        stack.push(("Local", last_off));
1534                        break;
1535                    }
1536                }
1537                _ => {}
1538            };
1539            last_off = cur + attrs.pos;
1540        }
1541        if !stack.is_empty() {
1542            stack.push(("OpDeladdrDoRequest", cur));
1543        }
1544        (stack, None)
1545    }
1546}
1547#[doc = "Remove address"]
1548pub struct PushOpDeladdrDoReply<Prev: Rec> {
1549    pub(crate) prev: Option<Prev>,
1550    pub(crate) header_offset: Option<usize>,
1551}
1552impl<Prev: Rec> Rec for PushOpDeladdrDoReply<Prev> {
1553    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1554        self.prev.as_mut().unwrap().as_rec_mut()
1555    }
1556    fn as_rec(&self) -> &Vec<u8> {
1557        self.prev.as_ref().unwrap().as_rec()
1558    }
1559}
1560impl<Prev: Rec> PushOpDeladdrDoReply<Prev> {
1561    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1562        Self::write_header(&mut prev, header);
1563        Self::new_without_header(prev)
1564    }
1565    fn new_without_header(prev: Prev) -> Self {
1566        Self {
1567            prev: Some(prev),
1568            header_offset: None,
1569        }
1570    }
1571    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1572        prev.as_rec_mut().extend(header.as_slice());
1573    }
1574    pub fn end_nested(mut self) -> Prev {
1575        let mut prev = self.prev.take().unwrap();
1576        if let Some(header_offset) = &self.header_offset {
1577            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1578        }
1579        prev
1580    }
1581}
1582impl<Prev: Rec> Drop for PushOpDeladdrDoReply<Prev> {
1583    fn drop(&mut self) {
1584        if let Some(prev) = &mut self.prev {
1585            if let Some(header_offset) = &self.header_offset {
1586                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1587            }
1588        }
1589    }
1590}
1591#[doc = "Remove address"]
1592#[derive(Clone)]
1593pub enum OpDeladdrDoReply {}
1594impl<'a> IterableOpDeladdrDoReply<'a> {}
1595impl OpDeladdrDoReply {
1596    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpDeladdrDoReply<'a>) {
1597        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
1598        (
1599            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
1600            IterableOpDeladdrDoReply::with_loc(attrs, buf.as_ptr() as usize),
1601        )
1602    }
1603    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1604        AddrAttrs::attr_from_type(r#type)
1605    }
1606}
1607#[derive(Clone, Copy, Default)]
1608pub struct IterableOpDeladdrDoReply<'a> {
1609    buf: &'a [u8],
1610    pos: usize,
1611    orig_loc: usize,
1612}
1613impl<'a> IterableOpDeladdrDoReply<'a> {
1614    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1615        Self {
1616            buf,
1617            pos: 0,
1618            orig_loc,
1619        }
1620    }
1621    pub fn get_buf(&self) -> &'a [u8] {
1622        self.buf
1623    }
1624}
1625impl<'a> Iterator for IterableOpDeladdrDoReply<'a> {
1626    type Item = Result<OpDeladdrDoReply, ErrorContext>;
1627    fn next(&mut self) -> Option<Self::Item> {
1628        let pos = self.pos;
1629        let mut r#type;
1630        loop {
1631            r#type = None;
1632            if self.buf.len() == self.pos {
1633                return None;
1634            }
1635            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1636                break;
1637            };
1638            r#type = Some(header.r#type);
1639            let res = match header.r#type {
1640                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1641                n => continue,
1642            };
1643            return Some(Ok(res));
1644        }
1645        Some(Err(ErrorContext::new(
1646            "OpDeladdrDoReply",
1647            r#type.and_then(|t| OpDeladdrDoReply::attr_from_type(t)),
1648            self.orig_loc,
1649            self.buf.as_ptr().wrapping_add(pos) as usize,
1650        )))
1651    }
1652}
1653impl std::fmt::Debug for IterableOpDeladdrDoReply<'_> {
1654    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1655        let mut fmt = f.debug_struct("OpDeladdrDoReply");
1656        for attr in self.clone() {
1657            let attr = match attr {
1658                Ok(a) => a,
1659                Err(err) => {
1660                    fmt.finish()?;
1661                    f.write_str("Err(")?;
1662                    err.fmt(f)?;
1663                    return f.write_str(")");
1664                }
1665            };
1666            match attr {};
1667        }
1668        fmt.finish()
1669    }
1670}
1671impl IterableOpDeladdrDoReply<'_> {
1672    pub fn lookup_attr(
1673        &self,
1674        offset: usize,
1675        missing_type: Option<u16>,
1676    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1677        let mut stack = Vec::new();
1678        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1679        if cur == offset + PushIfaddrmsg::len() {
1680            stack.push(("OpDeladdrDoReply", offset));
1681            return (
1682                stack,
1683                missing_type.and_then(|t| OpDeladdrDoReply::attr_from_type(t)),
1684            );
1685        }
1686        (stack, None)
1687    }
1688}
1689#[derive(Debug)]
1690pub struct RequestOpDeladdrDoRequest<'r> {
1691    request: Request<'r>,
1692}
1693impl<'r> RequestOpDeladdrDoRequest<'r> {
1694    pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
1695        PushOpDeladdrDoRequest::write_header(&mut request.buf_mut(), header);
1696        Self { request: request }
1697    }
1698    pub fn encode(&mut self) -> PushOpDeladdrDoRequest<&mut Vec<u8>> {
1699        PushOpDeladdrDoRequest::new_without_header(self.request.buf_mut())
1700    }
1701    pub fn into_encoder(self) -> PushOpDeladdrDoRequest<RequestBuf<'r>> {
1702        PushOpDeladdrDoRequest::new_without_header(self.request.buf)
1703    }
1704    pub fn decode_request<'buf>(
1705        buf: &'buf [u8],
1706    ) -> (PushIfaddrmsg, IterableOpDeladdrDoRequest<'buf>) {
1707        OpDeladdrDoRequest::new(buf)
1708    }
1709}
1710impl NetlinkRequest for RequestOpDeladdrDoRequest<'_> {
1711    fn protocol(&self) -> Protocol {
1712        Protocol::Raw {
1713            protonum: 0u16,
1714            request_type: 21u16,
1715        }
1716    }
1717    fn flags(&self) -> u16 {
1718        self.request.flags
1719    }
1720    fn payload(&self) -> &[u8] {
1721        self.request.buf()
1722    }
1723    type ReplyType<'buf> = (PushIfaddrmsg, IterableOpDeladdrDoReply<'buf>);
1724    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1725        OpDeladdrDoReply::new(buf)
1726    }
1727    fn lookup(
1728        buf: &[u8],
1729        offset: usize,
1730        missing_type: Option<u16>,
1731    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1732        OpDeladdrDoRequest::new(buf)
1733            .1
1734            .lookup_attr(offset, missing_type)
1735    }
1736}
1737#[doc = "Dump address information."]
1738pub struct PushOpGetaddrDumpRequest<Prev: Rec> {
1739    pub(crate) prev: Option<Prev>,
1740    pub(crate) header_offset: Option<usize>,
1741}
1742impl<Prev: Rec> Rec for PushOpGetaddrDumpRequest<Prev> {
1743    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1744        self.prev.as_mut().unwrap().as_rec_mut()
1745    }
1746    fn as_rec(&self) -> &Vec<u8> {
1747        self.prev.as_ref().unwrap().as_rec()
1748    }
1749}
1750impl<Prev: Rec> PushOpGetaddrDumpRequest<Prev> {
1751    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1752        Self::write_header(&mut prev, header);
1753        Self::new_without_header(prev)
1754    }
1755    fn new_without_header(prev: Prev) -> Self {
1756        Self {
1757            prev: Some(prev),
1758            header_offset: None,
1759        }
1760    }
1761    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1762        prev.as_rec_mut().extend(header.as_slice());
1763    }
1764    pub fn end_nested(mut self) -> Prev {
1765        let mut prev = self.prev.take().unwrap();
1766        if let Some(header_offset) = &self.header_offset {
1767            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1768        }
1769        prev
1770    }
1771}
1772impl<Prev: Rec> Drop for PushOpGetaddrDumpRequest<Prev> {
1773    fn drop(&mut self) {
1774        if let Some(prev) = &mut self.prev {
1775            if let Some(header_offset) = &self.header_offset {
1776                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1777            }
1778        }
1779    }
1780}
1781#[doc = "Dump address information."]
1782#[derive(Clone)]
1783pub enum OpGetaddrDumpRequest {}
1784impl<'a> IterableOpGetaddrDumpRequest<'a> {}
1785impl OpGetaddrDumpRequest {
1786    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetaddrDumpRequest<'a>) {
1787        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
1788        (
1789            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
1790            IterableOpGetaddrDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
1791        )
1792    }
1793    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1794        AddrAttrs::attr_from_type(r#type)
1795    }
1796}
1797#[derive(Clone, Copy, Default)]
1798pub struct IterableOpGetaddrDumpRequest<'a> {
1799    buf: &'a [u8],
1800    pos: usize,
1801    orig_loc: usize,
1802}
1803impl<'a> IterableOpGetaddrDumpRequest<'a> {
1804    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1805        Self {
1806            buf,
1807            pos: 0,
1808            orig_loc,
1809        }
1810    }
1811    pub fn get_buf(&self) -> &'a [u8] {
1812        self.buf
1813    }
1814}
1815impl<'a> Iterator for IterableOpGetaddrDumpRequest<'a> {
1816    type Item = Result<OpGetaddrDumpRequest, ErrorContext>;
1817    fn next(&mut self) -> Option<Self::Item> {
1818        let pos = self.pos;
1819        let mut r#type;
1820        loop {
1821            r#type = None;
1822            if self.buf.len() == self.pos {
1823                return None;
1824            }
1825            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1826                break;
1827            };
1828            r#type = Some(header.r#type);
1829            let res = match header.r#type {
1830                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1831                n => continue,
1832            };
1833            return Some(Ok(res));
1834        }
1835        Some(Err(ErrorContext::new(
1836            "OpGetaddrDumpRequest",
1837            r#type.and_then(|t| OpGetaddrDumpRequest::attr_from_type(t)),
1838            self.orig_loc,
1839            self.buf.as_ptr().wrapping_add(pos) as usize,
1840        )))
1841    }
1842}
1843impl std::fmt::Debug for IterableOpGetaddrDumpRequest<'_> {
1844    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1845        let mut fmt = f.debug_struct("OpGetaddrDumpRequest");
1846        for attr in self.clone() {
1847            let attr = match attr {
1848                Ok(a) => a,
1849                Err(err) => {
1850                    fmt.finish()?;
1851                    f.write_str("Err(")?;
1852                    err.fmt(f)?;
1853                    return f.write_str(")");
1854                }
1855            };
1856            match attr {};
1857        }
1858        fmt.finish()
1859    }
1860}
1861impl IterableOpGetaddrDumpRequest<'_> {
1862    pub fn lookup_attr(
1863        &self,
1864        offset: usize,
1865        missing_type: Option<u16>,
1866    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1867        let mut stack = Vec::new();
1868        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1869        if cur == offset + PushIfaddrmsg::len() {
1870            stack.push(("OpGetaddrDumpRequest", offset));
1871            return (
1872                stack,
1873                missing_type.and_then(|t| OpGetaddrDumpRequest::attr_from_type(t)),
1874            );
1875        }
1876        (stack, None)
1877    }
1878}
1879#[doc = "Dump address information."]
1880pub struct PushOpGetaddrDumpReply<Prev: Rec> {
1881    pub(crate) prev: Option<Prev>,
1882    pub(crate) header_offset: Option<usize>,
1883}
1884impl<Prev: Rec> Rec for PushOpGetaddrDumpReply<Prev> {
1885    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1886        self.prev.as_mut().unwrap().as_rec_mut()
1887    }
1888    fn as_rec(&self) -> &Vec<u8> {
1889        self.prev.as_ref().unwrap().as_rec()
1890    }
1891}
1892impl<Prev: Rec> PushOpGetaddrDumpReply<Prev> {
1893    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1894        Self::write_header(&mut prev, header);
1895        Self::new_without_header(prev)
1896    }
1897    fn new_without_header(prev: Prev) -> Self {
1898        Self {
1899            prev: Some(prev),
1900            header_offset: None,
1901        }
1902    }
1903    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1904        prev.as_rec_mut().extend(header.as_slice());
1905    }
1906    pub fn end_nested(mut self) -> Prev {
1907        let mut prev = self.prev.take().unwrap();
1908        if let Some(header_offset) = &self.header_offset {
1909            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1910        }
1911        prev
1912    }
1913    pub fn push_address(mut self, value: std::net::IpAddr) -> Self {
1914        push_header(self.as_rec_mut(), 1u16, {
1915            match &value {
1916                IpAddr::V4(_) => 4,
1917                IpAddr::V6(_) => 16,
1918            }
1919        } as u16);
1920        encode_ip(self.as_rec_mut(), value);
1921        self
1922    }
1923    pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
1924        push_header(self.as_rec_mut(), 2u16, {
1925            match &value {
1926                IpAddr::V4(_) => 4,
1927                IpAddr::V6(_) => 16,
1928            }
1929        } as u16);
1930        encode_ip(self.as_rec_mut(), value);
1931        self
1932    }
1933    pub fn push_label(mut self, value: &CStr) -> Self {
1934        push_header(
1935            self.as_rec_mut(),
1936            3u16,
1937            value.to_bytes_with_nul().len() as u16,
1938        );
1939        self.as_rec_mut().extend(value.to_bytes_with_nul());
1940        self
1941    }
1942    pub fn push_label_bytes(mut self, value: &[u8]) -> Self {
1943        push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
1944        self.as_rec_mut().extend(value);
1945        self.as_rec_mut().push(0);
1946        self
1947    }
1948    pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
1949        push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
1950        self.as_rec_mut().extend(value.as_slice());
1951        self
1952    }
1953    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
1954    pub fn push_flags(mut self, value: u32) -> Self {
1955        push_header(self.as_rec_mut(), 8u16, 4 as u16);
1956        self.as_rec_mut().extend(value.to_ne_bytes());
1957        self
1958    }
1959}
1960impl<Prev: Rec> Drop for PushOpGetaddrDumpReply<Prev> {
1961    fn drop(&mut self) {
1962        if let Some(prev) = &mut self.prev {
1963            if let Some(header_offset) = &self.header_offset {
1964                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1965            }
1966        }
1967    }
1968}
1969#[doc = "Dump address information."]
1970#[derive(Clone)]
1971pub enum OpGetaddrDumpReply<'a> {
1972    Address(std::net::IpAddr),
1973    Local(std::net::IpAddr),
1974    Label(&'a CStr),
1975    Cacheinfo(PushIfaCacheinfo),
1976    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
1977    Flags(u32),
1978}
1979impl<'a> IterableOpGetaddrDumpReply<'a> {
1980    pub fn get_address(&self) -> Result<std::net::IpAddr, ErrorContext> {
1981        let mut iter = self.clone();
1982        iter.pos = 0;
1983        for attr in iter {
1984            if let OpGetaddrDumpReply::Address(val) = attr? {
1985                return Ok(val);
1986            }
1987        }
1988        Err(ErrorContext::new_missing(
1989            "OpGetaddrDumpReply",
1990            "Address",
1991            self.orig_loc,
1992            self.buf.as_ptr() as usize,
1993        ))
1994    }
1995    pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
1996        let mut iter = self.clone();
1997        iter.pos = 0;
1998        for attr in iter {
1999            if let OpGetaddrDumpReply::Local(val) = attr? {
2000                return Ok(val);
2001            }
2002        }
2003        Err(ErrorContext::new_missing(
2004            "OpGetaddrDumpReply",
2005            "Local",
2006            self.orig_loc,
2007            self.buf.as_ptr() as usize,
2008        ))
2009    }
2010    pub fn get_label(&self) -> Result<&'a CStr, ErrorContext> {
2011        let mut iter = self.clone();
2012        iter.pos = 0;
2013        for attr in iter {
2014            if let OpGetaddrDumpReply::Label(val) = attr? {
2015                return Ok(val);
2016            }
2017        }
2018        Err(ErrorContext::new_missing(
2019            "OpGetaddrDumpReply",
2020            "Label",
2021            self.orig_loc,
2022            self.buf.as_ptr() as usize,
2023        ))
2024    }
2025    pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
2026        let mut iter = self.clone();
2027        iter.pos = 0;
2028        for attr in iter {
2029            if let OpGetaddrDumpReply::Cacheinfo(val) = attr? {
2030                return Ok(val);
2031            }
2032        }
2033        Err(ErrorContext::new_missing(
2034            "OpGetaddrDumpReply",
2035            "Cacheinfo",
2036            self.orig_loc,
2037            self.buf.as_ptr() as usize,
2038        ))
2039    }
2040    #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
2041    pub fn get_flags(&self) -> Result<u32, ErrorContext> {
2042        let mut iter = self.clone();
2043        iter.pos = 0;
2044        for attr in iter {
2045            if let OpGetaddrDumpReply::Flags(val) = attr? {
2046                return Ok(val);
2047            }
2048        }
2049        Err(ErrorContext::new_missing(
2050            "OpGetaddrDumpReply",
2051            "Flags",
2052            self.orig_loc,
2053            self.buf.as_ptr() as usize,
2054        ))
2055    }
2056}
2057impl OpGetaddrDumpReply<'_> {
2058    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetaddrDumpReply<'a>) {
2059        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2060        (
2061            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2062            IterableOpGetaddrDumpReply::with_loc(attrs, buf.as_ptr() as usize),
2063        )
2064    }
2065    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2066        AddrAttrs::attr_from_type(r#type)
2067    }
2068}
2069#[derive(Clone, Copy, Default)]
2070pub struct IterableOpGetaddrDumpReply<'a> {
2071    buf: &'a [u8],
2072    pos: usize,
2073    orig_loc: usize,
2074}
2075impl<'a> IterableOpGetaddrDumpReply<'a> {
2076    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2077        Self {
2078            buf,
2079            pos: 0,
2080            orig_loc,
2081        }
2082    }
2083    pub fn get_buf(&self) -> &'a [u8] {
2084        self.buf
2085    }
2086}
2087impl<'a> Iterator for IterableOpGetaddrDumpReply<'a> {
2088    type Item = Result<OpGetaddrDumpReply<'a>, ErrorContext>;
2089    fn next(&mut self) -> Option<Self::Item> {
2090        let pos = self.pos;
2091        let mut r#type;
2092        loop {
2093            r#type = None;
2094            if self.buf.len() == self.pos {
2095                return None;
2096            }
2097            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2098                break;
2099            };
2100            r#type = Some(header.r#type);
2101            let res = match header.r#type {
2102                1u16 => OpGetaddrDumpReply::Address({
2103                    let res = parse_ip(next);
2104                    let Some(val) = res else { break };
2105                    val
2106                }),
2107                2u16 => OpGetaddrDumpReply::Local({
2108                    let res = parse_ip(next);
2109                    let Some(val) = res else { break };
2110                    val
2111                }),
2112                3u16 => OpGetaddrDumpReply::Label({
2113                    let res = CStr::from_bytes_with_nul(next).ok();
2114                    let Some(val) = res else { break };
2115                    val
2116                }),
2117                6u16 => OpGetaddrDumpReply::Cacheinfo({
2118                    let res = PushIfaCacheinfo::new_from_slice(next);
2119                    let Some(val) = res else { break };
2120                    val
2121                }),
2122                8u16 => OpGetaddrDumpReply::Flags({
2123                    let res = parse_u32(next);
2124                    let Some(val) = res else { break };
2125                    val
2126                }),
2127                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2128                n => continue,
2129            };
2130            return Some(Ok(res));
2131        }
2132        Some(Err(ErrorContext::new(
2133            "OpGetaddrDumpReply",
2134            r#type.and_then(|t| OpGetaddrDumpReply::attr_from_type(t)),
2135            self.orig_loc,
2136            self.buf.as_ptr().wrapping_add(pos) as usize,
2137        )))
2138    }
2139}
2140impl<'a> std::fmt::Debug for IterableOpGetaddrDumpReply<'_> {
2141    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2142        let mut fmt = f.debug_struct("OpGetaddrDumpReply");
2143        for attr in self.clone() {
2144            let attr = match attr {
2145                Ok(a) => a,
2146                Err(err) => {
2147                    fmt.finish()?;
2148                    f.write_str("Err(")?;
2149                    err.fmt(f)?;
2150                    return f.write_str(")");
2151                }
2152            };
2153            match attr {
2154                OpGetaddrDumpReply::Address(val) => fmt.field("Address", &val),
2155                OpGetaddrDumpReply::Local(val) => fmt.field("Local", &val),
2156                OpGetaddrDumpReply::Label(val) => fmt.field("Label", &val),
2157                OpGetaddrDumpReply::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
2158                OpGetaddrDumpReply::Flags(val) => {
2159                    fmt.field("Flags", &FormatFlags(val.into(), IfaFlags::from_value))
2160                }
2161            };
2162        }
2163        fmt.finish()
2164    }
2165}
2166impl IterableOpGetaddrDumpReply<'_> {
2167    pub fn lookup_attr(
2168        &self,
2169        offset: usize,
2170        missing_type: Option<u16>,
2171    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2172        let mut stack = Vec::new();
2173        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2174        if cur == offset + PushIfaddrmsg::len() {
2175            stack.push(("OpGetaddrDumpReply", offset));
2176            return (
2177                stack,
2178                missing_type.and_then(|t| OpGetaddrDumpReply::attr_from_type(t)),
2179            );
2180        }
2181        if cur > offset || cur + self.buf.len() < offset {
2182            return (stack, None);
2183        }
2184        let mut attrs = self.clone();
2185        let mut last_off = cur + attrs.pos;
2186        while let Some(attr) = attrs.next() {
2187            let Ok(attr) = attr else { break };
2188            match attr {
2189                OpGetaddrDumpReply::Address(val) => {
2190                    if last_off == offset {
2191                        stack.push(("Address", last_off));
2192                        break;
2193                    }
2194                }
2195                OpGetaddrDumpReply::Local(val) => {
2196                    if last_off == offset {
2197                        stack.push(("Local", last_off));
2198                        break;
2199                    }
2200                }
2201                OpGetaddrDumpReply::Label(val) => {
2202                    if last_off == offset {
2203                        stack.push(("Label", last_off));
2204                        break;
2205                    }
2206                }
2207                OpGetaddrDumpReply::Cacheinfo(val) => {
2208                    if last_off == offset {
2209                        stack.push(("Cacheinfo", last_off));
2210                        break;
2211                    }
2212                }
2213                OpGetaddrDumpReply::Flags(val) => {
2214                    if last_off == offset {
2215                        stack.push(("Flags", last_off));
2216                        break;
2217                    }
2218                }
2219                _ => {}
2220            };
2221            last_off = cur + attrs.pos;
2222        }
2223        if !stack.is_empty() {
2224            stack.push(("OpGetaddrDumpReply", cur));
2225        }
2226        (stack, None)
2227    }
2228}
2229#[derive(Debug)]
2230pub struct RequestOpGetaddrDumpRequest<'r> {
2231    request: Request<'r>,
2232}
2233impl<'r> RequestOpGetaddrDumpRequest<'r> {
2234    pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
2235        PushOpGetaddrDumpRequest::write_header(&mut request.buf_mut(), header);
2236        Self {
2237            request: request.set_dump(),
2238        }
2239    }
2240    pub fn encode(&mut self) -> PushOpGetaddrDumpRequest<&mut Vec<u8>> {
2241        PushOpGetaddrDumpRequest::new_without_header(self.request.buf_mut())
2242    }
2243    pub fn into_encoder(self) -> PushOpGetaddrDumpRequest<RequestBuf<'r>> {
2244        PushOpGetaddrDumpRequest::new_without_header(self.request.buf)
2245    }
2246    pub fn decode_request<'buf>(
2247        buf: &'buf [u8],
2248    ) -> (PushIfaddrmsg, IterableOpGetaddrDumpRequest<'buf>) {
2249        OpGetaddrDumpRequest::new(buf)
2250    }
2251}
2252impl NetlinkRequest for RequestOpGetaddrDumpRequest<'_> {
2253    fn protocol(&self) -> Protocol {
2254        Protocol::Raw {
2255            protonum: 0u16,
2256            request_type: 22u16,
2257        }
2258    }
2259    fn flags(&self) -> u16 {
2260        self.request.flags
2261    }
2262    fn payload(&self) -> &[u8] {
2263        self.request.buf()
2264    }
2265    type ReplyType<'buf> = (PushIfaddrmsg, IterableOpGetaddrDumpReply<'buf>);
2266    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2267        OpGetaddrDumpReply::new(buf)
2268    }
2269    fn lookup(
2270        buf: &[u8],
2271        offset: usize,
2272        missing_type: Option<u16>,
2273    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2274        OpGetaddrDumpRequest::new(buf)
2275            .1
2276            .lookup_attr(offset, missing_type)
2277    }
2278}
2279#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2280pub struct PushOpGetmulticastDumpRequest<Prev: Rec> {
2281    pub(crate) prev: Option<Prev>,
2282    pub(crate) header_offset: Option<usize>,
2283}
2284impl<Prev: Rec> Rec for PushOpGetmulticastDumpRequest<Prev> {
2285    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2286        self.prev.as_mut().unwrap().as_rec_mut()
2287    }
2288    fn as_rec(&self) -> &Vec<u8> {
2289        self.prev.as_ref().unwrap().as_rec()
2290    }
2291}
2292impl<Prev: Rec> PushOpGetmulticastDumpRequest<Prev> {
2293    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
2294        Self::write_header(&mut prev, header);
2295        Self::new_without_header(prev)
2296    }
2297    fn new_without_header(prev: Prev) -> Self {
2298        Self {
2299            prev: Some(prev),
2300            header_offset: None,
2301        }
2302    }
2303    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
2304        prev.as_rec_mut().extend(header.as_slice());
2305    }
2306    pub fn end_nested(mut self) -> Prev {
2307        let mut prev = self.prev.take().unwrap();
2308        if let Some(header_offset) = &self.header_offset {
2309            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2310        }
2311        prev
2312    }
2313}
2314impl<Prev: Rec> Drop for PushOpGetmulticastDumpRequest<Prev> {
2315    fn drop(&mut self) {
2316        if let Some(prev) = &mut self.prev {
2317            if let Some(header_offset) = &self.header_offset {
2318                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2319            }
2320        }
2321    }
2322}
2323#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2324#[derive(Clone)]
2325pub enum OpGetmulticastDumpRequest {}
2326impl<'a> IterableOpGetmulticastDumpRequest<'a> {}
2327impl OpGetmulticastDumpRequest {
2328    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetmulticastDumpRequest<'a>) {
2329        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2330        (
2331            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2332            IterableOpGetmulticastDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
2333        )
2334    }
2335    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2336        AddrAttrs::attr_from_type(r#type)
2337    }
2338}
2339#[derive(Clone, Copy, Default)]
2340pub struct IterableOpGetmulticastDumpRequest<'a> {
2341    buf: &'a [u8],
2342    pos: usize,
2343    orig_loc: usize,
2344}
2345impl<'a> IterableOpGetmulticastDumpRequest<'a> {
2346    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2347        Self {
2348            buf,
2349            pos: 0,
2350            orig_loc,
2351        }
2352    }
2353    pub fn get_buf(&self) -> &'a [u8] {
2354        self.buf
2355    }
2356}
2357impl<'a> Iterator for IterableOpGetmulticastDumpRequest<'a> {
2358    type Item = Result<OpGetmulticastDumpRequest, ErrorContext>;
2359    fn next(&mut self) -> Option<Self::Item> {
2360        let pos = self.pos;
2361        let mut r#type;
2362        loop {
2363            r#type = None;
2364            if self.buf.len() == self.pos {
2365                return None;
2366            }
2367            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2368                break;
2369            };
2370            r#type = Some(header.r#type);
2371            let res = match header.r#type {
2372                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2373                n => continue,
2374            };
2375            return Some(Ok(res));
2376        }
2377        Some(Err(ErrorContext::new(
2378            "OpGetmulticastDumpRequest",
2379            r#type.and_then(|t| OpGetmulticastDumpRequest::attr_from_type(t)),
2380            self.orig_loc,
2381            self.buf.as_ptr().wrapping_add(pos) as usize,
2382        )))
2383    }
2384}
2385impl std::fmt::Debug for IterableOpGetmulticastDumpRequest<'_> {
2386    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2387        let mut fmt = f.debug_struct("OpGetmulticastDumpRequest");
2388        for attr in self.clone() {
2389            let attr = match attr {
2390                Ok(a) => a,
2391                Err(err) => {
2392                    fmt.finish()?;
2393                    f.write_str("Err(")?;
2394                    err.fmt(f)?;
2395                    return f.write_str(")");
2396                }
2397            };
2398            match attr {};
2399        }
2400        fmt.finish()
2401    }
2402}
2403impl IterableOpGetmulticastDumpRequest<'_> {
2404    pub fn lookup_attr(
2405        &self,
2406        offset: usize,
2407        missing_type: Option<u16>,
2408    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2409        let mut stack = Vec::new();
2410        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2411        if cur == offset + PushIfaddrmsg::len() {
2412            stack.push(("OpGetmulticastDumpRequest", offset));
2413            return (
2414                stack,
2415                missing_type.and_then(|t| OpGetmulticastDumpRequest::attr_from_type(t)),
2416            );
2417        }
2418        (stack, None)
2419    }
2420}
2421#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2422pub struct PushOpGetmulticastDumpReply<Prev: Rec> {
2423    pub(crate) prev: Option<Prev>,
2424    pub(crate) header_offset: Option<usize>,
2425}
2426impl<Prev: Rec> Rec for PushOpGetmulticastDumpReply<Prev> {
2427    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2428        self.prev.as_mut().unwrap().as_rec_mut()
2429    }
2430    fn as_rec(&self) -> &Vec<u8> {
2431        self.prev.as_ref().unwrap().as_rec()
2432    }
2433}
2434impl<Prev: Rec> PushOpGetmulticastDumpReply<Prev> {
2435    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
2436        Self::write_header(&mut prev, header);
2437        Self::new_without_header(prev)
2438    }
2439    fn new_without_header(prev: Prev) -> Self {
2440        Self {
2441            prev: Some(prev),
2442            header_offset: None,
2443        }
2444    }
2445    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
2446        prev.as_rec_mut().extend(header.as_slice());
2447    }
2448    pub fn end_nested(mut self) -> Prev {
2449        let mut prev = self.prev.take().unwrap();
2450        if let Some(header_offset) = &self.header_offset {
2451            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2452        }
2453        prev
2454    }
2455    pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
2456        push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
2457        self.as_rec_mut().extend(value.as_slice());
2458        self
2459    }
2460    pub fn push_multicast(mut self, value: &[u8]) -> Self {
2461        push_header(self.as_rec_mut(), 7u16, value.len() as u16);
2462        self.as_rec_mut().extend(value);
2463        self
2464    }
2465}
2466impl<Prev: Rec> Drop for PushOpGetmulticastDumpReply<Prev> {
2467    fn drop(&mut self) {
2468        if let Some(prev) = &mut self.prev {
2469            if let Some(header_offset) = &self.header_offset {
2470                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2471            }
2472        }
2473    }
2474}
2475#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2476#[derive(Clone)]
2477pub enum OpGetmulticastDumpReply<'a> {
2478    Cacheinfo(PushIfaCacheinfo),
2479    Multicast(&'a [u8]),
2480}
2481impl<'a> IterableOpGetmulticastDumpReply<'a> {
2482    pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
2483        let mut iter = self.clone();
2484        iter.pos = 0;
2485        for attr in iter {
2486            if let OpGetmulticastDumpReply::Cacheinfo(val) = attr? {
2487                return Ok(val);
2488            }
2489        }
2490        Err(ErrorContext::new_missing(
2491            "OpGetmulticastDumpReply",
2492            "Cacheinfo",
2493            self.orig_loc,
2494            self.buf.as_ptr() as usize,
2495        ))
2496    }
2497    pub fn get_multicast(&self) -> Result<&'a [u8], ErrorContext> {
2498        let mut iter = self.clone();
2499        iter.pos = 0;
2500        for attr in iter {
2501            if let OpGetmulticastDumpReply::Multicast(val) = attr? {
2502                return Ok(val);
2503            }
2504        }
2505        Err(ErrorContext::new_missing(
2506            "OpGetmulticastDumpReply",
2507            "Multicast",
2508            self.orig_loc,
2509            self.buf.as_ptr() as usize,
2510        ))
2511    }
2512}
2513impl OpGetmulticastDumpReply<'_> {
2514    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetmulticastDumpReply<'a>) {
2515        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2516        (
2517            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2518            IterableOpGetmulticastDumpReply::with_loc(attrs, buf.as_ptr() as usize),
2519        )
2520    }
2521    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2522        AddrAttrs::attr_from_type(r#type)
2523    }
2524}
2525#[derive(Clone, Copy, Default)]
2526pub struct IterableOpGetmulticastDumpReply<'a> {
2527    buf: &'a [u8],
2528    pos: usize,
2529    orig_loc: usize,
2530}
2531impl<'a> IterableOpGetmulticastDumpReply<'a> {
2532    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2533        Self {
2534            buf,
2535            pos: 0,
2536            orig_loc,
2537        }
2538    }
2539    pub fn get_buf(&self) -> &'a [u8] {
2540        self.buf
2541    }
2542}
2543impl<'a> Iterator for IterableOpGetmulticastDumpReply<'a> {
2544    type Item = Result<OpGetmulticastDumpReply<'a>, ErrorContext>;
2545    fn next(&mut self) -> Option<Self::Item> {
2546        let pos = self.pos;
2547        let mut r#type;
2548        loop {
2549            r#type = None;
2550            if self.buf.len() == self.pos {
2551                return None;
2552            }
2553            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2554                break;
2555            };
2556            r#type = Some(header.r#type);
2557            let res = match header.r#type {
2558                6u16 => OpGetmulticastDumpReply::Cacheinfo({
2559                    let res = PushIfaCacheinfo::new_from_slice(next);
2560                    let Some(val) = res else { break };
2561                    val
2562                }),
2563                7u16 => OpGetmulticastDumpReply::Multicast({
2564                    let res = Some(next);
2565                    let Some(val) = res else { break };
2566                    val
2567                }),
2568                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2569                n => continue,
2570            };
2571            return Some(Ok(res));
2572        }
2573        Some(Err(ErrorContext::new(
2574            "OpGetmulticastDumpReply",
2575            r#type.and_then(|t| OpGetmulticastDumpReply::attr_from_type(t)),
2576            self.orig_loc,
2577            self.buf.as_ptr().wrapping_add(pos) as usize,
2578        )))
2579    }
2580}
2581impl<'a> std::fmt::Debug for IterableOpGetmulticastDumpReply<'_> {
2582    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2583        let mut fmt = f.debug_struct("OpGetmulticastDumpReply");
2584        for attr in self.clone() {
2585            let attr = match attr {
2586                Ok(a) => a,
2587                Err(err) => {
2588                    fmt.finish()?;
2589                    f.write_str("Err(")?;
2590                    err.fmt(f)?;
2591                    return f.write_str(")");
2592                }
2593            };
2594            match attr {
2595                OpGetmulticastDumpReply::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
2596                OpGetmulticastDumpReply::Multicast(val) => fmt.field("Multicast", &val),
2597            };
2598        }
2599        fmt.finish()
2600    }
2601}
2602impl IterableOpGetmulticastDumpReply<'_> {
2603    pub fn lookup_attr(
2604        &self,
2605        offset: usize,
2606        missing_type: Option<u16>,
2607    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2608        let mut stack = Vec::new();
2609        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2610        if cur == offset + PushIfaddrmsg::len() {
2611            stack.push(("OpGetmulticastDumpReply", offset));
2612            return (
2613                stack,
2614                missing_type.and_then(|t| OpGetmulticastDumpReply::attr_from_type(t)),
2615            );
2616        }
2617        if cur > offset || cur + self.buf.len() < offset {
2618            return (stack, None);
2619        }
2620        let mut attrs = self.clone();
2621        let mut last_off = cur + attrs.pos;
2622        while let Some(attr) = attrs.next() {
2623            let Ok(attr) = attr else { break };
2624            match attr {
2625                OpGetmulticastDumpReply::Cacheinfo(val) => {
2626                    if last_off == offset {
2627                        stack.push(("Cacheinfo", last_off));
2628                        break;
2629                    }
2630                }
2631                OpGetmulticastDumpReply::Multicast(val) => {
2632                    if last_off == offset {
2633                        stack.push(("Multicast", last_off));
2634                        break;
2635                    }
2636                }
2637                _ => {}
2638            };
2639            last_off = cur + attrs.pos;
2640        }
2641        if !stack.is_empty() {
2642            stack.push(("OpGetmulticastDumpReply", cur));
2643        }
2644        (stack, None)
2645    }
2646}
2647#[derive(Debug)]
2648pub struct RequestOpGetmulticastDumpRequest<'r> {
2649    request: Request<'r>,
2650}
2651impl<'r> RequestOpGetmulticastDumpRequest<'r> {
2652    pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
2653        PushOpGetmulticastDumpRequest::write_header(&mut request.buf_mut(), header);
2654        Self {
2655            request: request.set_dump(),
2656        }
2657    }
2658    pub fn encode(&mut self) -> PushOpGetmulticastDumpRequest<&mut Vec<u8>> {
2659        PushOpGetmulticastDumpRequest::new_without_header(self.request.buf_mut())
2660    }
2661    pub fn into_encoder(self) -> PushOpGetmulticastDumpRequest<RequestBuf<'r>> {
2662        PushOpGetmulticastDumpRequest::new_without_header(self.request.buf)
2663    }
2664    pub fn decode_request<'buf>(
2665        buf: &'buf [u8],
2666    ) -> (PushIfaddrmsg, IterableOpGetmulticastDumpRequest<'buf>) {
2667        OpGetmulticastDumpRequest::new(buf)
2668    }
2669}
2670impl NetlinkRequest for RequestOpGetmulticastDumpRequest<'_> {
2671    fn protocol(&self) -> Protocol {
2672        Protocol::Raw {
2673            protonum: 0u16,
2674            request_type: 58u16,
2675        }
2676    }
2677    fn flags(&self) -> u16 {
2678        self.request.flags
2679    }
2680    fn payload(&self) -> &[u8] {
2681        self.request.buf()
2682    }
2683    type ReplyType<'buf> = (PushIfaddrmsg, IterableOpGetmulticastDumpReply<'buf>);
2684    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2685        OpGetmulticastDumpReply::new(buf)
2686    }
2687    fn lookup(
2688        buf: &[u8],
2689        offset: usize,
2690        missing_type: Option<u16>,
2691    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2692        OpGetmulticastDumpRequest::new(buf)
2693            .1
2694            .lookup_attr(offset, missing_type)
2695    }
2696}
2697#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2698pub struct PushOpGetmulticastDoRequest<Prev: Rec> {
2699    pub(crate) prev: Option<Prev>,
2700    pub(crate) header_offset: Option<usize>,
2701}
2702impl<Prev: Rec> Rec for PushOpGetmulticastDoRequest<Prev> {
2703    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2704        self.prev.as_mut().unwrap().as_rec_mut()
2705    }
2706    fn as_rec(&self) -> &Vec<u8> {
2707        self.prev.as_ref().unwrap().as_rec()
2708    }
2709}
2710impl<Prev: Rec> PushOpGetmulticastDoRequest<Prev> {
2711    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
2712        Self::write_header(&mut prev, header);
2713        Self::new_without_header(prev)
2714    }
2715    fn new_without_header(prev: Prev) -> Self {
2716        Self {
2717            prev: Some(prev),
2718            header_offset: None,
2719        }
2720    }
2721    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
2722        prev.as_rec_mut().extend(header.as_slice());
2723    }
2724    pub fn end_nested(mut self) -> Prev {
2725        let mut prev = self.prev.take().unwrap();
2726        if let Some(header_offset) = &self.header_offset {
2727            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2728        }
2729        prev
2730    }
2731}
2732impl<Prev: Rec> Drop for PushOpGetmulticastDoRequest<Prev> {
2733    fn drop(&mut self) {
2734        if let Some(prev) = &mut self.prev {
2735            if let Some(header_offset) = &self.header_offset {
2736                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2737            }
2738        }
2739    }
2740}
2741#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2742#[derive(Clone)]
2743pub enum OpGetmulticastDoRequest {}
2744impl<'a> IterableOpGetmulticastDoRequest<'a> {}
2745impl OpGetmulticastDoRequest {
2746    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetmulticastDoRequest<'a>) {
2747        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2748        (
2749            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2750            IterableOpGetmulticastDoRequest::with_loc(attrs, buf.as_ptr() as usize),
2751        )
2752    }
2753    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2754        AddrAttrs::attr_from_type(r#type)
2755    }
2756}
2757#[derive(Clone, Copy, Default)]
2758pub struct IterableOpGetmulticastDoRequest<'a> {
2759    buf: &'a [u8],
2760    pos: usize,
2761    orig_loc: usize,
2762}
2763impl<'a> IterableOpGetmulticastDoRequest<'a> {
2764    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2765        Self {
2766            buf,
2767            pos: 0,
2768            orig_loc,
2769        }
2770    }
2771    pub fn get_buf(&self) -> &'a [u8] {
2772        self.buf
2773    }
2774}
2775impl<'a> Iterator for IterableOpGetmulticastDoRequest<'a> {
2776    type Item = Result<OpGetmulticastDoRequest, ErrorContext>;
2777    fn next(&mut self) -> Option<Self::Item> {
2778        let pos = self.pos;
2779        let mut r#type;
2780        loop {
2781            r#type = None;
2782            if self.buf.len() == self.pos {
2783                return None;
2784            }
2785            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2786                break;
2787            };
2788            r#type = Some(header.r#type);
2789            let res = match header.r#type {
2790                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2791                n => continue,
2792            };
2793            return Some(Ok(res));
2794        }
2795        Some(Err(ErrorContext::new(
2796            "OpGetmulticastDoRequest",
2797            r#type.and_then(|t| OpGetmulticastDoRequest::attr_from_type(t)),
2798            self.orig_loc,
2799            self.buf.as_ptr().wrapping_add(pos) as usize,
2800        )))
2801    }
2802}
2803impl std::fmt::Debug for IterableOpGetmulticastDoRequest<'_> {
2804    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2805        let mut fmt = f.debug_struct("OpGetmulticastDoRequest");
2806        for attr in self.clone() {
2807            let attr = match attr {
2808                Ok(a) => a,
2809                Err(err) => {
2810                    fmt.finish()?;
2811                    f.write_str("Err(")?;
2812                    err.fmt(f)?;
2813                    return f.write_str(")");
2814                }
2815            };
2816            match attr {};
2817        }
2818        fmt.finish()
2819    }
2820}
2821impl IterableOpGetmulticastDoRequest<'_> {
2822    pub fn lookup_attr(
2823        &self,
2824        offset: usize,
2825        missing_type: Option<u16>,
2826    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2827        let mut stack = Vec::new();
2828        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2829        if cur == offset + PushIfaddrmsg::len() {
2830            stack.push(("OpGetmulticastDoRequest", offset));
2831            return (
2832                stack,
2833                missing_type.and_then(|t| OpGetmulticastDoRequest::attr_from_type(t)),
2834            );
2835        }
2836        (stack, None)
2837    }
2838}
2839#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2840pub struct PushOpGetmulticastDoReply<Prev: Rec> {
2841    pub(crate) prev: Option<Prev>,
2842    pub(crate) header_offset: Option<usize>,
2843}
2844impl<Prev: Rec> Rec for PushOpGetmulticastDoReply<Prev> {
2845    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2846        self.prev.as_mut().unwrap().as_rec_mut()
2847    }
2848    fn as_rec(&self) -> &Vec<u8> {
2849        self.prev.as_ref().unwrap().as_rec()
2850    }
2851}
2852impl<Prev: Rec> PushOpGetmulticastDoReply<Prev> {
2853    pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
2854        Self::write_header(&mut prev, header);
2855        Self::new_without_header(prev)
2856    }
2857    fn new_without_header(prev: Prev) -> Self {
2858        Self {
2859            prev: Some(prev),
2860            header_offset: None,
2861        }
2862    }
2863    fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
2864        prev.as_rec_mut().extend(header.as_slice());
2865    }
2866    pub fn end_nested(mut self) -> Prev {
2867        let mut prev = self.prev.take().unwrap();
2868        if let Some(header_offset) = &self.header_offset {
2869            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2870        }
2871        prev
2872    }
2873    pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
2874        push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
2875        self.as_rec_mut().extend(value.as_slice());
2876        self
2877    }
2878    pub fn push_multicast(mut self, value: &[u8]) -> Self {
2879        push_header(self.as_rec_mut(), 7u16, value.len() as u16);
2880        self.as_rec_mut().extend(value);
2881        self
2882    }
2883}
2884impl<Prev: Rec> Drop for PushOpGetmulticastDoReply<Prev> {
2885    fn drop(&mut self) {
2886        if let Some(prev) = &mut self.prev {
2887            if let Some(header_offset) = &self.header_offset {
2888                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2889            }
2890        }
2891    }
2892}
2893#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2894#[derive(Clone)]
2895pub enum OpGetmulticastDoReply<'a> {
2896    Cacheinfo(PushIfaCacheinfo),
2897    Multicast(&'a [u8]),
2898}
2899impl<'a> IterableOpGetmulticastDoReply<'a> {
2900    pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
2901        let mut iter = self.clone();
2902        iter.pos = 0;
2903        for attr in iter {
2904            if let OpGetmulticastDoReply::Cacheinfo(val) = attr? {
2905                return Ok(val);
2906            }
2907        }
2908        Err(ErrorContext::new_missing(
2909            "OpGetmulticastDoReply",
2910            "Cacheinfo",
2911            self.orig_loc,
2912            self.buf.as_ptr() as usize,
2913        ))
2914    }
2915    pub fn get_multicast(&self) -> Result<&'a [u8], ErrorContext> {
2916        let mut iter = self.clone();
2917        iter.pos = 0;
2918        for attr in iter {
2919            if let OpGetmulticastDoReply::Multicast(val) = attr? {
2920                return Ok(val);
2921            }
2922        }
2923        Err(ErrorContext::new_missing(
2924            "OpGetmulticastDoReply",
2925            "Multicast",
2926            self.orig_loc,
2927            self.buf.as_ptr() as usize,
2928        ))
2929    }
2930}
2931impl OpGetmulticastDoReply<'_> {
2932    pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetmulticastDoReply<'a>) {
2933        let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2934        (
2935            PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2936            IterableOpGetmulticastDoReply::with_loc(attrs, buf.as_ptr() as usize),
2937        )
2938    }
2939    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2940        AddrAttrs::attr_from_type(r#type)
2941    }
2942}
2943#[derive(Clone, Copy, Default)]
2944pub struct IterableOpGetmulticastDoReply<'a> {
2945    buf: &'a [u8],
2946    pos: usize,
2947    orig_loc: usize,
2948}
2949impl<'a> IterableOpGetmulticastDoReply<'a> {
2950    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2951        Self {
2952            buf,
2953            pos: 0,
2954            orig_loc,
2955        }
2956    }
2957    pub fn get_buf(&self) -> &'a [u8] {
2958        self.buf
2959    }
2960}
2961impl<'a> Iterator for IterableOpGetmulticastDoReply<'a> {
2962    type Item = Result<OpGetmulticastDoReply<'a>, ErrorContext>;
2963    fn next(&mut self) -> Option<Self::Item> {
2964        let pos = self.pos;
2965        let mut r#type;
2966        loop {
2967            r#type = None;
2968            if self.buf.len() == self.pos {
2969                return None;
2970            }
2971            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2972                break;
2973            };
2974            r#type = Some(header.r#type);
2975            let res = match header.r#type {
2976                6u16 => OpGetmulticastDoReply::Cacheinfo({
2977                    let res = PushIfaCacheinfo::new_from_slice(next);
2978                    let Some(val) = res else { break };
2979                    val
2980                }),
2981                7u16 => OpGetmulticastDoReply::Multicast({
2982                    let res = Some(next);
2983                    let Some(val) = res else { break };
2984                    val
2985                }),
2986                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2987                n => continue,
2988            };
2989            return Some(Ok(res));
2990        }
2991        Some(Err(ErrorContext::new(
2992            "OpGetmulticastDoReply",
2993            r#type.and_then(|t| OpGetmulticastDoReply::attr_from_type(t)),
2994            self.orig_loc,
2995            self.buf.as_ptr().wrapping_add(pos) as usize,
2996        )))
2997    }
2998}
2999impl<'a> std::fmt::Debug for IterableOpGetmulticastDoReply<'_> {
3000    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3001        let mut fmt = f.debug_struct("OpGetmulticastDoReply");
3002        for attr in self.clone() {
3003            let attr = match attr {
3004                Ok(a) => a,
3005                Err(err) => {
3006                    fmt.finish()?;
3007                    f.write_str("Err(")?;
3008                    err.fmt(f)?;
3009                    return f.write_str(")");
3010                }
3011            };
3012            match attr {
3013                OpGetmulticastDoReply::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
3014                OpGetmulticastDoReply::Multicast(val) => fmt.field("Multicast", &val),
3015            };
3016        }
3017        fmt.finish()
3018    }
3019}
3020impl IterableOpGetmulticastDoReply<'_> {
3021    pub fn lookup_attr(
3022        &self,
3023        offset: usize,
3024        missing_type: Option<u16>,
3025    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3026        let mut stack = Vec::new();
3027        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3028        if cur == offset + PushIfaddrmsg::len() {
3029            stack.push(("OpGetmulticastDoReply", offset));
3030            return (
3031                stack,
3032                missing_type.and_then(|t| OpGetmulticastDoReply::attr_from_type(t)),
3033            );
3034        }
3035        if cur > offset || cur + self.buf.len() < offset {
3036            return (stack, None);
3037        }
3038        let mut attrs = self.clone();
3039        let mut last_off = cur + attrs.pos;
3040        while let Some(attr) = attrs.next() {
3041            let Ok(attr) = attr else { break };
3042            match attr {
3043                OpGetmulticastDoReply::Cacheinfo(val) => {
3044                    if last_off == offset {
3045                        stack.push(("Cacheinfo", last_off));
3046                        break;
3047                    }
3048                }
3049                OpGetmulticastDoReply::Multicast(val) => {
3050                    if last_off == offset {
3051                        stack.push(("Multicast", last_off));
3052                        break;
3053                    }
3054                }
3055                _ => {}
3056            };
3057            last_off = cur + attrs.pos;
3058        }
3059        if !stack.is_empty() {
3060            stack.push(("OpGetmulticastDoReply", cur));
3061        }
3062        (stack, None)
3063    }
3064}
3065#[derive(Debug)]
3066pub struct RequestOpGetmulticastDoRequest<'r> {
3067    request: Request<'r>,
3068}
3069impl<'r> RequestOpGetmulticastDoRequest<'r> {
3070    pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
3071        PushOpGetmulticastDoRequest::write_header(&mut request.buf_mut(), header);
3072        Self { request: request }
3073    }
3074    pub fn encode(&mut self) -> PushOpGetmulticastDoRequest<&mut Vec<u8>> {
3075        PushOpGetmulticastDoRequest::new_without_header(self.request.buf_mut())
3076    }
3077    pub fn into_encoder(self) -> PushOpGetmulticastDoRequest<RequestBuf<'r>> {
3078        PushOpGetmulticastDoRequest::new_without_header(self.request.buf)
3079    }
3080    pub fn decode_request<'buf>(
3081        buf: &'buf [u8],
3082    ) -> (PushIfaddrmsg, IterableOpGetmulticastDoRequest<'buf>) {
3083        OpGetmulticastDoRequest::new(buf)
3084    }
3085}
3086impl NetlinkRequest for RequestOpGetmulticastDoRequest<'_> {
3087    fn protocol(&self) -> Protocol {
3088        Protocol::Raw {
3089            protonum: 0u16,
3090            request_type: 58u16,
3091        }
3092    }
3093    fn flags(&self) -> u16 {
3094        self.request.flags
3095    }
3096    fn payload(&self) -> &[u8] {
3097        self.request.buf()
3098    }
3099    type ReplyType<'buf> = (PushIfaddrmsg, IterableOpGetmulticastDoReply<'buf>);
3100    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
3101        OpGetmulticastDoReply::new(buf)
3102    }
3103    fn lookup(
3104        buf: &[u8],
3105        offset: usize,
3106        missing_type: Option<u16>,
3107    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3108        OpGetmulticastDoRequest::new(buf)
3109            .1
3110            .lookup_attr(offset, missing_type)
3111    }
3112}
3113#[derive(Debug)]
3114pub struct ChainedFinal<'a> {
3115    inner: Chained<'a>,
3116}
3117#[derive(Debug)]
3118pub struct Chained<'a> {
3119    buf: RequestBuf<'a>,
3120    first_seq: u32,
3121    lookups: Vec<(&'static str, LookupFn)>,
3122    last_header_offset: usize,
3123    last_kind: Option<RequestInfo>,
3124}
3125impl<'a> ChainedFinal<'a> {
3126    pub fn into_chained(self) -> Chained<'a> {
3127        self.inner
3128    }
3129    pub fn buf(&self) -> &Vec<u8> {
3130        self.inner.buf()
3131    }
3132    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
3133        self.inner.buf_mut()
3134    }
3135    fn get_index(&self, seq: u32) -> Option<u32> {
3136        let min = self.inner.first_seq;
3137        let max = min.wrapping_add(self.inner.lookups.len() as u32);
3138        return if min <= max {
3139            (min..max).contains(&seq).then(|| seq - min)
3140        } else if min <= seq {
3141            Some(seq - min)
3142        } else if seq < max {
3143            Some(u32::MAX - min + seq)
3144        } else {
3145            None
3146        };
3147    }
3148}
3149impl crate::traits::NetlinkChained for ChainedFinal<'_> {
3150    fn protonum(&self) -> u16 {
3151        PROTONUM
3152    }
3153    fn payload(&self) -> &[u8] {
3154        self.buf()
3155    }
3156    fn chain_len(&self) -> usize {
3157        self.inner.lookups.len()
3158    }
3159    fn get_index(&self, seq: u32) -> Option<usize> {
3160        self.get_index(seq).map(|n| n as usize)
3161    }
3162    fn name(&self, index: usize) -> &'static str {
3163        self.inner.lookups[index].0
3164    }
3165    fn lookup(&self, index: usize) -> LookupFn {
3166        self.inner.lookups[index].1
3167    }
3168}
3169impl Chained<'static> {
3170    pub fn new(first_seq: u32) -> Self {
3171        Self::new_from_buf(Vec::new(), first_seq)
3172    }
3173    pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
3174        Self {
3175            buf: RequestBuf::Own(buf),
3176            first_seq,
3177            lookups: Vec::new(),
3178            last_header_offset: 0,
3179            last_kind: None,
3180        }
3181    }
3182    pub fn into_buf(self) -> Vec<u8> {
3183        match self.buf {
3184            RequestBuf::Own(buf) => buf,
3185            _ => unreachable!(),
3186        }
3187    }
3188}
3189impl<'a> Chained<'a> {
3190    pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
3191        Self {
3192            buf: RequestBuf::Ref(buf),
3193            first_seq,
3194            lookups: Vec::new(),
3195            last_header_offset: 0,
3196            last_kind: None,
3197        }
3198    }
3199    pub fn finalize(mut self) -> ChainedFinal<'a> {
3200        self.update_header();
3201        ChainedFinal { inner: self }
3202    }
3203    pub fn request(&mut self) -> Request<'_> {
3204        self.update_header();
3205        self.last_header_offset = self.buf().len();
3206        self.buf_mut()
3207            .extend_from_slice(PushNlmsghdr::new().as_slice());
3208        let mut request = Request::new_extend(self.buf.buf_mut());
3209        self.last_kind = None;
3210        request.writeback = Some(&mut self.last_kind);
3211        request
3212    }
3213    pub fn buf(&self) -> &Vec<u8> {
3214        self.buf.buf()
3215    }
3216    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
3217        self.buf.buf_mut()
3218    }
3219    fn update_header(&mut self) {
3220        let Some(RequestInfo {
3221            protocol,
3222            flags,
3223            name,
3224            lookup,
3225        }) = self.last_kind
3226        else {
3227            if !self.buf().is_empty() {
3228                assert_eq!(
3229                    self.last_header_offset + PushNlmsghdr::len(),
3230                    self.buf().len()
3231                );
3232                self.buf.buf_mut().truncate(self.last_header_offset);
3233            }
3234            return;
3235        };
3236        let header_offset = self.last_header_offset;
3237        let request_type = match protocol {
3238            Protocol::Raw { request_type, .. } => request_type,
3239            Protocol::Generic(_) => unreachable!(),
3240        };
3241        let index = self.lookups.len();
3242        let seq = self.first_seq.wrapping_add(index as u32);
3243        self.lookups.push((name, lookup));
3244        let buf = self.buf_mut();
3245        align(buf);
3246        let mut header = PushNlmsghdr::new();
3247        header.set_len((buf.len() - header_offset) as u32);
3248        header.set_type(request_type);
3249        header.set_flags(flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16);
3250        header.set_seq(seq);
3251        buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
3252    }
3253}
3254use crate::traits::LookupFn;
3255use crate::utils::RequestBuf;
3256#[derive(Debug)]
3257pub struct Request<'buf> {
3258    buf: RequestBuf<'buf>,
3259    flags: u16,
3260    writeback: Option<&'buf mut Option<RequestInfo>>,
3261}
3262#[allow(unused)]
3263#[derive(Debug, Clone)]
3264pub struct RequestInfo {
3265    protocol: Protocol,
3266    flags: u16,
3267    name: &'static str,
3268    lookup: LookupFn,
3269}
3270impl Request<'static> {
3271    pub fn new() -> Self {
3272        Self::new_from_buf(Vec::new())
3273    }
3274    pub fn new_from_buf(buf: Vec<u8>) -> Self {
3275        Self {
3276            flags: 0,
3277            buf: RequestBuf::Own(buf),
3278            writeback: None,
3279        }
3280    }
3281    pub fn into_buf(self) -> Vec<u8> {
3282        match self.buf {
3283            RequestBuf::Own(buf) => buf,
3284            _ => unreachable!(),
3285        }
3286    }
3287}
3288impl<'buf> Request<'buf> {
3289    pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
3290        buf.clear();
3291        Self::new_extend(buf)
3292    }
3293    pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
3294        Self {
3295            flags: 0,
3296            buf: RequestBuf::Ref(buf),
3297            writeback: None,
3298        }
3299    }
3300    fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
3301        let Some(writeback) = &mut self.writeback else {
3302            return;
3303        };
3304        **writeback = Some(RequestInfo {
3305            protocol,
3306            flags: self.flags,
3307            name,
3308            lookup,
3309        })
3310    }
3311    pub fn buf(&self) -> &Vec<u8> {
3312        self.buf.buf()
3313    }
3314    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
3315        self.buf.buf_mut()
3316    }
3317    #[doc = "Set `NLM_F_CREATE` flag"]
3318    pub fn set_create(mut self) -> Self {
3319        self.flags |= consts::NLM_F_CREATE as u16;
3320        self
3321    }
3322    #[doc = "Set `NLM_F_EXCL` flag"]
3323    pub fn set_excl(mut self) -> Self {
3324        self.flags |= consts::NLM_F_EXCL as u16;
3325        self
3326    }
3327    #[doc = "Set `NLM_F_REPLACE` flag"]
3328    pub fn set_replace(mut self) -> Self {
3329        self.flags |= consts::NLM_F_REPLACE as u16;
3330        self
3331    }
3332    #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
3333    pub fn set_change(self) -> Self {
3334        self.set_create().set_replace()
3335    }
3336    #[doc = "Set `NLM_F_APPEND` flag"]
3337    pub fn set_append(mut self) -> Self {
3338        self.flags |= consts::NLM_F_APPEND as u16;
3339        self
3340    }
3341    #[doc = "Set `NLM_F_DUMP` flag"]
3342    fn set_dump(mut self) -> Self {
3343        self.flags |= consts::NLM_F_DUMP as u16;
3344        self
3345    }
3346    pub fn op_newaddr_do_request(self, header: &PushIfaddrmsg) -> RequestOpNewaddrDoRequest<'buf> {
3347        let mut res = RequestOpNewaddrDoRequest::new(self, header);
3348        res.request.do_writeback(
3349            res.protocol(),
3350            "op-newaddr-do-request",
3351            RequestOpNewaddrDoRequest::lookup,
3352        );
3353        res
3354    }
3355    pub fn op_deladdr_do_request(self, header: &PushIfaddrmsg) -> RequestOpDeladdrDoRequest<'buf> {
3356        let mut res = RequestOpDeladdrDoRequest::new(self, header);
3357        res.request.do_writeback(
3358            res.protocol(),
3359            "op-deladdr-do-request",
3360            RequestOpDeladdrDoRequest::lookup,
3361        );
3362        res
3363    }
3364    pub fn op_getaddr_dump_request(
3365        self,
3366        header: &PushIfaddrmsg,
3367    ) -> RequestOpGetaddrDumpRequest<'buf> {
3368        let mut res = RequestOpGetaddrDumpRequest::new(self, header);
3369        res.request.do_writeback(
3370            res.protocol(),
3371            "op-getaddr-dump-request",
3372            RequestOpGetaddrDumpRequest::lookup,
3373        );
3374        res
3375    }
3376    pub fn op_getmulticast_dump_request(
3377        self,
3378        header: &PushIfaddrmsg,
3379    ) -> RequestOpGetmulticastDumpRequest<'buf> {
3380        let mut res = RequestOpGetmulticastDumpRequest::new(self, header);
3381        res.request.do_writeback(
3382            res.protocol(),
3383            "op-getmulticast-dump-request",
3384            RequestOpGetmulticastDumpRequest::lookup,
3385        );
3386        res
3387    }
3388    pub fn op_getmulticast_do_request(
3389        self,
3390        header: &PushIfaddrmsg,
3391    ) -> RequestOpGetmulticastDoRequest<'buf> {
3392        let mut res = RequestOpGetmulticastDoRequest::new(self, header);
3393        res.request.do_writeback(
3394            res.protocol(),
3395            "op-getmulticast-do-request",
3396            RequestOpGetmulticastDoRequest::lookup,
3397        );
3398        res
3399    }
3400}