Skip to main content

netlink_bindings/handshake/
mod.rs

1#![doc = "Netlink protocol to request a transport layer security handshake\\."]
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::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12    consts,
13    traits::{NetlinkRequest, Protocol},
14    utils::*,
15};
16pub const PROTONAME: &str = "handshake";
17pub const PROTONAME_CSTR: &CStr = c"handshake";
18#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
19#[derive(Debug, Clone, Copy)]
20pub enum HandlerClass {
21    None = 0,
22    Tlshd = 1,
23    Max = 2,
24}
25impl HandlerClass {
26    pub fn from_value(value: u64) -> Option<Self> {
27        Some(match value {
28            0 => Self::None,
29            1 => Self::Tlshd,
30            2 => Self::Max,
31            _ => return None,
32        })
33    }
34}
35#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
36#[derive(Debug, Clone, Copy)]
37pub enum MsgType {
38    Unspec = 0,
39    Clienthello = 1,
40    Serverhello = 2,
41}
42impl MsgType {
43    pub fn from_value(value: u64) -> Option<Self> {
44        Some(match value {
45            0 => Self::Unspec,
46            1 => Self::Clienthello,
47            2 => Self::Serverhello,
48            _ => return None,
49        })
50    }
51}
52#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
53#[derive(Debug, Clone, Copy)]
54pub enum Auth {
55    Unspec = 0,
56    Unauth = 1,
57    Psk = 2,
58    X509 = 3,
59}
60impl Auth {
61    pub fn from_value(value: u64) -> Option<Self> {
62        Some(match value {
63            0 => Self::Unspec,
64            1 => Self::Unauth,
65            2 => Self::Psk,
66            3 => Self::X509,
67            _ => return None,
68        })
69    }
70}
71#[derive(Clone)]
72pub enum X509 {
73    Cert(i32),
74    Privkey(i32),
75}
76impl<'a> IterableX509<'a> {
77    pub fn get_cert(&self) -> Result<i32, ErrorContext> {
78        let mut iter = self.clone();
79        iter.pos = 0;
80        for attr in iter {
81            if let X509::Cert(val) = attr? {
82                return Ok(val);
83            }
84        }
85        Err(ErrorContext::new_missing(
86            "X509",
87            "Cert",
88            self.orig_loc,
89            self.buf.as_ptr() as usize,
90        ))
91    }
92    pub fn get_privkey(&self) -> Result<i32, ErrorContext> {
93        let mut iter = self.clone();
94        iter.pos = 0;
95        for attr in iter {
96            if let X509::Privkey(val) = attr? {
97                return Ok(val);
98            }
99        }
100        Err(ErrorContext::new_missing(
101            "X509",
102            "Privkey",
103            self.orig_loc,
104            self.buf.as_ptr() as usize,
105        ))
106    }
107}
108impl X509 {
109    pub fn new<'a>(buf: &'a [u8]) -> IterableX509<'a> {
110        IterableX509::with_loc(buf, buf.as_ptr() as usize)
111    }
112    fn attr_from_type(r#type: u16) -> Option<&'static str> {
113        let res = match r#type {
114            1u16 => "Cert",
115            2u16 => "Privkey",
116            _ => return None,
117        };
118        Some(res)
119    }
120}
121#[derive(Clone, Copy, Default)]
122pub struct IterableX509<'a> {
123    buf: &'a [u8],
124    pos: usize,
125    orig_loc: usize,
126}
127impl<'a> IterableX509<'a> {
128    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
129        Self {
130            buf,
131            pos: 0,
132            orig_loc,
133        }
134    }
135    pub fn get_buf(&self) -> &'a [u8] {
136        self.buf
137    }
138}
139impl<'a> Iterator for IterableX509<'a> {
140    type Item = Result<X509, ErrorContext>;
141    fn next(&mut self) -> Option<Self::Item> {
142        let pos = self.pos;
143        let mut r#type;
144        loop {
145            r#type = None;
146            if self.buf.len() == self.pos {
147                return None;
148            }
149            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
150                break;
151            };
152            r#type = Some(header.r#type);
153            let res = match header.r#type {
154                1u16 => X509::Cert({
155                    let res = parse_i32(next);
156                    let Some(val) = res else { break };
157                    val
158                }),
159                2u16 => X509::Privkey({
160                    let res = parse_i32(next);
161                    let Some(val) = res else { break };
162                    val
163                }),
164                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
165                n => continue,
166            };
167            return Some(Ok(res));
168        }
169        Some(Err(ErrorContext::new(
170            "X509",
171            r#type.and_then(|t| X509::attr_from_type(t)),
172            self.orig_loc,
173            self.buf.as_ptr().wrapping_add(pos) as usize,
174        )))
175    }
176}
177impl std::fmt::Debug for IterableX509<'_> {
178    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
179        let mut fmt = f.debug_struct("X509");
180        for attr in self.clone() {
181            let attr = match attr {
182                Ok(a) => a,
183                Err(err) => {
184                    fmt.finish()?;
185                    f.write_str("Err(")?;
186                    err.fmt(f)?;
187                    return f.write_str(")");
188                }
189            };
190            match attr {
191                X509::Cert(val) => fmt.field("Cert", &val),
192                X509::Privkey(val) => fmt.field("Privkey", &val),
193            };
194        }
195        fmt.finish()
196    }
197}
198impl IterableX509<'_> {
199    pub fn lookup_attr(
200        &self,
201        offset: usize,
202        missing_type: Option<u16>,
203    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
204        let mut stack = Vec::new();
205        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
206        if missing_type.is_some() && cur == offset {
207            stack.push(("X509", offset));
208            return (stack, missing_type.and_then(|t| X509::attr_from_type(t)));
209        }
210        if cur > offset || cur + self.buf.len() < offset {
211            return (stack, None);
212        }
213        let mut attrs = self.clone();
214        let mut last_off = cur + attrs.pos;
215        while let Some(attr) = attrs.next() {
216            let Ok(attr) = attr else { break };
217            match attr {
218                X509::Cert(val) => {
219                    if last_off == offset {
220                        stack.push(("Cert", last_off));
221                        break;
222                    }
223                }
224                X509::Privkey(val) => {
225                    if last_off == offset {
226                        stack.push(("Privkey", last_off));
227                        break;
228                    }
229                }
230                _ => {}
231            };
232            last_off = cur + attrs.pos;
233        }
234        if !stack.is_empty() {
235            stack.push(("X509", cur));
236        }
237        (stack, None)
238    }
239}
240#[derive(Clone)]
241pub enum Accept<'a> {
242    Sockfd(i32),
243    #[doc = "Associated type: [`HandlerClass`] (enum)"]
244    HandlerClass(u32),
245    #[doc = "Associated type: [`MsgType`] (enum)"]
246    MessageType(u32),
247    Timeout(u32),
248    #[doc = "Associated type: [`Auth`] (enum)"]
249    AuthMode(u32),
250    #[doc = "Attribute may repeat multiple times (treat it as array)"]
251    PeerIdentity(u32),
252    #[doc = "Attribute may repeat multiple times (treat it as array)"]
253    Certificate(IterableX509<'a>),
254    Peername(&'a CStr),
255    Keyring(u32),
256}
257impl<'a> IterableAccept<'a> {
258    pub fn get_sockfd(&self) -> Result<i32, ErrorContext> {
259        let mut iter = self.clone();
260        iter.pos = 0;
261        for attr in iter {
262            if let Accept::Sockfd(val) = attr? {
263                return Ok(val);
264            }
265        }
266        Err(ErrorContext::new_missing(
267            "Accept",
268            "Sockfd",
269            self.orig_loc,
270            self.buf.as_ptr() as usize,
271        ))
272    }
273    #[doc = "Associated type: [`HandlerClass`] (enum)"]
274    pub fn get_handler_class(&self) -> Result<u32, ErrorContext> {
275        let mut iter = self.clone();
276        iter.pos = 0;
277        for attr in iter {
278            if let Accept::HandlerClass(val) = attr? {
279                return Ok(val);
280            }
281        }
282        Err(ErrorContext::new_missing(
283            "Accept",
284            "HandlerClass",
285            self.orig_loc,
286            self.buf.as_ptr() as usize,
287        ))
288    }
289    #[doc = "Associated type: [`MsgType`] (enum)"]
290    pub fn get_message_type(&self) -> Result<u32, ErrorContext> {
291        let mut iter = self.clone();
292        iter.pos = 0;
293        for attr in iter {
294            if let Accept::MessageType(val) = attr? {
295                return Ok(val);
296            }
297        }
298        Err(ErrorContext::new_missing(
299            "Accept",
300            "MessageType",
301            self.orig_loc,
302            self.buf.as_ptr() as usize,
303        ))
304    }
305    pub fn get_timeout(&self) -> Result<u32, ErrorContext> {
306        let mut iter = self.clone();
307        iter.pos = 0;
308        for attr in iter {
309            if let Accept::Timeout(val) = attr? {
310                return Ok(val);
311            }
312        }
313        Err(ErrorContext::new_missing(
314            "Accept",
315            "Timeout",
316            self.orig_loc,
317            self.buf.as_ptr() as usize,
318        ))
319    }
320    #[doc = "Associated type: [`Auth`] (enum)"]
321    pub fn get_auth_mode(&self) -> Result<u32, ErrorContext> {
322        let mut iter = self.clone();
323        iter.pos = 0;
324        for attr in iter {
325            if let Accept::AuthMode(val) = attr? {
326                return Ok(val);
327            }
328        }
329        Err(ErrorContext::new_missing(
330            "Accept",
331            "AuthMode",
332            self.orig_loc,
333            self.buf.as_ptr() as usize,
334        ))
335    }
336    #[doc = "Attribute may repeat multiple times (treat it as array)"]
337    pub fn get_peer_identity(&self) -> MultiAttrIterable<Self, Accept<'a>, u32> {
338        MultiAttrIterable::new(self.clone(), |variant| {
339            if let Accept::PeerIdentity(val) = variant {
340                Some(val)
341            } else {
342                None
343            }
344        })
345    }
346    #[doc = "Attribute may repeat multiple times (treat it as array)"]
347    pub fn get_certificate(&self) -> MultiAttrIterable<Self, Accept<'a>, IterableX509<'a>> {
348        MultiAttrIterable::new(self.clone(), |variant| {
349            if let Accept::Certificate(val) = variant {
350                Some(val)
351            } else {
352                None
353            }
354        })
355    }
356    pub fn get_peername(&self) -> Result<&'a CStr, ErrorContext> {
357        let mut iter = self.clone();
358        iter.pos = 0;
359        for attr in iter {
360            if let Accept::Peername(val) = attr? {
361                return Ok(val);
362            }
363        }
364        Err(ErrorContext::new_missing(
365            "Accept",
366            "Peername",
367            self.orig_loc,
368            self.buf.as_ptr() as usize,
369        ))
370    }
371    pub fn get_keyring(&self) -> Result<u32, ErrorContext> {
372        let mut iter = self.clone();
373        iter.pos = 0;
374        for attr in iter {
375            if let Accept::Keyring(val) = attr? {
376                return Ok(val);
377            }
378        }
379        Err(ErrorContext::new_missing(
380            "Accept",
381            "Keyring",
382            self.orig_loc,
383            self.buf.as_ptr() as usize,
384        ))
385    }
386}
387impl Accept<'_> {
388    pub fn new<'a>(buf: &'a [u8]) -> IterableAccept<'a> {
389        IterableAccept::with_loc(buf, buf.as_ptr() as usize)
390    }
391    fn attr_from_type(r#type: u16) -> Option<&'static str> {
392        let res = match r#type {
393            1u16 => "Sockfd",
394            2u16 => "HandlerClass",
395            3u16 => "MessageType",
396            4u16 => "Timeout",
397            5u16 => "AuthMode",
398            6u16 => "PeerIdentity",
399            7u16 => "Certificate",
400            8u16 => "Peername",
401            9u16 => "Keyring",
402            _ => return None,
403        };
404        Some(res)
405    }
406}
407#[derive(Clone, Copy, Default)]
408pub struct IterableAccept<'a> {
409    buf: &'a [u8],
410    pos: usize,
411    orig_loc: usize,
412}
413impl<'a> IterableAccept<'a> {
414    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
415        Self {
416            buf,
417            pos: 0,
418            orig_loc,
419        }
420    }
421    pub fn get_buf(&self) -> &'a [u8] {
422        self.buf
423    }
424}
425impl<'a> Iterator for IterableAccept<'a> {
426    type Item = Result<Accept<'a>, ErrorContext>;
427    fn next(&mut self) -> Option<Self::Item> {
428        let pos = self.pos;
429        let mut r#type;
430        loop {
431            r#type = None;
432            if self.buf.len() == self.pos {
433                return None;
434            }
435            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
436                break;
437            };
438            r#type = Some(header.r#type);
439            let res = match header.r#type {
440                1u16 => Accept::Sockfd({
441                    let res = parse_i32(next);
442                    let Some(val) = res else { break };
443                    val
444                }),
445                2u16 => Accept::HandlerClass({
446                    let res = parse_u32(next);
447                    let Some(val) = res else { break };
448                    val
449                }),
450                3u16 => Accept::MessageType({
451                    let res = parse_u32(next);
452                    let Some(val) = res else { break };
453                    val
454                }),
455                4u16 => Accept::Timeout({
456                    let res = parse_u32(next);
457                    let Some(val) = res else { break };
458                    val
459                }),
460                5u16 => Accept::AuthMode({
461                    let res = parse_u32(next);
462                    let Some(val) = res else { break };
463                    val
464                }),
465                6u16 => Accept::PeerIdentity({
466                    let res = parse_u32(next);
467                    let Some(val) = res else { break };
468                    val
469                }),
470                7u16 => Accept::Certificate({
471                    let res = Some(IterableX509::with_loc(next, self.orig_loc));
472                    let Some(val) = res else { break };
473                    val
474                }),
475                8u16 => Accept::Peername({
476                    let res = CStr::from_bytes_with_nul(next).ok();
477                    let Some(val) = res else { break };
478                    val
479                }),
480                9u16 => Accept::Keyring({
481                    let res = parse_u32(next);
482                    let Some(val) = res else { break };
483                    val
484                }),
485                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
486                n => continue,
487            };
488            return Some(Ok(res));
489        }
490        Some(Err(ErrorContext::new(
491            "Accept",
492            r#type.and_then(|t| Accept::attr_from_type(t)),
493            self.orig_loc,
494            self.buf.as_ptr().wrapping_add(pos) as usize,
495        )))
496    }
497}
498impl<'a> std::fmt::Debug for IterableAccept<'_> {
499    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
500        let mut fmt = f.debug_struct("Accept");
501        for attr in self.clone() {
502            let attr = match attr {
503                Ok(a) => a,
504                Err(err) => {
505                    fmt.finish()?;
506                    f.write_str("Err(")?;
507                    err.fmt(f)?;
508                    return f.write_str(")");
509                }
510            };
511            match attr {
512                Accept::Sockfd(val) => fmt.field("Sockfd", &val),
513                Accept::HandlerClass(val) => fmt.field(
514                    "HandlerClass",
515                    &FormatEnum(val.into(), HandlerClass::from_value),
516                ),
517                Accept::MessageType(val) => {
518                    fmt.field("MessageType", &FormatEnum(val.into(), MsgType::from_value))
519                }
520                Accept::Timeout(val) => fmt.field("Timeout", &val),
521                Accept::AuthMode(val) => {
522                    fmt.field("AuthMode", &FormatEnum(val.into(), Auth::from_value))
523                }
524                Accept::PeerIdentity(val) => fmt.field("PeerIdentity", &val),
525                Accept::Certificate(val) => fmt.field("Certificate", &val),
526                Accept::Peername(val) => fmt.field("Peername", &val),
527                Accept::Keyring(val) => fmt.field("Keyring", &val),
528            };
529        }
530        fmt.finish()
531    }
532}
533impl IterableAccept<'_> {
534    pub fn lookup_attr(
535        &self,
536        offset: usize,
537        missing_type: Option<u16>,
538    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
539        let mut stack = Vec::new();
540        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
541        if missing_type.is_some() && cur == offset {
542            stack.push(("Accept", offset));
543            return (stack, missing_type.and_then(|t| Accept::attr_from_type(t)));
544        }
545        if cur > offset || cur + self.buf.len() < offset {
546            return (stack, None);
547        }
548        let mut attrs = self.clone();
549        let mut last_off = cur + attrs.pos;
550        let mut missing = None;
551        while let Some(attr) = attrs.next() {
552            let Ok(attr) = attr else { break };
553            match attr {
554                Accept::Sockfd(val) => {
555                    if last_off == offset {
556                        stack.push(("Sockfd", last_off));
557                        break;
558                    }
559                }
560                Accept::HandlerClass(val) => {
561                    if last_off == offset {
562                        stack.push(("HandlerClass", last_off));
563                        break;
564                    }
565                }
566                Accept::MessageType(val) => {
567                    if last_off == offset {
568                        stack.push(("MessageType", last_off));
569                        break;
570                    }
571                }
572                Accept::Timeout(val) => {
573                    if last_off == offset {
574                        stack.push(("Timeout", last_off));
575                        break;
576                    }
577                }
578                Accept::AuthMode(val) => {
579                    if last_off == offset {
580                        stack.push(("AuthMode", last_off));
581                        break;
582                    }
583                }
584                Accept::PeerIdentity(val) => {
585                    if last_off == offset {
586                        stack.push(("PeerIdentity", last_off));
587                        break;
588                    }
589                }
590                Accept::Certificate(val) => {
591                    (stack, missing) = val.lookup_attr(offset, missing_type);
592                    if !stack.is_empty() {
593                        break;
594                    }
595                }
596                Accept::Peername(val) => {
597                    if last_off == offset {
598                        stack.push(("Peername", last_off));
599                        break;
600                    }
601                }
602                Accept::Keyring(val) => {
603                    if last_off == offset {
604                        stack.push(("Keyring", last_off));
605                        break;
606                    }
607                }
608                _ => {}
609            };
610            last_off = cur + attrs.pos;
611        }
612        if !stack.is_empty() {
613            stack.push(("Accept", cur));
614        }
615        (stack, missing)
616    }
617}
618#[derive(Clone)]
619pub enum Done {
620    Status(u32),
621    Sockfd(i32),
622    #[doc = "Attribute may repeat multiple times (treat it as array)"]
623    RemoteAuth(u32),
624}
625impl<'a> IterableDone<'a> {
626    pub fn get_status(&self) -> Result<u32, ErrorContext> {
627        let mut iter = self.clone();
628        iter.pos = 0;
629        for attr in iter {
630            if let Done::Status(val) = attr? {
631                return Ok(val);
632            }
633        }
634        Err(ErrorContext::new_missing(
635            "Done",
636            "Status",
637            self.orig_loc,
638            self.buf.as_ptr() as usize,
639        ))
640    }
641    pub fn get_sockfd(&self) -> Result<i32, ErrorContext> {
642        let mut iter = self.clone();
643        iter.pos = 0;
644        for attr in iter {
645            if let Done::Sockfd(val) = attr? {
646                return Ok(val);
647            }
648        }
649        Err(ErrorContext::new_missing(
650            "Done",
651            "Sockfd",
652            self.orig_loc,
653            self.buf.as_ptr() as usize,
654        ))
655    }
656    #[doc = "Attribute may repeat multiple times (treat it as array)"]
657    pub fn get_remote_auth(&self) -> MultiAttrIterable<Self, Done, u32> {
658        MultiAttrIterable::new(self.clone(), |variant| {
659            if let Done::RemoteAuth(val) = variant {
660                Some(val)
661            } else {
662                None
663            }
664        })
665    }
666}
667impl Done {
668    pub fn new<'a>(buf: &'a [u8]) -> IterableDone<'a> {
669        IterableDone::with_loc(buf, buf.as_ptr() as usize)
670    }
671    fn attr_from_type(r#type: u16) -> Option<&'static str> {
672        let res = match r#type {
673            1u16 => "Status",
674            2u16 => "Sockfd",
675            3u16 => "RemoteAuth",
676            _ => return None,
677        };
678        Some(res)
679    }
680}
681#[derive(Clone, Copy, Default)]
682pub struct IterableDone<'a> {
683    buf: &'a [u8],
684    pos: usize,
685    orig_loc: usize,
686}
687impl<'a> IterableDone<'a> {
688    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
689        Self {
690            buf,
691            pos: 0,
692            orig_loc,
693        }
694    }
695    pub fn get_buf(&self) -> &'a [u8] {
696        self.buf
697    }
698}
699impl<'a> Iterator for IterableDone<'a> {
700    type Item = Result<Done, ErrorContext>;
701    fn next(&mut self) -> Option<Self::Item> {
702        let pos = self.pos;
703        let mut r#type;
704        loop {
705            r#type = None;
706            if self.buf.len() == self.pos {
707                return None;
708            }
709            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
710                break;
711            };
712            r#type = Some(header.r#type);
713            let res = match header.r#type {
714                1u16 => Done::Status({
715                    let res = parse_u32(next);
716                    let Some(val) = res else { break };
717                    val
718                }),
719                2u16 => Done::Sockfd({
720                    let res = parse_i32(next);
721                    let Some(val) = res else { break };
722                    val
723                }),
724                3u16 => Done::RemoteAuth({
725                    let res = parse_u32(next);
726                    let Some(val) = res else { break };
727                    val
728                }),
729                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
730                n => continue,
731            };
732            return Some(Ok(res));
733        }
734        Some(Err(ErrorContext::new(
735            "Done",
736            r#type.and_then(|t| Done::attr_from_type(t)),
737            self.orig_loc,
738            self.buf.as_ptr().wrapping_add(pos) as usize,
739        )))
740    }
741}
742impl std::fmt::Debug for IterableDone<'_> {
743    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
744        let mut fmt = f.debug_struct("Done");
745        for attr in self.clone() {
746            let attr = match attr {
747                Ok(a) => a,
748                Err(err) => {
749                    fmt.finish()?;
750                    f.write_str("Err(")?;
751                    err.fmt(f)?;
752                    return f.write_str(")");
753                }
754            };
755            match attr {
756                Done::Status(val) => fmt.field("Status", &val),
757                Done::Sockfd(val) => fmt.field("Sockfd", &val),
758                Done::RemoteAuth(val) => fmt.field("RemoteAuth", &val),
759            };
760        }
761        fmt.finish()
762    }
763}
764impl IterableDone<'_> {
765    pub fn lookup_attr(
766        &self,
767        offset: usize,
768        missing_type: Option<u16>,
769    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
770        let mut stack = Vec::new();
771        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
772        if missing_type.is_some() && cur == offset {
773            stack.push(("Done", offset));
774            return (stack, missing_type.and_then(|t| Done::attr_from_type(t)));
775        }
776        if cur > offset || cur + self.buf.len() < offset {
777            return (stack, None);
778        }
779        let mut attrs = self.clone();
780        let mut last_off = cur + attrs.pos;
781        while let Some(attr) = attrs.next() {
782            let Ok(attr) = attr else { break };
783            match attr {
784                Done::Status(val) => {
785                    if last_off == offset {
786                        stack.push(("Status", last_off));
787                        break;
788                    }
789                }
790                Done::Sockfd(val) => {
791                    if last_off == offset {
792                        stack.push(("Sockfd", last_off));
793                        break;
794                    }
795                }
796                Done::RemoteAuth(val) => {
797                    if last_off == offset {
798                        stack.push(("RemoteAuth", last_off));
799                        break;
800                    }
801                }
802                _ => {}
803            };
804            last_off = cur + attrs.pos;
805        }
806        if !stack.is_empty() {
807            stack.push(("Done", cur));
808        }
809        (stack, None)
810    }
811}
812pub struct PushX509<Prev: Rec> {
813    pub(crate) prev: Option<Prev>,
814    pub(crate) header_offset: Option<usize>,
815}
816impl<Prev: Rec> Rec for PushX509<Prev> {
817    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
818        self.prev.as_mut().unwrap().as_rec_mut()
819    }
820    fn as_rec(&self) -> &Vec<u8> {
821        self.prev.as_ref().unwrap().as_rec()
822    }
823}
824impl<Prev: Rec> PushX509<Prev> {
825    pub fn new(prev: Prev) -> Self {
826        Self {
827            prev: Some(prev),
828            header_offset: None,
829        }
830    }
831    pub fn end_nested(mut self) -> Prev {
832        let mut prev = self.prev.take().unwrap();
833        if let Some(header_offset) = &self.header_offset {
834            finalize_nested_header(prev.as_rec_mut(), *header_offset);
835        }
836        prev
837    }
838    pub fn push_cert(mut self, value: i32) -> Self {
839        push_header(self.as_rec_mut(), 1u16, 4 as u16);
840        self.as_rec_mut().extend(value.to_ne_bytes());
841        self
842    }
843    pub fn push_privkey(mut self, value: i32) -> Self {
844        push_header(self.as_rec_mut(), 2u16, 4 as u16);
845        self.as_rec_mut().extend(value.to_ne_bytes());
846        self
847    }
848}
849impl<Prev: Rec> Drop for PushX509<Prev> {
850    fn drop(&mut self) {
851        if let Some(prev) = &mut self.prev {
852            if let Some(header_offset) = &self.header_offset {
853                finalize_nested_header(prev.as_rec_mut(), *header_offset);
854            }
855        }
856    }
857}
858pub struct PushAccept<Prev: Rec> {
859    pub(crate) prev: Option<Prev>,
860    pub(crate) header_offset: Option<usize>,
861}
862impl<Prev: Rec> Rec for PushAccept<Prev> {
863    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
864        self.prev.as_mut().unwrap().as_rec_mut()
865    }
866    fn as_rec(&self) -> &Vec<u8> {
867        self.prev.as_ref().unwrap().as_rec()
868    }
869}
870impl<Prev: Rec> PushAccept<Prev> {
871    pub fn new(prev: Prev) -> Self {
872        Self {
873            prev: Some(prev),
874            header_offset: None,
875        }
876    }
877    pub fn end_nested(mut self) -> Prev {
878        let mut prev = self.prev.take().unwrap();
879        if let Some(header_offset) = &self.header_offset {
880            finalize_nested_header(prev.as_rec_mut(), *header_offset);
881        }
882        prev
883    }
884    pub fn push_sockfd(mut self, value: i32) -> Self {
885        push_header(self.as_rec_mut(), 1u16, 4 as u16);
886        self.as_rec_mut().extend(value.to_ne_bytes());
887        self
888    }
889    #[doc = "Associated type: [`HandlerClass`] (enum)"]
890    pub fn push_handler_class(mut self, value: u32) -> Self {
891        push_header(self.as_rec_mut(), 2u16, 4 as u16);
892        self.as_rec_mut().extend(value.to_ne_bytes());
893        self
894    }
895    #[doc = "Associated type: [`MsgType`] (enum)"]
896    pub fn push_message_type(mut self, value: u32) -> Self {
897        push_header(self.as_rec_mut(), 3u16, 4 as u16);
898        self.as_rec_mut().extend(value.to_ne_bytes());
899        self
900    }
901    pub fn push_timeout(mut self, value: u32) -> Self {
902        push_header(self.as_rec_mut(), 4u16, 4 as u16);
903        self.as_rec_mut().extend(value.to_ne_bytes());
904        self
905    }
906    #[doc = "Associated type: [`Auth`] (enum)"]
907    pub fn push_auth_mode(mut self, value: u32) -> Self {
908        push_header(self.as_rec_mut(), 5u16, 4 as u16);
909        self.as_rec_mut().extend(value.to_ne_bytes());
910        self
911    }
912    #[doc = "Attribute may repeat multiple times (treat it as array)"]
913    pub fn push_peer_identity(mut self, value: u32) -> Self {
914        push_header(self.as_rec_mut(), 6u16, 4 as u16);
915        self.as_rec_mut().extend(value.to_ne_bytes());
916        self
917    }
918    #[doc = "Attribute may repeat multiple times (treat it as array)"]
919    pub fn nested_certificate(mut self) -> PushX509<Self> {
920        let header_offset = push_nested_header(self.as_rec_mut(), 7u16);
921        PushX509 {
922            prev: Some(self),
923            header_offset: Some(header_offset),
924        }
925    }
926    pub fn push_peername(mut self, value: &CStr) -> Self {
927        push_header(
928            self.as_rec_mut(),
929            8u16,
930            value.to_bytes_with_nul().len() as u16,
931        );
932        self.as_rec_mut().extend(value.to_bytes_with_nul());
933        self
934    }
935    pub fn push_peername_bytes(mut self, value: &[u8]) -> Self {
936        push_header(self.as_rec_mut(), 8u16, (value.len() + 1) as u16);
937        self.as_rec_mut().extend(value);
938        self.as_rec_mut().push(0);
939        self
940    }
941    pub fn push_keyring(mut self, value: u32) -> Self {
942        push_header(self.as_rec_mut(), 9u16, 4 as u16);
943        self.as_rec_mut().extend(value.to_ne_bytes());
944        self
945    }
946}
947impl<Prev: Rec> Drop for PushAccept<Prev> {
948    fn drop(&mut self) {
949        if let Some(prev) = &mut self.prev {
950            if let Some(header_offset) = &self.header_offset {
951                finalize_nested_header(prev.as_rec_mut(), *header_offset);
952            }
953        }
954    }
955}
956pub struct PushDone<Prev: Rec> {
957    pub(crate) prev: Option<Prev>,
958    pub(crate) header_offset: Option<usize>,
959}
960impl<Prev: Rec> Rec for PushDone<Prev> {
961    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
962        self.prev.as_mut().unwrap().as_rec_mut()
963    }
964    fn as_rec(&self) -> &Vec<u8> {
965        self.prev.as_ref().unwrap().as_rec()
966    }
967}
968impl<Prev: Rec> PushDone<Prev> {
969    pub fn new(prev: Prev) -> Self {
970        Self {
971            prev: Some(prev),
972            header_offset: None,
973        }
974    }
975    pub fn end_nested(mut self) -> Prev {
976        let mut prev = self.prev.take().unwrap();
977        if let Some(header_offset) = &self.header_offset {
978            finalize_nested_header(prev.as_rec_mut(), *header_offset);
979        }
980        prev
981    }
982    pub fn push_status(mut self, value: u32) -> Self {
983        push_header(self.as_rec_mut(), 1u16, 4 as u16);
984        self.as_rec_mut().extend(value.to_ne_bytes());
985        self
986    }
987    pub fn push_sockfd(mut self, value: i32) -> Self {
988        push_header(self.as_rec_mut(), 2u16, 4 as u16);
989        self.as_rec_mut().extend(value.to_ne_bytes());
990        self
991    }
992    #[doc = "Attribute may repeat multiple times (treat it as array)"]
993    pub fn push_remote_auth(mut self, value: u32) -> Self {
994        push_header(self.as_rec_mut(), 3u16, 4 as u16);
995        self.as_rec_mut().extend(value.to_ne_bytes());
996        self
997    }
998}
999impl<Prev: Rec> Drop for PushDone<Prev> {
1000    fn drop(&mut self) {
1001        if let Some(prev) = &mut self.prev {
1002            if let Some(header_offset) = &self.header_offset {
1003                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1004            }
1005        }
1006    }
1007}
1008pub struct NotifGroup;
1009impl NotifGroup {
1010    pub const NONE: &str = "none";
1011    pub const NONE_CSTR: &CStr = c"none";
1012    pub const TLSHD: &str = "tlshd";
1013    pub const TLSHD_CSTR: &CStr = c"tlshd";
1014}
1015#[doc = "Handler retrieves next queued handshake request\nFlags: admin-perm\nRequest attributes:\n- [.push_handler_class()](PushAccept::push_handler_class)\n\nReply attributes:\n- [.get_sockfd()](IterableAccept::get_sockfd)\n- [.get_message_type()](IterableAccept::get_message_type)\n- [.get_timeout()](IterableAccept::get_timeout)\n- [.get_auth_mode()](IterableAccept::get_auth_mode)\n- [.get_peer_identity()](IterableAccept::get_peer_identity)\n- [.get_certificate()](IterableAccept::get_certificate)\n- [.get_peername()](IterableAccept::get_peername)\n- [.get_keyring()](IterableAccept::get_keyring)\n"]
1016#[derive(Debug)]
1017pub struct OpAcceptDo<'r> {
1018    request: Request<'r>,
1019}
1020impl<'r> OpAcceptDo<'r> {
1021    pub fn new(mut request: Request<'r>) -> Self {
1022        Self::write_header(request.buf_mut());
1023        Self { request: request }
1024    }
1025    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushAccept<&'buf mut Vec<u8>> {
1026        Self::write_header(buf);
1027        PushAccept::new(buf)
1028    }
1029    pub fn encode(&mut self) -> PushAccept<&mut Vec<u8>> {
1030        PushAccept::new(self.request.buf_mut())
1031    }
1032    pub fn into_encoder(self) -> PushAccept<RequestBuf<'r>> {
1033        PushAccept::new(self.request.buf)
1034    }
1035    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableAccept<'a> {
1036        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1037        IterableAccept::with_loc(attrs, buf.as_ptr() as usize)
1038    }
1039    fn write_header<Prev: Rec>(prev: &mut Prev) {
1040        let mut header = BuiltinNfgenmsg::new();
1041        header.cmd = 2u8;
1042        header.version = 1u8;
1043        prev.as_rec_mut().extend(header.as_slice());
1044    }
1045}
1046impl NetlinkRequest for OpAcceptDo<'_> {
1047    fn protocol(&self) -> Protocol {
1048        Protocol::Generic("handshake".as_bytes())
1049    }
1050    fn flags(&self) -> u16 {
1051        self.request.flags
1052    }
1053    fn payload(&self) -> &[u8] {
1054        self.request.buf()
1055    }
1056    type ReplyType<'buf> = IterableAccept<'buf>;
1057    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1058        Self::decode_request(buf)
1059    }
1060    fn lookup(
1061        buf: &[u8],
1062        offset: usize,
1063        missing_type: Option<u16>,
1064    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1065        Self::decode_request(buf).lookup_attr(offset, missing_type)
1066    }
1067}
1068#[doc = "Handler reports handshake completion\nRequest attributes:\n- [.push_status()](PushDone::push_status)\n- [.push_sockfd()](PushDone::push_sockfd)\n- [.push_remote_auth()](PushDone::push_remote_auth)\n"]
1069#[derive(Debug)]
1070pub struct OpDoneDo<'r> {
1071    request: Request<'r>,
1072}
1073impl<'r> OpDoneDo<'r> {
1074    pub fn new(mut request: Request<'r>) -> Self {
1075        Self::write_header(request.buf_mut());
1076        Self { request: request }
1077    }
1078    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushDone<&'buf mut Vec<u8>> {
1079        Self::write_header(buf);
1080        PushDone::new(buf)
1081    }
1082    pub fn encode(&mut self) -> PushDone<&mut Vec<u8>> {
1083        PushDone::new(self.request.buf_mut())
1084    }
1085    pub fn into_encoder(self) -> PushDone<RequestBuf<'r>> {
1086        PushDone::new(self.request.buf)
1087    }
1088    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableDone<'a> {
1089        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1090        IterableDone::with_loc(attrs, buf.as_ptr() as usize)
1091    }
1092    fn write_header<Prev: Rec>(prev: &mut Prev) {
1093        let mut header = BuiltinNfgenmsg::new();
1094        header.cmd = 3u8;
1095        header.version = 1u8;
1096        prev.as_rec_mut().extend(header.as_slice());
1097    }
1098}
1099impl NetlinkRequest for OpDoneDo<'_> {
1100    fn protocol(&self) -> Protocol {
1101        Protocol::Generic("handshake".as_bytes())
1102    }
1103    fn flags(&self) -> u16 {
1104        self.request.flags
1105    }
1106    fn payload(&self) -> &[u8] {
1107        self.request.buf()
1108    }
1109    type ReplyType<'buf> = IterableDone<'buf>;
1110    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1111        Self::decode_request(buf)
1112    }
1113    fn lookup(
1114        buf: &[u8],
1115        offset: usize,
1116        missing_type: Option<u16>,
1117    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1118        Self::decode_request(buf).lookup_attr(offset, missing_type)
1119    }
1120}
1121use crate::traits::LookupFn;
1122use crate::utils::RequestBuf;
1123#[derive(Debug)]
1124pub struct Request<'buf> {
1125    buf: RequestBuf<'buf>,
1126    flags: u16,
1127    writeback: Option<&'buf mut Option<RequestInfo>>,
1128}
1129#[allow(unused)]
1130#[derive(Debug, Clone)]
1131pub struct RequestInfo {
1132    protocol: Protocol,
1133    flags: u16,
1134    name: &'static str,
1135    lookup: LookupFn,
1136}
1137impl Request<'static> {
1138    pub fn new() -> Self {
1139        Self::new_from_buf(Vec::new())
1140    }
1141    pub fn new_from_buf(buf: Vec<u8>) -> Self {
1142        Self {
1143            flags: 0,
1144            buf: RequestBuf::Own(buf),
1145            writeback: None,
1146        }
1147    }
1148    pub fn into_buf(self) -> Vec<u8> {
1149        match self.buf {
1150            RequestBuf::Own(buf) => buf,
1151            _ => unreachable!(),
1152        }
1153    }
1154}
1155impl<'buf> Request<'buf> {
1156    pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
1157        buf.clear();
1158        Self::new_extend(buf)
1159    }
1160    pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
1161        Self {
1162            flags: 0,
1163            buf: RequestBuf::Ref(buf),
1164            writeback: None,
1165        }
1166    }
1167    fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
1168        let Some(writeback) = &mut self.writeback else {
1169            return;
1170        };
1171        **writeback = Some(RequestInfo {
1172            protocol,
1173            flags: self.flags,
1174            name,
1175            lookup,
1176        })
1177    }
1178    pub fn buf(&self) -> &Vec<u8> {
1179        self.buf.buf()
1180    }
1181    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1182        self.buf.buf_mut()
1183    }
1184    #[doc = "Set `NLM_F_CREATE` flag"]
1185    pub fn set_create(mut self) -> Self {
1186        self.flags |= consts::NLM_F_CREATE as u16;
1187        self
1188    }
1189    #[doc = "Set `NLM_F_EXCL` flag"]
1190    pub fn set_excl(mut self) -> Self {
1191        self.flags |= consts::NLM_F_EXCL as u16;
1192        self
1193    }
1194    #[doc = "Set `NLM_F_REPLACE` flag"]
1195    pub fn set_replace(mut self) -> Self {
1196        self.flags |= consts::NLM_F_REPLACE as u16;
1197        self
1198    }
1199    #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
1200    pub fn set_change(self) -> Self {
1201        self.set_create().set_replace()
1202    }
1203    #[doc = "Set `NLM_F_APPEND` flag"]
1204    pub fn set_append(mut self) -> Self {
1205        self.flags |= consts::NLM_F_APPEND as u16;
1206        self
1207    }
1208    #[doc = "Set `self.flags |= flags`"]
1209    pub fn set_flags(mut self, flags: u16) -> Self {
1210        self.flags |= flags;
1211        self
1212    }
1213    #[doc = "Set `self.flags ^= self.flags & flags`"]
1214    pub fn unset_flags(mut self, flags: u16) -> Self {
1215        self.flags ^= self.flags & flags;
1216        self
1217    }
1218    #[doc = "Handler retrieves next queued handshake request\nFlags: admin-perm\nRequest attributes:\n- [.push_handler_class()](PushAccept::push_handler_class)\n\nReply attributes:\n- [.get_sockfd()](IterableAccept::get_sockfd)\n- [.get_message_type()](IterableAccept::get_message_type)\n- [.get_timeout()](IterableAccept::get_timeout)\n- [.get_auth_mode()](IterableAccept::get_auth_mode)\n- [.get_peer_identity()](IterableAccept::get_peer_identity)\n- [.get_certificate()](IterableAccept::get_certificate)\n- [.get_peername()](IterableAccept::get_peername)\n- [.get_keyring()](IterableAccept::get_keyring)\n"]
1219    pub fn op_accept_do(self) -> OpAcceptDo<'buf> {
1220        let mut res = OpAcceptDo::new(self);
1221        res.request
1222            .do_writeback(res.protocol(), "op-accept-do", OpAcceptDo::lookup);
1223        res
1224    }
1225    #[doc = "Handler reports handshake completion\nRequest attributes:\n- [.push_status()](PushDone::push_status)\n- [.push_sockfd()](PushDone::push_sockfd)\n- [.push_remote_auth()](PushDone::push_remote_auth)\n"]
1226    pub fn op_done_do(self) -> OpDoneDo<'buf> {
1227        let mut res = OpDoneDo::new(self);
1228        res.request
1229            .do_writeback(res.protocol(), "op-done-do", OpDoneDo::lookup);
1230        res
1231    }
1232}
1233#[cfg(test)]
1234mod generated_tests {
1235    use super::*;
1236    #[test]
1237    fn tests() {
1238        let _ = IterableAccept::get_auth_mode;
1239        let _ = IterableAccept::get_certificate;
1240        let _ = IterableAccept::get_keyring;
1241        let _ = IterableAccept::get_message_type;
1242        let _ = IterableAccept::get_peer_identity;
1243        let _ = IterableAccept::get_peername;
1244        let _ = IterableAccept::get_sockfd;
1245        let _ = IterableAccept::get_timeout;
1246        let _ = PushAccept::<&mut Vec<u8>>::push_handler_class;
1247        let _ = PushDone::<&mut Vec<u8>>::push_remote_auth;
1248        let _ = PushDone::<&mut Vec<u8>>::push_sockfd;
1249        let _ = PushDone::<&mut Vec<u8>>::push_status;
1250    }
1251}