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}