1#![doc = "SUNRPC cache upcall support over generic netlink.\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 = "sunrpc";
17pub const PROTONAME_CSTR: &CStr = c"sunrpc";
18#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
19#[derive(Debug, Clone, Copy)]
20pub enum CacheType {
21 IpMap = 1 << 0,
22 UnixGid = 1 << 1,
23}
24impl CacheType {
25 pub fn from_value(value: u64) -> Option<Self> {
26 Some(match value {
27 n if n == 1 << 0 => Self::IpMap,
28 n if n == 1 << 1 => Self::UnixGid,
29 _ => return None,
30 })
31 }
32}
33#[derive(Clone)]
34pub enum CacheNotify {
35 #[doc = "Associated type: [`CacheType`] (enum)"]
36 CacheType(u32),
37}
38impl<'a> IterableCacheNotify<'a> {
39 #[doc = "Associated type: [`CacheType`] (enum)"]
40 pub fn get_cache_type(&self) -> Result<u32, ErrorContext> {
41 let mut iter = self.clone();
42 iter.pos = 0;
43 for attr in iter {
44 if let Ok(CacheNotify::CacheType(val)) = attr {
45 return Ok(val);
46 }
47 }
48 Err(ErrorContext::new_missing(
49 "CacheNotify",
50 "CacheType",
51 self.orig_loc,
52 self.buf.as_ptr() as usize,
53 ))
54 }
55}
56impl CacheNotify {
57 pub fn new<'a>(buf: &'a [u8]) -> IterableCacheNotify<'a> {
58 IterableCacheNotify::with_loc(buf, buf.as_ptr() as usize)
59 }
60 fn attr_from_type(r#type: u16) -> Option<&'static str> {
61 let res = match r#type {
62 1u16 => "CacheType",
63 _ => return None,
64 };
65 Some(res)
66 }
67}
68#[derive(Clone, Copy, Default)]
69pub struct IterableCacheNotify<'a> {
70 buf: &'a [u8],
71 pos: usize,
72 orig_loc: usize,
73}
74impl<'a> IterableCacheNotify<'a> {
75 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
76 Self {
77 buf,
78 pos: 0,
79 orig_loc,
80 }
81 }
82 pub fn get_buf(&self) -> &'a [u8] {
83 self.buf
84 }
85}
86impl<'a> Iterator for IterableCacheNotify<'a> {
87 type Item = Result<CacheNotify, ErrorContext>;
88 fn next(&mut self) -> Option<Self::Item> {
89 let mut pos;
90 let mut r#type;
91 loop {
92 pos = self.pos;
93 r#type = None;
94 if self.buf.len() == self.pos {
95 return None;
96 }
97 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
98 self.pos = self.buf.len();
99 break;
100 };
101 r#type = Some(header.r#type);
102 let res = match header.r#type {
103 1u16 => CacheNotify::CacheType({
104 let res = parse_u32(next);
105 let Some(val) = res else { break };
106 val
107 }),
108 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
109 n => continue,
110 };
111 return Some(Ok(res));
112 }
113 Some(Err(ErrorContext::new(
114 "CacheNotify",
115 r#type.and_then(|t| CacheNotify::attr_from_type(t)),
116 self.orig_loc,
117 self.buf.as_ptr().wrapping_add(pos) as usize,
118 )))
119 }
120}
121impl std::fmt::Debug for IterableCacheNotify<'_> {
122 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 let mut fmt = f.debug_struct("CacheNotify");
124 for attr in self.clone() {
125 let attr = match attr {
126 Ok(a) => a,
127 Err(err) => {
128 fmt.finish()?;
129 f.write_str("Err(")?;
130 err.fmt(f)?;
131 return f.write_str(")");
132 }
133 };
134 match attr {
135 CacheNotify::CacheType(val) => {
136 fmt.field("CacheType", &FormatFlags(val.into(), CacheType::from_value))
137 }
138 };
139 }
140 fmt.finish()
141 }
142}
143impl IterableCacheNotify<'_> {
144 pub fn lookup_attr(
145 &self,
146 offset: usize,
147 missing_type: Option<u16>,
148 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
149 let mut stack = Vec::new();
150 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
151 if missing_type.is_some() && cur == offset {
152 stack.push(("CacheNotify", offset));
153 return (
154 stack,
155 missing_type.and_then(|t| CacheNotify::attr_from_type(t)),
156 );
157 }
158 if cur > offset || cur + self.buf.len() < offset {
159 return (stack, None);
160 }
161 let mut attrs = self.clone();
162 let mut last_off = cur + attrs.pos;
163 while let Some(attr) = attrs.next() {
164 let Ok(attr) = attr else { break };
165 match attr {
166 CacheNotify::CacheType(val) => {
167 if last_off == offset {
168 stack.push(("CacheType", last_off));
169 break;
170 }
171 }
172 _ => {}
173 };
174 last_off = cur + attrs.pos;
175 }
176 if !stack.is_empty() {
177 stack.push(("CacheNotify", cur));
178 }
179 (stack, None)
180 }
181}
182#[derive(Clone)]
183pub enum IpMap<'a> {
184 Seqno(u64),
185 Class(&'a CStr),
186 Addr(&'a CStr),
187 Domain(&'a CStr),
188 Negative(()),
189 Expiry(u64),
190}
191impl<'a> IterableIpMap<'a> {
192 pub fn get_seqno(&self) -> Result<u64, ErrorContext> {
193 let mut iter = self.clone();
194 iter.pos = 0;
195 for attr in iter {
196 if let Ok(IpMap::Seqno(val)) = attr {
197 return Ok(val);
198 }
199 }
200 Err(ErrorContext::new_missing(
201 "IpMap",
202 "Seqno",
203 self.orig_loc,
204 self.buf.as_ptr() as usize,
205 ))
206 }
207 pub fn get_class(&self) -> Result<&'a CStr, ErrorContext> {
208 let mut iter = self.clone();
209 iter.pos = 0;
210 for attr in iter {
211 if let Ok(IpMap::Class(val)) = attr {
212 return Ok(val);
213 }
214 }
215 Err(ErrorContext::new_missing(
216 "IpMap",
217 "Class",
218 self.orig_loc,
219 self.buf.as_ptr() as usize,
220 ))
221 }
222 pub fn get_addr(&self) -> Result<&'a CStr, ErrorContext> {
223 let mut iter = self.clone();
224 iter.pos = 0;
225 for attr in iter {
226 if let Ok(IpMap::Addr(val)) = attr {
227 return Ok(val);
228 }
229 }
230 Err(ErrorContext::new_missing(
231 "IpMap",
232 "Addr",
233 self.orig_loc,
234 self.buf.as_ptr() as usize,
235 ))
236 }
237 pub fn get_domain(&self) -> Result<&'a CStr, ErrorContext> {
238 let mut iter = self.clone();
239 iter.pos = 0;
240 for attr in iter {
241 if let Ok(IpMap::Domain(val)) = attr {
242 return Ok(val);
243 }
244 }
245 Err(ErrorContext::new_missing(
246 "IpMap",
247 "Domain",
248 self.orig_loc,
249 self.buf.as_ptr() as usize,
250 ))
251 }
252 pub fn get_negative(&self) -> Result<(), ErrorContext> {
253 let mut iter = self.clone();
254 iter.pos = 0;
255 for attr in iter {
256 if let Ok(IpMap::Negative(val)) = attr {
257 return Ok(val);
258 }
259 }
260 Err(ErrorContext::new_missing(
261 "IpMap",
262 "Negative",
263 self.orig_loc,
264 self.buf.as_ptr() as usize,
265 ))
266 }
267 pub fn get_expiry(&self) -> Result<u64, ErrorContext> {
268 let mut iter = self.clone();
269 iter.pos = 0;
270 for attr in iter {
271 if let Ok(IpMap::Expiry(val)) = attr {
272 return Ok(val);
273 }
274 }
275 Err(ErrorContext::new_missing(
276 "IpMap",
277 "Expiry",
278 self.orig_loc,
279 self.buf.as_ptr() as usize,
280 ))
281 }
282}
283impl IpMap<'_> {
284 pub fn new<'a>(buf: &'a [u8]) -> IterableIpMap<'a> {
285 IterableIpMap::with_loc(buf, buf.as_ptr() as usize)
286 }
287 fn attr_from_type(r#type: u16) -> Option<&'static str> {
288 let res = match r#type {
289 1u16 => "Seqno",
290 2u16 => "Class",
291 3u16 => "Addr",
292 4u16 => "Domain",
293 5u16 => "Negative",
294 6u16 => "Expiry",
295 _ => return None,
296 };
297 Some(res)
298 }
299}
300#[derive(Clone, Copy, Default)]
301pub struct IterableIpMap<'a> {
302 buf: &'a [u8],
303 pos: usize,
304 orig_loc: usize,
305}
306impl<'a> IterableIpMap<'a> {
307 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
308 Self {
309 buf,
310 pos: 0,
311 orig_loc,
312 }
313 }
314 pub fn get_buf(&self) -> &'a [u8] {
315 self.buf
316 }
317}
318impl<'a> Iterator for IterableIpMap<'a> {
319 type Item = Result<IpMap<'a>, ErrorContext>;
320 fn next(&mut self) -> Option<Self::Item> {
321 let mut pos;
322 let mut r#type;
323 loop {
324 pos = self.pos;
325 r#type = None;
326 if self.buf.len() == self.pos {
327 return None;
328 }
329 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
330 self.pos = self.buf.len();
331 break;
332 };
333 r#type = Some(header.r#type);
334 let res = match header.r#type {
335 1u16 => IpMap::Seqno({
336 let res = parse_u64(next);
337 let Some(val) = res else { break };
338 val
339 }),
340 2u16 => IpMap::Class({
341 let res = CStr::from_bytes_with_nul(next).ok();
342 let Some(val) = res else { break };
343 val
344 }),
345 3u16 => IpMap::Addr({
346 let res = CStr::from_bytes_with_nul(next).ok();
347 let Some(val) = res else { break };
348 val
349 }),
350 4u16 => IpMap::Domain({
351 let res = CStr::from_bytes_with_nul(next).ok();
352 let Some(val) = res else { break };
353 val
354 }),
355 5u16 => IpMap::Negative(()),
356 6u16 => IpMap::Expiry({
357 let res = parse_u64(next);
358 let Some(val) = res else { break };
359 val
360 }),
361 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
362 n => continue,
363 };
364 return Some(Ok(res));
365 }
366 Some(Err(ErrorContext::new(
367 "IpMap",
368 r#type.and_then(|t| IpMap::attr_from_type(t)),
369 self.orig_loc,
370 self.buf.as_ptr().wrapping_add(pos) as usize,
371 )))
372 }
373}
374impl<'a> std::fmt::Debug for IterableIpMap<'_> {
375 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
376 let mut fmt = f.debug_struct("IpMap");
377 for attr in self.clone() {
378 let attr = match attr {
379 Ok(a) => a,
380 Err(err) => {
381 fmt.finish()?;
382 f.write_str("Err(")?;
383 err.fmt(f)?;
384 return f.write_str(")");
385 }
386 };
387 match attr {
388 IpMap::Seqno(val) => fmt.field("Seqno", &val),
389 IpMap::Class(val) => fmt.field("Class", &val),
390 IpMap::Addr(val) => fmt.field("Addr", &val),
391 IpMap::Domain(val) => fmt.field("Domain", &val),
392 IpMap::Negative(val) => fmt.field("Negative", &val),
393 IpMap::Expiry(val) => fmt.field("Expiry", &val),
394 };
395 }
396 fmt.finish()
397 }
398}
399impl IterableIpMap<'_> {
400 pub fn lookup_attr(
401 &self,
402 offset: usize,
403 missing_type: Option<u16>,
404 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
405 let mut stack = Vec::new();
406 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
407 if missing_type.is_some() && cur == offset {
408 stack.push(("IpMap", offset));
409 return (stack, missing_type.and_then(|t| IpMap::attr_from_type(t)));
410 }
411 if cur > offset || cur + self.buf.len() < offset {
412 return (stack, None);
413 }
414 let mut attrs = self.clone();
415 let mut last_off = cur + attrs.pos;
416 while let Some(attr) = attrs.next() {
417 let Ok(attr) = attr else { break };
418 match attr {
419 IpMap::Seqno(val) => {
420 if last_off == offset {
421 stack.push(("Seqno", last_off));
422 break;
423 }
424 }
425 IpMap::Class(val) => {
426 if last_off == offset {
427 stack.push(("Class", last_off));
428 break;
429 }
430 }
431 IpMap::Addr(val) => {
432 if last_off == offset {
433 stack.push(("Addr", last_off));
434 break;
435 }
436 }
437 IpMap::Domain(val) => {
438 if last_off == offset {
439 stack.push(("Domain", last_off));
440 break;
441 }
442 }
443 IpMap::Negative(val) => {
444 if last_off == offset {
445 stack.push(("Negative", last_off));
446 break;
447 }
448 }
449 IpMap::Expiry(val) => {
450 if last_off == offset {
451 stack.push(("Expiry", last_off));
452 break;
453 }
454 }
455 _ => {}
456 };
457 last_off = cur + attrs.pos;
458 }
459 if !stack.is_empty() {
460 stack.push(("IpMap", cur));
461 }
462 (stack, None)
463 }
464}
465#[derive(Clone)]
466pub enum IpMapReqs<'a> {
467 #[doc = "Attribute may repeat multiple times (treat it as array)"]
468 Requests(IterableIpMap<'a>),
469}
470impl<'a> IterableIpMapReqs<'a> {
471 #[doc = "Attribute may repeat multiple times (treat it as array)"]
472 pub fn get_requests(&self) -> MultiAttrIterable<Self, IpMapReqs<'a>, IterableIpMap<'a>> {
473 MultiAttrIterable::new(self.clone(), |variant| {
474 if let IpMapReqs::Requests(val) = variant {
475 Some(val)
476 } else {
477 None
478 }
479 })
480 }
481}
482impl IpMapReqs<'_> {
483 pub fn new<'a>(buf: &'a [u8]) -> IterableIpMapReqs<'a> {
484 IterableIpMapReqs::with_loc(buf, buf.as_ptr() as usize)
485 }
486 fn attr_from_type(r#type: u16) -> Option<&'static str> {
487 let res = match r#type {
488 1u16 => "Requests",
489 _ => return None,
490 };
491 Some(res)
492 }
493}
494#[derive(Clone, Copy, Default)]
495pub struct IterableIpMapReqs<'a> {
496 buf: &'a [u8],
497 pos: usize,
498 orig_loc: usize,
499}
500impl<'a> IterableIpMapReqs<'a> {
501 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
502 Self {
503 buf,
504 pos: 0,
505 orig_loc,
506 }
507 }
508 pub fn get_buf(&self) -> &'a [u8] {
509 self.buf
510 }
511}
512impl<'a> Iterator for IterableIpMapReqs<'a> {
513 type Item = Result<IpMapReqs<'a>, ErrorContext>;
514 fn next(&mut self) -> Option<Self::Item> {
515 let mut pos;
516 let mut r#type;
517 loop {
518 pos = self.pos;
519 r#type = None;
520 if self.buf.len() == self.pos {
521 return None;
522 }
523 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
524 self.pos = self.buf.len();
525 break;
526 };
527 r#type = Some(header.r#type);
528 let res = match header.r#type {
529 1u16 => IpMapReqs::Requests({
530 let res = Some(IterableIpMap::with_loc(next, self.orig_loc));
531 let Some(val) = res else { break };
532 val
533 }),
534 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
535 n => continue,
536 };
537 return Some(Ok(res));
538 }
539 Some(Err(ErrorContext::new(
540 "IpMapReqs",
541 r#type.and_then(|t| IpMapReqs::attr_from_type(t)),
542 self.orig_loc,
543 self.buf.as_ptr().wrapping_add(pos) as usize,
544 )))
545 }
546}
547impl<'a> std::fmt::Debug for IterableIpMapReqs<'_> {
548 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
549 let mut fmt = f.debug_struct("IpMapReqs");
550 for attr in self.clone() {
551 let attr = match attr {
552 Ok(a) => a,
553 Err(err) => {
554 fmt.finish()?;
555 f.write_str("Err(")?;
556 err.fmt(f)?;
557 return f.write_str(")");
558 }
559 };
560 match attr {
561 IpMapReqs::Requests(val) => fmt.field("Requests", &val),
562 };
563 }
564 fmt.finish()
565 }
566}
567impl IterableIpMapReqs<'_> {
568 pub fn lookup_attr(
569 &self,
570 offset: usize,
571 missing_type: Option<u16>,
572 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
573 let mut stack = Vec::new();
574 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
575 if missing_type.is_some() && cur == offset {
576 stack.push(("IpMapReqs", offset));
577 return (
578 stack,
579 missing_type.and_then(|t| IpMapReqs::attr_from_type(t)),
580 );
581 }
582 if cur > offset || cur + self.buf.len() < offset {
583 return (stack, None);
584 }
585 let mut attrs = self.clone();
586 let mut last_off = cur + attrs.pos;
587 let mut missing = None;
588 while let Some(attr) = attrs.next() {
589 let Ok(attr) = attr else { break };
590 match attr {
591 IpMapReqs::Requests(val) => {
592 (stack, missing) = val.lookup_attr(offset, missing_type);
593 if !stack.is_empty() {
594 break;
595 }
596 }
597 _ => {}
598 };
599 last_off = cur + attrs.pos;
600 }
601 if !stack.is_empty() {
602 stack.push(("IpMapReqs", cur));
603 }
604 (stack, missing)
605 }
606}
607#[derive(Clone)]
608pub enum UnixGid {
609 Seqno(u64),
610 Uid(u32),
611 #[doc = "Attribute may repeat multiple times (treat it as array)"]
612 Gids(u32),
613 Negative(()),
614 Expiry(u64),
615}
616impl<'a> IterableUnixGid<'a> {
617 pub fn get_seqno(&self) -> Result<u64, ErrorContext> {
618 let mut iter = self.clone();
619 iter.pos = 0;
620 for attr in iter {
621 if let Ok(UnixGid::Seqno(val)) = attr {
622 return Ok(val);
623 }
624 }
625 Err(ErrorContext::new_missing(
626 "UnixGid",
627 "Seqno",
628 self.orig_loc,
629 self.buf.as_ptr() as usize,
630 ))
631 }
632 pub fn get_uid(&self) -> Result<u32, ErrorContext> {
633 let mut iter = self.clone();
634 iter.pos = 0;
635 for attr in iter {
636 if let Ok(UnixGid::Uid(val)) = attr {
637 return Ok(val);
638 }
639 }
640 Err(ErrorContext::new_missing(
641 "UnixGid",
642 "Uid",
643 self.orig_loc,
644 self.buf.as_ptr() as usize,
645 ))
646 }
647 #[doc = "Attribute may repeat multiple times (treat it as array)"]
648 pub fn get_gids(&self) -> MultiAttrIterable<Self, UnixGid, u32> {
649 MultiAttrIterable::new(self.clone(), |variant| {
650 if let UnixGid::Gids(val) = variant {
651 Some(val)
652 } else {
653 None
654 }
655 })
656 }
657 pub fn get_negative(&self) -> Result<(), ErrorContext> {
658 let mut iter = self.clone();
659 iter.pos = 0;
660 for attr in iter {
661 if let Ok(UnixGid::Negative(val)) = attr {
662 return Ok(val);
663 }
664 }
665 Err(ErrorContext::new_missing(
666 "UnixGid",
667 "Negative",
668 self.orig_loc,
669 self.buf.as_ptr() as usize,
670 ))
671 }
672 pub fn get_expiry(&self) -> Result<u64, ErrorContext> {
673 let mut iter = self.clone();
674 iter.pos = 0;
675 for attr in iter {
676 if let Ok(UnixGid::Expiry(val)) = attr {
677 return Ok(val);
678 }
679 }
680 Err(ErrorContext::new_missing(
681 "UnixGid",
682 "Expiry",
683 self.orig_loc,
684 self.buf.as_ptr() as usize,
685 ))
686 }
687}
688impl UnixGid {
689 pub fn new<'a>(buf: &'a [u8]) -> IterableUnixGid<'a> {
690 IterableUnixGid::with_loc(buf, buf.as_ptr() as usize)
691 }
692 fn attr_from_type(r#type: u16) -> Option<&'static str> {
693 let res = match r#type {
694 1u16 => "Seqno",
695 2u16 => "Uid",
696 3u16 => "Gids",
697 4u16 => "Negative",
698 5u16 => "Expiry",
699 _ => return None,
700 };
701 Some(res)
702 }
703}
704#[derive(Clone, Copy, Default)]
705pub struct IterableUnixGid<'a> {
706 buf: &'a [u8],
707 pos: usize,
708 orig_loc: usize,
709}
710impl<'a> IterableUnixGid<'a> {
711 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
712 Self {
713 buf,
714 pos: 0,
715 orig_loc,
716 }
717 }
718 pub fn get_buf(&self) -> &'a [u8] {
719 self.buf
720 }
721}
722impl<'a> Iterator for IterableUnixGid<'a> {
723 type Item = Result<UnixGid, ErrorContext>;
724 fn next(&mut self) -> Option<Self::Item> {
725 let mut pos;
726 let mut r#type;
727 loop {
728 pos = self.pos;
729 r#type = None;
730 if self.buf.len() == self.pos {
731 return None;
732 }
733 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
734 self.pos = self.buf.len();
735 break;
736 };
737 r#type = Some(header.r#type);
738 let res = match header.r#type {
739 1u16 => UnixGid::Seqno({
740 let res = parse_u64(next);
741 let Some(val) = res else { break };
742 val
743 }),
744 2u16 => UnixGid::Uid({
745 let res = parse_u32(next);
746 let Some(val) = res else { break };
747 val
748 }),
749 3u16 => UnixGid::Gids({
750 let res = parse_u32(next);
751 let Some(val) = res else { break };
752 val
753 }),
754 4u16 => UnixGid::Negative(()),
755 5u16 => UnixGid::Expiry({
756 let res = parse_u64(next);
757 let Some(val) = res else { break };
758 val
759 }),
760 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
761 n => continue,
762 };
763 return Some(Ok(res));
764 }
765 Some(Err(ErrorContext::new(
766 "UnixGid",
767 r#type.and_then(|t| UnixGid::attr_from_type(t)),
768 self.orig_loc,
769 self.buf.as_ptr().wrapping_add(pos) as usize,
770 )))
771 }
772}
773impl std::fmt::Debug for IterableUnixGid<'_> {
774 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
775 let mut fmt = f.debug_struct("UnixGid");
776 for attr in self.clone() {
777 let attr = match attr {
778 Ok(a) => a,
779 Err(err) => {
780 fmt.finish()?;
781 f.write_str("Err(")?;
782 err.fmt(f)?;
783 return f.write_str(")");
784 }
785 };
786 match attr {
787 UnixGid::Seqno(val) => fmt.field("Seqno", &val),
788 UnixGid::Uid(val) => fmt.field("Uid", &val),
789 UnixGid::Gids(val) => fmt.field("Gids", &val),
790 UnixGid::Negative(val) => fmt.field("Negative", &val),
791 UnixGid::Expiry(val) => fmt.field("Expiry", &val),
792 };
793 }
794 fmt.finish()
795 }
796}
797impl IterableUnixGid<'_> {
798 pub fn lookup_attr(
799 &self,
800 offset: usize,
801 missing_type: Option<u16>,
802 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
803 let mut stack = Vec::new();
804 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
805 if missing_type.is_some() && cur == offset {
806 stack.push(("UnixGid", offset));
807 return (stack, missing_type.and_then(|t| UnixGid::attr_from_type(t)));
808 }
809 if cur > offset || cur + self.buf.len() < offset {
810 return (stack, None);
811 }
812 let mut attrs = self.clone();
813 let mut last_off = cur + attrs.pos;
814 while let Some(attr) = attrs.next() {
815 let Ok(attr) = attr else { break };
816 match attr {
817 UnixGid::Seqno(val) => {
818 if last_off == offset {
819 stack.push(("Seqno", last_off));
820 break;
821 }
822 }
823 UnixGid::Uid(val) => {
824 if last_off == offset {
825 stack.push(("Uid", last_off));
826 break;
827 }
828 }
829 UnixGid::Gids(val) => {
830 if last_off == offset {
831 stack.push(("Gids", last_off));
832 break;
833 }
834 }
835 UnixGid::Negative(val) => {
836 if last_off == offset {
837 stack.push(("Negative", last_off));
838 break;
839 }
840 }
841 UnixGid::Expiry(val) => {
842 if last_off == offset {
843 stack.push(("Expiry", last_off));
844 break;
845 }
846 }
847 _ => {}
848 };
849 last_off = cur + attrs.pos;
850 }
851 if !stack.is_empty() {
852 stack.push(("UnixGid", cur));
853 }
854 (stack, None)
855 }
856}
857#[derive(Clone)]
858pub enum UnixGidReqs<'a> {
859 #[doc = "Attribute may repeat multiple times (treat it as array)"]
860 Requests(IterableUnixGid<'a>),
861}
862impl<'a> IterableUnixGidReqs<'a> {
863 #[doc = "Attribute may repeat multiple times (treat it as array)"]
864 pub fn get_requests(&self) -> MultiAttrIterable<Self, UnixGidReqs<'a>, IterableUnixGid<'a>> {
865 MultiAttrIterable::new(self.clone(), |variant| {
866 if let UnixGidReqs::Requests(val) = variant {
867 Some(val)
868 } else {
869 None
870 }
871 })
872 }
873}
874impl UnixGidReqs<'_> {
875 pub fn new<'a>(buf: &'a [u8]) -> IterableUnixGidReqs<'a> {
876 IterableUnixGidReqs::with_loc(buf, buf.as_ptr() as usize)
877 }
878 fn attr_from_type(r#type: u16) -> Option<&'static str> {
879 let res = match r#type {
880 1u16 => "Requests",
881 _ => return None,
882 };
883 Some(res)
884 }
885}
886#[derive(Clone, Copy, Default)]
887pub struct IterableUnixGidReqs<'a> {
888 buf: &'a [u8],
889 pos: usize,
890 orig_loc: usize,
891}
892impl<'a> IterableUnixGidReqs<'a> {
893 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
894 Self {
895 buf,
896 pos: 0,
897 orig_loc,
898 }
899 }
900 pub fn get_buf(&self) -> &'a [u8] {
901 self.buf
902 }
903}
904impl<'a> Iterator for IterableUnixGidReqs<'a> {
905 type Item = Result<UnixGidReqs<'a>, ErrorContext>;
906 fn next(&mut self) -> Option<Self::Item> {
907 let mut pos;
908 let mut r#type;
909 loop {
910 pos = self.pos;
911 r#type = None;
912 if self.buf.len() == self.pos {
913 return None;
914 }
915 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
916 self.pos = self.buf.len();
917 break;
918 };
919 r#type = Some(header.r#type);
920 let res = match header.r#type {
921 1u16 => UnixGidReqs::Requests({
922 let res = Some(IterableUnixGid::with_loc(next, self.orig_loc));
923 let Some(val) = res else { break };
924 val
925 }),
926 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
927 n => continue,
928 };
929 return Some(Ok(res));
930 }
931 Some(Err(ErrorContext::new(
932 "UnixGidReqs",
933 r#type.and_then(|t| UnixGidReqs::attr_from_type(t)),
934 self.orig_loc,
935 self.buf.as_ptr().wrapping_add(pos) as usize,
936 )))
937 }
938}
939impl<'a> std::fmt::Debug for IterableUnixGidReqs<'_> {
940 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
941 let mut fmt = f.debug_struct("UnixGidReqs");
942 for attr in self.clone() {
943 let attr = match attr {
944 Ok(a) => a,
945 Err(err) => {
946 fmt.finish()?;
947 f.write_str("Err(")?;
948 err.fmt(f)?;
949 return f.write_str(")");
950 }
951 };
952 match attr {
953 UnixGidReqs::Requests(val) => fmt.field("Requests", &val),
954 };
955 }
956 fmt.finish()
957 }
958}
959impl IterableUnixGidReqs<'_> {
960 pub fn lookup_attr(
961 &self,
962 offset: usize,
963 missing_type: Option<u16>,
964 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
965 let mut stack = Vec::new();
966 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
967 if missing_type.is_some() && cur == offset {
968 stack.push(("UnixGidReqs", offset));
969 return (
970 stack,
971 missing_type.and_then(|t| UnixGidReqs::attr_from_type(t)),
972 );
973 }
974 if cur > offset || cur + self.buf.len() < offset {
975 return (stack, None);
976 }
977 let mut attrs = self.clone();
978 let mut last_off = cur + attrs.pos;
979 let mut missing = None;
980 while let Some(attr) = attrs.next() {
981 let Ok(attr) = attr else { break };
982 match attr {
983 UnixGidReqs::Requests(val) => {
984 (stack, missing) = val.lookup_attr(offset, missing_type);
985 if !stack.is_empty() {
986 break;
987 }
988 }
989 _ => {}
990 };
991 last_off = cur + attrs.pos;
992 }
993 if !stack.is_empty() {
994 stack.push(("UnixGidReqs", cur));
995 }
996 (stack, missing)
997 }
998}
999#[derive(Clone)]
1000pub enum CacheFlush {
1001 #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
1002 Mask(u32),
1003}
1004impl<'a> IterableCacheFlush<'a> {
1005 #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
1006 pub fn get_mask(&self) -> Result<u32, ErrorContext> {
1007 let mut iter = self.clone();
1008 iter.pos = 0;
1009 for attr in iter {
1010 if let Ok(CacheFlush::Mask(val)) = attr {
1011 return Ok(val);
1012 }
1013 }
1014 Err(ErrorContext::new_missing(
1015 "CacheFlush",
1016 "Mask",
1017 self.orig_loc,
1018 self.buf.as_ptr() as usize,
1019 ))
1020 }
1021}
1022impl CacheFlush {
1023 pub fn new<'a>(buf: &'a [u8]) -> IterableCacheFlush<'a> {
1024 IterableCacheFlush::with_loc(buf, buf.as_ptr() as usize)
1025 }
1026 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1027 let res = match r#type {
1028 1u16 => "Mask",
1029 _ => return None,
1030 };
1031 Some(res)
1032 }
1033}
1034#[derive(Clone, Copy, Default)]
1035pub struct IterableCacheFlush<'a> {
1036 buf: &'a [u8],
1037 pos: usize,
1038 orig_loc: usize,
1039}
1040impl<'a> IterableCacheFlush<'a> {
1041 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1042 Self {
1043 buf,
1044 pos: 0,
1045 orig_loc,
1046 }
1047 }
1048 pub fn get_buf(&self) -> &'a [u8] {
1049 self.buf
1050 }
1051}
1052impl<'a> Iterator for IterableCacheFlush<'a> {
1053 type Item = Result<CacheFlush, ErrorContext>;
1054 fn next(&mut self) -> Option<Self::Item> {
1055 let mut pos;
1056 let mut r#type;
1057 loop {
1058 pos = self.pos;
1059 r#type = None;
1060 if self.buf.len() == self.pos {
1061 return None;
1062 }
1063 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1064 self.pos = self.buf.len();
1065 break;
1066 };
1067 r#type = Some(header.r#type);
1068 let res = match header.r#type {
1069 1u16 => CacheFlush::Mask({
1070 let res = parse_u32(next);
1071 let Some(val) = res else { break };
1072 val
1073 }),
1074 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1075 n => continue,
1076 };
1077 return Some(Ok(res));
1078 }
1079 Some(Err(ErrorContext::new(
1080 "CacheFlush",
1081 r#type.and_then(|t| CacheFlush::attr_from_type(t)),
1082 self.orig_loc,
1083 self.buf.as_ptr().wrapping_add(pos) as usize,
1084 )))
1085 }
1086}
1087impl std::fmt::Debug for IterableCacheFlush<'_> {
1088 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1089 let mut fmt = f.debug_struct("CacheFlush");
1090 for attr in self.clone() {
1091 let attr = match attr {
1092 Ok(a) => a,
1093 Err(err) => {
1094 fmt.finish()?;
1095 f.write_str("Err(")?;
1096 err.fmt(f)?;
1097 return f.write_str(")");
1098 }
1099 };
1100 match attr {
1101 CacheFlush::Mask(val) => {
1102 fmt.field("Mask", &FormatFlags(val.into(), CacheType::from_value))
1103 }
1104 };
1105 }
1106 fmt.finish()
1107 }
1108}
1109impl IterableCacheFlush<'_> {
1110 pub fn lookup_attr(
1111 &self,
1112 offset: usize,
1113 missing_type: Option<u16>,
1114 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1115 let mut stack = Vec::new();
1116 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1117 if missing_type.is_some() && cur == offset {
1118 stack.push(("CacheFlush", offset));
1119 return (
1120 stack,
1121 missing_type.and_then(|t| CacheFlush::attr_from_type(t)),
1122 );
1123 }
1124 if cur > offset || cur + self.buf.len() < offset {
1125 return (stack, None);
1126 }
1127 let mut attrs = self.clone();
1128 let mut last_off = cur + attrs.pos;
1129 while let Some(attr) = attrs.next() {
1130 let Ok(attr) = attr else { break };
1131 match attr {
1132 CacheFlush::Mask(val) => {
1133 if last_off == offset {
1134 stack.push(("Mask", last_off));
1135 break;
1136 }
1137 }
1138 _ => {}
1139 };
1140 last_off = cur + attrs.pos;
1141 }
1142 if !stack.is_empty() {
1143 stack.push(("CacheFlush", cur));
1144 }
1145 (stack, None)
1146 }
1147}
1148pub struct PushCacheNotify<Prev: Pusher> {
1149 pub(crate) prev: Option<Prev>,
1150 pub(crate) header_offset: Option<usize>,
1151}
1152impl<Prev: Pusher> Pusher for PushCacheNotify<Prev> {
1153 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1154 self.prev.as_mut().unwrap().as_vec_mut()
1155 }
1156 fn as_vec(&self) -> &Vec<u8> {
1157 self.prev.as_ref().unwrap().as_vec()
1158 }
1159}
1160impl<Prev: Pusher> PushCacheNotify<Prev> {
1161 pub fn new(prev: Prev) -> Self {
1162 Self {
1163 prev: Some(prev),
1164 header_offset: None,
1165 }
1166 }
1167 pub fn end_nested(mut self) -> Prev {
1168 let mut prev = self.prev.take().unwrap();
1169 if let Some(header_offset) = &self.header_offset {
1170 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1171 }
1172 prev
1173 }
1174 #[doc = "Associated type: [`CacheType`] (enum)"]
1175 pub fn push_cache_type(mut self, value: u32) -> Self {
1176 push_header(self.as_vec_mut(), 1u16, 4 as u16);
1177 self.as_vec_mut().extend(value.to_ne_bytes());
1178 self
1179 }
1180}
1181impl<Prev: Pusher> Drop for PushCacheNotify<Prev> {
1182 fn drop(&mut self) {
1183 if let Some(prev) = &mut self.prev {
1184 if let Some(header_offset) = &self.header_offset {
1185 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1186 }
1187 }
1188 }
1189}
1190pub struct PushIpMap<Prev: Pusher> {
1191 pub(crate) prev: Option<Prev>,
1192 pub(crate) header_offset: Option<usize>,
1193}
1194impl<Prev: Pusher> Pusher for PushIpMap<Prev> {
1195 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1196 self.prev.as_mut().unwrap().as_vec_mut()
1197 }
1198 fn as_vec(&self) -> &Vec<u8> {
1199 self.prev.as_ref().unwrap().as_vec()
1200 }
1201}
1202impl<Prev: Pusher> PushIpMap<Prev> {
1203 pub fn new(prev: Prev) -> Self {
1204 Self {
1205 prev: Some(prev),
1206 header_offset: None,
1207 }
1208 }
1209 pub fn end_nested(mut self) -> Prev {
1210 let mut prev = self.prev.take().unwrap();
1211 if let Some(header_offset) = &self.header_offset {
1212 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1213 }
1214 prev
1215 }
1216 pub fn push_seqno(mut self, value: u64) -> Self {
1217 push_header(self.as_vec_mut(), 1u16, 8 as u16);
1218 self.as_vec_mut().extend(value.to_ne_bytes());
1219 self
1220 }
1221 pub fn push_class(mut self, value: &CStr) -> Self {
1222 push_header(
1223 self.as_vec_mut(),
1224 2u16,
1225 value.to_bytes_with_nul().len() as u16,
1226 );
1227 self.as_vec_mut().extend(value.to_bytes_with_nul());
1228 self
1229 }
1230 pub fn push_class_bytes(mut self, value: &[u8]) -> Self {
1231 push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
1232 self.as_vec_mut().extend(value);
1233 self.as_vec_mut().push(0);
1234 self
1235 }
1236 pub fn push_addr(mut self, value: &CStr) -> Self {
1237 push_header(
1238 self.as_vec_mut(),
1239 3u16,
1240 value.to_bytes_with_nul().len() as u16,
1241 );
1242 self.as_vec_mut().extend(value.to_bytes_with_nul());
1243 self
1244 }
1245 pub fn push_addr_bytes(mut self, value: &[u8]) -> Self {
1246 push_header(self.as_vec_mut(), 3u16, (value.len() + 1) as u16);
1247 self.as_vec_mut().extend(value);
1248 self.as_vec_mut().push(0);
1249 self
1250 }
1251 pub fn push_domain(mut self, value: &CStr) -> Self {
1252 push_header(
1253 self.as_vec_mut(),
1254 4u16,
1255 value.to_bytes_with_nul().len() as u16,
1256 );
1257 self.as_vec_mut().extend(value.to_bytes_with_nul());
1258 self
1259 }
1260 pub fn push_domain_bytes(mut self, value: &[u8]) -> Self {
1261 push_header(self.as_vec_mut(), 4u16, (value.len() + 1) as u16);
1262 self.as_vec_mut().extend(value);
1263 self.as_vec_mut().push(0);
1264 self
1265 }
1266 pub fn push_negative(mut self, value: ()) -> Self {
1267 push_header(self.as_vec_mut(), 5u16, 0 as u16);
1268 self
1269 }
1270 pub fn push_expiry(mut self, value: u64) -> Self {
1271 push_header(self.as_vec_mut(), 6u16, 8 as u16);
1272 self.as_vec_mut().extend(value.to_ne_bytes());
1273 self
1274 }
1275}
1276impl<Prev: Pusher> Drop for PushIpMap<Prev> {
1277 fn drop(&mut self) {
1278 if let Some(prev) = &mut self.prev {
1279 if let Some(header_offset) = &self.header_offset {
1280 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1281 }
1282 }
1283 }
1284}
1285pub struct PushIpMapReqs<Prev: Pusher> {
1286 pub(crate) prev: Option<Prev>,
1287 pub(crate) header_offset: Option<usize>,
1288}
1289impl<Prev: Pusher> Pusher for PushIpMapReqs<Prev> {
1290 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1291 self.prev.as_mut().unwrap().as_vec_mut()
1292 }
1293 fn as_vec(&self) -> &Vec<u8> {
1294 self.prev.as_ref().unwrap().as_vec()
1295 }
1296}
1297impl<Prev: Pusher> PushIpMapReqs<Prev> {
1298 pub fn new(prev: Prev) -> Self {
1299 Self {
1300 prev: Some(prev),
1301 header_offset: None,
1302 }
1303 }
1304 pub fn end_nested(mut self) -> Prev {
1305 let mut prev = self.prev.take().unwrap();
1306 if let Some(header_offset) = &self.header_offset {
1307 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1308 }
1309 prev
1310 }
1311 #[doc = "Attribute may repeat multiple times (treat it as array)"]
1312 pub fn nested_requests(mut self) -> PushIpMap<Self> {
1313 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
1314 PushIpMap {
1315 prev: Some(self),
1316 header_offset: Some(header_offset),
1317 }
1318 }
1319}
1320impl<Prev: Pusher> Drop for PushIpMapReqs<Prev> {
1321 fn drop(&mut self) {
1322 if let Some(prev) = &mut self.prev {
1323 if let Some(header_offset) = &self.header_offset {
1324 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1325 }
1326 }
1327 }
1328}
1329pub struct PushUnixGid<Prev: Pusher> {
1330 pub(crate) prev: Option<Prev>,
1331 pub(crate) header_offset: Option<usize>,
1332}
1333impl<Prev: Pusher> Pusher for PushUnixGid<Prev> {
1334 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1335 self.prev.as_mut().unwrap().as_vec_mut()
1336 }
1337 fn as_vec(&self) -> &Vec<u8> {
1338 self.prev.as_ref().unwrap().as_vec()
1339 }
1340}
1341impl<Prev: Pusher> PushUnixGid<Prev> {
1342 pub fn new(prev: Prev) -> Self {
1343 Self {
1344 prev: Some(prev),
1345 header_offset: None,
1346 }
1347 }
1348 pub fn end_nested(mut self) -> Prev {
1349 let mut prev = self.prev.take().unwrap();
1350 if let Some(header_offset) = &self.header_offset {
1351 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1352 }
1353 prev
1354 }
1355 pub fn push_seqno(mut self, value: u64) -> Self {
1356 push_header(self.as_vec_mut(), 1u16, 8 as u16);
1357 self.as_vec_mut().extend(value.to_ne_bytes());
1358 self
1359 }
1360 pub fn push_uid(mut self, value: u32) -> Self {
1361 push_header(self.as_vec_mut(), 2u16, 4 as u16);
1362 self.as_vec_mut().extend(value.to_ne_bytes());
1363 self
1364 }
1365 #[doc = "Attribute may repeat multiple times (treat it as array)"]
1366 pub fn push_gids(mut self, value: u32) -> Self {
1367 push_header(self.as_vec_mut(), 3u16, 4 as u16);
1368 self.as_vec_mut().extend(value.to_ne_bytes());
1369 self
1370 }
1371 pub fn push_negative(mut self, value: ()) -> Self {
1372 push_header(self.as_vec_mut(), 4u16, 0 as u16);
1373 self
1374 }
1375 pub fn push_expiry(mut self, value: u64) -> Self {
1376 push_header(self.as_vec_mut(), 5u16, 8 as u16);
1377 self.as_vec_mut().extend(value.to_ne_bytes());
1378 self
1379 }
1380}
1381impl<Prev: Pusher> Drop for PushUnixGid<Prev> {
1382 fn drop(&mut self) {
1383 if let Some(prev) = &mut self.prev {
1384 if let Some(header_offset) = &self.header_offset {
1385 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1386 }
1387 }
1388 }
1389}
1390pub struct PushUnixGidReqs<Prev: Pusher> {
1391 pub(crate) prev: Option<Prev>,
1392 pub(crate) header_offset: Option<usize>,
1393}
1394impl<Prev: Pusher> Pusher for PushUnixGidReqs<Prev> {
1395 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1396 self.prev.as_mut().unwrap().as_vec_mut()
1397 }
1398 fn as_vec(&self) -> &Vec<u8> {
1399 self.prev.as_ref().unwrap().as_vec()
1400 }
1401}
1402impl<Prev: Pusher> PushUnixGidReqs<Prev> {
1403 pub fn new(prev: Prev) -> Self {
1404 Self {
1405 prev: Some(prev),
1406 header_offset: None,
1407 }
1408 }
1409 pub fn end_nested(mut self) -> Prev {
1410 let mut prev = self.prev.take().unwrap();
1411 if let Some(header_offset) = &self.header_offset {
1412 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1413 }
1414 prev
1415 }
1416 #[doc = "Attribute may repeat multiple times (treat it as array)"]
1417 pub fn nested_requests(mut self) -> PushUnixGid<Self> {
1418 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
1419 PushUnixGid {
1420 prev: Some(self),
1421 header_offset: Some(header_offset),
1422 }
1423 }
1424}
1425impl<Prev: Pusher> Drop for PushUnixGidReqs<Prev> {
1426 fn drop(&mut self) {
1427 if let Some(prev) = &mut self.prev {
1428 if let Some(header_offset) = &self.header_offset {
1429 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1430 }
1431 }
1432 }
1433}
1434pub struct PushCacheFlush<Prev: Pusher> {
1435 pub(crate) prev: Option<Prev>,
1436 pub(crate) header_offset: Option<usize>,
1437}
1438impl<Prev: Pusher> Pusher for PushCacheFlush<Prev> {
1439 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1440 self.prev.as_mut().unwrap().as_vec_mut()
1441 }
1442 fn as_vec(&self) -> &Vec<u8> {
1443 self.prev.as_ref().unwrap().as_vec()
1444 }
1445}
1446impl<Prev: Pusher> PushCacheFlush<Prev> {
1447 pub fn new(prev: Prev) -> Self {
1448 Self {
1449 prev: Some(prev),
1450 header_offset: None,
1451 }
1452 }
1453 pub fn end_nested(mut self) -> Prev {
1454 let mut prev = self.prev.take().unwrap();
1455 if let Some(header_offset) = &self.header_offset {
1456 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1457 }
1458 prev
1459 }
1460 #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
1461 pub fn push_mask(mut self, value: u32) -> Self {
1462 push_header(self.as_vec_mut(), 1u16, 4 as u16);
1463 self.as_vec_mut().extend(value.to_ne_bytes());
1464 self
1465 }
1466}
1467impl<Prev: Pusher> Drop for PushCacheFlush<Prev> {
1468 fn drop(&mut self) {
1469 if let Some(prev) = &mut self.prev {
1470 if let Some(header_offset) = &self.header_offset {
1471 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1472 }
1473 }
1474 }
1475}
1476#[doc = "Notify attributes:\n- [`.get_cache_type()`](IterableCacheNotify::get_cache_type)\n"]
1477#[derive(Debug)]
1478pub struct OpCacheNotifyNotif;
1479impl OpCacheNotifyNotif {
1480 pub const CMD: u8 = 1u8;
1481 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterableCacheNotify<'a> {
1482 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1483 IterableCacheNotify::with_loc(attrs, buf.as_ptr() as usize)
1484 }
1485}
1486pub struct NotifGroup;
1487impl NotifGroup {
1488 pub const NONE: &str = "none";
1489 pub const NONE_CSTR: &CStr = c"none";
1490 #[doc = "Notifications:\n- [`OpCacheNotifyNotif`]\n"]
1491 pub const EXPORTD: &str = "exportd";
1492 #[doc = "Notifications:\n- [`OpCacheNotifyNotif`]\n"]
1493 pub const EXPORTD_CSTR: &CStr = c"exportd";
1494}
1495#[doc = "Dump all pending ip_map requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableIpMapReqs::get_requests)\n\n"]
1496#[derive(Debug)]
1497pub struct OpIpMapGetReqsDump<'r> {
1498 request: Request<'r>,
1499}
1500impl<'r> OpIpMapGetReqsDump<'r> {
1501 pub fn new(mut request: Request<'r>) -> Self {
1502 Self::write_header(request.buf_mut());
1503 Self {
1504 request: request.set_dump(),
1505 }
1506 }
1507 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushIpMapReqs<&'buf mut Vec<u8>> {
1508 Self::write_header(buf);
1509 PushIpMapReqs::new(buf)
1510 }
1511 pub fn encode(&mut self) -> PushIpMapReqs<&mut Vec<u8>> {
1512 PushIpMapReqs::new(self.request.buf_mut())
1513 }
1514 pub fn into_encoder(self) -> PushIpMapReqs<RequestBuf<'r>> {
1515 PushIpMapReqs::new(self.request.buf)
1516 }
1517 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableIpMapReqs<'a> {
1518 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1519 IterableIpMapReqs::with_loc(attrs, buf.as_ptr() as usize)
1520 }
1521 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1522 let mut header = BuiltinNfgenmsg::new();
1523 header.cmd = 2u8;
1524 header.version = 1u8;
1525 prev.as_vec_mut().extend(header.as_slice());
1526 }
1527}
1528impl NetlinkRequest for OpIpMapGetReqsDump<'_> {
1529 fn protocol(&self) -> Protocol {
1530 Protocol::Generic("sunrpc".as_bytes())
1531 }
1532 fn flags(&self) -> u16 {
1533 self.request.flags
1534 }
1535 fn payload(&self) -> &[u8] {
1536 self.request.buf()
1537 }
1538 type ReplyType<'buf> = IterableIpMapReqs<'buf>;
1539 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1540 Self::decode_request(buf)
1541 }
1542 fn lookup(
1543 buf: &[u8],
1544 offset: usize,
1545 missing_type: Option<u16>,
1546 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1547 Self::decode_request(buf).lookup_attr(offset, missing_type)
1548 }
1549}
1550#[doc = "Respond to one or more ip_map requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushIpMapReqs::nested_requests)\n\n"]
1551#[derive(Debug)]
1552pub struct OpIpMapSetReqsDo<'r> {
1553 request: Request<'r>,
1554}
1555impl<'r> OpIpMapSetReqsDo<'r> {
1556 pub fn new(mut request: Request<'r>) -> Self {
1557 Self::write_header(request.buf_mut());
1558 Self { request: request }
1559 }
1560 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushIpMapReqs<&'buf mut Vec<u8>> {
1561 Self::write_header(buf);
1562 PushIpMapReqs::new(buf)
1563 }
1564 pub fn encode(&mut self) -> PushIpMapReqs<&mut Vec<u8>> {
1565 PushIpMapReqs::new(self.request.buf_mut())
1566 }
1567 pub fn into_encoder(self) -> PushIpMapReqs<RequestBuf<'r>> {
1568 PushIpMapReqs::new(self.request.buf)
1569 }
1570 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableIpMapReqs<'a> {
1571 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1572 IterableIpMapReqs::with_loc(attrs, buf.as_ptr() as usize)
1573 }
1574 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1575 let mut header = BuiltinNfgenmsg::new();
1576 header.cmd = 3u8;
1577 header.version = 1u8;
1578 prev.as_vec_mut().extend(header.as_slice());
1579 }
1580}
1581impl NetlinkRequest for OpIpMapSetReqsDo<'_> {
1582 fn protocol(&self) -> Protocol {
1583 Protocol::Generic("sunrpc".as_bytes())
1584 }
1585 fn flags(&self) -> u16 {
1586 self.request.flags
1587 }
1588 fn payload(&self) -> &[u8] {
1589 self.request.buf()
1590 }
1591 type ReplyType<'buf> = IterableIpMapReqs<'buf>;
1592 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1593 Self::decode_request(buf)
1594 }
1595 fn lookup(
1596 buf: &[u8],
1597 offset: usize,
1598 missing_type: Option<u16>,
1599 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1600 Self::decode_request(buf).lookup_attr(offset, missing_type)
1601 }
1602}
1603#[doc = "Dump all pending unix_gid requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableUnixGidReqs::get_requests)\n\n"]
1604#[derive(Debug)]
1605pub struct OpUnixGidGetReqsDump<'r> {
1606 request: Request<'r>,
1607}
1608impl<'r> OpUnixGidGetReqsDump<'r> {
1609 pub fn new(mut request: Request<'r>) -> Self {
1610 Self::write_header(request.buf_mut());
1611 Self {
1612 request: request.set_dump(),
1613 }
1614 }
1615 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushUnixGidReqs<&'buf mut Vec<u8>> {
1616 Self::write_header(buf);
1617 PushUnixGidReqs::new(buf)
1618 }
1619 pub fn encode(&mut self) -> PushUnixGidReqs<&mut Vec<u8>> {
1620 PushUnixGidReqs::new(self.request.buf_mut())
1621 }
1622 pub fn into_encoder(self) -> PushUnixGidReqs<RequestBuf<'r>> {
1623 PushUnixGidReqs::new(self.request.buf)
1624 }
1625 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableUnixGidReqs<'a> {
1626 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1627 IterableUnixGidReqs::with_loc(attrs, buf.as_ptr() as usize)
1628 }
1629 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1630 let mut header = BuiltinNfgenmsg::new();
1631 header.cmd = 4u8;
1632 header.version = 1u8;
1633 prev.as_vec_mut().extend(header.as_slice());
1634 }
1635}
1636impl NetlinkRequest for OpUnixGidGetReqsDump<'_> {
1637 fn protocol(&self) -> Protocol {
1638 Protocol::Generic("sunrpc".as_bytes())
1639 }
1640 fn flags(&self) -> u16 {
1641 self.request.flags
1642 }
1643 fn payload(&self) -> &[u8] {
1644 self.request.buf()
1645 }
1646 type ReplyType<'buf> = IterableUnixGidReqs<'buf>;
1647 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1648 Self::decode_request(buf)
1649 }
1650 fn lookup(
1651 buf: &[u8],
1652 offset: usize,
1653 missing_type: Option<u16>,
1654 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1655 Self::decode_request(buf).lookup_attr(offset, missing_type)
1656 }
1657}
1658#[doc = "Respond to one or more unix_gid requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushUnixGidReqs::nested_requests)\n\n"]
1659#[derive(Debug)]
1660pub struct OpUnixGidSetReqsDo<'r> {
1661 request: Request<'r>,
1662}
1663impl<'r> OpUnixGidSetReqsDo<'r> {
1664 pub fn new(mut request: Request<'r>) -> Self {
1665 Self::write_header(request.buf_mut());
1666 Self { request: request }
1667 }
1668 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushUnixGidReqs<&'buf mut Vec<u8>> {
1669 Self::write_header(buf);
1670 PushUnixGidReqs::new(buf)
1671 }
1672 pub fn encode(&mut self) -> PushUnixGidReqs<&mut Vec<u8>> {
1673 PushUnixGidReqs::new(self.request.buf_mut())
1674 }
1675 pub fn into_encoder(self) -> PushUnixGidReqs<RequestBuf<'r>> {
1676 PushUnixGidReqs::new(self.request.buf)
1677 }
1678 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableUnixGidReqs<'a> {
1679 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1680 IterableUnixGidReqs::with_loc(attrs, buf.as_ptr() as usize)
1681 }
1682 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1683 let mut header = BuiltinNfgenmsg::new();
1684 header.cmd = 5u8;
1685 header.version = 1u8;
1686 prev.as_vec_mut().extend(header.as_slice());
1687 }
1688}
1689impl NetlinkRequest for OpUnixGidSetReqsDo<'_> {
1690 fn protocol(&self) -> Protocol {
1691 Protocol::Generic("sunrpc".as_bytes())
1692 }
1693 fn flags(&self) -> u16 {
1694 self.request.flags
1695 }
1696 fn payload(&self) -> &[u8] {
1697 self.request.buf()
1698 }
1699 type ReplyType<'buf> = IterableUnixGidReqs<'buf>;
1700 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1701 Self::decode_request(buf)
1702 }
1703 fn lookup(
1704 buf: &[u8],
1705 offset: usize,
1706 missing_type: Option<u16>,
1707 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1708 Self::decode_request(buf).lookup_attr(offset, missing_type)
1709 }
1710}
1711#[doc = "Flush sunrpc caches (ip_map and/or unix_gid)\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mask()](PushCacheFlush::push_mask)\n\n"]
1712#[derive(Debug)]
1713pub struct OpCacheFlushDo<'r> {
1714 request: Request<'r>,
1715}
1716impl<'r> OpCacheFlushDo<'r> {
1717 pub fn new(mut request: Request<'r>) -> Self {
1718 Self::write_header(request.buf_mut());
1719 Self { request: request }
1720 }
1721 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushCacheFlush<&'buf mut Vec<u8>> {
1722 Self::write_header(buf);
1723 PushCacheFlush::new(buf)
1724 }
1725 pub fn encode(&mut self) -> PushCacheFlush<&mut Vec<u8>> {
1726 PushCacheFlush::new(self.request.buf_mut())
1727 }
1728 pub fn into_encoder(self) -> PushCacheFlush<RequestBuf<'r>> {
1729 PushCacheFlush::new(self.request.buf)
1730 }
1731 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableCacheFlush<'a> {
1732 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1733 IterableCacheFlush::with_loc(attrs, buf.as_ptr() as usize)
1734 }
1735 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1736 let mut header = BuiltinNfgenmsg::new();
1737 header.cmd = 6u8;
1738 header.version = 1u8;
1739 prev.as_vec_mut().extend(header.as_slice());
1740 }
1741}
1742impl NetlinkRequest for OpCacheFlushDo<'_> {
1743 fn protocol(&self) -> Protocol {
1744 Protocol::Generic("sunrpc".as_bytes())
1745 }
1746 fn flags(&self) -> u16 {
1747 self.request.flags
1748 }
1749 fn payload(&self) -> &[u8] {
1750 self.request.buf()
1751 }
1752 type ReplyType<'buf> = IterableCacheFlush<'buf>;
1753 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1754 Self::decode_request(buf)
1755 }
1756 fn lookup(
1757 buf: &[u8],
1758 offset: usize,
1759 missing_type: Option<u16>,
1760 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1761 Self::decode_request(buf).lookup_attr(offset, missing_type)
1762 }
1763}
1764use crate::traits::LookupFn;
1765use crate::utils::RequestBuf;
1766#[derive(Debug)]
1767pub struct Request<'buf> {
1768 buf: RequestBuf<'buf>,
1769 flags: u16,
1770 writeback: Option<&'buf mut Option<RequestInfo>>,
1771}
1772#[allow(unused)]
1773#[derive(Debug, Clone)]
1774pub struct RequestInfo {
1775 protocol: Protocol,
1776 flags: u16,
1777 name: &'static str,
1778 lookup: LookupFn,
1779}
1780impl Request<'static> {
1781 pub fn new() -> Self {
1782 Self::new_from_buf(Vec::new())
1783 }
1784 pub fn new_from_buf(buf: Vec<u8>) -> Self {
1785 Self {
1786 flags: 0,
1787 buf: RequestBuf::Own(buf),
1788 writeback: None,
1789 }
1790 }
1791 pub fn into_buf(self) -> Vec<u8> {
1792 match self.buf {
1793 RequestBuf::Own(buf) => buf,
1794 _ => unreachable!(),
1795 }
1796 }
1797}
1798impl<'buf> Request<'buf> {
1799 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
1800 buf.clear();
1801 Self::new_extend(buf)
1802 }
1803 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
1804 Self {
1805 flags: 0,
1806 buf: RequestBuf::Ref(buf),
1807 writeback: None,
1808 }
1809 }
1810 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
1811 let Some(writeback) = &mut self.writeback else {
1812 return;
1813 };
1814 **writeback = Some(RequestInfo {
1815 protocol,
1816 flags: self.flags,
1817 name,
1818 lookup,
1819 })
1820 }
1821 pub fn buf(&self) -> &Vec<u8> {
1822 self.buf.buf()
1823 }
1824 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1825 self.buf.buf_mut()
1826 }
1827 #[doc = "Set `NLM_F_CREATE` flag"]
1828 pub fn set_create(mut self) -> Self {
1829 self.flags |= consts::NLM_F_CREATE as u16;
1830 self
1831 }
1832 #[doc = "Set `NLM_F_EXCL` flag"]
1833 pub fn set_excl(mut self) -> Self {
1834 self.flags |= consts::NLM_F_EXCL as u16;
1835 self
1836 }
1837 #[doc = "Set `NLM_F_REPLACE` flag"]
1838 pub fn set_replace(mut self) -> Self {
1839 self.flags |= consts::NLM_F_REPLACE as u16;
1840 self
1841 }
1842 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
1843 pub fn set_change(self) -> Self {
1844 self.set_create().set_replace()
1845 }
1846 #[doc = "Set `NLM_F_APPEND` flag"]
1847 pub fn set_append(mut self) -> Self {
1848 self.flags |= consts::NLM_F_APPEND as u16;
1849 self
1850 }
1851 #[doc = "Set `self.flags |= flags`"]
1852 pub fn set_flags(mut self, flags: u16) -> Self {
1853 self.flags |= flags;
1854 self
1855 }
1856 #[doc = "Set `self.flags ^= self.flags & flags`"]
1857 pub fn unset_flags(mut self, flags: u16) -> Self {
1858 self.flags ^= self.flags & flags;
1859 self
1860 }
1861 #[doc = "Set `NLM_F_DUMP` flag"]
1862 fn set_dump(mut self) -> Self {
1863 self.flags |= consts::NLM_F_DUMP as u16;
1864 self
1865 }
1866 #[doc = "Dump all pending ip_map requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableIpMapReqs::get_requests)\n\n"]
1867 pub fn op_ip_map_get_reqs_dump(self) -> OpIpMapGetReqsDump<'buf> {
1868 let mut res = OpIpMapGetReqsDump::new(self);
1869 res.request.do_writeback(
1870 res.protocol(),
1871 "op-ip-map-get-reqs-dump",
1872 OpIpMapGetReqsDump::lookup,
1873 );
1874 res
1875 }
1876 #[doc = "Respond to one or more ip_map requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushIpMapReqs::nested_requests)\n\n"]
1877 pub fn op_ip_map_set_reqs_do(self) -> OpIpMapSetReqsDo<'buf> {
1878 let mut res = OpIpMapSetReqsDo::new(self);
1879 res.request.do_writeback(
1880 res.protocol(),
1881 "op-ip-map-set-reqs-do",
1882 OpIpMapSetReqsDo::lookup,
1883 );
1884 res
1885 }
1886 #[doc = "Dump all pending unix_gid requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableUnixGidReqs::get_requests)\n\n"]
1887 pub fn op_unix_gid_get_reqs_dump(self) -> OpUnixGidGetReqsDump<'buf> {
1888 let mut res = OpUnixGidGetReqsDump::new(self);
1889 res.request.do_writeback(
1890 res.protocol(),
1891 "op-unix-gid-get-reqs-dump",
1892 OpUnixGidGetReqsDump::lookup,
1893 );
1894 res
1895 }
1896 #[doc = "Respond to one or more unix_gid requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushUnixGidReqs::nested_requests)\n\n"]
1897 pub fn op_unix_gid_set_reqs_do(self) -> OpUnixGidSetReqsDo<'buf> {
1898 let mut res = OpUnixGidSetReqsDo::new(self);
1899 res.request.do_writeback(
1900 res.protocol(),
1901 "op-unix-gid-set-reqs-do",
1902 OpUnixGidSetReqsDo::lookup,
1903 );
1904 res
1905 }
1906 #[doc = "Flush sunrpc caches (ip_map and/or unix_gid)\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mask()](PushCacheFlush::push_mask)\n\n"]
1907 pub fn op_cache_flush_do(self) -> OpCacheFlushDo<'buf> {
1908 let mut res = OpCacheFlushDo::new(self);
1909 res.request
1910 .do_writeback(res.protocol(), "op-cache-flush-do", OpCacheFlushDo::lookup);
1911 res
1912 }
1913}
1914#[cfg(test)]
1915mod generated_tests {
1916 use super::*;
1917 #[test]
1918 fn tests() {
1919 let _ = IterableCacheNotify::get_cache_type;
1920 let _ = IterableIpMapReqs::get_requests;
1921 let _ = IterableUnixGidReqs::get_requests;
1922 let _ = OpCacheNotifyNotif;
1923 let _ = PushCacheFlush::<&mut Vec<u8>>::push_mask;
1924 let _ = PushIpMapReqs::<&mut Vec<u8>>::nested_requests;
1925 let _ = PushUnixGidReqs::<&mut Vec<u8>>::nested_requests;
1926 }
1927}