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