Skip to main content

netlink_bindings/handshake/
mod.rs

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