1#![doc = "NFSD configuration 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 = "nfsd";
17pub const PROTONAME_CSTR: &CStr = c"nfsd";
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 SvcExport = 1 << 0,
22 Expkey = 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::SvcExport,
28 n if n == 1 << 1 => Self::Expkey,
29 _ => return None,
30 })
31 }
32}
33#[doc = "These flags are ordered to match the [NFSEXP]()\\* flags in\ninclude/linux/nfsd/export.h\n"]
34#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
35#[derive(Debug, Clone, Copy)]
36pub enum ExportFlags {
37 Readonly = 1 << 0,
38 InsecurePort = 1 << 1,
39 Rootsquash = 1 << 2,
40 Allsquash = 1 << 3,
41 Async = 1 << 4,
42 GatheredWrites = 1 << 5,
43 Noreaddirplus = 1 << 6,
44 SecurityLabel = 1 << 7,
45 SignFh = 1 << 8,
46 Nohide = 1 << 9,
47 Nosubtreecheck = 1 << 10,
48 Noauthnlm = 1 << 11,
49 Msnfs = 1 << 12,
50 Fsid = 1 << 13,
51 Crossmount = 1 << 14,
52 Noacl = 1 << 15,
53 V4root = 1 << 16,
54 Pnfs = 1 << 17,
55}
56impl ExportFlags {
57 pub fn from_value(value: u64) -> Option<Self> {
58 Some(match value {
59 n if n == 1 << 0 => Self::Readonly,
60 n if n == 1 << 1 => Self::InsecurePort,
61 n if n == 1 << 2 => Self::Rootsquash,
62 n if n == 1 << 3 => Self::Allsquash,
63 n if n == 1 << 4 => Self::Async,
64 n if n == 1 << 5 => Self::GatheredWrites,
65 n if n == 1 << 6 => Self::Noreaddirplus,
66 n if n == 1 << 7 => Self::SecurityLabel,
67 n if n == 1 << 8 => Self::SignFh,
68 n if n == 1 << 9 => Self::Nohide,
69 n if n == 1 << 10 => Self::Nosubtreecheck,
70 n if n == 1 << 11 => Self::Noauthnlm,
71 n if n == 1 << 12 => Self::Msnfs,
72 n if n == 1 << 13 => Self::Fsid,
73 n if n == 1 << 14 => Self::Crossmount,
74 n if n == 1 << 15 => Self::Noacl,
75 n if n == 1 << 16 => Self::V4root,
76 n if n == 1 << 17 => Self::Pnfs,
77 _ => return None,
78 })
79 }
80}
81#[doc = "These flags are ordered to match the [NFSEXP_XPRTSEC]()\\* flags in\ninclude/linux/nfsd/export.h\n"]
82#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
83#[derive(Debug, Clone, Copy)]
84pub enum XprtsecMode {
85 None = 1 << 0,
86 Tls = 1 << 1,
87 Mtls = 1 << 2,
88}
89impl XprtsecMode {
90 pub fn from_value(value: u64) -> Option<Self> {
91 Some(match value {
92 n if n == 1 << 0 => Self::None,
93 n if n == 1 << 1 => Self::Tls,
94 n if n == 1 << 2 => Self::Mtls,
95 _ => return None,
96 })
97 }
98}
99#[derive(Clone)]
100pub enum CacheNotify {
101 #[doc = "Associated type: [`CacheType`] (enum)"]
102 CacheType(u32),
103}
104impl<'a> IterableCacheNotify<'a> {
105 #[doc = "Associated type: [`CacheType`] (enum)"]
106 pub fn get_cache_type(&self) -> Result<u32, ErrorContext> {
107 let mut iter = self.clone();
108 iter.pos = 0;
109 for attr in iter {
110 if let Ok(CacheNotify::CacheType(val)) = attr {
111 return Ok(val);
112 }
113 }
114 Err(ErrorContext::new_missing(
115 "CacheNotify",
116 "CacheType",
117 self.orig_loc,
118 self.buf.as_ptr() as usize,
119 ))
120 }
121}
122impl CacheNotify {
123 pub fn new<'a>(buf: &'a [u8]) -> IterableCacheNotify<'a> {
124 IterableCacheNotify::with_loc(buf, buf.as_ptr() as usize)
125 }
126 fn attr_from_type(r#type: u16) -> Option<&'static str> {
127 let res = match r#type {
128 1u16 => "CacheType",
129 _ => return None,
130 };
131 Some(res)
132 }
133}
134#[derive(Clone, Copy, Default)]
135pub struct IterableCacheNotify<'a> {
136 buf: &'a [u8],
137 pos: usize,
138 orig_loc: usize,
139}
140impl<'a> IterableCacheNotify<'a> {
141 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
142 Self {
143 buf,
144 pos: 0,
145 orig_loc,
146 }
147 }
148 pub fn get_buf(&self) -> &'a [u8] {
149 self.buf
150 }
151}
152impl<'a> Iterator for IterableCacheNotify<'a> {
153 type Item = Result<CacheNotify, ErrorContext>;
154 fn next(&mut self) -> Option<Self::Item> {
155 let mut pos;
156 let mut r#type;
157 loop {
158 pos = self.pos;
159 r#type = None;
160 if self.buf.len() == self.pos {
161 return None;
162 }
163 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
164 self.pos = self.buf.len();
165 break;
166 };
167 r#type = Some(header.r#type);
168 let res = match header.r#type {
169 1u16 => CacheNotify::CacheType({
170 let res = parse_u32(next);
171 let Some(val) = res else { break };
172 val
173 }),
174 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
175 n => continue,
176 };
177 return Some(Ok(res));
178 }
179 Some(Err(ErrorContext::new(
180 "CacheNotify",
181 r#type.and_then(|t| CacheNotify::attr_from_type(t)),
182 self.orig_loc,
183 self.buf.as_ptr().wrapping_add(pos) as usize,
184 )))
185 }
186}
187impl std::fmt::Debug for IterableCacheNotify<'_> {
188 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189 let mut fmt = f.debug_struct("CacheNotify");
190 for attr in self.clone() {
191 let attr = match attr {
192 Ok(a) => a,
193 Err(err) => {
194 fmt.finish()?;
195 f.write_str("Err(")?;
196 err.fmt(f)?;
197 return f.write_str(")");
198 }
199 };
200 match attr {
201 CacheNotify::CacheType(val) => {
202 fmt.field("CacheType", &FormatFlags(val.into(), CacheType::from_value))
203 }
204 };
205 }
206 fmt.finish()
207 }
208}
209impl IterableCacheNotify<'_> {
210 pub fn lookup_attr(
211 &self,
212 offset: usize,
213 missing_type: Option<u16>,
214 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
215 let mut stack = Vec::new();
216 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
217 if missing_type.is_some() && cur == offset {
218 stack.push(("CacheNotify", offset));
219 return (
220 stack,
221 missing_type.and_then(|t| CacheNotify::attr_from_type(t)),
222 );
223 }
224 if cur > offset || cur + self.buf.len() < offset {
225 return (stack, None);
226 }
227 let mut attrs = self.clone();
228 let mut last_off = cur + attrs.pos;
229 while let Some(attr) = attrs.next() {
230 let Ok(attr) = attr else { break };
231 match attr {
232 CacheNotify::CacheType(val) => {
233 if last_off == offset {
234 stack.push(("CacheType", last_off));
235 break;
236 }
237 }
238 _ => {}
239 };
240 last_off = cur + attrs.pos;
241 }
242 if !stack.is_empty() {
243 stack.push(("CacheNotify", cur));
244 }
245 (stack, None)
246 }
247}
248#[derive(Clone)]
249pub enum RpcStatus<'a> {
250 Xid(u32),
251 Flags(u32),
252 Prog(u32),
253 Version(u8),
254 Proc(u32),
255 ServiceTime(i64),
256 Pad(&'a [u8]),
257 Saddr4(std::net::Ipv4Addr),
258 Daddr4(std::net::Ipv4Addr),
259 Saddr6(&'a [u8]),
260 Daddr6(&'a [u8]),
261 Sport(u16),
262 Dport(u16),
263 #[doc = "Attribute may repeat multiple times (treat it as array)"]
264 CompoundOps(u32),
265}
266impl<'a> IterableRpcStatus<'a> {
267 pub fn get_xid(&self) -> Result<u32, ErrorContext> {
268 let mut iter = self.clone();
269 iter.pos = 0;
270 for attr in iter {
271 if let Ok(RpcStatus::Xid(val)) = attr {
272 return Ok(val);
273 }
274 }
275 Err(ErrorContext::new_missing(
276 "RpcStatus",
277 "Xid",
278 self.orig_loc,
279 self.buf.as_ptr() as usize,
280 ))
281 }
282 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
283 let mut iter = self.clone();
284 iter.pos = 0;
285 for attr in iter {
286 if let Ok(RpcStatus::Flags(val)) = attr {
287 return Ok(val);
288 }
289 }
290 Err(ErrorContext::new_missing(
291 "RpcStatus",
292 "Flags",
293 self.orig_loc,
294 self.buf.as_ptr() as usize,
295 ))
296 }
297 pub fn get_prog(&self) -> Result<u32, ErrorContext> {
298 let mut iter = self.clone();
299 iter.pos = 0;
300 for attr in iter {
301 if let Ok(RpcStatus::Prog(val)) = attr {
302 return Ok(val);
303 }
304 }
305 Err(ErrorContext::new_missing(
306 "RpcStatus",
307 "Prog",
308 self.orig_loc,
309 self.buf.as_ptr() as usize,
310 ))
311 }
312 pub fn get_version(&self) -> Result<u8, ErrorContext> {
313 let mut iter = self.clone();
314 iter.pos = 0;
315 for attr in iter {
316 if let Ok(RpcStatus::Version(val)) = attr {
317 return Ok(val);
318 }
319 }
320 Err(ErrorContext::new_missing(
321 "RpcStatus",
322 "Version",
323 self.orig_loc,
324 self.buf.as_ptr() as usize,
325 ))
326 }
327 pub fn get_proc(&self) -> Result<u32, ErrorContext> {
328 let mut iter = self.clone();
329 iter.pos = 0;
330 for attr in iter {
331 if let Ok(RpcStatus::Proc(val)) = attr {
332 return Ok(val);
333 }
334 }
335 Err(ErrorContext::new_missing(
336 "RpcStatus",
337 "Proc",
338 self.orig_loc,
339 self.buf.as_ptr() as usize,
340 ))
341 }
342 pub fn get_service_time(&self) -> Result<i64, ErrorContext> {
343 let mut iter = self.clone();
344 iter.pos = 0;
345 for attr in iter {
346 if let Ok(RpcStatus::ServiceTime(val)) = attr {
347 return Ok(val);
348 }
349 }
350 Err(ErrorContext::new_missing(
351 "RpcStatus",
352 "ServiceTime",
353 self.orig_loc,
354 self.buf.as_ptr() as usize,
355 ))
356 }
357 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
358 let mut iter = self.clone();
359 iter.pos = 0;
360 for attr in iter {
361 if let Ok(RpcStatus::Pad(val)) = attr {
362 return Ok(val);
363 }
364 }
365 Err(ErrorContext::new_missing(
366 "RpcStatus",
367 "Pad",
368 self.orig_loc,
369 self.buf.as_ptr() as usize,
370 ))
371 }
372 pub fn get_saddr4(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
373 let mut iter = self.clone();
374 iter.pos = 0;
375 for attr in iter {
376 if let Ok(RpcStatus::Saddr4(val)) = attr {
377 return Ok(val);
378 }
379 }
380 Err(ErrorContext::new_missing(
381 "RpcStatus",
382 "Saddr4",
383 self.orig_loc,
384 self.buf.as_ptr() as usize,
385 ))
386 }
387 pub fn get_daddr4(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
388 let mut iter = self.clone();
389 iter.pos = 0;
390 for attr in iter {
391 if let Ok(RpcStatus::Daddr4(val)) = attr {
392 return Ok(val);
393 }
394 }
395 Err(ErrorContext::new_missing(
396 "RpcStatus",
397 "Daddr4",
398 self.orig_loc,
399 self.buf.as_ptr() as usize,
400 ))
401 }
402 pub fn get_saddr6(&self) -> Result<&'a [u8], ErrorContext> {
403 let mut iter = self.clone();
404 iter.pos = 0;
405 for attr in iter {
406 if let Ok(RpcStatus::Saddr6(val)) = attr {
407 return Ok(val);
408 }
409 }
410 Err(ErrorContext::new_missing(
411 "RpcStatus",
412 "Saddr6",
413 self.orig_loc,
414 self.buf.as_ptr() as usize,
415 ))
416 }
417 pub fn get_daddr6(&self) -> Result<&'a [u8], ErrorContext> {
418 let mut iter = self.clone();
419 iter.pos = 0;
420 for attr in iter {
421 if let Ok(RpcStatus::Daddr6(val)) = attr {
422 return Ok(val);
423 }
424 }
425 Err(ErrorContext::new_missing(
426 "RpcStatus",
427 "Daddr6",
428 self.orig_loc,
429 self.buf.as_ptr() as usize,
430 ))
431 }
432 pub fn get_sport(&self) -> Result<u16, ErrorContext> {
433 let mut iter = self.clone();
434 iter.pos = 0;
435 for attr in iter {
436 if let Ok(RpcStatus::Sport(val)) = attr {
437 return Ok(val);
438 }
439 }
440 Err(ErrorContext::new_missing(
441 "RpcStatus",
442 "Sport",
443 self.orig_loc,
444 self.buf.as_ptr() as usize,
445 ))
446 }
447 pub fn get_dport(&self) -> Result<u16, ErrorContext> {
448 let mut iter = self.clone();
449 iter.pos = 0;
450 for attr in iter {
451 if let Ok(RpcStatus::Dport(val)) = attr {
452 return Ok(val);
453 }
454 }
455 Err(ErrorContext::new_missing(
456 "RpcStatus",
457 "Dport",
458 self.orig_loc,
459 self.buf.as_ptr() as usize,
460 ))
461 }
462 #[doc = "Attribute may repeat multiple times (treat it as array)"]
463 pub fn get_compound_ops(&self) -> MultiAttrIterable<Self, RpcStatus<'a>, u32> {
464 MultiAttrIterable::new(self.clone(), |variant| {
465 if let RpcStatus::CompoundOps(val) = variant {
466 Some(val)
467 } else {
468 None
469 }
470 })
471 }
472}
473impl RpcStatus<'_> {
474 pub fn new<'a>(buf: &'a [u8]) -> IterableRpcStatus<'a> {
475 IterableRpcStatus::with_loc(buf, buf.as_ptr() as usize)
476 }
477 fn attr_from_type(r#type: u16) -> Option<&'static str> {
478 let res = match r#type {
479 1u16 => "Xid",
480 2u16 => "Flags",
481 3u16 => "Prog",
482 4u16 => "Version",
483 5u16 => "Proc",
484 6u16 => "ServiceTime",
485 7u16 => "Pad",
486 8u16 => "Saddr4",
487 9u16 => "Daddr4",
488 10u16 => "Saddr6",
489 11u16 => "Daddr6",
490 12u16 => "Sport",
491 13u16 => "Dport",
492 14u16 => "CompoundOps",
493 _ => return None,
494 };
495 Some(res)
496 }
497}
498#[derive(Clone, Copy, Default)]
499pub struct IterableRpcStatus<'a> {
500 buf: &'a [u8],
501 pos: usize,
502 orig_loc: usize,
503}
504impl<'a> IterableRpcStatus<'a> {
505 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
506 Self {
507 buf,
508 pos: 0,
509 orig_loc,
510 }
511 }
512 pub fn get_buf(&self) -> &'a [u8] {
513 self.buf
514 }
515}
516impl<'a> Iterator for IterableRpcStatus<'a> {
517 type Item = Result<RpcStatus<'a>, ErrorContext>;
518 fn next(&mut self) -> Option<Self::Item> {
519 let mut pos;
520 let mut r#type;
521 loop {
522 pos = self.pos;
523 r#type = None;
524 if self.buf.len() == self.pos {
525 return None;
526 }
527 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
528 self.pos = self.buf.len();
529 break;
530 };
531 r#type = Some(header.r#type);
532 let res = match header.r#type {
533 1u16 => RpcStatus::Xid({
534 let res = parse_be_u32(next);
535 let Some(val) = res else { break };
536 val
537 }),
538 2u16 => RpcStatus::Flags({
539 let res = parse_u32(next);
540 let Some(val) = res else { break };
541 val
542 }),
543 3u16 => RpcStatus::Prog({
544 let res = parse_u32(next);
545 let Some(val) = res else { break };
546 val
547 }),
548 4u16 => RpcStatus::Version({
549 let res = parse_u8(next);
550 let Some(val) = res else { break };
551 val
552 }),
553 5u16 => RpcStatus::Proc({
554 let res = parse_u32(next);
555 let Some(val) = res else { break };
556 val
557 }),
558 6u16 => RpcStatus::ServiceTime({
559 let res = parse_i64(next);
560 let Some(val) = res else { break };
561 val
562 }),
563 7u16 => RpcStatus::Pad({
564 let res = Some(next);
565 let Some(val) = res else { break };
566 val
567 }),
568 8u16 => RpcStatus::Saddr4({
569 let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
570 let Some(val) = res else { break };
571 val
572 }),
573 9u16 => RpcStatus::Daddr4({
574 let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
575 let Some(val) = res else { break };
576 val
577 }),
578 10u16 => RpcStatus::Saddr6({
579 let res = Some(next);
580 let Some(val) = res else { break };
581 val
582 }),
583 11u16 => RpcStatus::Daddr6({
584 let res = Some(next);
585 let Some(val) = res else { break };
586 val
587 }),
588 12u16 => RpcStatus::Sport({
589 let res = parse_be_u16(next);
590 let Some(val) = res else { break };
591 val
592 }),
593 13u16 => RpcStatus::Dport({
594 let res = parse_be_u16(next);
595 let Some(val) = res else { break };
596 val
597 }),
598 14u16 => RpcStatus::CompoundOps({
599 let res = parse_u32(next);
600 let Some(val) = res else { break };
601 val
602 }),
603 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
604 n => continue,
605 };
606 return Some(Ok(res));
607 }
608 Some(Err(ErrorContext::new(
609 "RpcStatus",
610 r#type.and_then(|t| RpcStatus::attr_from_type(t)),
611 self.orig_loc,
612 self.buf.as_ptr().wrapping_add(pos) as usize,
613 )))
614 }
615}
616impl<'a> std::fmt::Debug for IterableRpcStatus<'_> {
617 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
618 let mut fmt = f.debug_struct("RpcStatus");
619 for attr in self.clone() {
620 let attr = match attr {
621 Ok(a) => a,
622 Err(err) => {
623 fmt.finish()?;
624 f.write_str("Err(")?;
625 err.fmt(f)?;
626 return f.write_str(")");
627 }
628 };
629 match attr {
630 RpcStatus::Xid(val) => fmt.field("Xid", &val),
631 RpcStatus::Flags(val) => fmt.field("Flags", &val),
632 RpcStatus::Prog(val) => fmt.field("Prog", &val),
633 RpcStatus::Version(val) => fmt.field("Version", &val),
634 RpcStatus::Proc(val) => fmt.field("Proc", &val),
635 RpcStatus::ServiceTime(val) => fmt.field("ServiceTime", &val),
636 RpcStatus::Pad(val) => fmt.field("Pad", &val),
637 RpcStatus::Saddr4(val) => fmt.field("Saddr4", &val),
638 RpcStatus::Daddr4(val) => fmt.field("Daddr4", &val),
639 RpcStatus::Saddr6(val) => fmt.field("Saddr6", &val),
640 RpcStatus::Daddr6(val) => fmt.field("Daddr6", &val),
641 RpcStatus::Sport(val) => fmt.field("Sport", &val),
642 RpcStatus::Dport(val) => fmt.field("Dport", &val),
643 RpcStatus::CompoundOps(val) => fmt.field("CompoundOps", &val),
644 };
645 }
646 fmt.finish()
647 }
648}
649impl IterableRpcStatus<'_> {
650 pub fn lookup_attr(
651 &self,
652 offset: usize,
653 missing_type: Option<u16>,
654 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
655 let mut stack = Vec::new();
656 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
657 if missing_type.is_some() && cur == offset {
658 stack.push(("RpcStatus", offset));
659 return (
660 stack,
661 missing_type.and_then(|t| RpcStatus::attr_from_type(t)),
662 );
663 }
664 if cur > offset || cur + self.buf.len() < offset {
665 return (stack, None);
666 }
667 let mut attrs = self.clone();
668 let mut last_off = cur + attrs.pos;
669 while let Some(attr) = attrs.next() {
670 let Ok(attr) = attr else { break };
671 match attr {
672 RpcStatus::Xid(val) => {
673 if last_off == offset {
674 stack.push(("Xid", last_off));
675 break;
676 }
677 }
678 RpcStatus::Flags(val) => {
679 if last_off == offset {
680 stack.push(("Flags", last_off));
681 break;
682 }
683 }
684 RpcStatus::Prog(val) => {
685 if last_off == offset {
686 stack.push(("Prog", last_off));
687 break;
688 }
689 }
690 RpcStatus::Version(val) => {
691 if last_off == offset {
692 stack.push(("Version", last_off));
693 break;
694 }
695 }
696 RpcStatus::Proc(val) => {
697 if last_off == offset {
698 stack.push(("Proc", last_off));
699 break;
700 }
701 }
702 RpcStatus::ServiceTime(val) => {
703 if last_off == offset {
704 stack.push(("ServiceTime", last_off));
705 break;
706 }
707 }
708 RpcStatus::Pad(val) => {
709 if last_off == offset {
710 stack.push(("Pad", last_off));
711 break;
712 }
713 }
714 RpcStatus::Saddr4(val) => {
715 if last_off == offset {
716 stack.push(("Saddr4", last_off));
717 break;
718 }
719 }
720 RpcStatus::Daddr4(val) => {
721 if last_off == offset {
722 stack.push(("Daddr4", last_off));
723 break;
724 }
725 }
726 RpcStatus::Saddr6(val) => {
727 if last_off == offset {
728 stack.push(("Saddr6", last_off));
729 break;
730 }
731 }
732 RpcStatus::Daddr6(val) => {
733 if last_off == offset {
734 stack.push(("Daddr6", last_off));
735 break;
736 }
737 }
738 RpcStatus::Sport(val) => {
739 if last_off == offset {
740 stack.push(("Sport", last_off));
741 break;
742 }
743 }
744 RpcStatus::Dport(val) => {
745 if last_off == offset {
746 stack.push(("Dport", last_off));
747 break;
748 }
749 }
750 RpcStatus::CompoundOps(val) => {
751 if last_off == offset {
752 stack.push(("CompoundOps", last_off));
753 break;
754 }
755 }
756 _ => {}
757 };
758 last_off = cur + attrs.pos;
759 }
760 if !stack.is_empty() {
761 stack.push(("RpcStatus", cur));
762 }
763 (stack, None)
764 }
765}
766#[derive(Clone)]
767pub enum Server<'a> {
768 #[doc = "Attribute may repeat multiple times (treat it as array)"]
769 Threads(u32),
770 Gracetime(u32),
771 Leasetime(u32),
772 Scope(&'a CStr),
773 MinThreads(u32),
774 FhKey(&'a [u8]),
775}
776impl<'a> IterableServer<'a> {
777 #[doc = "Attribute may repeat multiple times (treat it as array)"]
778 pub fn get_threads(&self) -> MultiAttrIterable<Self, Server<'a>, u32> {
779 MultiAttrIterable::new(self.clone(), |variant| {
780 if let Server::Threads(val) = variant {
781 Some(val)
782 } else {
783 None
784 }
785 })
786 }
787 pub fn get_gracetime(&self) -> Result<u32, ErrorContext> {
788 let mut iter = self.clone();
789 iter.pos = 0;
790 for attr in iter {
791 if let Ok(Server::Gracetime(val)) = attr {
792 return Ok(val);
793 }
794 }
795 Err(ErrorContext::new_missing(
796 "Server",
797 "Gracetime",
798 self.orig_loc,
799 self.buf.as_ptr() as usize,
800 ))
801 }
802 pub fn get_leasetime(&self) -> Result<u32, ErrorContext> {
803 let mut iter = self.clone();
804 iter.pos = 0;
805 for attr in iter {
806 if let Ok(Server::Leasetime(val)) = attr {
807 return Ok(val);
808 }
809 }
810 Err(ErrorContext::new_missing(
811 "Server",
812 "Leasetime",
813 self.orig_loc,
814 self.buf.as_ptr() as usize,
815 ))
816 }
817 pub fn get_scope(&self) -> Result<&'a CStr, ErrorContext> {
818 let mut iter = self.clone();
819 iter.pos = 0;
820 for attr in iter {
821 if let Ok(Server::Scope(val)) = attr {
822 return Ok(val);
823 }
824 }
825 Err(ErrorContext::new_missing(
826 "Server",
827 "Scope",
828 self.orig_loc,
829 self.buf.as_ptr() as usize,
830 ))
831 }
832 pub fn get_min_threads(&self) -> Result<u32, ErrorContext> {
833 let mut iter = self.clone();
834 iter.pos = 0;
835 for attr in iter {
836 if let Ok(Server::MinThreads(val)) = attr {
837 return Ok(val);
838 }
839 }
840 Err(ErrorContext::new_missing(
841 "Server",
842 "MinThreads",
843 self.orig_loc,
844 self.buf.as_ptr() as usize,
845 ))
846 }
847 pub fn get_fh_key(&self) -> Result<&'a [u8], ErrorContext> {
848 let mut iter = self.clone();
849 iter.pos = 0;
850 for attr in iter {
851 if let Ok(Server::FhKey(val)) = attr {
852 return Ok(val);
853 }
854 }
855 Err(ErrorContext::new_missing(
856 "Server",
857 "FhKey",
858 self.orig_loc,
859 self.buf.as_ptr() as usize,
860 ))
861 }
862}
863impl Server<'_> {
864 pub fn new<'a>(buf: &'a [u8]) -> IterableServer<'a> {
865 IterableServer::with_loc(buf, buf.as_ptr() as usize)
866 }
867 fn attr_from_type(r#type: u16) -> Option<&'static str> {
868 let res = match r#type {
869 1u16 => "Threads",
870 2u16 => "Gracetime",
871 3u16 => "Leasetime",
872 4u16 => "Scope",
873 5u16 => "MinThreads",
874 6u16 => "FhKey",
875 _ => return None,
876 };
877 Some(res)
878 }
879}
880#[derive(Clone, Copy, Default)]
881pub struct IterableServer<'a> {
882 buf: &'a [u8],
883 pos: usize,
884 orig_loc: usize,
885}
886impl<'a> IterableServer<'a> {
887 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
888 Self {
889 buf,
890 pos: 0,
891 orig_loc,
892 }
893 }
894 pub fn get_buf(&self) -> &'a [u8] {
895 self.buf
896 }
897}
898impl<'a> Iterator for IterableServer<'a> {
899 type Item = Result<Server<'a>, ErrorContext>;
900 fn next(&mut self) -> Option<Self::Item> {
901 let mut pos;
902 let mut r#type;
903 loop {
904 pos = self.pos;
905 r#type = None;
906 if self.buf.len() == self.pos {
907 return None;
908 }
909 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
910 self.pos = self.buf.len();
911 break;
912 };
913 r#type = Some(header.r#type);
914 let res = match header.r#type {
915 1u16 => Server::Threads({
916 let res = parse_u32(next);
917 let Some(val) = res else { break };
918 val
919 }),
920 2u16 => Server::Gracetime({
921 let res = parse_u32(next);
922 let Some(val) = res else { break };
923 val
924 }),
925 3u16 => Server::Leasetime({
926 let res = parse_u32(next);
927 let Some(val) = res else { break };
928 val
929 }),
930 4u16 => Server::Scope({
931 let res = CStr::from_bytes_with_nul(next).ok();
932 let Some(val) = res else { break };
933 val
934 }),
935 5u16 => Server::MinThreads({
936 let res = parse_u32(next);
937 let Some(val) = res else { break };
938 val
939 }),
940 6u16 => Server::FhKey({
941 let res = Some(next);
942 let Some(val) = res else { break };
943 val
944 }),
945 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
946 n => continue,
947 };
948 return Some(Ok(res));
949 }
950 Some(Err(ErrorContext::new(
951 "Server",
952 r#type.and_then(|t| Server::attr_from_type(t)),
953 self.orig_loc,
954 self.buf.as_ptr().wrapping_add(pos) as usize,
955 )))
956 }
957}
958impl<'a> std::fmt::Debug for IterableServer<'_> {
959 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
960 let mut fmt = f.debug_struct("Server");
961 for attr in self.clone() {
962 let attr = match attr {
963 Ok(a) => a,
964 Err(err) => {
965 fmt.finish()?;
966 f.write_str("Err(")?;
967 err.fmt(f)?;
968 return f.write_str(")");
969 }
970 };
971 match attr {
972 Server::Threads(val) => fmt.field("Threads", &val),
973 Server::Gracetime(val) => fmt.field("Gracetime", &val),
974 Server::Leasetime(val) => fmt.field("Leasetime", &val),
975 Server::Scope(val) => fmt.field("Scope", &val),
976 Server::MinThreads(val) => fmt.field("MinThreads", &val),
977 Server::FhKey(val) => fmt.field("FhKey", &val),
978 };
979 }
980 fmt.finish()
981 }
982}
983impl IterableServer<'_> {
984 pub fn lookup_attr(
985 &self,
986 offset: usize,
987 missing_type: Option<u16>,
988 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
989 let mut stack = Vec::new();
990 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
991 if missing_type.is_some() && cur == offset {
992 stack.push(("Server", offset));
993 return (stack, missing_type.and_then(|t| Server::attr_from_type(t)));
994 }
995 if cur > offset || cur + self.buf.len() < offset {
996 return (stack, None);
997 }
998 let mut attrs = self.clone();
999 let mut last_off = cur + attrs.pos;
1000 while let Some(attr) = attrs.next() {
1001 let Ok(attr) = attr else { break };
1002 match attr {
1003 Server::Threads(val) => {
1004 if last_off == offset {
1005 stack.push(("Threads", last_off));
1006 break;
1007 }
1008 }
1009 Server::Gracetime(val) => {
1010 if last_off == offset {
1011 stack.push(("Gracetime", last_off));
1012 break;
1013 }
1014 }
1015 Server::Leasetime(val) => {
1016 if last_off == offset {
1017 stack.push(("Leasetime", last_off));
1018 break;
1019 }
1020 }
1021 Server::Scope(val) => {
1022 if last_off == offset {
1023 stack.push(("Scope", last_off));
1024 break;
1025 }
1026 }
1027 Server::MinThreads(val) => {
1028 if last_off == offset {
1029 stack.push(("MinThreads", last_off));
1030 break;
1031 }
1032 }
1033 Server::FhKey(val) => {
1034 if last_off == offset {
1035 stack.push(("FhKey", last_off));
1036 break;
1037 }
1038 }
1039 _ => {}
1040 };
1041 last_off = cur + attrs.pos;
1042 }
1043 if !stack.is_empty() {
1044 stack.push(("Server", cur));
1045 }
1046 (stack, None)
1047 }
1048}
1049#[derive(Clone)]
1050pub enum Version {
1051 Major(u32),
1052 Minor(u32),
1053 Enabled(()),
1054}
1055impl<'a> IterableVersion<'a> {
1056 pub fn get_major(&self) -> Result<u32, ErrorContext> {
1057 let mut iter = self.clone();
1058 iter.pos = 0;
1059 for attr in iter {
1060 if let Ok(Version::Major(val)) = attr {
1061 return Ok(val);
1062 }
1063 }
1064 Err(ErrorContext::new_missing(
1065 "Version",
1066 "Major",
1067 self.orig_loc,
1068 self.buf.as_ptr() as usize,
1069 ))
1070 }
1071 pub fn get_minor(&self) -> Result<u32, ErrorContext> {
1072 let mut iter = self.clone();
1073 iter.pos = 0;
1074 for attr in iter {
1075 if let Ok(Version::Minor(val)) = attr {
1076 return Ok(val);
1077 }
1078 }
1079 Err(ErrorContext::new_missing(
1080 "Version",
1081 "Minor",
1082 self.orig_loc,
1083 self.buf.as_ptr() as usize,
1084 ))
1085 }
1086 pub fn get_enabled(&self) -> Result<(), ErrorContext> {
1087 let mut iter = self.clone();
1088 iter.pos = 0;
1089 for attr in iter {
1090 if let Ok(Version::Enabled(val)) = attr {
1091 return Ok(val);
1092 }
1093 }
1094 Err(ErrorContext::new_missing(
1095 "Version",
1096 "Enabled",
1097 self.orig_loc,
1098 self.buf.as_ptr() as usize,
1099 ))
1100 }
1101}
1102impl Version {
1103 pub fn new<'a>(buf: &'a [u8]) -> IterableVersion<'a> {
1104 IterableVersion::with_loc(buf, buf.as_ptr() as usize)
1105 }
1106 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1107 let res = match r#type {
1108 1u16 => "Major",
1109 2u16 => "Minor",
1110 3u16 => "Enabled",
1111 _ => return None,
1112 };
1113 Some(res)
1114 }
1115}
1116#[derive(Clone, Copy, Default)]
1117pub struct IterableVersion<'a> {
1118 buf: &'a [u8],
1119 pos: usize,
1120 orig_loc: usize,
1121}
1122impl<'a> IterableVersion<'a> {
1123 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1124 Self {
1125 buf,
1126 pos: 0,
1127 orig_loc,
1128 }
1129 }
1130 pub fn get_buf(&self) -> &'a [u8] {
1131 self.buf
1132 }
1133}
1134impl<'a> Iterator for IterableVersion<'a> {
1135 type Item = Result<Version, ErrorContext>;
1136 fn next(&mut self) -> Option<Self::Item> {
1137 let mut pos;
1138 let mut r#type;
1139 loop {
1140 pos = self.pos;
1141 r#type = None;
1142 if self.buf.len() == self.pos {
1143 return None;
1144 }
1145 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1146 self.pos = self.buf.len();
1147 break;
1148 };
1149 r#type = Some(header.r#type);
1150 let res = match header.r#type {
1151 1u16 => Version::Major({
1152 let res = parse_u32(next);
1153 let Some(val) = res else { break };
1154 val
1155 }),
1156 2u16 => Version::Minor({
1157 let res = parse_u32(next);
1158 let Some(val) = res else { break };
1159 val
1160 }),
1161 3u16 => Version::Enabled(()),
1162 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1163 n => continue,
1164 };
1165 return Some(Ok(res));
1166 }
1167 Some(Err(ErrorContext::new(
1168 "Version",
1169 r#type.and_then(|t| Version::attr_from_type(t)),
1170 self.orig_loc,
1171 self.buf.as_ptr().wrapping_add(pos) as usize,
1172 )))
1173 }
1174}
1175impl std::fmt::Debug for IterableVersion<'_> {
1176 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1177 let mut fmt = f.debug_struct("Version");
1178 for attr in self.clone() {
1179 let attr = match attr {
1180 Ok(a) => a,
1181 Err(err) => {
1182 fmt.finish()?;
1183 f.write_str("Err(")?;
1184 err.fmt(f)?;
1185 return f.write_str(")");
1186 }
1187 };
1188 match attr {
1189 Version::Major(val) => fmt.field("Major", &val),
1190 Version::Minor(val) => fmt.field("Minor", &val),
1191 Version::Enabled(val) => fmt.field("Enabled", &val),
1192 };
1193 }
1194 fmt.finish()
1195 }
1196}
1197impl IterableVersion<'_> {
1198 pub fn lookup_attr(
1199 &self,
1200 offset: usize,
1201 missing_type: Option<u16>,
1202 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1203 let mut stack = Vec::new();
1204 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1205 if missing_type.is_some() && cur == offset {
1206 stack.push(("Version", offset));
1207 return (stack, missing_type.and_then(|t| Version::attr_from_type(t)));
1208 }
1209 if cur > offset || cur + self.buf.len() < offset {
1210 return (stack, None);
1211 }
1212 let mut attrs = self.clone();
1213 let mut last_off = cur + attrs.pos;
1214 while let Some(attr) = attrs.next() {
1215 let Ok(attr) = attr else { break };
1216 match attr {
1217 Version::Major(val) => {
1218 if last_off == offset {
1219 stack.push(("Major", last_off));
1220 break;
1221 }
1222 }
1223 Version::Minor(val) => {
1224 if last_off == offset {
1225 stack.push(("Minor", last_off));
1226 break;
1227 }
1228 }
1229 Version::Enabled(val) => {
1230 if last_off == offset {
1231 stack.push(("Enabled", last_off));
1232 break;
1233 }
1234 }
1235 _ => {}
1236 };
1237 last_off = cur + attrs.pos;
1238 }
1239 if !stack.is_empty() {
1240 stack.push(("Version", cur));
1241 }
1242 (stack, None)
1243 }
1244}
1245#[derive(Clone)]
1246pub enum ServerProto<'a> {
1247 #[doc = "Attribute may repeat multiple times (treat it as array)"]
1248 Version(IterableVersion<'a>),
1249}
1250impl<'a> IterableServerProto<'a> {
1251 #[doc = "Attribute may repeat multiple times (treat it as array)"]
1252 pub fn get_version(&self) -> MultiAttrIterable<Self, ServerProto<'a>, IterableVersion<'a>> {
1253 MultiAttrIterable::new(self.clone(), |variant| {
1254 if let ServerProto::Version(val) = variant {
1255 Some(val)
1256 } else {
1257 None
1258 }
1259 })
1260 }
1261}
1262impl ServerProto<'_> {
1263 pub fn new<'a>(buf: &'a [u8]) -> IterableServerProto<'a> {
1264 IterableServerProto::with_loc(buf, buf.as_ptr() as usize)
1265 }
1266 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1267 let res = match r#type {
1268 1u16 => "Version",
1269 _ => return None,
1270 };
1271 Some(res)
1272 }
1273}
1274#[derive(Clone, Copy, Default)]
1275pub struct IterableServerProto<'a> {
1276 buf: &'a [u8],
1277 pos: usize,
1278 orig_loc: usize,
1279}
1280impl<'a> IterableServerProto<'a> {
1281 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1282 Self {
1283 buf,
1284 pos: 0,
1285 orig_loc,
1286 }
1287 }
1288 pub fn get_buf(&self) -> &'a [u8] {
1289 self.buf
1290 }
1291}
1292impl<'a> Iterator for IterableServerProto<'a> {
1293 type Item = Result<ServerProto<'a>, ErrorContext>;
1294 fn next(&mut self) -> Option<Self::Item> {
1295 let mut pos;
1296 let mut r#type;
1297 loop {
1298 pos = self.pos;
1299 r#type = None;
1300 if self.buf.len() == self.pos {
1301 return None;
1302 }
1303 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1304 self.pos = self.buf.len();
1305 break;
1306 };
1307 r#type = Some(header.r#type);
1308 let res = match header.r#type {
1309 1u16 => ServerProto::Version({
1310 let res = Some(IterableVersion::with_loc(next, self.orig_loc));
1311 let Some(val) = res else { break };
1312 val
1313 }),
1314 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1315 n => continue,
1316 };
1317 return Some(Ok(res));
1318 }
1319 Some(Err(ErrorContext::new(
1320 "ServerProto",
1321 r#type.and_then(|t| ServerProto::attr_from_type(t)),
1322 self.orig_loc,
1323 self.buf.as_ptr().wrapping_add(pos) as usize,
1324 )))
1325 }
1326}
1327impl<'a> std::fmt::Debug for IterableServerProto<'_> {
1328 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1329 let mut fmt = f.debug_struct("ServerProto");
1330 for attr in self.clone() {
1331 let attr = match attr {
1332 Ok(a) => a,
1333 Err(err) => {
1334 fmt.finish()?;
1335 f.write_str("Err(")?;
1336 err.fmt(f)?;
1337 return f.write_str(")");
1338 }
1339 };
1340 match attr {
1341 ServerProto::Version(val) => fmt.field("Version", &val),
1342 };
1343 }
1344 fmt.finish()
1345 }
1346}
1347impl IterableServerProto<'_> {
1348 pub fn lookup_attr(
1349 &self,
1350 offset: usize,
1351 missing_type: Option<u16>,
1352 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1353 let mut stack = Vec::new();
1354 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1355 if missing_type.is_some() && cur == offset {
1356 stack.push(("ServerProto", offset));
1357 return (
1358 stack,
1359 missing_type.and_then(|t| ServerProto::attr_from_type(t)),
1360 );
1361 }
1362 if cur > offset || cur + self.buf.len() < offset {
1363 return (stack, None);
1364 }
1365 let mut attrs = self.clone();
1366 let mut last_off = cur + attrs.pos;
1367 let mut missing = None;
1368 while let Some(attr) = attrs.next() {
1369 let Ok(attr) = attr else { break };
1370 match attr {
1371 ServerProto::Version(val) => {
1372 (stack, missing) = val.lookup_attr(offset, missing_type);
1373 if !stack.is_empty() {
1374 break;
1375 }
1376 }
1377 _ => {}
1378 };
1379 last_off = cur + attrs.pos;
1380 }
1381 if !stack.is_empty() {
1382 stack.push(("ServerProto", cur));
1383 }
1384 (stack, missing)
1385 }
1386}
1387#[derive(Clone)]
1388pub enum Sock<'a> {
1389 Addr(&'a [u8]),
1390 TransportName(&'a CStr),
1391}
1392impl<'a> IterableSock<'a> {
1393 pub fn get_addr(&self) -> Result<&'a [u8], ErrorContext> {
1394 let mut iter = self.clone();
1395 iter.pos = 0;
1396 for attr in iter {
1397 if let Ok(Sock::Addr(val)) = attr {
1398 return Ok(val);
1399 }
1400 }
1401 Err(ErrorContext::new_missing(
1402 "Sock",
1403 "Addr",
1404 self.orig_loc,
1405 self.buf.as_ptr() as usize,
1406 ))
1407 }
1408 pub fn get_transport_name(&self) -> Result<&'a CStr, ErrorContext> {
1409 let mut iter = self.clone();
1410 iter.pos = 0;
1411 for attr in iter {
1412 if let Ok(Sock::TransportName(val)) = attr {
1413 return Ok(val);
1414 }
1415 }
1416 Err(ErrorContext::new_missing(
1417 "Sock",
1418 "TransportName",
1419 self.orig_loc,
1420 self.buf.as_ptr() as usize,
1421 ))
1422 }
1423}
1424impl Sock<'_> {
1425 pub fn new<'a>(buf: &'a [u8]) -> IterableSock<'a> {
1426 IterableSock::with_loc(buf, buf.as_ptr() as usize)
1427 }
1428 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1429 let res = match r#type {
1430 1u16 => "Addr",
1431 2u16 => "TransportName",
1432 _ => return None,
1433 };
1434 Some(res)
1435 }
1436}
1437#[derive(Clone, Copy, Default)]
1438pub struct IterableSock<'a> {
1439 buf: &'a [u8],
1440 pos: usize,
1441 orig_loc: usize,
1442}
1443impl<'a> IterableSock<'a> {
1444 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1445 Self {
1446 buf,
1447 pos: 0,
1448 orig_loc,
1449 }
1450 }
1451 pub fn get_buf(&self) -> &'a [u8] {
1452 self.buf
1453 }
1454}
1455impl<'a> Iterator for IterableSock<'a> {
1456 type Item = Result<Sock<'a>, ErrorContext>;
1457 fn next(&mut self) -> Option<Self::Item> {
1458 let mut pos;
1459 let mut r#type;
1460 loop {
1461 pos = self.pos;
1462 r#type = None;
1463 if self.buf.len() == self.pos {
1464 return None;
1465 }
1466 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1467 self.pos = self.buf.len();
1468 break;
1469 };
1470 r#type = Some(header.r#type);
1471 let res = match header.r#type {
1472 1u16 => Sock::Addr({
1473 let res = Some(next);
1474 let Some(val) = res else { break };
1475 val
1476 }),
1477 2u16 => Sock::TransportName({
1478 let res = CStr::from_bytes_with_nul(next).ok();
1479 let Some(val) = res else { break };
1480 val
1481 }),
1482 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1483 n => continue,
1484 };
1485 return Some(Ok(res));
1486 }
1487 Some(Err(ErrorContext::new(
1488 "Sock",
1489 r#type.and_then(|t| Sock::attr_from_type(t)),
1490 self.orig_loc,
1491 self.buf.as_ptr().wrapping_add(pos) as usize,
1492 )))
1493 }
1494}
1495impl<'a> std::fmt::Debug for IterableSock<'_> {
1496 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1497 let mut fmt = f.debug_struct("Sock");
1498 for attr in self.clone() {
1499 let attr = match attr {
1500 Ok(a) => a,
1501 Err(err) => {
1502 fmt.finish()?;
1503 f.write_str("Err(")?;
1504 err.fmt(f)?;
1505 return f.write_str(")");
1506 }
1507 };
1508 match attr {
1509 Sock::Addr(val) => fmt.field("Addr", &val),
1510 Sock::TransportName(val) => fmt.field("TransportName", &val),
1511 };
1512 }
1513 fmt.finish()
1514 }
1515}
1516impl IterableSock<'_> {
1517 pub fn lookup_attr(
1518 &self,
1519 offset: usize,
1520 missing_type: Option<u16>,
1521 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1522 let mut stack = Vec::new();
1523 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1524 if missing_type.is_some() && cur == offset {
1525 stack.push(("Sock", offset));
1526 return (stack, missing_type.and_then(|t| Sock::attr_from_type(t)));
1527 }
1528 if cur > offset || cur + self.buf.len() < offset {
1529 return (stack, None);
1530 }
1531 let mut attrs = self.clone();
1532 let mut last_off = cur + attrs.pos;
1533 while let Some(attr) = attrs.next() {
1534 let Ok(attr) = attr else { break };
1535 match attr {
1536 Sock::Addr(val) => {
1537 if last_off == offset {
1538 stack.push(("Addr", last_off));
1539 break;
1540 }
1541 }
1542 Sock::TransportName(val) => {
1543 if last_off == offset {
1544 stack.push(("TransportName", last_off));
1545 break;
1546 }
1547 }
1548 _ => {}
1549 };
1550 last_off = cur + attrs.pos;
1551 }
1552 if !stack.is_empty() {
1553 stack.push(("Sock", cur));
1554 }
1555 (stack, None)
1556 }
1557}
1558#[derive(Clone)]
1559pub enum ServerSock<'a> {
1560 #[doc = "Attribute may repeat multiple times (treat it as array)"]
1561 Addr(IterableSock<'a>),
1562}
1563impl<'a> IterableServerSock<'a> {
1564 #[doc = "Attribute may repeat multiple times (treat it as array)"]
1565 pub fn get_addr(&self) -> MultiAttrIterable<Self, ServerSock<'a>, IterableSock<'a>> {
1566 MultiAttrIterable::new(self.clone(), |variant| {
1567 if let ServerSock::Addr(val) = variant {
1568 Some(val)
1569 } else {
1570 None
1571 }
1572 })
1573 }
1574}
1575impl ServerSock<'_> {
1576 pub fn new<'a>(buf: &'a [u8]) -> IterableServerSock<'a> {
1577 IterableServerSock::with_loc(buf, buf.as_ptr() as usize)
1578 }
1579 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1580 let res = match r#type {
1581 1u16 => "Addr",
1582 _ => return None,
1583 };
1584 Some(res)
1585 }
1586}
1587#[derive(Clone, Copy, Default)]
1588pub struct IterableServerSock<'a> {
1589 buf: &'a [u8],
1590 pos: usize,
1591 orig_loc: usize,
1592}
1593impl<'a> IterableServerSock<'a> {
1594 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1595 Self {
1596 buf,
1597 pos: 0,
1598 orig_loc,
1599 }
1600 }
1601 pub fn get_buf(&self) -> &'a [u8] {
1602 self.buf
1603 }
1604}
1605impl<'a> Iterator for IterableServerSock<'a> {
1606 type Item = Result<ServerSock<'a>, ErrorContext>;
1607 fn next(&mut self) -> Option<Self::Item> {
1608 let mut pos;
1609 let mut r#type;
1610 loop {
1611 pos = self.pos;
1612 r#type = None;
1613 if self.buf.len() == self.pos {
1614 return None;
1615 }
1616 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1617 self.pos = self.buf.len();
1618 break;
1619 };
1620 r#type = Some(header.r#type);
1621 let res = match header.r#type {
1622 1u16 => ServerSock::Addr({
1623 let res = Some(IterableSock::with_loc(next, self.orig_loc));
1624 let Some(val) = res else { break };
1625 val
1626 }),
1627 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1628 n => continue,
1629 };
1630 return Some(Ok(res));
1631 }
1632 Some(Err(ErrorContext::new(
1633 "ServerSock",
1634 r#type.and_then(|t| ServerSock::attr_from_type(t)),
1635 self.orig_loc,
1636 self.buf.as_ptr().wrapping_add(pos) as usize,
1637 )))
1638 }
1639}
1640impl<'a> std::fmt::Debug for IterableServerSock<'_> {
1641 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1642 let mut fmt = f.debug_struct("ServerSock");
1643 for attr in self.clone() {
1644 let attr = match attr {
1645 Ok(a) => a,
1646 Err(err) => {
1647 fmt.finish()?;
1648 f.write_str("Err(")?;
1649 err.fmt(f)?;
1650 return f.write_str(")");
1651 }
1652 };
1653 match attr {
1654 ServerSock::Addr(val) => fmt.field("Addr", &val),
1655 };
1656 }
1657 fmt.finish()
1658 }
1659}
1660impl IterableServerSock<'_> {
1661 pub fn lookup_attr(
1662 &self,
1663 offset: usize,
1664 missing_type: Option<u16>,
1665 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1666 let mut stack = Vec::new();
1667 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1668 if missing_type.is_some() && cur == offset {
1669 stack.push(("ServerSock", offset));
1670 return (
1671 stack,
1672 missing_type.and_then(|t| ServerSock::attr_from_type(t)),
1673 );
1674 }
1675 if cur > offset || cur + self.buf.len() < offset {
1676 return (stack, None);
1677 }
1678 let mut attrs = self.clone();
1679 let mut last_off = cur + attrs.pos;
1680 let mut missing = None;
1681 while let Some(attr) = attrs.next() {
1682 let Ok(attr) = attr else { break };
1683 match attr {
1684 ServerSock::Addr(val) => {
1685 (stack, missing) = val.lookup_attr(offset, missing_type);
1686 if !stack.is_empty() {
1687 break;
1688 }
1689 }
1690 _ => {}
1691 };
1692 last_off = cur + attrs.pos;
1693 }
1694 if !stack.is_empty() {
1695 stack.push(("ServerSock", cur));
1696 }
1697 (stack, missing)
1698 }
1699}
1700#[derive(Clone)]
1701pub enum PoolMode<'a> {
1702 Mode(&'a CStr),
1703 Npools(u32),
1704}
1705impl<'a> IterablePoolMode<'a> {
1706 pub fn get_mode(&self) -> Result<&'a CStr, ErrorContext> {
1707 let mut iter = self.clone();
1708 iter.pos = 0;
1709 for attr in iter {
1710 if let Ok(PoolMode::Mode(val)) = attr {
1711 return Ok(val);
1712 }
1713 }
1714 Err(ErrorContext::new_missing(
1715 "PoolMode",
1716 "Mode",
1717 self.orig_loc,
1718 self.buf.as_ptr() as usize,
1719 ))
1720 }
1721 pub fn get_npools(&self) -> Result<u32, ErrorContext> {
1722 let mut iter = self.clone();
1723 iter.pos = 0;
1724 for attr in iter {
1725 if let Ok(PoolMode::Npools(val)) = attr {
1726 return Ok(val);
1727 }
1728 }
1729 Err(ErrorContext::new_missing(
1730 "PoolMode",
1731 "Npools",
1732 self.orig_loc,
1733 self.buf.as_ptr() as usize,
1734 ))
1735 }
1736}
1737impl PoolMode<'_> {
1738 pub fn new<'a>(buf: &'a [u8]) -> IterablePoolMode<'a> {
1739 IterablePoolMode::with_loc(buf, buf.as_ptr() as usize)
1740 }
1741 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1742 let res = match r#type {
1743 1u16 => "Mode",
1744 2u16 => "Npools",
1745 _ => return None,
1746 };
1747 Some(res)
1748 }
1749}
1750#[derive(Clone, Copy, Default)]
1751pub struct IterablePoolMode<'a> {
1752 buf: &'a [u8],
1753 pos: usize,
1754 orig_loc: usize,
1755}
1756impl<'a> IterablePoolMode<'a> {
1757 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1758 Self {
1759 buf,
1760 pos: 0,
1761 orig_loc,
1762 }
1763 }
1764 pub fn get_buf(&self) -> &'a [u8] {
1765 self.buf
1766 }
1767}
1768impl<'a> Iterator for IterablePoolMode<'a> {
1769 type Item = Result<PoolMode<'a>, ErrorContext>;
1770 fn next(&mut self) -> Option<Self::Item> {
1771 let mut pos;
1772 let mut r#type;
1773 loop {
1774 pos = self.pos;
1775 r#type = None;
1776 if self.buf.len() == self.pos {
1777 return None;
1778 }
1779 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1780 self.pos = self.buf.len();
1781 break;
1782 };
1783 r#type = Some(header.r#type);
1784 let res = match header.r#type {
1785 1u16 => PoolMode::Mode({
1786 let res = CStr::from_bytes_with_nul(next).ok();
1787 let Some(val) = res else { break };
1788 val
1789 }),
1790 2u16 => PoolMode::Npools({
1791 let res = parse_u32(next);
1792 let Some(val) = res else { break };
1793 val
1794 }),
1795 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1796 n => continue,
1797 };
1798 return Some(Ok(res));
1799 }
1800 Some(Err(ErrorContext::new(
1801 "PoolMode",
1802 r#type.and_then(|t| PoolMode::attr_from_type(t)),
1803 self.orig_loc,
1804 self.buf.as_ptr().wrapping_add(pos) as usize,
1805 )))
1806 }
1807}
1808impl<'a> std::fmt::Debug for IterablePoolMode<'_> {
1809 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1810 let mut fmt = f.debug_struct("PoolMode");
1811 for attr in self.clone() {
1812 let attr = match attr {
1813 Ok(a) => a,
1814 Err(err) => {
1815 fmt.finish()?;
1816 f.write_str("Err(")?;
1817 err.fmt(f)?;
1818 return f.write_str(")");
1819 }
1820 };
1821 match attr {
1822 PoolMode::Mode(val) => fmt.field("Mode", &val),
1823 PoolMode::Npools(val) => fmt.field("Npools", &val),
1824 };
1825 }
1826 fmt.finish()
1827 }
1828}
1829impl IterablePoolMode<'_> {
1830 pub fn lookup_attr(
1831 &self,
1832 offset: usize,
1833 missing_type: Option<u16>,
1834 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1835 let mut stack = Vec::new();
1836 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1837 if missing_type.is_some() && cur == offset {
1838 stack.push(("PoolMode", offset));
1839 return (
1840 stack,
1841 missing_type.and_then(|t| PoolMode::attr_from_type(t)),
1842 );
1843 }
1844 if cur > offset || cur + self.buf.len() < offset {
1845 return (stack, None);
1846 }
1847 let mut attrs = self.clone();
1848 let mut last_off = cur + attrs.pos;
1849 while let Some(attr) = attrs.next() {
1850 let Ok(attr) = attr else { break };
1851 match attr {
1852 PoolMode::Mode(val) => {
1853 if last_off == offset {
1854 stack.push(("Mode", last_off));
1855 break;
1856 }
1857 }
1858 PoolMode::Npools(val) => {
1859 if last_off == offset {
1860 stack.push(("Npools", last_off));
1861 break;
1862 }
1863 }
1864 _ => {}
1865 };
1866 last_off = cur + attrs.pos;
1867 }
1868 if !stack.is_empty() {
1869 stack.push(("PoolMode", cur));
1870 }
1871 (stack, None)
1872 }
1873}
1874#[derive(Clone)]
1875pub enum Fslocation<'a> {
1876 Host(&'a CStr),
1877 Path(&'a CStr),
1878}
1879impl<'a> IterableFslocation<'a> {
1880 pub fn get_host(&self) -> Result<&'a CStr, ErrorContext> {
1881 let mut iter = self.clone();
1882 iter.pos = 0;
1883 for attr in iter {
1884 if let Ok(Fslocation::Host(val)) = attr {
1885 return Ok(val);
1886 }
1887 }
1888 Err(ErrorContext::new_missing(
1889 "Fslocation",
1890 "Host",
1891 self.orig_loc,
1892 self.buf.as_ptr() as usize,
1893 ))
1894 }
1895 pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
1896 let mut iter = self.clone();
1897 iter.pos = 0;
1898 for attr in iter {
1899 if let Ok(Fslocation::Path(val)) = attr {
1900 return Ok(val);
1901 }
1902 }
1903 Err(ErrorContext::new_missing(
1904 "Fslocation",
1905 "Path",
1906 self.orig_loc,
1907 self.buf.as_ptr() as usize,
1908 ))
1909 }
1910}
1911impl Fslocation<'_> {
1912 pub fn new<'a>(buf: &'a [u8]) -> IterableFslocation<'a> {
1913 IterableFslocation::with_loc(buf, buf.as_ptr() as usize)
1914 }
1915 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1916 let res = match r#type {
1917 1u16 => "Host",
1918 2u16 => "Path",
1919 _ => return None,
1920 };
1921 Some(res)
1922 }
1923}
1924#[derive(Clone, Copy, Default)]
1925pub struct IterableFslocation<'a> {
1926 buf: &'a [u8],
1927 pos: usize,
1928 orig_loc: usize,
1929}
1930impl<'a> IterableFslocation<'a> {
1931 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1932 Self {
1933 buf,
1934 pos: 0,
1935 orig_loc,
1936 }
1937 }
1938 pub fn get_buf(&self) -> &'a [u8] {
1939 self.buf
1940 }
1941}
1942impl<'a> Iterator for IterableFslocation<'a> {
1943 type Item = Result<Fslocation<'a>, ErrorContext>;
1944 fn next(&mut self) -> Option<Self::Item> {
1945 let mut pos;
1946 let mut r#type;
1947 loop {
1948 pos = self.pos;
1949 r#type = None;
1950 if self.buf.len() == self.pos {
1951 return None;
1952 }
1953 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1954 self.pos = self.buf.len();
1955 break;
1956 };
1957 r#type = Some(header.r#type);
1958 let res = match header.r#type {
1959 1u16 => Fslocation::Host({
1960 let res = CStr::from_bytes_with_nul(next).ok();
1961 let Some(val) = res else { break };
1962 val
1963 }),
1964 2u16 => Fslocation::Path({
1965 let res = CStr::from_bytes_with_nul(next).ok();
1966 let Some(val) = res else { break };
1967 val
1968 }),
1969 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1970 n => continue,
1971 };
1972 return Some(Ok(res));
1973 }
1974 Some(Err(ErrorContext::new(
1975 "Fslocation",
1976 r#type.and_then(|t| Fslocation::attr_from_type(t)),
1977 self.orig_loc,
1978 self.buf.as_ptr().wrapping_add(pos) as usize,
1979 )))
1980 }
1981}
1982impl<'a> std::fmt::Debug for IterableFslocation<'_> {
1983 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1984 let mut fmt = f.debug_struct("Fslocation");
1985 for attr in self.clone() {
1986 let attr = match attr {
1987 Ok(a) => a,
1988 Err(err) => {
1989 fmt.finish()?;
1990 f.write_str("Err(")?;
1991 err.fmt(f)?;
1992 return f.write_str(")");
1993 }
1994 };
1995 match attr {
1996 Fslocation::Host(val) => fmt.field("Host", &val),
1997 Fslocation::Path(val) => fmt.field("Path", &val),
1998 };
1999 }
2000 fmt.finish()
2001 }
2002}
2003impl IterableFslocation<'_> {
2004 pub fn lookup_attr(
2005 &self,
2006 offset: usize,
2007 missing_type: Option<u16>,
2008 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2009 let mut stack = Vec::new();
2010 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2011 if missing_type.is_some() && cur == offset {
2012 stack.push(("Fslocation", offset));
2013 return (
2014 stack,
2015 missing_type.and_then(|t| Fslocation::attr_from_type(t)),
2016 );
2017 }
2018 if cur > offset || cur + self.buf.len() < offset {
2019 return (stack, None);
2020 }
2021 let mut attrs = self.clone();
2022 let mut last_off = cur + attrs.pos;
2023 while let Some(attr) = attrs.next() {
2024 let Ok(attr) = attr else { break };
2025 match attr {
2026 Fslocation::Host(val) => {
2027 if last_off == offset {
2028 stack.push(("Host", last_off));
2029 break;
2030 }
2031 }
2032 Fslocation::Path(val) => {
2033 if last_off == offset {
2034 stack.push(("Path", last_off));
2035 break;
2036 }
2037 }
2038 _ => {}
2039 };
2040 last_off = cur + attrs.pos;
2041 }
2042 if !stack.is_empty() {
2043 stack.push(("Fslocation", cur));
2044 }
2045 (stack, None)
2046 }
2047}
2048#[derive(Clone)]
2049pub enum Fslocations<'a> {
2050 #[doc = "Attribute may repeat multiple times (treat it as array)"]
2051 Location(IterableFslocation<'a>),
2052}
2053impl<'a> IterableFslocations<'a> {
2054 #[doc = "Attribute may repeat multiple times (treat it as array)"]
2055 pub fn get_location(&self) -> MultiAttrIterable<Self, Fslocations<'a>, IterableFslocation<'a>> {
2056 MultiAttrIterable::new(self.clone(), |variant| {
2057 if let Fslocations::Location(val) = variant {
2058 Some(val)
2059 } else {
2060 None
2061 }
2062 })
2063 }
2064}
2065impl Fslocations<'_> {
2066 pub fn new<'a>(buf: &'a [u8]) -> IterableFslocations<'a> {
2067 IterableFslocations::with_loc(buf, buf.as_ptr() as usize)
2068 }
2069 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2070 let res = match r#type {
2071 1u16 => "Location",
2072 _ => return None,
2073 };
2074 Some(res)
2075 }
2076}
2077#[derive(Clone, Copy, Default)]
2078pub struct IterableFslocations<'a> {
2079 buf: &'a [u8],
2080 pos: usize,
2081 orig_loc: usize,
2082}
2083impl<'a> IterableFslocations<'a> {
2084 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2085 Self {
2086 buf,
2087 pos: 0,
2088 orig_loc,
2089 }
2090 }
2091 pub fn get_buf(&self) -> &'a [u8] {
2092 self.buf
2093 }
2094}
2095impl<'a> Iterator for IterableFslocations<'a> {
2096 type Item = Result<Fslocations<'a>, ErrorContext>;
2097 fn next(&mut self) -> Option<Self::Item> {
2098 let mut pos;
2099 let mut r#type;
2100 loop {
2101 pos = self.pos;
2102 r#type = None;
2103 if self.buf.len() == self.pos {
2104 return None;
2105 }
2106 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2107 self.pos = self.buf.len();
2108 break;
2109 };
2110 r#type = Some(header.r#type);
2111 let res = match header.r#type {
2112 1u16 => Fslocations::Location({
2113 let res = Some(IterableFslocation::with_loc(next, self.orig_loc));
2114 let Some(val) = res else { break };
2115 val
2116 }),
2117 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2118 n => continue,
2119 };
2120 return Some(Ok(res));
2121 }
2122 Some(Err(ErrorContext::new(
2123 "Fslocations",
2124 r#type.and_then(|t| Fslocations::attr_from_type(t)),
2125 self.orig_loc,
2126 self.buf.as_ptr().wrapping_add(pos) as usize,
2127 )))
2128 }
2129}
2130impl<'a> std::fmt::Debug for IterableFslocations<'_> {
2131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2132 let mut fmt = f.debug_struct("Fslocations");
2133 for attr in self.clone() {
2134 let attr = match attr {
2135 Ok(a) => a,
2136 Err(err) => {
2137 fmt.finish()?;
2138 f.write_str("Err(")?;
2139 err.fmt(f)?;
2140 return f.write_str(")");
2141 }
2142 };
2143 match attr {
2144 Fslocations::Location(val) => fmt.field("Location", &val),
2145 };
2146 }
2147 fmt.finish()
2148 }
2149}
2150impl IterableFslocations<'_> {
2151 pub fn lookup_attr(
2152 &self,
2153 offset: usize,
2154 missing_type: Option<u16>,
2155 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2156 let mut stack = Vec::new();
2157 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2158 if missing_type.is_some() && cur == offset {
2159 stack.push(("Fslocations", offset));
2160 return (
2161 stack,
2162 missing_type.and_then(|t| Fslocations::attr_from_type(t)),
2163 );
2164 }
2165 if cur > offset || cur + self.buf.len() < offset {
2166 return (stack, None);
2167 }
2168 let mut attrs = self.clone();
2169 let mut last_off = cur + attrs.pos;
2170 let mut missing = None;
2171 while let Some(attr) = attrs.next() {
2172 let Ok(attr) = attr else { break };
2173 match attr {
2174 Fslocations::Location(val) => {
2175 (stack, missing) = val.lookup_attr(offset, missing_type);
2176 if !stack.is_empty() {
2177 break;
2178 }
2179 }
2180 _ => {}
2181 };
2182 last_off = cur + attrs.pos;
2183 }
2184 if !stack.is_empty() {
2185 stack.push(("Fslocations", cur));
2186 }
2187 (stack, missing)
2188 }
2189}
2190#[derive(Clone)]
2191pub enum AuthFlavor {
2192 Pseudoflavor(u32),
2193 #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
2194 Flags(u32),
2195}
2196impl<'a> IterableAuthFlavor<'a> {
2197 pub fn get_pseudoflavor(&self) -> Result<u32, ErrorContext> {
2198 let mut iter = self.clone();
2199 iter.pos = 0;
2200 for attr in iter {
2201 if let Ok(AuthFlavor::Pseudoflavor(val)) = attr {
2202 return Ok(val);
2203 }
2204 }
2205 Err(ErrorContext::new_missing(
2206 "AuthFlavor",
2207 "Pseudoflavor",
2208 self.orig_loc,
2209 self.buf.as_ptr() as usize,
2210 ))
2211 }
2212 #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
2213 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
2214 let mut iter = self.clone();
2215 iter.pos = 0;
2216 for attr in iter {
2217 if let Ok(AuthFlavor::Flags(val)) = attr {
2218 return Ok(val);
2219 }
2220 }
2221 Err(ErrorContext::new_missing(
2222 "AuthFlavor",
2223 "Flags",
2224 self.orig_loc,
2225 self.buf.as_ptr() as usize,
2226 ))
2227 }
2228}
2229impl AuthFlavor {
2230 pub fn new<'a>(buf: &'a [u8]) -> IterableAuthFlavor<'a> {
2231 IterableAuthFlavor::with_loc(buf, buf.as_ptr() as usize)
2232 }
2233 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2234 let res = match r#type {
2235 1u16 => "Pseudoflavor",
2236 2u16 => "Flags",
2237 _ => return None,
2238 };
2239 Some(res)
2240 }
2241}
2242#[derive(Clone, Copy, Default)]
2243pub struct IterableAuthFlavor<'a> {
2244 buf: &'a [u8],
2245 pos: usize,
2246 orig_loc: usize,
2247}
2248impl<'a> IterableAuthFlavor<'a> {
2249 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2250 Self {
2251 buf,
2252 pos: 0,
2253 orig_loc,
2254 }
2255 }
2256 pub fn get_buf(&self) -> &'a [u8] {
2257 self.buf
2258 }
2259}
2260impl<'a> Iterator for IterableAuthFlavor<'a> {
2261 type Item = Result<AuthFlavor, ErrorContext>;
2262 fn next(&mut self) -> Option<Self::Item> {
2263 let mut pos;
2264 let mut r#type;
2265 loop {
2266 pos = self.pos;
2267 r#type = None;
2268 if self.buf.len() == self.pos {
2269 return None;
2270 }
2271 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2272 self.pos = self.buf.len();
2273 break;
2274 };
2275 r#type = Some(header.r#type);
2276 let res = match header.r#type {
2277 1u16 => AuthFlavor::Pseudoflavor({
2278 let res = parse_u32(next);
2279 let Some(val) = res else { break };
2280 val
2281 }),
2282 2u16 => AuthFlavor::Flags({
2283 let res = parse_u32(next);
2284 let Some(val) = res else { break };
2285 val
2286 }),
2287 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2288 n => continue,
2289 };
2290 return Some(Ok(res));
2291 }
2292 Some(Err(ErrorContext::new(
2293 "AuthFlavor",
2294 r#type.and_then(|t| AuthFlavor::attr_from_type(t)),
2295 self.orig_loc,
2296 self.buf.as_ptr().wrapping_add(pos) as usize,
2297 )))
2298 }
2299}
2300impl std::fmt::Debug for IterableAuthFlavor<'_> {
2301 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2302 let mut fmt = f.debug_struct("AuthFlavor");
2303 for attr in self.clone() {
2304 let attr = match attr {
2305 Ok(a) => a,
2306 Err(err) => {
2307 fmt.finish()?;
2308 f.write_str("Err(")?;
2309 err.fmt(f)?;
2310 return f.write_str(")");
2311 }
2312 };
2313 match attr {
2314 AuthFlavor::Pseudoflavor(val) => fmt.field("Pseudoflavor", &val),
2315 AuthFlavor::Flags(val) => {
2316 fmt.field("Flags", &FormatFlags(val.into(), ExportFlags::from_value))
2317 }
2318 };
2319 }
2320 fmt.finish()
2321 }
2322}
2323impl IterableAuthFlavor<'_> {
2324 pub fn lookup_attr(
2325 &self,
2326 offset: usize,
2327 missing_type: Option<u16>,
2328 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2329 let mut stack = Vec::new();
2330 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2331 if missing_type.is_some() && cur == offset {
2332 stack.push(("AuthFlavor", offset));
2333 return (
2334 stack,
2335 missing_type.and_then(|t| AuthFlavor::attr_from_type(t)),
2336 );
2337 }
2338 if cur > offset || cur + self.buf.len() < offset {
2339 return (stack, None);
2340 }
2341 let mut attrs = self.clone();
2342 let mut last_off = cur + attrs.pos;
2343 while let Some(attr) = attrs.next() {
2344 let Ok(attr) = attr else { break };
2345 match attr {
2346 AuthFlavor::Pseudoflavor(val) => {
2347 if last_off == offset {
2348 stack.push(("Pseudoflavor", last_off));
2349 break;
2350 }
2351 }
2352 AuthFlavor::Flags(val) => {
2353 if last_off == offset {
2354 stack.push(("Flags", last_off));
2355 break;
2356 }
2357 }
2358 _ => {}
2359 };
2360 last_off = cur + attrs.pos;
2361 }
2362 if !stack.is_empty() {
2363 stack.push(("AuthFlavor", cur));
2364 }
2365 (stack, None)
2366 }
2367}
2368#[derive(Clone)]
2369pub enum SvcExport<'a> {
2370 Seqno(u64),
2371 Client(&'a CStr),
2372 Path(&'a CStr),
2373 Negative(()),
2374 Expiry(u64),
2375 AnonUid(u32),
2376 AnonGid(u32),
2377 Fslocations(IterableFslocations<'a>),
2378 Uuid(&'a [u8]),
2379 #[doc = "Attribute may repeat multiple times (treat it as array)"]
2380 Secinfo(IterableAuthFlavor<'a>),
2381 #[doc = "Associated type: [`XprtsecMode`] (enum)\nAttribute may repeat multiple times (treat it as array)"]
2382 Xprtsec(u32),
2383 #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
2384 Flags(u32),
2385 Fsid(i32),
2386}
2387impl<'a> IterableSvcExport<'a> {
2388 pub fn get_seqno(&self) -> Result<u64, ErrorContext> {
2389 let mut iter = self.clone();
2390 iter.pos = 0;
2391 for attr in iter {
2392 if let Ok(SvcExport::Seqno(val)) = attr {
2393 return Ok(val);
2394 }
2395 }
2396 Err(ErrorContext::new_missing(
2397 "SvcExport",
2398 "Seqno",
2399 self.orig_loc,
2400 self.buf.as_ptr() as usize,
2401 ))
2402 }
2403 pub fn get_client(&self) -> Result<&'a CStr, ErrorContext> {
2404 let mut iter = self.clone();
2405 iter.pos = 0;
2406 for attr in iter {
2407 if let Ok(SvcExport::Client(val)) = attr {
2408 return Ok(val);
2409 }
2410 }
2411 Err(ErrorContext::new_missing(
2412 "SvcExport",
2413 "Client",
2414 self.orig_loc,
2415 self.buf.as_ptr() as usize,
2416 ))
2417 }
2418 pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
2419 let mut iter = self.clone();
2420 iter.pos = 0;
2421 for attr in iter {
2422 if let Ok(SvcExport::Path(val)) = attr {
2423 return Ok(val);
2424 }
2425 }
2426 Err(ErrorContext::new_missing(
2427 "SvcExport",
2428 "Path",
2429 self.orig_loc,
2430 self.buf.as_ptr() as usize,
2431 ))
2432 }
2433 pub fn get_negative(&self) -> Result<(), ErrorContext> {
2434 let mut iter = self.clone();
2435 iter.pos = 0;
2436 for attr in iter {
2437 if let Ok(SvcExport::Negative(val)) = attr {
2438 return Ok(val);
2439 }
2440 }
2441 Err(ErrorContext::new_missing(
2442 "SvcExport",
2443 "Negative",
2444 self.orig_loc,
2445 self.buf.as_ptr() as usize,
2446 ))
2447 }
2448 pub fn get_expiry(&self) -> Result<u64, ErrorContext> {
2449 let mut iter = self.clone();
2450 iter.pos = 0;
2451 for attr in iter {
2452 if let Ok(SvcExport::Expiry(val)) = attr {
2453 return Ok(val);
2454 }
2455 }
2456 Err(ErrorContext::new_missing(
2457 "SvcExport",
2458 "Expiry",
2459 self.orig_loc,
2460 self.buf.as_ptr() as usize,
2461 ))
2462 }
2463 pub fn get_anon_uid(&self) -> Result<u32, ErrorContext> {
2464 let mut iter = self.clone();
2465 iter.pos = 0;
2466 for attr in iter {
2467 if let Ok(SvcExport::AnonUid(val)) = attr {
2468 return Ok(val);
2469 }
2470 }
2471 Err(ErrorContext::new_missing(
2472 "SvcExport",
2473 "AnonUid",
2474 self.orig_loc,
2475 self.buf.as_ptr() as usize,
2476 ))
2477 }
2478 pub fn get_anon_gid(&self) -> Result<u32, ErrorContext> {
2479 let mut iter = self.clone();
2480 iter.pos = 0;
2481 for attr in iter {
2482 if let Ok(SvcExport::AnonGid(val)) = attr {
2483 return Ok(val);
2484 }
2485 }
2486 Err(ErrorContext::new_missing(
2487 "SvcExport",
2488 "AnonGid",
2489 self.orig_loc,
2490 self.buf.as_ptr() as usize,
2491 ))
2492 }
2493 pub fn get_fslocations(&self) -> Result<IterableFslocations<'a>, ErrorContext> {
2494 let mut iter = self.clone();
2495 iter.pos = 0;
2496 for attr in iter {
2497 if let Ok(SvcExport::Fslocations(val)) = attr {
2498 return Ok(val);
2499 }
2500 }
2501 Err(ErrorContext::new_missing(
2502 "SvcExport",
2503 "Fslocations",
2504 self.orig_loc,
2505 self.buf.as_ptr() as usize,
2506 ))
2507 }
2508 pub fn get_uuid(&self) -> Result<&'a [u8], ErrorContext> {
2509 let mut iter = self.clone();
2510 iter.pos = 0;
2511 for attr in iter {
2512 if let Ok(SvcExport::Uuid(val)) = attr {
2513 return Ok(val);
2514 }
2515 }
2516 Err(ErrorContext::new_missing(
2517 "SvcExport",
2518 "Uuid",
2519 self.orig_loc,
2520 self.buf.as_ptr() as usize,
2521 ))
2522 }
2523 #[doc = "Attribute may repeat multiple times (treat it as array)"]
2524 pub fn get_secinfo(&self) -> MultiAttrIterable<Self, SvcExport<'a>, IterableAuthFlavor<'a>> {
2525 MultiAttrIterable::new(self.clone(), |variant| {
2526 if let SvcExport::Secinfo(val) = variant {
2527 Some(val)
2528 } else {
2529 None
2530 }
2531 })
2532 }
2533 #[doc = "Associated type: [`XprtsecMode`] (enum)\nAttribute may repeat multiple times (treat it as array)"]
2534 pub fn get_xprtsec(&self) -> MultiAttrIterable<Self, SvcExport<'a>, u32> {
2535 MultiAttrIterable::new(self.clone(), |variant| {
2536 if let SvcExport::Xprtsec(val) = variant {
2537 Some(val)
2538 } else {
2539 None
2540 }
2541 })
2542 }
2543 #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
2544 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
2545 let mut iter = self.clone();
2546 iter.pos = 0;
2547 for attr in iter {
2548 if let Ok(SvcExport::Flags(val)) = attr {
2549 return Ok(val);
2550 }
2551 }
2552 Err(ErrorContext::new_missing(
2553 "SvcExport",
2554 "Flags",
2555 self.orig_loc,
2556 self.buf.as_ptr() as usize,
2557 ))
2558 }
2559 pub fn get_fsid(&self) -> Result<i32, ErrorContext> {
2560 let mut iter = self.clone();
2561 iter.pos = 0;
2562 for attr in iter {
2563 if let Ok(SvcExport::Fsid(val)) = attr {
2564 return Ok(val);
2565 }
2566 }
2567 Err(ErrorContext::new_missing(
2568 "SvcExport",
2569 "Fsid",
2570 self.orig_loc,
2571 self.buf.as_ptr() as usize,
2572 ))
2573 }
2574}
2575impl SvcExport<'_> {
2576 pub fn new<'a>(buf: &'a [u8]) -> IterableSvcExport<'a> {
2577 IterableSvcExport::with_loc(buf, buf.as_ptr() as usize)
2578 }
2579 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2580 let res = match r#type {
2581 1u16 => "Seqno",
2582 2u16 => "Client",
2583 3u16 => "Path",
2584 4u16 => "Negative",
2585 5u16 => "Expiry",
2586 6u16 => "AnonUid",
2587 7u16 => "AnonGid",
2588 8u16 => "Fslocations",
2589 9u16 => "Uuid",
2590 10u16 => "Secinfo",
2591 11u16 => "Xprtsec",
2592 12u16 => "Flags",
2593 13u16 => "Fsid",
2594 _ => return None,
2595 };
2596 Some(res)
2597 }
2598}
2599#[derive(Clone, Copy, Default)]
2600pub struct IterableSvcExport<'a> {
2601 buf: &'a [u8],
2602 pos: usize,
2603 orig_loc: usize,
2604}
2605impl<'a> IterableSvcExport<'a> {
2606 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2607 Self {
2608 buf,
2609 pos: 0,
2610 orig_loc,
2611 }
2612 }
2613 pub fn get_buf(&self) -> &'a [u8] {
2614 self.buf
2615 }
2616}
2617impl<'a> Iterator for IterableSvcExport<'a> {
2618 type Item = Result<SvcExport<'a>, ErrorContext>;
2619 fn next(&mut self) -> Option<Self::Item> {
2620 let mut pos;
2621 let mut r#type;
2622 loop {
2623 pos = self.pos;
2624 r#type = None;
2625 if self.buf.len() == self.pos {
2626 return None;
2627 }
2628 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2629 self.pos = self.buf.len();
2630 break;
2631 };
2632 r#type = Some(header.r#type);
2633 let res = match header.r#type {
2634 1u16 => SvcExport::Seqno({
2635 let res = parse_u64(next);
2636 let Some(val) = res else { break };
2637 val
2638 }),
2639 2u16 => SvcExport::Client({
2640 let res = CStr::from_bytes_with_nul(next).ok();
2641 let Some(val) = res else { break };
2642 val
2643 }),
2644 3u16 => SvcExport::Path({
2645 let res = CStr::from_bytes_with_nul(next).ok();
2646 let Some(val) = res else { break };
2647 val
2648 }),
2649 4u16 => SvcExport::Negative(()),
2650 5u16 => SvcExport::Expiry({
2651 let res = parse_u64(next);
2652 let Some(val) = res else { break };
2653 val
2654 }),
2655 6u16 => SvcExport::AnonUid({
2656 let res = parse_u32(next);
2657 let Some(val) = res else { break };
2658 val
2659 }),
2660 7u16 => SvcExport::AnonGid({
2661 let res = parse_u32(next);
2662 let Some(val) = res else { break };
2663 val
2664 }),
2665 8u16 => SvcExport::Fslocations({
2666 let res = Some(IterableFslocations::with_loc(next, self.orig_loc));
2667 let Some(val) = res else { break };
2668 val
2669 }),
2670 9u16 => SvcExport::Uuid({
2671 let res = Some(next);
2672 let Some(val) = res else { break };
2673 val
2674 }),
2675 10u16 => SvcExport::Secinfo({
2676 let res = Some(IterableAuthFlavor::with_loc(next, self.orig_loc));
2677 let Some(val) = res else { break };
2678 val
2679 }),
2680 11u16 => SvcExport::Xprtsec({
2681 let res = parse_u32(next);
2682 let Some(val) = res else { break };
2683 val
2684 }),
2685 12u16 => SvcExport::Flags({
2686 let res = parse_u32(next);
2687 let Some(val) = res else { break };
2688 val
2689 }),
2690 13u16 => SvcExport::Fsid({
2691 let res = parse_i32(next);
2692 let Some(val) = res else { break };
2693 val
2694 }),
2695 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2696 n => continue,
2697 };
2698 return Some(Ok(res));
2699 }
2700 Some(Err(ErrorContext::new(
2701 "SvcExport",
2702 r#type.and_then(|t| SvcExport::attr_from_type(t)),
2703 self.orig_loc,
2704 self.buf.as_ptr().wrapping_add(pos) as usize,
2705 )))
2706 }
2707}
2708impl<'a> std::fmt::Debug for IterableSvcExport<'_> {
2709 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2710 let mut fmt = f.debug_struct("SvcExport");
2711 for attr in self.clone() {
2712 let attr = match attr {
2713 Ok(a) => a,
2714 Err(err) => {
2715 fmt.finish()?;
2716 f.write_str("Err(")?;
2717 err.fmt(f)?;
2718 return f.write_str(")");
2719 }
2720 };
2721 match attr {
2722 SvcExport::Seqno(val) => fmt.field("Seqno", &val),
2723 SvcExport::Client(val) => fmt.field("Client", &val),
2724 SvcExport::Path(val) => fmt.field("Path", &val),
2725 SvcExport::Negative(val) => fmt.field("Negative", &val),
2726 SvcExport::Expiry(val) => fmt.field("Expiry", &val),
2727 SvcExport::AnonUid(val) => fmt.field("AnonUid", &val),
2728 SvcExport::AnonGid(val) => fmt.field("AnonGid", &val),
2729 SvcExport::Fslocations(val) => fmt.field("Fslocations", &val),
2730 SvcExport::Uuid(val) => fmt.field("Uuid", &val),
2731 SvcExport::Secinfo(val) => fmt.field("Secinfo", &val),
2732 SvcExport::Xprtsec(val) => {
2733 fmt.field("Xprtsec", &FormatFlags(val.into(), XprtsecMode::from_value))
2734 }
2735 SvcExport::Flags(val) => {
2736 fmt.field("Flags", &FormatFlags(val.into(), ExportFlags::from_value))
2737 }
2738 SvcExport::Fsid(val) => fmt.field("Fsid", &val),
2739 };
2740 }
2741 fmt.finish()
2742 }
2743}
2744impl IterableSvcExport<'_> {
2745 pub fn lookup_attr(
2746 &self,
2747 offset: usize,
2748 missing_type: Option<u16>,
2749 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2750 let mut stack = Vec::new();
2751 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2752 if missing_type.is_some() && cur == offset {
2753 stack.push(("SvcExport", offset));
2754 return (
2755 stack,
2756 missing_type.and_then(|t| SvcExport::attr_from_type(t)),
2757 );
2758 }
2759 if cur > offset || cur + self.buf.len() < offset {
2760 return (stack, None);
2761 }
2762 let mut attrs = self.clone();
2763 let mut last_off = cur + attrs.pos;
2764 let mut missing = None;
2765 while let Some(attr) = attrs.next() {
2766 let Ok(attr) = attr else { break };
2767 match attr {
2768 SvcExport::Seqno(val) => {
2769 if last_off == offset {
2770 stack.push(("Seqno", last_off));
2771 break;
2772 }
2773 }
2774 SvcExport::Client(val) => {
2775 if last_off == offset {
2776 stack.push(("Client", last_off));
2777 break;
2778 }
2779 }
2780 SvcExport::Path(val) => {
2781 if last_off == offset {
2782 stack.push(("Path", last_off));
2783 break;
2784 }
2785 }
2786 SvcExport::Negative(val) => {
2787 if last_off == offset {
2788 stack.push(("Negative", last_off));
2789 break;
2790 }
2791 }
2792 SvcExport::Expiry(val) => {
2793 if last_off == offset {
2794 stack.push(("Expiry", last_off));
2795 break;
2796 }
2797 }
2798 SvcExport::AnonUid(val) => {
2799 if last_off == offset {
2800 stack.push(("AnonUid", last_off));
2801 break;
2802 }
2803 }
2804 SvcExport::AnonGid(val) => {
2805 if last_off == offset {
2806 stack.push(("AnonGid", last_off));
2807 break;
2808 }
2809 }
2810 SvcExport::Fslocations(val) => {
2811 (stack, missing) = val.lookup_attr(offset, missing_type);
2812 if !stack.is_empty() {
2813 break;
2814 }
2815 }
2816 SvcExport::Uuid(val) => {
2817 if last_off == offset {
2818 stack.push(("Uuid", last_off));
2819 break;
2820 }
2821 }
2822 SvcExport::Secinfo(val) => {
2823 (stack, missing) = val.lookup_attr(offset, missing_type);
2824 if !stack.is_empty() {
2825 break;
2826 }
2827 }
2828 SvcExport::Xprtsec(val) => {
2829 if last_off == offset {
2830 stack.push(("Xprtsec", last_off));
2831 break;
2832 }
2833 }
2834 SvcExport::Flags(val) => {
2835 if last_off == offset {
2836 stack.push(("Flags", last_off));
2837 break;
2838 }
2839 }
2840 SvcExport::Fsid(val) => {
2841 if last_off == offset {
2842 stack.push(("Fsid", last_off));
2843 break;
2844 }
2845 }
2846 _ => {}
2847 };
2848 last_off = cur + attrs.pos;
2849 }
2850 if !stack.is_empty() {
2851 stack.push(("SvcExport", cur));
2852 }
2853 (stack, missing)
2854 }
2855}
2856#[derive(Clone)]
2857pub enum SvcExportReqs<'a> {
2858 #[doc = "Attribute may repeat multiple times (treat it as array)"]
2859 Requests(IterableSvcExport<'a>),
2860}
2861impl<'a> IterableSvcExportReqs<'a> {
2862 #[doc = "Attribute may repeat multiple times (treat it as array)"]
2863 pub fn get_requests(
2864 &self,
2865 ) -> MultiAttrIterable<Self, SvcExportReqs<'a>, IterableSvcExport<'a>> {
2866 MultiAttrIterable::new(self.clone(), |variant| {
2867 if let SvcExportReqs::Requests(val) = variant {
2868 Some(val)
2869 } else {
2870 None
2871 }
2872 })
2873 }
2874}
2875impl SvcExportReqs<'_> {
2876 pub fn new<'a>(buf: &'a [u8]) -> IterableSvcExportReqs<'a> {
2877 IterableSvcExportReqs::with_loc(buf, buf.as_ptr() as usize)
2878 }
2879 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2880 let res = match r#type {
2881 1u16 => "Requests",
2882 _ => return None,
2883 };
2884 Some(res)
2885 }
2886}
2887#[derive(Clone, Copy, Default)]
2888pub struct IterableSvcExportReqs<'a> {
2889 buf: &'a [u8],
2890 pos: usize,
2891 orig_loc: usize,
2892}
2893impl<'a> IterableSvcExportReqs<'a> {
2894 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2895 Self {
2896 buf,
2897 pos: 0,
2898 orig_loc,
2899 }
2900 }
2901 pub fn get_buf(&self) -> &'a [u8] {
2902 self.buf
2903 }
2904}
2905impl<'a> Iterator for IterableSvcExportReqs<'a> {
2906 type Item = Result<SvcExportReqs<'a>, ErrorContext>;
2907 fn next(&mut self) -> Option<Self::Item> {
2908 let mut pos;
2909 let mut r#type;
2910 loop {
2911 pos = self.pos;
2912 r#type = None;
2913 if self.buf.len() == self.pos {
2914 return None;
2915 }
2916 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2917 self.pos = self.buf.len();
2918 break;
2919 };
2920 r#type = Some(header.r#type);
2921 let res = match header.r#type {
2922 1u16 => SvcExportReqs::Requests({
2923 let res = Some(IterableSvcExport::with_loc(next, self.orig_loc));
2924 let Some(val) = res else { break };
2925 val
2926 }),
2927 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2928 n => continue,
2929 };
2930 return Some(Ok(res));
2931 }
2932 Some(Err(ErrorContext::new(
2933 "SvcExportReqs",
2934 r#type.and_then(|t| SvcExportReqs::attr_from_type(t)),
2935 self.orig_loc,
2936 self.buf.as_ptr().wrapping_add(pos) as usize,
2937 )))
2938 }
2939}
2940impl<'a> std::fmt::Debug for IterableSvcExportReqs<'_> {
2941 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2942 let mut fmt = f.debug_struct("SvcExportReqs");
2943 for attr in self.clone() {
2944 let attr = match attr {
2945 Ok(a) => a,
2946 Err(err) => {
2947 fmt.finish()?;
2948 f.write_str("Err(")?;
2949 err.fmt(f)?;
2950 return f.write_str(")");
2951 }
2952 };
2953 match attr {
2954 SvcExportReqs::Requests(val) => fmt.field("Requests", &val),
2955 };
2956 }
2957 fmt.finish()
2958 }
2959}
2960impl IterableSvcExportReqs<'_> {
2961 pub fn lookup_attr(
2962 &self,
2963 offset: usize,
2964 missing_type: Option<u16>,
2965 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2966 let mut stack = Vec::new();
2967 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2968 if missing_type.is_some() && cur == offset {
2969 stack.push(("SvcExportReqs", offset));
2970 return (
2971 stack,
2972 missing_type.and_then(|t| SvcExportReqs::attr_from_type(t)),
2973 );
2974 }
2975 if cur > offset || cur + self.buf.len() < offset {
2976 return (stack, None);
2977 }
2978 let mut attrs = self.clone();
2979 let mut last_off = cur + attrs.pos;
2980 let mut missing = None;
2981 while let Some(attr) = attrs.next() {
2982 let Ok(attr) = attr else { break };
2983 match attr {
2984 SvcExportReqs::Requests(val) => {
2985 (stack, missing) = val.lookup_attr(offset, missing_type);
2986 if !stack.is_empty() {
2987 break;
2988 }
2989 }
2990 _ => {}
2991 };
2992 last_off = cur + attrs.pos;
2993 }
2994 if !stack.is_empty() {
2995 stack.push(("SvcExportReqs", cur));
2996 }
2997 (stack, missing)
2998 }
2999}
3000#[derive(Clone)]
3001pub enum Expkey<'a> {
3002 Seqno(u64),
3003 Client(&'a CStr),
3004 Fsidtype(u8),
3005 Fsid(&'a [u8]),
3006 Negative(()),
3007 Expiry(u64),
3008 Path(&'a CStr),
3009}
3010impl<'a> IterableExpkey<'a> {
3011 pub fn get_seqno(&self) -> Result<u64, ErrorContext> {
3012 let mut iter = self.clone();
3013 iter.pos = 0;
3014 for attr in iter {
3015 if let Ok(Expkey::Seqno(val)) = attr {
3016 return Ok(val);
3017 }
3018 }
3019 Err(ErrorContext::new_missing(
3020 "Expkey",
3021 "Seqno",
3022 self.orig_loc,
3023 self.buf.as_ptr() as usize,
3024 ))
3025 }
3026 pub fn get_client(&self) -> Result<&'a CStr, ErrorContext> {
3027 let mut iter = self.clone();
3028 iter.pos = 0;
3029 for attr in iter {
3030 if let Ok(Expkey::Client(val)) = attr {
3031 return Ok(val);
3032 }
3033 }
3034 Err(ErrorContext::new_missing(
3035 "Expkey",
3036 "Client",
3037 self.orig_loc,
3038 self.buf.as_ptr() as usize,
3039 ))
3040 }
3041 pub fn get_fsidtype(&self) -> Result<u8, ErrorContext> {
3042 let mut iter = self.clone();
3043 iter.pos = 0;
3044 for attr in iter {
3045 if let Ok(Expkey::Fsidtype(val)) = attr {
3046 return Ok(val);
3047 }
3048 }
3049 Err(ErrorContext::new_missing(
3050 "Expkey",
3051 "Fsidtype",
3052 self.orig_loc,
3053 self.buf.as_ptr() as usize,
3054 ))
3055 }
3056 pub fn get_fsid(&self) -> Result<&'a [u8], ErrorContext> {
3057 let mut iter = self.clone();
3058 iter.pos = 0;
3059 for attr in iter {
3060 if let Ok(Expkey::Fsid(val)) = attr {
3061 return Ok(val);
3062 }
3063 }
3064 Err(ErrorContext::new_missing(
3065 "Expkey",
3066 "Fsid",
3067 self.orig_loc,
3068 self.buf.as_ptr() as usize,
3069 ))
3070 }
3071 pub fn get_negative(&self) -> Result<(), ErrorContext> {
3072 let mut iter = self.clone();
3073 iter.pos = 0;
3074 for attr in iter {
3075 if let Ok(Expkey::Negative(val)) = attr {
3076 return Ok(val);
3077 }
3078 }
3079 Err(ErrorContext::new_missing(
3080 "Expkey",
3081 "Negative",
3082 self.orig_loc,
3083 self.buf.as_ptr() as usize,
3084 ))
3085 }
3086 pub fn get_expiry(&self) -> Result<u64, ErrorContext> {
3087 let mut iter = self.clone();
3088 iter.pos = 0;
3089 for attr in iter {
3090 if let Ok(Expkey::Expiry(val)) = attr {
3091 return Ok(val);
3092 }
3093 }
3094 Err(ErrorContext::new_missing(
3095 "Expkey",
3096 "Expiry",
3097 self.orig_loc,
3098 self.buf.as_ptr() as usize,
3099 ))
3100 }
3101 pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
3102 let mut iter = self.clone();
3103 iter.pos = 0;
3104 for attr in iter {
3105 if let Ok(Expkey::Path(val)) = attr {
3106 return Ok(val);
3107 }
3108 }
3109 Err(ErrorContext::new_missing(
3110 "Expkey",
3111 "Path",
3112 self.orig_loc,
3113 self.buf.as_ptr() as usize,
3114 ))
3115 }
3116}
3117impl Expkey<'_> {
3118 pub fn new<'a>(buf: &'a [u8]) -> IterableExpkey<'a> {
3119 IterableExpkey::with_loc(buf, buf.as_ptr() as usize)
3120 }
3121 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3122 let res = match r#type {
3123 1u16 => "Seqno",
3124 2u16 => "Client",
3125 3u16 => "Fsidtype",
3126 4u16 => "Fsid",
3127 5u16 => "Negative",
3128 6u16 => "Expiry",
3129 7u16 => "Path",
3130 _ => return None,
3131 };
3132 Some(res)
3133 }
3134}
3135#[derive(Clone, Copy, Default)]
3136pub struct IterableExpkey<'a> {
3137 buf: &'a [u8],
3138 pos: usize,
3139 orig_loc: usize,
3140}
3141impl<'a> IterableExpkey<'a> {
3142 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3143 Self {
3144 buf,
3145 pos: 0,
3146 orig_loc,
3147 }
3148 }
3149 pub fn get_buf(&self) -> &'a [u8] {
3150 self.buf
3151 }
3152}
3153impl<'a> Iterator for IterableExpkey<'a> {
3154 type Item = Result<Expkey<'a>, ErrorContext>;
3155 fn next(&mut self) -> Option<Self::Item> {
3156 let mut pos;
3157 let mut r#type;
3158 loop {
3159 pos = self.pos;
3160 r#type = None;
3161 if self.buf.len() == self.pos {
3162 return None;
3163 }
3164 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3165 self.pos = self.buf.len();
3166 break;
3167 };
3168 r#type = Some(header.r#type);
3169 let res = match header.r#type {
3170 1u16 => Expkey::Seqno({
3171 let res = parse_u64(next);
3172 let Some(val) = res else { break };
3173 val
3174 }),
3175 2u16 => Expkey::Client({
3176 let res = CStr::from_bytes_with_nul(next).ok();
3177 let Some(val) = res else { break };
3178 val
3179 }),
3180 3u16 => Expkey::Fsidtype({
3181 let res = parse_u8(next);
3182 let Some(val) = res else { break };
3183 val
3184 }),
3185 4u16 => Expkey::Fsid({
3186 let res = Some(next);
3187 let Some(val) = res else { break };
3188 val
3189 }),
3190 5u16 => Expkey::Negative(()),
3191 6u16 => Expkey::Expiry({
3192 let res = parse_u64(next);
3193 let Some(val) = res else { break };
3194 val
3195 }),
3196 7u16 => Expkey::Path({
3197 let res = CStr::from_bytes_with_nul(next).ok();
3198 let Some(val) = res else { break };
3199 val
3200 }),
3201 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3202 n => continue,
3203 };
3204 return Some(Ok(res));
3205 }
3206 Some(Err(ErrorContext::new(
3207 "Expkey",
3208 r#type.and_then(|t| Expkey::attr_from_type(t)),
3209 self.orig_loc,
3210 self.buf.as_ptr().wrapping_add(pos) as usize,
3211 )))
3212 }
3213}
3214impl<'a> std::fmt::Debug for IterableExpkey<'_> {
3215 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3216 let mut fmt = f.debug_struct("Expkey");
3217 for attr in self.clone() {
3218 let attr = match attr {
3219 Ok(a) => a,
3220 Err(err) => {
3221 fmt.finish()?;
3222 f.write_str("Err(")?;
3223 err.fmt(f)?;
3224 return f.write_str(")");
3225 }
3226 };
3227 match attr {
3228 Expkey::Seqno(val) => fmt.field("Seqno", &val),
3229 Expkey::Client(val) => fmt.field("Client", &val),
3230 Expkey::Fsidtype(val) => fmt.field("Fsidtype", &val),
3231 Expkey::Fsid(val) => fmt.field("Fsid", &val),
3232 Expkey::Negative(val) => fmt.field("Negative", &val),
3233 Expkey::Expiry(val) => fmt.field("Expiry", &val),
3234 Expkey::Path(val) => fmt.field("Path", &val),
3235 };
3236 }
3237 fmt.finish()
3238 }
3239}
3240impl IterableExpkey<'_> {
3241 pub fn lookup_attr(
3242 &self,
3243 offset: usize,
3244 missing_type: Option<u16>,
3245 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3246 let mut stack = Vec::new();
3247 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3248 if missing_type.is_some() && cur == offset {
3249 stack.push(("Expkey", offset));
3250 return (stack, missing_type.and_then(|t| Expkey::attr_from_type(t)));
3251 }
3252 if cur > offset || cur + self.buf.len() < offset {
3253 return (stack, None);
3254 }
3255 let mut attrs = self.clone();
3256 let mut last_off = cur + attrs.pos;
3257 while let Some(attr) = attrs.next() {
3258 let Ok(attr) = attr else { break };
3259 match attr {
3260 Expkey::Seqno(val) => {
3261 if last_off == offset {
3262 stack.push(("Seqno", last_off));
3263 break;
3264 }
3265 }
3266 Expkey::Client(val) => {
3267 if last_off == offset {
3268 stack.push(("Client", last_off));
3269 break;
3270 }
3271 }
3272 Expkey::Fsidtype(val) => {
3273 if last_off == offset {
3274 stack.push(("Fsidtype", last_off));
3275 break;
3276 }
3277 }
3278 Expkey::Fsid(val) => {
3279 if last_off == offset {
3280 stack.push(("Fsid", last_off));
3281 break;
3282 }
3283 }
3284 Expkey::Negative(val) => {
3285 if last_off == offset {
3286 stack.push(("Negative", last_off));
3287 break;
3288 }
3289 }
3290 Expkey::Expiry(val) => {
3291 if last_off == offset {
3292 stack.push(("Expiry", last_off));
3293 break;
3294 }
3295 }
3296 Expkey::Path(val) => {
3297 if last_off == offset {
3298 stack.push(("Path", last_off));
3299 break;
3300 }
3301 }
3302 _ => {}
3303 };
3304 last_off = cur + attrs.pos;
3305 }
3306 if !stack.is_empty() {
3307 stack.push(("Expkey", cur));
3308 }
3309 (stack, None)
3310 }
3311}
3312#[derive(Clone)]
3313pub enum ExpkeyReqs<'a> {
3314 #[doc = "Attribute may repeat multiple times (treat it as array)"]
3315 Requests(IterableExpkey<'a>),
3316}
3317impl<'a> IterableExpkeyReqs<'a> {
3318 #[doc = "Attribute may repeat multiple times (treat it as array)"]
3319 pub fn get_requests(&self) -> MultiAttrIterable<Self, ExpkeyReqs<'a>, IterableExpkey<'a>> {
3320 MultiAttrIterable::new(self.clone(), |variant| {
3321 if let ExpkeyReqs::Requests(val) = variant {
3322 Some(val)
3323 } else {
3324 None
3325 }
3326 })
3327 }
3328}
3329impl ExpkeyReqs<'_> {
3330 pub fn new<'a>(buf: &'a [u8]) -> IterableExpkeyReqs<'a> {
3331 IterableExpkeyReqs::with_loc(buf, buf.as_ptr() as usize)
3332 }
3333 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3334 let res = match r#type {
3335 1u16 => "Requests",
3336 _ => return None,
3337 };
3338 Some(res)
3339 }
3340}
3341#[derive(Clone, Copy, Default)]
3342pub struct IterableExpkeyReqs<'a> {
3343 buf: &'a [u8],
3344 pos: usize,
3345 orig_loc: usize,
3346}
3347impl<'a> IterableExpkeyReqs<'a> {
3348 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3349 Self {
3350 buf,
3351 pos: 0,
3352 orig_loc,
3353 }
3354 }
3355 pub fn get_buf(&self) -> &'a [u8] {
3356 self.buf
3357 }
3358}
3359impl<'a> Iterator for IterableExpkeyReqs<'a> {
3360 type Item = Result<ExpkeyReqs<'a>, ErrorContext>;
3361 fn next(&mut self) -> Option<Self::Item> {
3362 let mut pos;
3363 let mut r#type;
3364 loop {
3365 pos = self.pos;
3366 r#type = None;
3367 if self.buf.len() == self.pos {
3368 return None;
3369 }
3370 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3371 self.pos = self.buf.len();
3372 break;
3373 };
3374 r#type = Some(header.r#type);
3375 let res = match header.r#type {
3376 1u16 => ExpkeyReqs::Requests({
3377 let res = Some(IterableExpkey::with_loc(next, self.orig_loc));
3378 let Some(val) = res else { break };
3379 val
3380 }),
3381 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3382 n => continue,
3383 };
3384 return Some(Ok(res));
3385 }
3386 Some(Err(ErrorContext::new(
3387 "ExpkeyReqs",
3388 r#type.and_then(|t| ExpkeyReqs::attr_from_type(t)),
3389 self.orig_loc,
3390 self.buf.as_ptr().wrapping_add(pos) as usize,
3391 )))
3392 }
3393}
3394impl<'a> std::fmt::Debug for IterableExpkeyReqs<'_> {
3395 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3396 let mut fmt = f.debug_struct("ExpkeyReqs");
3397 for attr in self.clone() {
3398 let attr = match attr {
3399 Ok(a) => a,
3400 Err(err) => {
3401 fmt.finish()?;
3402 f.write_str("Err(")?;
3403 err.fmt(f)?;
3404 return f.write_str(")");
3405 }
3406 };
3407 match attr {
3408 ExpkeyReqs::Requests(val) => fmt.field("Requests", &val),
3409 };
3410 }
3411 fmt.finish()
3412 }
3413}
3414impl IterableExpkeyReqs<'_> {
3415 pub fn lookup_attr(
3416 &self,
3417 offset: usize,
3418 missing_type: Option<u16>,
3419 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3420 let mut stack = Vec::new();
3421 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3422 if missing_type.is_some() && cur == offset {
3423 stack.push(("ExpkeyReqs", offset));
3424 return (
3425 stack,
3426 missing_type.and_then(|t| ExpkeyReqs::attr_from_type(t)),
3427 );
3428 }
3429 if cur > offset || cur + self.buf.len() < offset {
3430 return (stack, None);
3431 }
3432 let mut attrs = self.clone();
3433 let mut last_off = cur + attrs.pos;
3434 let mut missing = None;
3435 while let Some(attr) = attrs.next() {
3436 let Ok(attr) = attr else { break };
3437 match attr {
3438 ExpkeyReqs::Requests(val) => {
3439 (stack, missing) = val.lookup_attr(offset, missing_type);
3440 if !stack.is_empty() {
3441 break;
3442 }
3443 }
3444 _ => {}
3445 };
3446 last_off = cur + attrs.pos;
3447 }
3448 if !stack.is_empty() {
3449 stack.push(("ExpkeyReqs", cur));
3450 }
3451 (stack, missing)
3452 }
3453}
3454#[derive(Clone)]
3455pub enum CacheFlush {
3456 #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
3457 Mask(u32),
3458}
3459impl<'a> IterableCacheFlush<'a> {
3460 #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
3461 pub fn get_mask(&self) -> Result<u32, ErrorContext> {
3462 let mut iter = self.clone();
3463 iter.pos = 0;
3464 for attr in iter {
3465 if let Ok(CacheFlush::Mask(val)) = attr {
3466 return Ok(val);
3467 }
3468 }
3469 Err(ErrorContext::new_missing(
3470 "CacheFlush",
3471 "Mask",
3472 self.orig_loc,
3473 self.buf.as_ptr() as usize,
3474 ))
3475 }
3476}
3477impl CacheFlush {
3478 pub fn new<'a>(buf: &'a [u8]) -> IterableCacheFlush<'a> {
3479 IterableCacheFlush::with_loc(buf, buf.as_ptr() as usize)
3480 }
3481 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3482 let res = match r#type {
3483 1u16 => "Mask",
3484 _ => return None,
3485 };
3486 Some(res)
3487 }
3488}
3489#[derive(Clone, Copy, Default)]
3490pub struct IterableCacheFlush<'a> {
3491 buf: &'a [u8],
3492 pos: usize,
3493 orig_loc: usize,
3494}
3495impl<'a> IterableCacheFlush<'a> {
3496 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3497 Self {
3498 buf,
3499 pos: 0,
3500 orig_loc,
3501 }
3502 }
3503 pub fn get_buf(&self) -> &'a [u8] {
3504 self.buf
3505 }
3506}
3507impl<'a> Iterator for IterableCacheFlush<'a> {
3508 type Item = Result<CacheFlush, ErrorContext>;
3509 fn next(&mut self) -> Option<Self::Item> {
3510 let mut pos;
3511 let mut r#type;
3512 loop {
3513 pos = self.pos;
3514 r#type = None;
3515 if self.buf.len() == self.pos {
3516 return None;
3517 }
3518 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3519 self.pos = self.buf.len();
3520 break;
3521 };
3522 r#type = Some(header.r#type);
3523 let res = match header.r#type {
3524 1u16 => CacheFlush::Mask({
3525 let res = parse_u32(next);
3526 let Some(val) = res else { break };
3527 val
3528 }),
3529 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3530 n => continue,
3531 };
3532 return Some(Ok(res));
3533 }
3534 Some(Err(ErrorContext::new(
3535 "CacheFlush",
3536 r#type.and_then(|t| CacheFlush::attr_from_type(t)),
3537 self.orig_loc,
3538 self.buf.as_ptr().wrapping_add(pos) as usize,
3539 )))
3540 }
3541}
3542impl std::fmt::Debug for IterableCacheFlush<'_> {
3543 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3544 let mut fmt = f.debug_struct("CacheFlush");
3545 for attr in self.clone() {
3546 let attr = match attr {
3547 Ok(a) => a,
3548 Err(err) => {
3549 fmt.finish()?;
3550 f.write_str("Err(")?;
3551 err.fmt(f)?;
3552 return f.write_str(")");
3553 }
3554 };
3555 match attr {
3556 CacheFlush::Mask(val) => {
3557 fmt.field("Mask", &FormatFlags(val.into(), CacheType::from_value))
3558 }
3559 };
3560 }
3561 fmt.finish()
3562 }
3563}
3564impl IterableCacheFlush<'_> {
3565 pub fn lookup_attr(
3566 &self,
3567 offset: usize,
3568 missing_type: Option<u16>,
3569 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3570 let mut stack = Vec::new();
3571 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3572 if missing_type.is_some() && cur == offset {
3573 stack.push(("CacheFlush", offset));
3574 return (
3575 stack,
3576 missing_type.and_then(|t| CacheFlush::attr_from_type(t)),
3577 );
3578 }
3579 if cur > offset || cur + self.buf.len() < offset {
3580 return (stack, None);
3581 }
3582 let mut attrs = self.clone();
3583 let mut last_off = cur + attrs.pos;
3584 while let Some(attr) = attrs.next() {
3585 let Ok(attr) = attr else { break };
3586 match attr {
3587 CacheFlush::Mask(val) => {
3588 if last_off == offset {
3589 stack.push(("Mask", last_off));
3590 break;
3591 }
3592 }
3593 _ => {}
3594 };
3595 last_off = cur + attrs.pos;
3596 }
3597 if !stack.is_empty() {
3598 stack.push(("CacheFlush", cur));
3599 }
3600 (stack, None)
3601 }
3602}
3603#[derive(Clone)]
3604pub enum UnlockIp<'a> {
3605 #[doc = "struct sockaddr_in or struct sockaddr_in6.\n"]
3606 Address(&'a [u8]),
3607}
3608impl<'a> IterableUnlockIp<'a> {
3609 #[doc = "struct sockaddr_in or struct sockaddr_in6.\n"]
3610 pub fn get_address(&self) -> Result<&'a [u8], ErrorContext> {
3611 let mut iter = self.clone();
3612 iter.pos = 0;
3613 for attr in iter {
3614 if let Ok(UnlockIp::Address(val)) = attr {
3615 return Ok(val);
3616 }
3617 }
3618 Err(ErrorContext::new_missing(
3619 "UnlockIp",
3620 "Address",
3621 self.orig_loc,
3622 self.buf.as_ptr() as usize,
3623 ))
3624 }
3625}
3626impl UnlockIp<'_> {
3627 pub fn new<'a>(buf: &'a [u8]) -> IterableUnlockIp<'a> {
3628 IterableUnlockIp::with_loc(buf, buf.as_ptr() as usize)
3629 }
3630 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3631 let res = match r#type {
3632 1u16 => "Address",
3633 _ => return None,
3634 };
3635 Some(res)
3636 }
3637}
3638#[derive(Clone, Copy, Default)]
3639pub struct IterableUnlockIp<'a> {
3640 buf: &'a [u8],
3641 pos: usize,
3642 orig_loc: usize,
3643}
3644impl<'a> IterableUnlockIp<'a> {
3645 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3646 Self {
3647 buf,
3648 pos: 0,
3649 orig_loc,
3650 }
3651 }
3652 pub fn get_buf(&self) -> &'a [u8] {
3653 self.buf
3654 }
3655}
3656impl<'a> Iterator for IterableUnlockIp<'a> {
3657 type Item = Result<UnlockIp<'a>, ErrorContext>;
3658 fn next(&mut self) -> Option<Self::Item> {
3659 let mut pos;
3660 let mut r#type;
3661 loop {
3662 pos = self.pos;
3663 r#type = None;
3664 if self.buf.len() == self.pos {
3665 return None;
3666 }
3667 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3668 self.pos = self.buf.len();
3669 break;
3670 };
3671 r#type = Some(header.r#type);
3672 let res = match header.r#type {
3673 1u16 => UnlockIp::Address({
3674 let res = Some(next);
3675 let Some(val) = res else { break };
3676 val
3677 }),
3678 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3679 n => continue,
3680 };
3681 return Some(Ok(res));
3682 }
3683 Some(Err(ErrorContext::new(
3684 "UnlockIp",
3685 r#type.and_then(|t| UnlockIp::attr_from_type(t)),
3686 self.orig_loc,
3687 self.buf.as_ptr().wrapping_add(pos) as usize,
3688 )))
3689 }
3690}
3691impl<'a> std::fmt::Debug for IterableUnlockIp<'_> {
3692 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3693 let mut fmt = f.debug_struct("UnlockIp");
3694 for attr in self.clone() {
3695 let attr = match attr {
3696 Ok(a) => a,
3697 Err(err) => {
3698 fmt.finish()?;
3699 f.write_str("Err(")?;
3700 err.fmt(f)?;
3701 return f.write_str(")");
3702 }
3703 };
3704 match attr {
3705 UnlockIp::Address(val) => fmt.field("Address", &val),
3706 };
3707 }
3708 fmt.finish()
3709 }
3710}
3711impl IterableUnlockIp<'_> {
3712 pub fn lookup_attr(
3713 &self,
3714 offset: usize,
3715 missing_type: Option<u16>,
3716 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3717 let mut stack = Vec::new();
3718 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3719 if missing_type.is_some() && cur == offset {
3720 stack.push(("UnlockIp", offset));
3721 return (
3722 stack,
3723 missing_type.and_then(|t| UnlockIp::attr_from_type(t)),
3724 );
3725 }
3726 if cur > offset || cur + self.buf.len() < offset {
3727 return (stack, None);
3728 }
3729 let mut attrs = self.clone();
3730 let mut last_off = cur + attrs.pos;
3731 while let Some(attr) = attrs.next() {
3732 let Ok(attr) = attr else { break };
3733 match attr {
3734 UnlockIp::Address(val) => {
3735 if last_off == offset {
3736 stack.push(("Address", last_off));
3737 break;
3738 }
3739 }
3740 _ => {}
3741 };
3742 last_off = cur + attrs.pos;
3743 }
3744 if !stack.is_empty() {
3745 stack.push(("UnlockIp", cur));
3746 }
3747 (stack, None)
3748 }
3749}
3750#[derive(Clone)]
3751pub enum UnlockFilesystem<'a> {
3752 #[doc = "Filesystem path whose state should be released.\n"]
3753 Path(&'a CStr),
3754}
3755impl<'a> IterableUnlockFilesystem<'a> {
3756 #[doc = "Filesystem path whose state should be released.\n"]
3757 pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
3758 let mut iter = self.clone();
3759 iter.pos = 0;
3760 for attr in iter {
3761 if let Ok(UnlockFilesystem::Path(val)) = attr {
3762 return Ok(val);
3763 }
3764 }
3765 Err(ErrorContext::new_missing(
3766 "UnlockFilesystem",
3767 "Path",
3768 self.orig_loc,
3769 self.buf.as_ptr() as usize,
3770 ))
3771 }
3772}
3773impl UnlockFilesystem<'_> {
3774 pub fn new<'a>(buf: &'a [u8]) -> IterableUnlockFilesystem<'a> {
3775 IterableUnlockFilesystem::with_loc(buf, buf.as_ptr() as usize)
3776 }
3777 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3778 let res = match r#type {
3779 1u16 => "Path",
3780 _ => return None,
3781 };
3782 Some(res)
3783 }
3784}
3785#[derive(Clone, Copy, Default)]
3786pub struct IterableUnlockFilesystem<'a> {
3787 buf: &'a [u8],
3788 pos: usize,
3789 orig_loc: usize,
3790}
3791impl<'a> IterableUnlockFilesystem<'a> {
3792 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3793 Self {
3794 buf,
3795 pos: 0,
3796 orig_loc,
3797 }
3798 }
3799 pub fn get_buf(&self) -> &'a [u8] {
3800 self.buf
3801 }
3802}
3803impl<'a> Iterator for IterableUnlockFilesystem<'a> {
3804 type Item = Result<UnlockFilesystem<'a>, ErrorContext>;
3805 fn next(&mut self) -> Option<Self::Item> {
3806 let mut pos;
3807 let mut r#type;
3808 loop {
3809 pos = self.pos;
3810 r#type = None;
3811 if self.buf.len() == self.pos {
3812 return None;
3813 }
3814 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3815 self.pos = self.buf.len();
3816 break;
3817 };
3818 r#type = Some(header.r#type);
3819 let res = match header.r#type {
3820 1u16 => UnlockFilesystem::Path({
3821 let res = CStr::from_bytes_with_nul(next).ok();
3822 let Some(val) = res else { break };
3823 val
3824 }),
3825 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3826 n => continue,
3827 };
3828 return Some(Ok(res));
3829 }
3830 Some(Err(ErrorContext::new(
3831 "UnlockFilesystem",
3832 r#type.and_then(|t| UnlockFilesystem::attr_from_type(t)),
3833 self.orig_loc,
3834 self.buf.as_ptr().wrapping_add(pos) as usize,
3835 )))
3836 }
3837}
3838impl<'a> std::fmt::Debug for IterableUnlockFilesystem<'_> {
3839 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3840 let mut fmt = f.debug_struct("UnlockFilesystem");
3841 for attr in self.clone() {
3842 let attr = match attr {
3843 Ok(a) => a,
3844 Err(err) => {
3845 fmt.finish()?;
3846 f.write_str("Err(")?;
3847 err.fmt(f)?;
3848 return f.write_str(")");
3849 }
3850 };
3851 match attr {
3852 UnlockFilesystem::Path(val) => fmt.field("Path", &val),
3853 };
3854 }
3855 fmt.finish()
3856 }
3857}
3858impl IterableUnlockFilesystem<'_> {
3859 pub fn lookup_attr(
3860 &self,
3861 offset: usize,
3862 missing_type: Option<u16>,
3863 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3864 let mut stack = Vec::new();
3865 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3866 if missing_type.is_some() && cur == offset {
3867 stack.push(("UnlockFilesystem", offset));
3868 return (
3869 stack,
3870 missing_type.and_then(|t| UnlockFilesystem::attr_from_type(t)),
3871 );
3872 }
3873 if cur > offset || cur + self.buf.len() < offset {
3874 return (stack, None);
3875 }
3876 let mut attrs = self.clone();
3877 let mut last_off = cur + attrs.pos;
3878 while let Some(attr) = attrs.next() {
3879 let Ok(attr) = attr else { break };
3880 match attr {
3881 UnlockFilesystem::Path(val) => {
3882 if last_off == offset {
3883 stack.push(("Path", last_off));
3884 break;
3885 }
3886 }
3887 _ => {}
3888 };
3889 last_off = cur + attrs.pos;
3890 }
3891 if !stack.is_empty() {
3892 stack.push(("UnlockFilesystem", cur));
3893 }
3894 (stack, None)
3895 }
3896}
3897#[derive(Clone)]
3898pub enum UnlockExport<'a> {
3899 #[doc = "Export path whose NFSv4 state should be revoked. All state (opens,\nlocks, delegations, layouts) acquired through any export of this path is\nrevoked, regardless of which client holds the state. Intended for use\nafter all clients have been unexported from a given path, enabling the\nunderlying filesystem to be unmounted.\n"]
3900 Path(&'a CStr),
3901}
3902impl<'a> IterableUnlockExport<'a> {
3903 #[doc = "Export path whose NFSv4 state should be revoked. All state (opens,\nlocks, delegations, layouts) acquired through any export of this path is\nrevoked, regardless of which client holds the state. Intended for use\nafter all clients have been unexported from a given path, enabling the\nunderlying filesystem to be unmounted.\n"]
3904 pub fn get_path(&self) -> Result<&'a CStr, ErrorContext> {
3905 let mut iter = self.clone();
3906 iter.pos = 0;
3907 for attr in iter {
3908 if let Ok(UnlockExport::Path(val)) = attr {
3909 return Ok(val);
3910 }
3911 }
3912 Err(ErrorContext::new_missing(
3913 "UnlockExport",
3914 "Path",
3915 self.orig_loc,
3916 self.buf.as_ptr() as usize,
3917 ))
3918 }
3919}
3920impl UnlockExport<'_> {
3921 pub fn new<'a>(buf: &'a [u8]) -> IterableUnlockExport<'a> {
3922 IterableUnlockExport::with_loc(buf, buf.as_ptr() as usize)
3923 }
3924 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3925 let res = match r#type {
3926 1u16 => "Path",
3927 _ => return None,
3928 };
3929 Some(res)
3930 }
3931}
3932#[derive(Clone, Copy, Default)]
3933pub struct IterableUnlockExport<'a> {
3934 buf: &'a [u8],
3935 pos: usize,
3936 orig_loc: usize,
3937}
3938impl<'a> IterableUnlockExport<'a> {
3939 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3940 Self {
3941 buf,
3942 pos: 0,
3943 orig_loc,
3944 }
3945 }
3946 pub fn get_buf(&self) -> &'a [u8] {
3947 self.buf
3948 }
3949}
3950impl<'a> Iterator for IterableUnlockExport<'a> {
3951 type Item = Result<UnlockExport<'a>, ErrorContext>;
3952 fn next(&mut self) -> Option<Self::Item> {
3953 let mut pos;
3954 let mut r#type;
3955 loop {
3956 pos = self.pos;
3957 r#type = None;
3958 if self.buf.len() == self.pos {
3959 return None;
3960 }
3961 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3962 self.pos = self.buf.len();
3963 break;
3964 };
3965 r#type = Some(header.r#type);
3966 let res = match header.r#type {
3967 1u16 => UnlockExport::Path({
3968 let res = CStr::from_bytes_with_nul(next).ok();
3969 let Some(val) = res else { break };
3970 val
3971 }),
3972 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3973 n => continue,
3974 };
3975 return Some(Ok(res));
3976 }
3977 Some(Err(ErrorContext::new(
3978 "UnlockExport",
3979 r#type.and_then(|t| UnlockExport::attr_from_type(t)),
3980 self.orig_loc,
3981 self.buf.as_ptr().wrapping_add(pos) as usize,
3982 )))
3983 }
3984}
3985impl<'a> std::fmt::Debug for IterableUnlockExport<'_> {
3986 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3987 let mut fmt = f.debug_struct("UnlockExport");
3988 for attr in self.clone() {
3989 let attr = match attr {
3990 Ok(a) => a,
3991 Err(err) => {
3992 fmt.finish()?;
3993 f.write_str("Err(")?;
3994 err.fmt(f)?;
3995 return f.write_str(")");
3996 }
3997 };
3998 match attr {
3999 UnlockExport::Path(val) => fmt.field("Path", &val),
4000 };
4001 }
4002 fmt.finish()
4003 }
4004}
4005impl IterableUnlockExport<'_> {
4006 pub fn lookup_attr(
4007 &self,
4008 offset: usize,
4009 missing_type: Option<u16>,
4010 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4011 let mut stack = Vec::new();
4012 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4013 if missing_type.is_some() && cur == offset {
4014 stack.push(("UnlockExport", offset));
4015 return (
4016 stack,
4017 missing_type.and_then(|t| UnlockExport::attr_from_type(t)),
4018 );
4019 }
4020 if cur > offset || cur + self.buf.len() < offset {
4021 return (stack, None);
4022 }
4023 let mut attrs = self.clone();
4024 let mut last_off = cur + attrs.pos;
4025 while let Some(attr) = attrs.next() {
4026 let Ok(attr) = attr else { break };
4027 match attr {
4028 UnlockExport::Path(val) => {
4029 if last_off == offset {
4030 stack.push(("Path", last_off));
4031 break;
4032 }
4033 }
4034 _ => {}
4035 };
4036 last_off = cur + attrs.pos;
4037 }
4038 if !stack.is_empty() {
4039 stack.push(("UnlockExport", cur));
4040 }
4041 (stack, None)
4042 }
4043}
4044pub struct PushCacheNotify<Prev: Pusher> {
4045 pub(crate) prev: Option<Prev>,
4046 pub(crate) header_offset: Option<usize>,
4047}
4048impl<Prev: Pusher> Pusher for PushCacheNotify<Prev> {
4049 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4050 self.prev.as_mut().unwrap().as_vec_mut()
4051 }
4052 fn as_vec(&self) -> &Vec<u8> {
4053 self.prev.as_ref().unwrap().as_vec()
4054 }
4055}
4056impl<Prev: Pusher> PushCacheNotify<Prev> {
4057 pub fn new(prev: Prev) -> Self {
4058 Self {
4059 prev: Some(prev),
4060 header_offset: None,
4061 }
4062 }
4063 pub fn end_nested(mut self) -> Prev {
4064 let mut prev = self.prev.take().unwrap();
4065 if let Some(header_offset) = &self.header_offset {
4066 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4067 }
4068 prev
4069 }
4070 #[doc = "Associated type: [`CacheType`] (enum)"]
4071 pub fn push_cache_type(mut self, value: u32) -> Self {
4072 push_header(self.as_vec_mut(), 1u16, 4 as u16);
4073 self.as_vec_mut().extend(value.to_ne_bytes());
4074 self
4075 }
4076}
4077impl<Prev: Pusher> Drop for PushCacheNotify<Prev> {
4078 fn drop(&mut self) {
4079 if let Some(prev) = &mut self.prev {
4080 if let Some(header_offset) = &self.header_offset {
4081 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4082 }
4083 }
4084 }
4085}
4086pub struct PushRpcStatus<Prev: Pusher> {
4087 pub(crate) prev: Option<Prev>,
4088 pub(crate) header_offset: Option<usize>,
4089}
4090impl<Prev: Pusher> Pusher for PushRpcStatus<Prev> {
4091 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4092 self.prev.as_mut().unwrap().as_vec_mut()
4093 }
4094 fn as_vec(&self) -> &Vec<u8> {
4095 self.prev.as_ref().unwrap().as_vec()
4096 }
4097}
4098impl<Prev: Pusher> PushRpcStatus<Prev> {
4099 pub fn new(prev: Prev) -> Self {
4100 Self {
4101 prev: Some(prev),
4102 header_offset: None,
4103 }
4104 }
4105 pub fn end_nested(mut self) -> Prev {
4106 let mut prev = self.prev.take().unwrap();
4107 if let Some(header_offset) = &self.header_offset {
4108 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4109 }
4110 prev
4111 }
4112 pub fn push_xid(mut self, value: u32) -> Self {
4113 push_header(self.as_vec_mut(), 1u16, 4 as u16);
4114 self.as_vec_mut().extend(value.to_be_bytes());
4115 self
4116 }
4117 pub fn push_flags(mut self, value: u32) -> Self {
4118 push_header(self.as_vec_mut(), 2u16, 4 as u16);
4119 self.as_vec_mut().extend(value.to_ne_bytes());
4120 self
4121 }
4122 pub fn push_prog(mut self, value: u32) -> Self {
4123 push_header(self.as_vec_mut(), 3u16, 4 as u16);
4124 self.as_vec_mut().extend(value.to_ne_bytes());
4125 self
4126 }
4127 pub fn push_version(mut self, value: u8) -> Self {
4128 push_header(self.as_vec_mut(), 4u16, 1 as u16);
4129 self.as_vec_mut().extend(value.to_ne_bytes());
4130 self
4131 }
4132 pub fn push_proc(mut self, value: u32) -> Self {
4133 push_header(self.as_vec_mut(), 5u16, 4 as u16);
4134 self.as_vec_mut().extend(value.to_ne_bytes());
4135 self
4136 }
4137 pub fn push_service_time(mut self, value: i64) -> Self {
4138 push_header(self.as_vec_mut(), 6u16, 8 as u16);
4139 self.as_vec_mut().extend(value.to_ne_bytes());
4140 self
4141 }
4142 pub fn push_pad(mut self, value: &[u8]) -> Self {
4143 push_header(self.as_vec_mut(), 7u16, value.len() as u16);
4144 self.as_vec_mut().extend(value);
4145 self
4146 }
4147 pub fn push_saddr4(mut self, value: std::net::Ipv4Addr) -> Self {
4148 push_header(self.as_vec_mut(), 8u16, 4 as u16);
4149 self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
4150 self
4151 }
4152 pub fn push_daddr4(mut self, value: std::net::Ipv4Addr) -> Self {
4153 push_header(self.as_vec_mut(), 9u16, 4 as u16);
4154 self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
4155 self
4156 }
4157 pub fn push_saddr6(mut self, value: &[u8]) -> Self {
4158 push_header(self.as_vec_mut(), 10u16, value.len() as u16);
4159 self.as_vec_mut().extend(value);
4160 self
4161 }
4162 pub fn push_daddr6(mut self, value: &[u8]) -> Self {
4163 push_header(self.as_vec_mut(), 11u16, value.len() as u16);
4164 self.as_vec_mut().extend(value);
4165 self
4166 }
4167 pub fn push_sport(mut self, value: u16) -> Self {
4168 push_header(self.as_vec_mut(), 12u16, 2 as u16);
4169 self.as_vec_mut().extend(value.to_be_bytes());
4170 self
4171 }
4172 pub fn push_dport(mut self, value: u16) -> Self {
4173 push_header(self.as_vec_mut(), 13u16, 2 as u16);
4174 self.as_vec_mut().extend(value.to_be_bytes());
4175 self
4176 }
4177 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4178 pub fn push_compound_ops(mut self, value: u32) -> Self {
4179 push_header(self.as_vec_mut(), 14u16, 4 as u16);
4180 self.as_vec_mut().extend(value.to_ne_bytes());
4181 self
4182 }
4183}
4184impl<Prev: Pusher> Drop for PushRpcStatus<Prev> {
4185 fn drop(&mut self) {
4186 if let Some(prev) = &mut self.prev {
4187 if let Some(header_offset) = &self.header_offset {
4188 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4189 }
4190 }
4191 }
4192}
4193pub struct PushServer<Prev: Pusher> {
4194 pub(crate) prev: Option<Prev>,
4195 pub(crate) header_offset: Option<usize>,
4196}
4197impl<Prev: Pusher> Pusher for PushServer<Prev> {
4198 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4199 self.prev.as_mut().unwrap().as_vec_mut()
4200 }
4201 fn as_vec(&self) -> &Vec<u8> {
4202 self.prev.as_ref().unwrap().as_vec()
4203 }
4204}
4205impl<Prev: Pusher> PushServer<Prev> {
4206 pub fn new(prev: Prev) -> Self {
4207 Self {
4208 prev: Some(prev),
4209 header_offset: None,
4210 }
4211 }
4212 pub fn end_nested(mut self) -> Prev {
4213 let mut prev = self.prev.take().unwrap();
4214 if let Some(header_offset) = &self.header_offset {
4215 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4216 }
4217 prev
4218 }
4219 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4220 pub fn push_threads(mut self, value: u32) -> Self {
4221 push_header(self.as_vec_mut(), 1u16, 4 as u16);
4222 self.as_vec_mut().extend(value.to_ne_bytes());
4223 self
4224 }
4225 pub fn push_gracetime(mut self, value: u32) -> Self {
4226 push_header(self.as_vec_mut(), 2u16, 4 as u16);
4227 self.as_vec_mut().extend(value.to_ne_bytes());
4228 self
4229 }
4230 pub fn push_leasetime(mut self, value: u32) -> Self {
4231 push_header(self.as_vec_mut(), 3u16, 4 as u16);
4232 self.as_vec_mut().extend(value.to_ne_bytes());
4233 self
4234 }
4235 pub fn push_scope(mut self, value: &CStr) -> Self {
4236 push_header(
4237 self.as_vec_mut(),
4238 4u16,
4239 value.to_bytes_with_nul().len() as u16,
4240 );
4241 self.as_vec_mut().extend(value.to_bytes_with_nul());
4242 self
4243 }
4244 pub fn push_scope_bytes(mut self, value: &[u8]) -> Self {
4245 push_header(self.as_vec_mut(), 4u16, (value.len() + 1) as u16);
4246 self.as_vec_mut().extend(value);
4247 self.as_vec_mut().push(0);
4248 self
4249 }
4250 pub fn push_min_threads(mut self, value: u32) -> Self {
4251 push_header(self.as_vec_mut(), 5u16, 4 as u16);
4252 self.as_vec_mut().extend(value.to_ne_bytes());
4253 self
4254 }
4255 pub fn push_fh_key(mut self, value: &[u8]) -> Self {
4256 push_header(self.as_vec_mut(), 6u16, value.len() as u16);
4257 self.as_vec_mut().extend(value);
4258 self
4259 }
4260}
4261impl<Prev: Pusher> Drop for PushServer<Prev> {
4262 fn drop(&mut self) {
4263 if let Some(prev) = &mut self.prev {
4264 if let Some(header_offset) = &self.header_offset {
4265 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4266 }
4267 }
4268 }
4269}
4270pub struct PushVersion<Prev: Pusher> {
4271 pub(crate) prev: Option<Prev>,
4272 pub(crate) header_offset: Option<usize>,
4273}
4274impl<Prev: Pusher> Pusher for PushVersion<Prev> {
4275 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4276 self.prev.as_mut().unwrap().as_vec_mut()
4277 }
4278 fn as_vec(&self) -> &Vec<u8> {
4279 self.prev.as_ref().unwrap().as_vec()
4280 }
4281}
4282impl<Prev: Pusher> PushVersion<Prev> {
4283 pub fn new(prev: Prev) -> Self {
4284 Self {
4285 prev: Some(prev),
4286 header_offset: None,
4287 }
4288 }
4289 pub fn end_nested(mut self) -> Prev {
4290 let mut prev = self.prev.take().unwrap();
4291 if let Some(header_offset) = &self.header_offset {
4292 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4293 }
4294 prev
4295 }
4296 pub fn push_major(mut self, value: u32) -> Self {
4297 push_header(self.as_vec_mut(), 1u16, 4 as u16);
4298 self.as_vec_mut().extend(value.to_ne_bytes());
4299 self
4300 }
4301 pub fn push_minor(mut self, value: u32) -> Self {
4302 push_header(self.as_vec_mut(), 2u16, 4 as u16);
4303 self.as_vec_mut().extend(value.to_ne_bytes());
4304 self
4305 }
4306 pub fn push_enabled(mut self, value: ()) -> Self {
4307 push_header(self.as_vec_mut(), 3u16, 0 as u16);
4308 self
4309 }
4310}
4311impl<Prev: Pusher> Drop for PushVersion<Prev> {
4312 fn drop(&mut self) {
4313 if let Some(prev) = &mut self.prev {
4314 if let Some(header_offset) = &self.header_offset {
4315 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4316 }
4317 }
4318 }
4319}
4320pub struct PushServerProto<Prev: Pusher> {
4321 pub(crate) prev: Option<Prev>,
4322 pub(crate) header_offset: Option<usize>,
4323}
4324impl<Prev: Pusher> Pusher for PushServerProto<Prev> {
4325 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4326 self.prev.as_mut().unwrap().as_vec_mut()
4327 }
4328 fn as_vec(&self) -> &Vec<u8> {
4329 self.prev.as_ref().unwrap().as_vec()
4330 }
4331}
4332impl<Prev: Pusher> PushServerProto<Prev> {
4333 pub fn new(prev: Prev) -> Self {
4334 Self {
4335 prev: Some(prev),
4336 header_offset: None,
4337 }
4338 }
4339 pub fn end_nested(mut self) -> Prev {
4340 let mut prev = self.prev.take().unwrap();
4341 if let Some(header_offset) = &self.header_offset {
4342 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4343 }
4344 prev
4345 }
4346 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4347 pub fn nested_version(mut self) -> PushVersion<Self> {
4348 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4349 PushVersion {
4350 prev: Some(self),
4351 header_offset: Some(header_offset),
4352 }
4353 }
4354}
4355impl<Prev: Pusher> Drop for PushServerProto<Prev> {
4356 fn drop(&mut self) {
4357 if let Some(prev) = &mut self.prev {
4358 if let Some(header_offset) = &self.header_offset {
4359 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4360 }
4361 }
4362 }
4363}
4364pub struct PushSock<Prev: Pusher> {
4365 pub(crate) prev: Option<Prev>,
4366 pub(crate) header_offset: Option<usize>,
4367}
4368impl<Prev: Pusher> Pusher for PushSock<Prev> {
4369 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4370 self.prev.as_mut().unwrap().as_vec_mut()
4371 }
4372 fn as_vec(&self) -> &Vec<u8> {
4373 self.prev.as_ref().unwrap().as_vec()
4374 }
4375}
4376impl<Prev: Pusher> PushSock<Prev> {
4377 pub fn new(prev: Prev) -> Self {
4378 Self {
4379 prev: Some(prev),
4380 header_offset: None,
4381 }
4382 }
4383 pub fn end_nested(mut self) -> Prev {
4384 let mut prev = self.prev.take().unwrap();
4385 if let Some(header_offset) = &self.header_offset {
4386 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4387 }
4388 prev
4389 }
4390 pub fn push_addr(mut self, value: &[u8]) -> Self {
4391 push_header(self.as_vec_mut(), 1u16, value.len() as u16);
4392 self.as_vec_mut().extend(value);
4393 self
4394 }
4395 pub fn push_transport_name(mut self, value: &CStr) -> Self {
4396 push_header(
4397 self.as_vec_mut(),
4398 2u16,
4399 value.to_bytes_with_nul().len() as u16,
4400 );
4401 self.as_vec_mut().extend(value.to_bytes_with_nul());
4402 self
4403 }
4404 pub fn push_transport_name_bytes(mut self, value: &[u8]) -> Self {
4405 push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
4406 self.as_vec_mut().extend(value);
4407 self.as_vec_mut().push(0);
4408 self
4409 }
4410}
4411impl<Prev: Pusher> Drop for PushSock<Prev> {
4412 fn drop(&mut self) {
4413 if let Some(prev) = &mut self.prev {
4414 if let Some(header_offset) = &self.header_offset {
4415 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4416 }
4417 }
4418 }
4419}
4420pub struct PushServerSock<Prev: Pusher> {
4421 pub(crate) prev: Option<Prev>,
4422 pub(crate) header_offset: Option<usize>,
4423}
4424impl<Prev: Pusher> Pusher for PushServerSock<Prev> {
4425 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4426 self.prev.as_mut().unwrap().as_vec_mut()
4427 }
4428 fn as_vec(&self) -> &Vec<u8> {
4429 self.prev.as_ref().unwrap().as_vec()
4430 }
4431}
4432impl<Prev: Pusher> PushServerSock<Prev> {
4433 pub fn new(prev: Prev) -> Self {
4434 Self {
4435 prev: Some(prev),
4436 header_offset: None,
4437 }
4438 }
4439 pub fn end_nested(mut self) -> Prev {
4440 let mut prev = self.prev.take().unwrap();
4441 if let Some(header_offset) = &self.header_offset {
4442 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4443 }
4444 prev
4445 }
4446 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4447 pub fn nested_addr(mut self) -> PushSock<Self> {
4448 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4449 PushSock {
4450 prev: Some(self),
4451 header_offset: Some(header_offset),
4452 }
4453 }
4454}
4455impl<Prev: Pusher> Drop for PushServerSock<Prev> {
4456 fn drop(&mut self) {
4457 if let Some(prev) = &mut self.prev {
4458 if let Some(header_offset) = &self.header_offset {
4459 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4460 }
4461 }
4462 }
4463}
4464pub struct PushPoolMode<Prev: Pusher> {
4465 pub(crate) prev: Option<Prev>,
4466 pub(crate) header_offset: Option<usize>,
4467}
4468impl<Prev: Pusher> Pusher for PushPoolMode<Prev> {
4469 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4470 self.prev.as_mut().unwrap().as_vec_mut()
4471 }
4472 fn as_vec(&self) -> &Vec<u8> {
4473 self.prev.as_ref().unwrap().as_vec()
4474 }
4475}
4476impl<Prev: Pusher> PushPoolMode<Prev> {
4477 pub fn new(prev: Prev) -> Self {
4478 Self {
4479 prev: Some(prev),
4480 header_offset: None,
4481 }
4482 }
4483 pub fn end_nested(mut self) -> Prev {
4484 let mut prev = self.prev.take().unwrap();
4485 if let Some(header_offset) = &self.header_offset {
4486 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4487 }
4488 prev
4489 }
4490 pub fn push_mode(mut self, value: &CStr) -> Self {
4491 push_header(
4492 self.as_vec_mut(),
4493 1u16,
4494 value.to_bytes_with_nul().len() as u16,
4495 );
4496 self.as_vec_mut().extend(value.to_bytes_with_nul());
4497 self
4498 }
4499 pub fn push_mode_bytes(mut self, value: &[u8]) -> Self {
4500 push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
4501 self.as_vec_mut().extend(value);
4502 self.as_vec_mut().push(0);
4503 self
4504 }
4505 pub fn push_npools(mut self, value: u32) -> Self {
4506 push_header(self.as_vec_mut(), 2u16, 4 as u16);
4507 self.as_vec_mut().extend(value.to_ne_bytes());
4508 self
4509 }
4510}
4511impl<Prev: Pusher> Drop for PushPoolMode<Prev> {
4512 fn drop(&mut self) {
4513 if let Some(prev) = &mut self.prev {
4514 if let Some(header_offset) = &self.header_offset {
4515 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4516 }
4517 }
4518 }
4519}
4520pub struct PushFslocation<Prev: Pusher> {
4521 pub(crate) prev: Option<Prev>,
4522 pub(crate) header_offset: Option<usize>,
4523}
4524impl<Prev: Pusher> Pusher for PushFslocation<Prev> {
4525 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4526 self.prev.as_mut().unwrap().as_vec_mut()
4527 }
4528 fn as_vec(&self) -> &Vec<u8> {
4529 self.prev.as_ref().unwrap().as_vec()
4530 }
4531}
4532impl<Prev: Pusher> PushFslocation<Prev> {
4533 pub fn new(prev: Prev) -> Self {
4534 Self {
4535 prev: Some(prev),
4536 header_offset: None,
4537 }
4538 }
4539 pub fn end_nested(mut self) -> Prev {
4540 let mut prev = self.prev.take().unwrap();
4541 if let Some(header_offset) = &self.header_offset {
4542 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4543 }
4544 prev
4545 }
4546 pub fn push_host(mut self, value: &CStr) -> Self {
4547 push_header(
4548 self.as_vec_mut(),
4549 1u16,
4550 value.to_bytes_with_nul().len() as u16,
4551 );
4552 self.as_vec_mut().extend(value.to_bytes_with_nul());
4553 self
4554 }
4555 pub fn push_host_bytes(mut self, value: &[u8]) -> Self {
4556 push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
4557 self.as_vec_mut().extend(value);
4558 self.as_vec_mut().push(0);
4559 self
4560 }
4561 pub fn push_path(mut self, value: &CStr) -> Self {
4562 push_header(
4563 self.as_vec_mut(),
4564 2u16,
4565 value.to_bytes_with_nul().len() as u16,
4566 );
4567 self.as_vec_mut().extend(value.to_bytes_with_nul());
4568 self
4569 }
4570 pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
4571 push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
4572 self.as_vec_mut().extend(value);
4573 self.as_vec_mut().push(0);
4574 self
4575 }
4576}
4577impl<Prev: Pusher> Drop for PushFslocation<Prev> {
4578 fn drop(&mut self) {
4579 if let Some(prev) = &mut self.prev {
4580 if let Some(header_offset) = &self.header_offset {
4581 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4582 }
4583 }
4584 }
4585}
4586pub struct PushFslocations<Prev: Pusher> {
4587 pub(crate) prev: Option<Prev>,
4588 pub(crate) header_offset: Option<usize>,
4589}
4590impl<Prev: Pusher> Pusher for PushFslocations<Prev> {
4591 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4592 self.prev.as_mut().unwrap().as_vec_mut()
4593 }
4594 fn as_vec(&self) -> &Vec<u8> {
4595 self.prev.as_ref().unwrap().as_vec()
4596 }
4597}
4598impl<Prev: Pusher> PushFslocations<Prev> {
4599 pub fn new(prev: Prev) -> Self {
4600 Self {
4601 prev: Some(prev),
4602 header_offset: None,
4603 }
4604 }
4605 pub fn end_nested(mut self) -> Prev {
4606 let mut prev = self.prev.take().unwrap();
4607 if let Some(header_offset) = &self.header_offset {
4608 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4609 }
4610 prev
4611 }
4612 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4613 pub fn nested_location(mut self) -> PushFslocation<Self> {
4614 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4615 PushFslocation {
4616 prev: Some(self),
4617 header_offset: Some(header_offset),
4618 }
4619 }
4620}
4621impl<Prev: Pusher> Drop for PushFslocations<Prev> {
4622 fn drop(&mut self) {
4623 if let Some(prev) = &mut self.prev {
4624 if let Some(header_offset) = &self.header_offset {
4625 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4626 }
4627 }
4628 }
4629}
4630pub struct PushAuthFlavor<Prev: Pusher> {
4631 pub(crate) prev: Option<Prev>,
4632 pub(crate) header_offset: Option<usize>,
4633}
4634impl<Prev: Pusher> Pusher for PushAuthFlavor<Prev> {
4635 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4636 self.prev.as_mut().unwrap().as_vec_mut()
4637 }
4638 fn as_vec(&self) -> &Vec<u8> {
4639 self.prev.as_ref().unwrap().as_vec()
4640 }
4641}
4642impl<Prev: Pusher> PushAuthFlavor<Prev> {
4643 pub fn new(prev: Prev) -> Self {
4644 Self {
4645 prev: Some(prev),
4646 header_offset: None,
4647 }
4648 }
4649 pub fn end_nested(mut self) -> Prev {
4650 let mut prev = self.prev.take().unwrap();
4651 if let Some(header_offset) = &self.header_offset {
4652 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4653 }
4654 prev
4655 }
4656 pub fn push_pseudoflavor(mut self, value: u32) -> Self {
4657 push_header(self.as_vec_mut(), 1u16, 4 as u16);
4658 self.as_vec_mut().extend(value.to_ne_bytes());
4659 self
4660 }
4661 #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
4662 pub fn push_flags(mut self, value: u32) -> Self {
4663 push_header(self.as_vec_mut(), 2u16, 4 as u16);
4664 self.as_vec_mut().extend(value.to_ne_bytes());
4665 self
4666 }
4667}
4668impl<Prev: Pusher> Drop for PushAuthFlavor<Prev> {
4669 fn drop(&mut self) {
4670 if let Some(prev) = &mut self.prev {
4671 if let Some(header_offset) = &self.header_offset {
4672 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4673 }
4674 }
4675 }
4676}
4677pub struct PushSvcExport<Prev: Pusher> {
4678 pub(crate) prev: Option<Prev>,
4679 pub(crate) header_offset: Option<usize>,
4680}
4681impl<Prev: Pusher> Pusher for PushSvcExport<Prev> {
4682 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4683 self.prev.as_mut().unwrap().as_vec_mut()
4684 }
4685 fn as_vec(&self) -> &Vec<u8> {
4686 self.prev.as_ref().unwrap().as_vec()
4687 }
4688}
4689impl<Prev: Pusher> PushSvcExport<Prev> {
4690 pub fn new(prev: Prev) -> Self {
4691 Self {
4692 prev: Some(prev),
4693 header_offset: None,
4694 }
4695 }
4696 pub fn end_nested(mut self) -> Prev {
4697 let mut prev = self.prev.take().unwrap();
4698 if let Some(header_offset) = &self.header_offset {
4699 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4700 }
4701 prev
4702 }
4703 pub fn push_seqno(mut self, value: u64) -> Self {
4704 push_header(self.as_vec_mut(), 1u16, 8 as u16);
4705 self.as_vec_mut().extend(value.to_ne_bytes());
4706 self
4707 }
4708 pub fn push_client(mut self, value: &CStr) -> Self {
4709 push_header(
4710 self.as_vec_mut(),
4711 2u16,
4712 value.to_bytes_with_nul().len() as u16,
4713 );
4714 self.as_vec_mut().extend(value.to_bytes_with_nul());
4715 self
4716 }
4717 pub fn push_client_bytes(mut self, value: &[u8]) -> Self {
4718 push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
4719 self.as_vec_mut().extend(value);
4720 self.as_vec_mut().push(0);
4721 self
4722 }
4723 pub fn push_path(mut self, value: &CStr) -> Self {
4724 push_header(
4725 self.as_vec_mut(),
4726 3u16,
4727 value.to_bytes_with_nul().len() as u16,
4728 );
4729 self.as_vec_mut().extend(value.to_bytes_with_nul());
4730 self
4731 }
4732 pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
4733 push_header(self.as_vec_mut(), 3u16, (value.len() + 1) as u16);
4734 self.as_vec_mut().extend(value);
4735 self.as_vec_mut().push(0);
4736 self
4737 }
4738 pub fn push_negative(mut self, value: ()) -> Self {
4739 push_header(self.as_vec_mut(), 4u16, 0 as u16);
4740 self
4741 }
4742 pub fn push_expiry(mut self, value: u64) -> Self {
4743 push_header(self.as_vec_mut(), 5u16, 8 as u16);
4744 self.as_vec_mut().extend(value.to_ne_bytes());
4745 self
4746 }
4747 pub fn push_anon_uid(mut self, value: u32) -> Self {
4748 push_header(self.as_vec_mut(), 6u16, 4 as u16);
4749 self.as_vec_mut().extend(value.to_ne_bytes());
4750 self
4751 }
4752 pub fn push_anon_gid(mut self, value: u32) -> Self {
4753 push_header(self.as_vec_mut(), 7u16, 4 as u16);
4754 self.as_vec_mut().extend(value.to_ne_bytes());
4755 self
4756 }
4757 pub fn nested_fslocations(mut self) -> PushFslocations<Self> {
4758 let header_offset = push_nested_header(self.as_vec_mut(), 8u16);
4759 PushFslocations {
4760 prev: Some(self),
4761 header_offset: Some(header_offset),
4762 }
4763 }
4764 pub fn push_uuid(mut self, value: &[u8]) -> Self {
4765 push_header(self.as_vec_mut(), 9u16, value.len() as u16);
4766 self.as_vec_mut().extend(value);
4767 self
4768 }
4769 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4770 pub fn nested_secinfo(mut self) -> PushAuthFlavor<Self> {
4771 let header_offset = push_nested_header(self.as_vec_mut(), 10u16);
4772 PushAuthFlavor {
4773 prev: Some(self),
4774 header_offset: Some(header_offset),
4775 }
4776 }
4777 #[doc = "Associated type: [`XprtsecMode`] (enum)\nAttribute may repeat multiple times (treat it as array)"]
4778 pub fn push_xprtsec(mut self, value: u32) -> Self {
4779 push_header(self.as_vec_mut(), 11u16, 4 as u16);
4780 self.as_vec_mut().extend(value.to_ne_bytes());
4781 self
4782 }
4783 #[doc = "Associated type: [`ExportFlags`] (1 bit per enumeration)"]
4784 pub fn push_flags(mut self, value: u32) -> Self {
4785 push_header(self.as_vec_mut(), 12u16, 4 as u16);
4786 self.as_vec_mut().extend(value.to_ne_bytes());
4787 self
4788 }
4789 pub fn push_fsid(mut self, value: i32) -> Self {
4790 push_header(self.as_vec_mut(), 13u16, 4 as u16);
4791 self.as_vec_mut().extend(value.to_ne_bytes());
4792 self
4793 }
4794}
4795impl<Prev: Pusher> Drop for PushSvcExport<Prev> {
4796 fn drop(&mut self) {
4797 if let Some(prev) = &mut self.prev {
4798 if let Some(header_offset) = &self.header_offset {
4799 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4800 }
4801 }
4802 }
4803}
4804pub struct PushSvcExportReqs<Prev: Pusher> {
4805 pub(crate) prev: Option<Prev>,
4806 pub(crate) header_offset: Option<usize>,
4807}
4808impl<Prev: Pusher> Pusher for PushSvcExportReqs<Prev> {
4809 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4810 self.prev.as_mut().unwrap().as_vec_mut()
4811 }
4812 fn as_vec(&self) -> &Vec<u8> {
4813 self.prev.as_ref().unwrap().as_vec()
4814 }
4815}
4816impl<Prev: Pusher> PushSvcExportReqs<Prev> {
4817 pub fn new(prev: Prev) -> Self {
4818 Self {
4819 prev: Some(prev),
4820 header_offset: None,
4821 }
4822 }
4823 pub fn end_nested(mut self) -> Prev {
4824 let mut prev = self.prev.take().unwrap();
4825 if let Some(header_offset) = &self.header_offset {
4826 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4827 }
4828 prev
4829 }
4830 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4831 pub fn nested_requests(mut self) -> PushSvcExport<Self> {
4832 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4833 PushSvcExport {
4834 prev: Some(self),
4835 header_offset: Some(header_offset),
4836 }
4837 }
4838}
4839impl<Prev: Pusher> Drop for PushSvcExportReqs<Prev> {
4840 fn drop(&mut self) {
4841 if let Some(prev) = &mut self.prev {
4842 if let Some(header_offset) = &self.header_offset {
4843 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4844 }
4845 }
4846 }
4847}
4848pub struct PushExpkey<Prev: Pusher> {
4849 pub(crate) prev: Option<Prev>,
4850 pub(crate) header_offset: Option<usize>,
4851}
4852impl<Prev: Pusher> Pusher for PushExpkey<Prev> {
4853 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4854 self.prev.as_mut().unwrap().as_vec_mut()
4855 }
4856 fn as_vec(&self) -> &Vec<u8> {
4857 self.prev.as_ref().unwrap().as_vec()
4858 }
4859}
4860impl<Prev: Pusher> PushExpkey<Prev> {
4861 pub fn new(prev: Prev) -> Self {
4862 Self {
4863 prev: Some(prev),
4864 header_offset: None,
4865 }
4866 }
4867 pub fn end_nested(mut self) -> Prev {
4868 let mut prev = self.prev.take().unwrap();
4869 if let Some(header_offset) = &self.header_offset {
4870 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4871 }
4872 prev
4873 }
4874 pub fn push_seqno(mut self, value: u64) -> Self {
4875 push_header(self.as_vec_mut(), 1u16, 8 as u16);
4876 self.as_vec_mut().extend(value.to_ne_bytes());
4877 self
4878 }
4879 pub fn push_client(mut self, value: &CStr) -> Self {
4880 push_header(
4881 self.as_vec_mut(),
4882 2u16,
4883 value.to_bytes_with_nul().len() as u16,
4884 );
4885 self.as_vec_mut().extend(value.to_bytes_with_nul());
4886 self
4887 }
4888 pub fn push_client_bytes(mut self, value: &[u8]) -> Self {
4889 push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
4890 self.as_vec_mut().extend(value);
4891 self.as_vec_mut().push(0);
4892 self
4893 }
4894 pub fn push_fsidtype(mut self, value: u8) -> Self {
4895 push_header(self.as_vec_mut(), 3u16, 1 as u16);
4896 self.as_vec_mut().extend(value.to_ne_bytes());
4897 self
4898 }
4899 pub fn push_fsid(mut self, value: &[u8]) -> Self {
4900 push_header(self.as_vec_mut(), 4u16, value.len() as u16);
4901 self.as_vec_mut().extend(value);
4902 self
4903 }
4904 pub fn push_negative(mut self, value: ()) -> Self {
4905 push_header(self.as_vec_mut(), 5u16, 0 as u16);
4906 self
4907 }
4908 pub fn push_expiry(mut self, value: u64) -> Self {
4909 push_header(self.as_vec_mut(), 6u16, 8 as u16);
4910 self.as_vec_mut().extend(value.to_ne_bytes());
4911 self
4912 }
4913 pub fn push_path(mut self, value: &CStr) -> Self {
4914 push_header(
4915 self.as_vec_mut(),
4916 7u16,
4917 value.to_bytes_with_nul().len() as u16,
4918 );
4919 self.as_vec_mut().extend(value.to_bytes_with_nul());
4920 self
4921 }
4922 pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
4923 push_header(self.as_vec_mut(), 7u16, (value.len() + 1) as u16);
4924 self.as_vec_mut().extend(value);
4925 self.as_vec_mut().push(0);
4926 self
4927 }
4928}
4929impl<Prev: Pusher> Drop for PushExpkey<Prev> {
4930 fn drop(&mut self) {
4931 if let Some(prev) = &mut self.prev {
4932 if let Some(header_offset) = &self.header_offset {
4933 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4934 }
4935 }
4936 }
4937}
4938pub struct PushExpkeyReqs<Prev: Pusher> {
4939 pub(crate) prev: Option<Prev>,
4940 pub(crate) header_offset: Option<usize>,
4941}
4942impl<Prev: Pusher> Pusher for PushExpkeyReqs<Prev> {
4943 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4944 self.prev.as_mut().unwrap().as_vec_mut()
4945 }
4946 fn as_vec(&self) -> &Vec<u8> {
4947 self.prev.as_ref().unwrap().as_vec()
4948 }
4949}
4950impl<Prev: Pusher> PushExpkeyReqs<Prev> {
4951 pub fn new(prev: Prev) -> Self {
4952 Self {
4953 prev: Some(prev),
4954 header_offset: None,
4955 }
4956 }
4957 pub fn end_nested(mut self) -> Prev {
4958 let mut prev = self.prev.take().unwrap();
4959 if let Some(header_offset) = &self.header_offset {
4960 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4961 }
4962 prev
4963 }
4964 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4965 pub fn nested_requests(mut self) -> PushExpkey<Self> {
4966 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
4967 PushExpkey {
4968 prev: Some(self),
4969 header_offset: Some(header_offset),
4970 }
4971 }
4972}
4973impl<Prev: Pusher> Drop for PushExpkeyReqs<Prev> {
4974 fn drop(&mut self) {
4975 if let Some(prev) = &mut self.prev {
4976 if let Some(header_offset) = &self.header_offset {
4977 finalize_nested_header(prev.as_vec_mut(), *header_offset);
4978 }
4979 }
4980 }
4981}
4982pub struct PushCacheFlush<Prev: Pusher> {
4983 pub(crate) prev: Option<Prev>,
4984 pub(crate) header_offset: Option<usize>,
4985}
4986impl<Prev: Pusher> Pusher for PushCacheFlush<Prev> {
4987 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
4988 self.prev.as_mut().unwrap().as_vec_mut()
4989 }
4990 fn as_vec(&self) -> &Vec<u8> {
4991 self.prev.as_ref().unwrap().as_vec()
4992 }
4993}
4994impl<Prev: Pusher> PushCacheFlush<Prev> {
4995 pub fn new(prev: Prev) -> Self {
4996 Self {
4997 prev: Some(prev),
4998 header_offset: None,
4999 }
5000 }
5001 pub fn end_nested(mut self) -> Prev {
5002 let mut prev = self.prev.take().unwrap();
5003 if let Some(header_offset) = &self.header_offset {
5004 finalize_nested_header(prev.as_vec_mut(), *header_offset);
5005 }
5006 prev
5007 }
5008 #[doc = "Associated type: [`CacheType`] (1 bit per enumeration)"]
5009 pub fn push_mask(mut self, value: u32) -> Self {
5010 push_header(self.as_vec_mut(), 1u16, 4 as u16);
5011 self.as_vec_mut().extend(value.to_ne_bytes());
5012 self
5013 }
5014}
5015impl<Prev: Pusher> Drop for PushCacheFlush<Prev> {
5016 fn drop(&mut self) {
5017 if let Some(prev) = &mut self.prev {
5018 if let Some(header_offset) = &self.header_offset {
5019 finalize_nested_header(prev.as_vec_mut(), *header_offset);
5020 }
5021 }
5022 }
5023}
5024pub struct PushUnlockIp<Prev: Pusher> {
5025 pub(crate) prev: Option<Prev>,
5026 pub(crate) header_offset: Option<usize>,
5027}
5028impl<Prev: Pusher> Pusher for PushUnlockIp<Prev> {
5029 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
5030 self.prev.as_mut().unwrap().as_vec_mut()
5031 }
5032 fn as_vec(&self) -> &Vec<u8> {
5033 self.prev.as_ref().unwrap().as_vec()
5034 }
5035}
5036impl<Prev: Pusher> PushUnlockIp<Prev> {
5037 pub fn new(prev: Prev) -> Self {
5038 Self {
5039 prev: Some(prev),
5040 header_offset: None,
5041 }
5042 }
5043 pub fn end_nested(mut self) -> Prev {
5044 let mut prev = self.prev.take().unwrap();
5045 if let Some(header_offset) = &self.header_offset {
5046 finalize_nested_header(prev.as_vec_mut(), *header_offset);
5047 }
5048 prev
5049 }
5050 #[doc = "struct sockaddr_in or struct sockaddr_in6.\n"]
5051 pub fn push_address(mut self, value: &[u8]) -> Self {
5052 push_header(self.as_vec_mut(), 1u16, value.len() as u16);
5053 self.as_vec_mut().extend(value);
5054 self
5055 }
5056}
5057impl<Prev: Pusher> Drop for PushUnlockIp<Prev> {
5058 fn drop(&mut self) {
5059 if let Some(prev) = &mut self.prev {
5060 if let Some(header_offset) = &self.header_offset {
5061 finalize_nested_header(prev.as_vec_mut(), *header_offset);
5062 }
5063 }
5064 }
5065}
5066pub struct PushUnlockFilesystem<Prev: Pusher> {
5067 pub(crate) prev: Option<Prev>,
5068 pub(crate) header_offset: Option<usize>,
5069}
5070impl<Prev: Pusher> Pusher for PushUnlockFilesystem<Prev> {
5071 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
5072 self.prev.as_mut().unwrap().as_vec_mut()
5073 }
5074 fn as_vec(&self) -> &Vec<u8> {
5075 self.prev.as_ref().unwrap().as_vec()
5076 }
5077}
5078impl<Prev: Pusher> PushUnlockFilesystem<Prev> {
5079 pub fn new(prev: Prev) -> Self {
5080 Self {
5081 prev: Some(prev),
5082 header_offset: None,
5083 }
5084 }
5085 pub fn end_nested(mut self) -> Prev {
5086 let mut prev = self.prev.take().unwrap();
5087 if let Some(header_offset) = &self.header_offset {
5088 finalize_nested_header(prev.as_vec_mut(), *header_offset);
5089 }
5090 prev
5091 }
5092 #[doc = "Filesystem path whose state should be released.\n"]
5093 pub fn push_path(mut self, value: &CStr) -> Self {
5094 push_header(
5095 self.as_vec_mut(),
5096 1u16,
5097 value.to_bytes_with_nul().len() as u16,
5098 );
5099 self.as_vec_mut().extend(value.to_bytes_with_nul());
5100 self
5101 }
5102 #[doc = "Filesystem path whose state should be released.\n"]
5103 pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
5104 push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
5105 self.as_vec_mut().extend(value);
5106 self.as_vec_mut().push(0);
5107 self
5108 }
5109}
5110impl<Prev: Pusher> Drop for PushUnlockFilesystem<Prev> {
5111 fn drop(&mut self) {
5112 if let Some(prev) = &mut self.prev {
5113 if let Some(header_offset) = &self.header_offset {
5114 finalize_nested_header(prev.as_vec_mut(), *header_offset);
5115 }
5116 }
5117 }
5118}
5119pub struct PushUnlockExport<Prev: Pusher> {
5120 pub(crate) prev: Option<Prev>,
5121 pub(crate) header_offset: Option<usize>,
5122}
5123impl<Prev: Pusher> Pusher for PushUnlockExport<Prev> {
5124 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
5125 self.prev.as_mut().unwrap().as_vec_mut()
5126 }
5127 fn as_vec(&self) -> &Vec<u8> {
5128 self.prev.as_ref().unwrap().as_vec()
5129 }
5130}
5131impl<Prev: Pusher> PushUnlockExport<Prev> {
5132 pub fn new(prev: Prev) -> Self {
5133 Self {
5134 prev: Some(prev),
5135 header_offset: None,
5136 }
5137 }
5138 pub fn end_nested(mut self) -> Prev {
5139 let mut prev = self.prev.take().unwrap();
5140 if let Some(header_offset) = &self.header_offset {
5141 finalize_nested_header(prev.as_vec_mut(), *header_offset);
5142 }
5143 prev
5144 }
5145 #[doc = "Export path whose NFSv4 state should be revoked. All state (opens,\nlocks, delegations, layouts) acquired through any export of this path is\nrevoked, regardless of which client holds the state. Intended for use\nafter all clients have been unexported from a given path, enabling the\nunderlying filesystem to be unmounted.\n"]
5146 pub fn push_path(mut self, value: &CStr) -> Self {
5147 push_header(
5148 self.as_vec_mut(),
5149 1u16,
5150 value.to_bytes_with_nul().len() as u16,
5151 );
5152 self.as_vec_mut().extend(value.to_bytes_with_nul());
5153 self
5154 }
5155 #[doc = "Export path whose NFSv4 state should be revoked. All state (opens,\nlocks, delegations, layouts) acquired through any export of this path is\nrevoked, regardless of which client holds the state. Intended for use\nafter all clients have been unexported from a given path, enabling the\nunderlying filesystem to be unmounted.\n"]
5156 pub fn push_path_bytes(mut self, value: &[u8]) -> Self {
5157 push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
5158 self.as_vec_mut().extend(value);
5159 self.as_vec_mut().push(0);
5160 self
5161 }
5162}
5163impl<Prev: Pusher> Drop for PushUnlockExport<Prev> {
5164 fn drop(&mut self) {
5165 if let Some(prev) = &mut self.prev {
5166 if let Some(header_offset) = &self.header_offset {
5167 finalize_nested_header(prev.as_vec_mut(), *header_offset);
5168 }
5169 }
5170 }
5171}
5172#[doc = "Notify attributes:\n- [`.get_cache_type()`](IterableCacheNotify::get_cache_type)\n"]
5173#[derive(Debug)]
5174pub struct OpCacheNotifyNotif;
5175impl OpCacheNotifyNotif {
5176 pub const CMD: u8 = 10u8;
5177 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterableCacheNotify<'a> {
5178 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5179 IterableCacheNotify::with_loc(attrs, buf.as_ptr() as usize)
5180 }
5181}
5182pub struct NotifGroup;
5183impl NotifGroup {
5184 pub const NONE: &str = "none";
5185 pub const NONE_CSTR: &CStr = c"none";
5186 #[doc = "Notifications:\n- [`OpCacheNotifyNotif`]\n"]
5187 pub const EXPORTD: &str = "exportd";
5188 #[doc = "Notifications:\n- [`OpCacheNotifyNotif`]\n"]
5189 pub const EXPORTD_CSTR: &CStr = c"exportd";
5190}
5191#[doc = "dump pending nfsd rpc\n\nReply attributes:\n- [.get_xid()](IterableRpcStatus::get_xid)\n- [.get_flags()](IterableRpcStatus::get_flags)\n- [.get_prog()](IterableRpcStatus::get_prog)\n- [.get_version()](IterableRpcStatus::get_version)\n- [.get_proc()](IterableRpcStatus::get_proc)\n- [.get_service_time()](IterableRpcStatus::get_service_time)\n- [.get_saddr4()](IterableRpcStatus::get_saddr4)\n- [.get_daddr4()](IterableRpcStatus::get_daddr4)\n- [.get_saddr6()](IterableRpcStatus::get_saddr6)\n- [.get_daddr6()](IterableRpcStatus::get_daddr6)\n- [.get_sport()](IterableRpcStatus::get_sport)\n- [.get_dport()](IterableRpcStatus::get_dport)\n- [.get_compound_ops()](IterableRpcStatus::get_compound_ops)\n\n"]
5192#[derive(Debug)]
5193pub struct OpRpcStatusGetDump<'r> {
5194 request: Request<'r>,
5195}
5196impl<'r> OpRpcStatusGetDump<'r> {
5197 pub fn new(mut request: Request<'r>) -> Self {
5198 Self::write_header(request.buf_mut());
5199 Self {
5200 request: request.set_dump(),
5201 }
5202 }
5203 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushRpcStatus<&'buf mut Vec<u8>> {
5204 Self::write_header(buf);
5205 PushRpcStatus::new(buf)
5206 }
5207 pub fn encode(&mut self) -> PushRpcStatus<&mut Vec<u8>> {
5208 PushRpcStatus::new(self.request.buf_mut())
5209 }
5210 pub fn into_encoder(self) -> PushRpcStatus<RequestBuf<'r>> {
5211 PushRpcStatus::new(self.request.buf)
5212 }
5213 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableRpcStatus<'a> {
5214 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5215 IterableRpcStatus::with_loc(attrs, buf.as_ptr() as usize)
5216 }
5217 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5218 let mut header = BuiltinNfgenmsg::new();
5219 header.cmd = 1u8;
5220 header.version = 1u8;
5221 prev.as_vec_mut().extend(header.as_slice());
5222 }
5223}
5224impl NetlinkRequest for OpRpcStatusGetDump<'_> {
5225 fn protocol(&self) -> Protocol {
5226 Protocol::Generic("nfsd".as_bytes())
5227 }
5228 fn flags(&self) -> u16 {
5229 self.request.flags
5230 }
5231 fn payload(&self) -> &[u8] {
5232 self.request.buf()
5233 }
5234 type ReplyType<'buf> = IterableRpcStatus<'buf>;
5235 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5236 Self::decode_request(buf)
5237 }
5238 fn lookup(
5239 buf: &[u8],
5240 offset: usize,
5241 missing_type: Option<u16>,
5242 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5243 Self::decode_request(buf).lookup_attr(offset, missing_type)
5244 }
5245}
5246#[doc = "set the maximum number of running threads\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_threads()](PushServer::push_threads)\n- [.push_gracetime()](PushServer::push_gracetime)\n- [.push_leasetime()](PushServer::push_leasetime)\n- [.push_scope()](PushServer::push_scope)\n- [.push_min_threads()](PushServer::push_min_threads)\n- [.push_fh_key()](PushServer::push_fh_key)\n\n"]
5247#[derive(Debug)]
5248pub struct OpThreadsSetDo<'r> {
5249 request: Request<'r>,
5250}
5251impl<'r> OpThreadsSetDo<'r> {
5252 pub fn new(mut request: Request<'r>) -> Self {
5253 Self::write_header(request.buf_mut());
5254 Self { request: request }
5255 }
5256 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServer<&'buf mut Vec<u8>> {
5257 Self::write_header(buf);
5258 PushServer::new(buf)
5259 }
5260 pub fn encode(&mut self) -> PushServer<&mut Vec<u8>> {
5261 PushServer::new(self.request.buf_mut())
5262 }
5263 pub fn into_encoder(self) -> PushServer<RequestBuf<'r>> {
5264 PushServer::new(self.request.buf)
5265 }
5266 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServer<'a> {
5267 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5268 IterableServer::with_loc(attrs, buf.as_ptr() as usize)
5269 }
5270 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5271 let mut header = BuiltinNfgenmsg::new();
5272 header.cmd = 2u8;
5273 header.version = 1u8;
5274 prev.as_vec_mut().extend(header.as_slice());
5275 }
5276}
5277impl NetlinkRequest for OpThreadsSetDo<'_> {
5278 fn protocol(&self) -> Protocol {
5279 Protocol::Generic("nfsd".as_bytes())
5280 }
5281 fn flags(&self) -> u16 {
5282 self.request.flags
5283 }
5284 fn payload(&self) -> &[u8] {
5285 self.request.buf()
5286 }
5287 type ReplyType<'buf> = IterableServer<'buf>;
5288 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5289 Self::decode_request(buf)
5290 }
5291 fn lookup(
5292 buf: &[u8],
5293 offset: usize,
5294 missing_type: Option<u16>,
5295 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5296 Self::decode_request(buf).lookup_attr(offset, missing_type)
5297 }
5298}
5299#[doc = "get the maximum number of running threads\n\nReply attributes:\n- [.get_threads()](IterableServer::get_threads)\n- [.get_gracetime()](IterableServer::get_gracetime)\n- [.get_leasetime()](IterableServer::get_leasetime)\n- [.get_scope()](IterableServer::get_scope)\n- [.get_min_threads()](IterableServer::get_min_threads)\n\n"]
5300#[derive(Debug)]
5301pub struct OpThreadsGetDo<'r> {
5302 request: Request<'r>,
5303}
5304impl<'r> OpThreadsGetDo<'r> {
5305 pub fn new(mut request: Request<'r>) -> Self {
5306 Self::write_header(request.buf_mut());
5307 Self { request: request }
5308 }
5309 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServer<&'buf mut Vec<u8>> {
5310 Self::write_header(buf);
5311 PushServer::new(buf)
5312 }
5313 pub fn encode(&mut self) -> PushServer<&mut Vec<u8>> {
5314 PushServer::new(self.request.buf_mut())
5315 }
5316 pub fn into_encoder(self) -> PushServer<RequestBuf<'r>> {
5317 PushServer::new(self.request.buf)
5318 }
5319 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServer<'a> {
5320 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5321 IterableServer::with_loc(attrs, buf.as_ptr() as usize)
5322 }
5323 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5324 let mut header = BuiltinNfgenmsg::new();
5325 header.cmd = 3u8;
5326 header.version = 1u8;
5327 prev.as_vec_mut().extend(header.as_slice());
5328 }
5329}
5330impl NetlinkRequest for OpThreadsGetDo<'_> {
5331 fn protocol(&self) -> Protocol {
5332 Protocol::Generic("nfsd".as_bytes())
5333 }
5334 fn flags(&self) -> u16 {
5335 self.request.flags
5336 }
5337 fn payload(&self) -> &[u8] {
5338 self.request.buf()
5339 }
5340 type ReplyType<'buf> = IterableServer<'buf>;
5341 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5342 Self::decode_request(buf)
5343 }
5344 fn lookup(
5345 buf: &[u8],
5346 offset: usize,
5347 missing_type: Option<u16>,
5348 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5349 Self::decode_request(buf).lookup_attr(offset, missing_type)
5350 }
5351}
5352#[doc = "set nfs enabled versions\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_version()](PushServerProto::nested_version)\n\n"]
5353#[derive(Debug)]
5354pub struct OpVersionSetDo<'r> {
5355 request: Request<'r>,
5356}
5357impl<'r> OpVersionSetDo<'r> {
5358 pub fn new(mut request: Request<'r>) -> Self {
5359 Self::write_header(request.buf_mut());
5360 Self { request: request }
5361 }
5362 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServerProto<&'buf mut Vec<u8>> {
5363 Self::write_header(buf);
5364 PushServerProto::new(buf)
5365 }
5366 pub fn encode(&mut self) -> PushServerProto<&mut Vec<u8>> {
5367 PushServerProto::new(self.request.buf_mut())
5368 }
5369 pub fn into_encoder(self) -> PushServerProto<RequestBuf<'r>> {
5370 PushServerProto::new(self.request.buf)
5371 }
5372 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServerProto<'a> {
5373 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5374 IterableServerProto::with_loc(attrs, buf.as_ptr() as usize)
5375 }
5376 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5377 let mut header = BuiltinNfgenmsg::new();
5378 header.cmd = 4u8;
5379 header.version = 1u8;
5380 prev.as_vec_mut().extend(header.as_slice());
5381 }
5382}
5383impl NetlinkRequest for OpVersionSetDo<'_> {
5384 fn protocol(&self) -> Protocol {
5385 Protocol::Generic("nfsd".as_bytes())
5386 }
5387 fn flags(&self) -> u16 {
5388 self.request.flags
5389 }
5390 fn payload(&self) -> &[u8] {
5391 self.request.buf()
5392 }
5393 type ReplyType<'buf> = IterableServerProto<'buf>;
5394 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5395 Self::decode_request(buf)
5396 }
5397 fn lookup(
5398 buf: &[u8],
5399 offset: usize,
5400 missing_type: Option<u16>,
5401 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5402 Self::decode_request(buf).lookup_attr(offset, missing_type)
5403 }
5404}
5405#[doc = "get nfs enabled versions\n\nReply attributes:\n- [.get_version()](IterableServerProto::get_version)\n\n"]
5406#[derive(Debug)]
5407pub struct OpVersionGetDo<'r> {
5408 request: Request<'r>,
5409}
5410impl<'r> OpVersionGetDo<'r> {
5411 pub fn new(mut request: Request<'r>) -> Self {
5412 Self::write_header(request.buf_mut());
5413 Self { request: request }
5414 }
5415 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServerProto<&'buf mut Vec<u8>> {
5416 Self::write_header(buf);
5417 PushServerProto::new(buf)
5418 }
5419 pub fn encode(&mut self) -> PushServerProto<&mut Vec<u8>> {
5420 PushServerProto::new(self.request.buf_mut())
5421 }
5422 pub fn into_encoder(self) -> PushServerProto<RequestBuf<'r>> {
5423 PushServerProto::new(self.request.buf)
5424 }
5425 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServerProto<'a> {
5426 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5427 IterableServerProto::with_loc(attrs, buf.as_ptr() as usize)
5428 }
5429 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5430 let mut header = BuiltinNfgenmsg::new();
5431 header.cmd = 5u8;
5432 header.version = 1u8;
5433 prev.as_vec_mut().extend(header.as_slice());
5434 }
5435}
5436impl NetlinkRequest for OpVersionGetDo<'_> {
5437 fn protocol(&self) -> Protocol {
5438 Protocol::Generic("nfsd".as_bytes())
5439 }
5440 fn flags(&self) -> u16 {
5441 self.request.flags
5442 }
5443 fn payload(&self) -> &[u8] {
5444 self.request.buf()
5445 }
5446 type ReplyType<'buf> = IterableServerProto<'buf>;
5447 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5448 Self::decode_request(buf)
5449 }
5450 fn lookup(
5451 buf: &[u8],
5452 offset: usize,
5453 missing_type: Option<u16>,
5454 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5455 Self::decode_request(buf).lookup_attr(offset, missing_type)
5456 }
5457}
5458#[doc = "set nfs running sockets\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_addr()](PushServerSock::nested_addr)\n\n"]
5459#[derive(Debug)]
5460pub struct OpListenerSetDo<'r> {
5461 request: Request<'r>,
5462}
5463impl<'r> OpListenerSetDo<'r> {
5464 pub fn new(mut request: Request<'r>) -> Self {
5465 Self::write_header(request.buf_mut());
5466 Self { request: request }
5467 }
5468 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServerSock<&'buf mut Vec<u8>> {
5469 Self::write_header(buf);
5470 PushServerSock::new(buf)
5471 }
5472 pub fn encode(&mut self) -> PushServerSock<&mut Vec<u8>> {
5473 PushServerSock::new(self.request.buf_mut())
5474 }
5475 pub fn into_encoder(self) -> PushServerSock<RequestBuf<'r>> {
5476 PushServerSock::new(self.request.buf)
5477 }
5478 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServerSock<'a> {
5479 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5480 IterableServerSock::with_loc(attrs, buf.as_ptr() as usize)
5481 }
5482 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5483 let mut header = BuiltinNfgenmsg::new();
5484 header.cmd = 6u8;
5485 header.version = 1u8;
5486 prev.as_vec_mut().extend(header.as_slice());
5487 }
5488}
5489impl NetlinkRequest for OpListenerSetDo<'_> {
5490 fn protocol(&self) -> Protocol {
5491 Protocol::Generic("nfsd".as_bytes())
5492 }
5493 fn flags(&self) -> u16 {
5494 self.request.flags
5495 }
5496 fn payload(&self) -> &[u8] {
5497 self.request.buf()
5498 }
5499 type ReplyType<'buf> = IterableServerSock<'buf>;
5500 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5501 Self::decode_request(buf)
5502 }
5503 fn lookup(
5504 buf: &[u8],
5505 offset: usize,
5506 missing_type: Option<u16>,
5507 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5508 Self::decode_request(buf).lookup_attr(offset, missing_type)
5509 }
5510}
5511#[doc = "get nfs running listeners\n\nReply attributes:\n- [.get_addr()](IterableServerSock::get_addr)\n\n"]
5512#[derive(Debug)]
5513pub struct OpListenerGetDo<'r> {
5514 request: Request<'r>,
5515}
5516impl<'r> OpListenerGetDo<'r> {
5517 pub fn new(mut request: Request<'r>) -> Self {
5518 Self::write_header(request.buf_mut());
5519 Self { request: request }
5520 }
5521 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushServerSock<&'buf mut Vec<u8>> {
5522 Self::write_header(buf);
5523 PushServerSock::new(buf)
5524 }
5525 pub fn encode(&mut self) -> PushServerSock<&mut Vec<u8>> {
5526 PushServerSock::new(self.request.buf_mut())
5527 }
5528 pub fn into_encoder(self) -> PushServerSock<RequestBuf<'r>> {
5529 PushServerSock::new(self.request.buf)
5530 }
5531 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableServerSock<'a> {
5532 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5533 IterableServerSock::with_loc(attrs, buf.as_ptr() as usize)
5534 }
5535 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5536 let mut header = BuiltinNfgenmsg::new();
5537 header.cmd = 7u8;
5538 header.version = 1u8;
5539 prev.as_vec_mut().extend(header.as_slice());
5540 }
5541}
5542impl NetlinkRequest for OpListenerGetDo<'_> {
5543 fn protocol(&self) -> Protocol {
5544 Protocol::Generic("nfsd".as_bytes())
5545 }
5546 fn flags(&self) -> u16 {
5547 self.request.flags
5548 }
5549 fn payload(&self) -> &[u8] {
5550 self.request.buf()
5551 }
5552 type ReplyType<'buf> = IterableServerSock<'buf>;
5553 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5554 Self::decode_request(buf)
5555 }
5556 fn lookup(
5557 buf: &[u8],
5558 offset: usize,
5559 missing_type: Option<u16>,
5560 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5561 Self::decode_request(buf).lookup_attr(offset, missing_type)
5562 }
5563}
5564#[doc = "set the current server pool-mode\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mode()](PushPoolMode::push_mode)\n\n"]
5565#[derive(Debug)]
5566pub struct OpPoolModeSetDo<'r> {
5567 request: Request<'r>,
5568}
5569impl<'r> OpPoolModeSetDo<'r> {
5570 pub fn new(mut request: Request<'r>) -> Self {
5571 Self::write_header(request.buf_mut());
5572 Self { request: request }
5573 }
5574 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushPoolMode<&'buf mut Vec<u8>> {
5575 Self::write_header(buf);
5576 PushPoolMode::new(buf)
5577 }
5578 pub fn encode(&mut self) -> PushPoolMode<&mut Vec<u8>> {
5579 PushPoolMode::new(self.request.buf_mut())
5580 }
5581 pub fn into_encoder(self) -> PushPoolMode<RequestBuf<'r>> {
5582 PushPoolMode::new(self.request.buf)
5583 }
5584 pub fn decode_request<'a>(buf: &'a [u8]) -> IterablePoolMode<'a> {
5585 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5586 IterablePoolMode::with_loc(attrs, buf.as_ptr() as usize)
5587 }
5588 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5589 let mut header = BuiltinNfgenmsg::new();
5590 header.cmd = 8u8;
5591 header.version = 1u8;
5592 prev.as_vec_mut().extend(header.as_slice());
5593 }
5594}
5595impl NetlinkRequest for OpPoolModeSetDo<'_> {
5596 fn protocol(&self) -> Protocol {
5597 Protocol::Generic("nfsd".as_bytes())
5598 }
5599 fn flags(&self) -> u16 {
5600 self.request.flags
5601 }
5602 fn payload(&self) -> &[u8] {
5603 self.request.buf()
5604 }
5605 type ReplyType<'buf> = IterablePoolMode<'buf>;
5606 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5607 Self::decode_request(buf)
5608 }
5609 fn lookup(
5610 buf: &[u8],
5611 offset: usize,
5612 missing_type: Option<u16>,
5613 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5614 Self::decode_request(buf).lookup_attr(offset, missing_type)
5615 }
5616}
5617#[doc = "get info about server pool-mode\n\nReply attributes:\n- [.get_mode()](IterablePoolMode::get_mode)\n- [.get_npools()](IterablePoolMode::get_npools)\n\n"]
5618#[derive(Debug)]
5619pub struct OpPoolModeGetDo<'r> {
5620 request: Request<'r>,
5621}
5622impl<'r> OpPoolModeGetDo<'r> {
5623 pub fn new(mut request: Request<'r>) -> Self {
5624 Self::write_header(request.buf_mut());
5625 Self { request: request }
5626 }
5627 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushPoolMode<&'buf mut Vec<u8>> {
5628 Self::write_header(buf);
5629 PushPoolMode::new(buf)
5630 }
5631 pub fn encode(&mut self) -> PushPoolMode<&mut Vec<u8>> {
5632 PushPoolMode::new(self.request.buf_mut())
5633 }
5634 pub fn into_encoder(self) -> PushPoolMode<RequestBuf<'r>> {
5635 PushPoolMode::new(self.request.buf)
5636 }
5637 pub fn decode_request<'a>(buf: &'a [u8]) -> IterablePoolMode<'a> {
5638 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5639 IterablePoolMode::with_loc(attrs, buf.as_ptr() as usize)
5640 }
5641 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5642 let mut header = BuiltinNfgenmsg::new();
5643 header.cmd = 9u8;
5644 header.version = 1u8;
5645 prev.as_vec_mut().extend(header.as_slice());
5646 }
5647}
5648impl NetlinkRequest for OpPoolModeGetDo<'_> {
5649 fn protocol(&self) -> Protocol {
5650 Protocol::Generic("nfsd".as_bytes())
5651 }
5652 fn flags(&self) -> u16 {
5653 self.request.flags
5654 }
5655 fn payload(&self) -> &[u8] {
5656 self.request.buf()
5657 }
5658 type ReplyType<'buf> = IterablePoolMode<'buf>;
5659 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5660 Self::decode_request(buf)
5661 }
5662 fn lookup(
5663 buf: &[u8],
5664 offset: usize,
5665 missing_type: Option<u16>,
5666 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5667 Self::decode_request(buf).lookup_attr(offset, missing_type)
5668 }
5669}
5670#[doc = "Dump all pending svc_export requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableSvcExportReqs::get_requests)\n\n"]
5671#[derive(Debug)]
5672pub struct OpSvcExportGetReqsDump<'r> {
5673 request: Request<'r>,
5674}
5675impl<'r> OpSvcExportGetReqsDump<'r> {
5676 pub fn new(mut request: Request<'r>) -> Self {
5677 Self::write_header(request.buf_mut());
5678 Self {
5679 request: request.set_dump(),
5680 }
5681 }
5682 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushSvcExportReqs<&'buf mut Vec<u8>> {
5683 Self::write_header(buf);
5684 PushSvcExportReqs::new(buf)
5685 }
5686 pub fn encode(&mut self) -> PushSvcExportReqs<&mut Vec<u8>> {
5687 PushSvcExportReqs::new(self.request.buf_mut())
5688 }
5689 pub fn into_encoder(self) -> PushSvcExportReqs<RequestBuf<'r>> {
5690 PushSvcExportReqs::new(self.request.buf)
5691 }
5692 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableSvcExportReqs<'a> {
5693 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5694 IterableSvcExportReqs::with_loc(attrs, buf.as_ptr() as usize)
5695 }
5696 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5697 let mut header = BuiltinNfgenmsg::new();
5698 header.cmd = 11u8;
5699 header.version = 1u8;
5700 prev.as_vec_mut().extend(header.as_slice());
5701 }
5702}
5703impl NetlinkRequest for OpSvcExportGetReqsDump<'_> {
5704 fn protocol(&self) -> Protocol {
5705 Protocol::Generic("nfsd".as_bytes())
5706 }
5707 fn flags(&self) -> u16 {
5708 self.request.flags
5709 }
5710 fn payload(&self) -> &[u8] {
5711 self.request.buf()
5712 }
5713 type ReplyType<'buf> = IterableSvcExportReqs<'buf>;
5714 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5715 Self::decode_request(buf)
5716 }
5717 fn lookup(
5718 buf: &[u8],
5719 offset: usize,
5720 missing_type: Option<u16>,
5721 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5722 Self::decode_request(buf).lookup_attr(offset, missing_type)
5723 }
5724}
5725#[doc = "Respond to one or more svc_export requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushSvcExportReqs::nested_requests)\n\n"]
5726#[derive(Debug)]
5727pub struct OpSvcExportSetReqsDo<'r> {
5728 request: Request<'r>,
5729}
5730impl<'r> OpSvcExportSetReqsDo<'r> {
5731 pub fn new(mut request: Request<'r>) -> Self {
5732 Self::write_header(request.buf_mut());
5733 Self { request: request }
5734 }
5735 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushSvcExportReqs<&'buf mut Vec<u8>> {
5736 Self::write_header(buf);
5737 PushSvcExportReqs::new(buf)
5738 }
5739 pub fn encode(&mut self) -> PushSvcExportReqs<&mut Vec<u8>> {
5740 PushSvcExportReqs::new(self.request.buf_mut())
5741 }
5742 pub fn into_encoder(self) -> PushSvcExportReqs<RequestBuf<'r>> {
5743 PushSvcExportReqs::new(self.request.buf)
5744 }
5745 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableSvcExportReqs<'a> {
5746 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5747 IterableSvcExportReqs::with_loc(attrs, buf.as_ptr() as usize)
5748 }
5749 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5750 let mut header = BuiltinNfgenmsg::new();
5751 header.cmd = 12u8;
5752 header.version = 1u8;
5753 prev.as_vec_mut().extend(header.as_slice());
5754 }
5755}
5756impl NetlinkRequest for OpSvcExportSetReqsDo<'_> {
5757 fn protocol(&self) -> Protocol {
5758 Protocol::Generic("nfsd".as_bytes())
5759 }
5760 fn flags(&self) -> u16 {
5761 self.request.flags
5762 }
5763 fn payload(&self) -> &[u8] {
5764 self.request.buf()
5765 }
5766 type ReplyType<'buf> = IterableSvcExportReqs<'buf>;
5767 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5768 Self::decode_request(buf)
5769 }
5770 fn lookup(
5771 buf: &[u8],
5772 offset: usize,
5773 missing_type: Option<u16>,
5774 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5775 Self::decode_request(buf).lookup_attr(offset, missing_type)
5776 }
5777}
5778#[doc = "Dump all pending expkey requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableExpkeyReqs::get_requests)\n\n"]
5779#[derive(Debug)]
5780pub struct OpExpkeyGetReqsDump<'r> {
5781 request: Request<'r>,
5782}
5783impl<'r> OpExpkeyGetReqsDump<'r> {
5784 pub fn new(mut request: Request<'r>) -> Self {
5785 Self::write_header(request.buf_mut());
5786 Self {
5787 request: request.set_dump(),
5788 }
5789 }
5790 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushExpkeyReqs<&'buf mut Vec<u8>> {
5791 Self::write_header(buf);
5792 PushExpkeyReqs::new(buf)
5793 }
5794 pub fn encode(&mut self) -> PushExpkeyReqs<&mut Vec<u8>> {
5795 PushExpkeyReqs::new(self.request.buf_mut())
5796 }
5797 pub fn into_encoder(self) -> PushExpkeyReqs<RequestBuf<'r>> {
5798 PushExpkeyReqs::new(self.request.buf)
5799 }
5800 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableExpkeyReqs<'a> {
5801 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5802 IterableExpkeyReqs::with_loc(attrs, buf.as_ptr() as usize)
5803 }
5804 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5805 let mut header = BuiltinNfgenmsg::new();
5806 header.cmd = 13u8;
5807 header.version = 1u8;
5808 prev.as_vec_mut().extend(header.as_slice());
5809 }
5810}
5811impl NetlinkRequest for OpExpkeyGetReqsDump<'_> {
5812 fn protocol(&self) -> Protocol {
5813 Protocol::Generic("nfsd".as_bytes())
5814 }
5815 fn flags(&self) -> u16 {
5816 self.request.flags
5817 }
5818 fn payload(&self) -> &[u8] {
5819 self.request.buf()
5820 }
5821 type ReplyType<'buf> = IterableExpkeyReqs<'buf>;
5822 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5823 Self::decode_request(buf)
5824 }
5825 fn lookup(
5826 buf: &[u8],
5827 offset: usize,
5828 missing_type: Option<u16>,
5829 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5830 Self::decode_request(buf).lookup_attr(offset, missing_type)
5831 }
5832}
5833#[doc = "Respond to one or more expkey requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushExpkeyReqs::nested_requests)\n\n"]
5834#[derive(Debug)]
5835pub struct OpExpkeySetReqsDo<'r> {
5836 request: Request<'r>,
5837}
5838impl<'r> OpExpkeySetReqsDo<'r> {
5839 pub fn new(mut request: Request<'r>) -> Self {
5840 Self::write_header(request.buf_mut());
5841 Self { request: request }
5842 }
5843 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushExpkeyReqs<&'buf mut Vec<u8>> {
5844 Self::write_header(buf);
5845 PushExpkeyReqs::new(buf)
5846 }
5847 pub fn encode(&mut self) -> PushExpkeyReqs<&mut Vec<u8>> {
5848 PushExpkeyReqs::new(self.request.buf_mut())
5849 }
5850 pub fn into_encoder(self) -> PushExpkeyReqs<RequestBuf<'r>> {
5851 PushExpkeyReqs::new(self.request.buf)
5852 }
5853 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableExpkeyReqs<'a> {
5854 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5855 IterableExpkeyReqs::with_loc(attrs, buf.as_ptr() as usize)
5856 }
5857 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5858 let mut header = BuiltinNfgenmsg::new();
5859 header.cmd = 14u8;
5860 header.version = 1u8;
5861 prev.as_vec_mut().extend(header.as_slice());
5862 }
5863}
5864impl NetlinkRequest for OpExpkeySetReqsDo<'_> {
5865 fn protocol(&self) -> Protocol {
5866 Protocol::Generic("nfsd".as_bytes())
5867 }
5868 fn flags(&self) -> u16 {
5869 self.request.flags
5870 }
5871 fn payload(&self) -> &[u8] {
5872 self.request.buf()
5873 }
5874 type ReplyType<'buf> = IterableExpkeyReqs<'buf>;
5875 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5876 Self::decode_request(buf)
5877 }
5878 fn lookup(
5879 buf: &[u8],
5880 offset: usize,
5881 missing_type: Option<u16>,
5882 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5883 Self::decode_request(buf).lookup_attr(offset, missing_type)
5884 }
5885}
5886#[doc = "Flush nfsd caches (svc_export and/or expkey)\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mask()](PushCacheFlush::push_mask)\n\n"]
5887#[derive(Debug)]
5888pub struct OpCacheFlushDo<'r> {
5889 request: Request<'r>,
5890}
5891impl<'r> OpCacheFlushDo<'r> {
5892 pub fn new(mut request: Request<'r>) -> Self {
5893 Self::write_header(request.buf_mut());
5894 Self { request: request }
5895 }
5896 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushCacheFlush<&'buf mut Vec<u8>> {
5897 Self::write_header(buf);
5898 PushCacheFlush::new(buf)
5899 }
5900 pub fn encode(&mut self) -> PushCacheFlush<&mut Vec<u8>> {
5901 PushCacheFlush::new(self.request.buf_mut())
5902 }
5903 pub fn into_encoder(self) -> PushCacheFlush<RequestBuf<'r>> {
5904 PushCacheFlush::new(self.request.buf)
5905 }
5906 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableCacheFlush<'a> {
5907 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5908 IterableCacheFlush::with_loc(attrs, buf.as_ptr() as usize)
5909 }
5910 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5911 let mut header = BuiltinNfgenmsg::new();
5912 header.cmd = 15u8;
5913 header.version = 1u8;
5914 prev.as_vec_mut().extend(header.as_slice());
5915 }
5916}
5917impl NetlinkRequest for OpCacheFlushDo<'_> {
5918 fn protocol(&self) -> Protocol {
5919 Protocol::Generic("nfsd".as_bytes())
5920 }
5921 fn flags(&self) -> u16 {
5922 self.request.flags
5923 }
5924 fn payload(&self) -> &[u8] {
5925 self.request.buf()
5926 }
5927 type ReplyType<'buf> = IterableCacheFlush<'buf>;
5928 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5929 Self::decode_request(buf)
5930 }
5931 fn lookup(
5932 buf: &[u8],
5933 offset: usize,
5934 missing_type: Option<u16>,
5935 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5936 Self::decode_request(buf).lookup_attr(offset, missing_type)
5937 }
5938}
5939#[doc = "release NLM locks held by an IP address\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_address()](PushUnlockIp::push_address)\n\n"]
5940#[derive(Debug)]
5941pub struct OpUnlockIpDo<'r> {
5942 request: Request<'r>,
5943}
5944impl<'r> OpUnlockIpDo<'r> {
5945 pub fn new(mut request: Request<'r>) -> Self {
5946 Self::write_header(request.buf_mut());
5947 Self { request: request }
5948 }
5949 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushUnlockIp<&'buf mut Vec<u8>> {
5950 Self::write_header(buf);
5951 PushUnlockIp::new(buf)
5952 }
5953 pub fn encode(&mut self) -> PushUnlockIp<&mut Vec<u8>> {
5954 PushUnlockIp::new(self.request.buf_mut())
5955 }
5956 pub fn into_encoder(self) -> PushUnlockIp<RequestBuf<'r>> {
5957 PushUnlockIp::new(self.request.buf)
5958 }
5959 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableUnlockIp<'a> {
5960 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
5961 IterableUnlockIp::with_loc(attrs, buf.as_ptr() as usize)
5962 }
5963 fn write_header<Prev: Pusher>(prev: &mut Prev) {
5964 let mut header = BuiltinNfgenmsg::new();
5965 header.cmd = 16u8;
5966 header.version = 1u8;
5967 prev.as_vec_mut().extend(header.as_slice());
5968 }
5969}
5970impl NetlinkRequest for OpUnlockIpDo<'_> {
5971 fn protocol(&self) -> Protocol {
5972 Protocol::Generic("nfsd".as_bytes())
5973 }
5974 fn flags(&self) -> u16 {
5975 self.request.flags
5976 }
5977 fn payload(&self) -> &[u8] {
5978 self.request.buf()
5979 }
5980 type ReplyType<'buf> = IterableUnlockIp<'buf>;
5981 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5982 Self::decode_request(buf)
5983 }
5984 fn lookup(
5985 buf: &[u8],
5986 offset: usize,
5987 missing_type: Option<u16>,
5988 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5989 Self::decode_request(buf).lookup_attr(offset, missing_type)
5990 }
5991}
5992#[doc = "revoke NFS state under a filesystem path\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_path()](PushUnlockFilesystem::push_path)\n\n"]
5993#[derive(Debug)]
5994pub struct OpUnlockFilesystemDo<'r> {
5995 request: Request<'r>,
5996}
5997impl<'r> OpUnlockFilesystemDo<'r> {
5998 pub fn new(mut request: Request<'r>) -> Self {
5999 Self::write_header(request.buf_mut());
6000 Self { request: request }
6001 }
6002 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushUnlockFilesystem<&'buf mut Vec<u8>> {
6003 Self::write_header(buf);
6004 PushUnlockFilesystem::new(buf)
6005 }
6006 pub fn encode(&mut self) -> PushUnlockFilesystem<&mut Vec<u8>> {
6007 PushUnlockFilesystem::new(self.request.buf_mut())
6008 }
6009 pub fn into_encoder(self) -> PushUnlockFilesystem<RequestBuf<'r>> {
6010 PushUnlockFilesystem::new(self.request.buf)
6011 }
6012 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableUnlockFilesystem<'a> {
6013 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
6014 IterableUnlockFilesystem::with_loc(attrs, buf.as_ptr() as usize)
6015 }
6016 fn write_header<Prev: Pusher>(prev: &mut Prev) {
6017 let mut header = BuiltinNfgenmsg::new();
6018 header.cmd = 17u8;
6019 header.version = 1u8;
6020 prev.as_vec_mut().extend(header.as_slice());
6021 }
6022}
6023impl NetlinkRequest for OpUnlockFilesystemDo<'_> {
6024 fn protocol(&self) -> Protocol {
6025 Protocol::Generic("nfsd".as_bytes())
6026 }
6027 fn flags(&self) -> u16 {
6028 self.request.flags
6029 }
6030 fn payload(&self) -> &[u8] {
6031 self.request.buf()
6032 }
6033 type ReplyType<'buf> = IterableUnlockFilesystem<'buf>;
6034 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
6035 Self::decode_request(buf)
6036 }
6037 fn lookup(
6038 buf: &[u8],
6039 offset: usize,
6040 missing_type: Option<u16>,
6041 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6042 Self::decode_request(buf).lookup_attr(offset, missing_type)
6043 }
6044}
6045#[doc = "Revoke NFSv4 state acquired through exports of a given path. Unlike\nunlock-filesystem, which operates at superblock granularity, this\ncommand targets only state associated with a specific export path.\nUserspace (exportfs -u) sends this after removing the last client for a\npath so the underlying filesystem can be unmounted.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_path()](PushUnlockExport::push_path)\n\n"]
6046#[derive(Debug)]
6047pub struct OpUnlockExportDo<'r> {
6048 request: Request<'r>,
6049}
6050impl<'r> OpUnlockExportDo<'r> {
6051 pub fn new(mut request: Request<'r>) -> Self {
6052 Self::write_header(request.buf_mut());
6053 Self { request: request }
6054 }
6055 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushUnlockExport<&'buf mut Vec<u8>> {
6056 Self::write_header(buf);
6057 PushUnlockExport::new(buf)
6058 }
6059 pub fn encode(&mut self) -> PushUnlockExport<&mut Vec<u8>> {
6060 PushUnlockExport::new(self.request.buf_mut())
6061 }
6062 pub fn into_encoder(self) -> PushUnlockExport<RequestBuf<'r>> {
6063 PushUnlockExport::new(self.request.buf)
6064 }
6065 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableUnlockExport<'a> {
6066 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
6067 IterableUnlockExport::with_loc(attrs, buf.as_ptr() as usize)
6068 }
6069 fn write_header<Prev: Pusher>(prev: &mut Prev) {
6070 let mut header = BuiltinNfgenmsg::new();
6071 header.cmd = 18u8;
6072 header.version = 1u8;
6073 prev.as_vec_mut().extend(header.as_slice());
6074 }
6075}
6076impl NetlinkRequest for OpUnlockExportDo<'_> {
6077 fn protocol(&self) -> Protocol {
6078 Protocol::Generic("nfsd".as_bytes())
6079 }
6080 fn flags(&self) -> u16 {
6081 self.request.flags
6082 }
6083 fn payload(&self) -> &[u8] {
6084 self.request.buf()
6085 }
6086 type ReplyType<'buf> = IterableUnlockExport<'buf>;
6087 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
6088 Self::decode_request(buf)
6089 }
6090 fn lookup(
6091 buf: &[u8],
6092 offset: usize,
6093 missing_type: Option<u16>,
6094 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6095 Self::decode_request(buf).lookup_attr(offset, missing_type)
6096 }
6097}
6098use crate::traits::LookupFn;
6099use crate::utils::RequestBuf;
6100#[derive(Debug)]
6101pub struct Request<'buf> {
6102 buf: RequestBuf<'buf>,
6103 flags: u16,
6104 writeback: Option<&'buf mut Option<RequestInfo>>,
6105}
6106#[allow(unused)]
6107#[derive(Debug, Clone)]
6108pub struct RequestInfo {
6109 protocol: Protocol,
6110 flags: u16,
6111 name: &'static str,
6112 lookup: LookupFn,
6113}
6114impl Request<'static> {
6115 pub fn new() -> Self {
6116 Self::new_from_buf(Vec::new())
6117 }
6118 pub fn new_from_buf(buf: Vec<u8>) -> Self {
6119 Self {
6120 flags: 0,
6121 buf: RequestBuf::Own(buf),
6122 writeback: None,
6123 }
6124 }
6125 pub fn into_buf(self) -> Vec<u8> {
6126 match self.buf {
6127 RequestBuf::Own(buf) => buf,
6128 _ => unreachable!(),
6129 }
6130 }
6131}
6132impl<'buf> Request<'buf> {
6133 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
6134 buf.clear();
6135 Self::new_extend(buf)
6136 }
6137 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
6138 Self {
6139 flags: 0,
6140 buf: RequestBuf::Ref(buf),
6141 writeback: None,
6142 }
6143 }
6144 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
6145 let Some(writeback) = &mut self.writeback else {
6146 return;
6147 };
6148 **writeback = Some(RequestInfo {
6149 protocol,
6150 flags: self.flags,
6151 name,
6152 lookup,
6153 })
6154 }
6155 pub fn buf(&self) -> &Vec<u8> {
6156 self.buf.buf()
6157 }
6158 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
6159 self.buf.buf_mut()
6160 }
6161 #[doc = "Set `NLM_F_CREATE` flag"]
6162 pub fn set_create(mut self) -> Self {
6163 self.flags |= consts::NLM_F_CREATE as u16;
6164 self
6165 }
6166 #[doc = "Set `NLM_F_EXCL` flag"]
6167 pub fn set_excl(mut self) -> Self {
6168 self.flags |= consts::NLM_F_EXCL as u16;
6169 self
6170 }
6171 #[doc = "Set `NLM_F_REPLACE` flag"]
6172 pub fn set_replace(mut self) -> Self {
6173 self.flags |= consts::NLM_F_REPLACE as u16;
6174 self
6175 }
6176 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
6177 pub fn set_change(self) -> Self {
6178 self.set_create().set_replace()
6179 }
6180 #[doc = "Set `NLM_F_APPEND` flag"]
6181 pub fn set_append(mut self) -> Self {
6182 self.flags |= consts::NLM_F_APPEND as u16;
6183 self
6184 }
6185 #[doc = "Set `self.flags |= flags`"]
6186 pub fn set_flags(mut self, flags: u16) -> Self {
6187 self.flags |= flags;
6188 self
6189 }
6190 #[doc = "Set `self.flags ^= self.flags & flags`"]
6191 pub fn unset_flags(mut self, flags: u16) -> Self {
6192 self.flags ^= self.flags & flags;
6193 self
6194 }
6195 #[doc = "Set `NLM_F_DUMP` flag"]
6196 fn set_dump(mut self) -> Self {
6197 self.flags |= consts::NLM_F_DUMP as u16;
6198 self
6199 }
6200 #[doc = "dump pending nfsd rpc\n\nReply attributes:\n- [.get_xid()](IterableRpcStatus::get_xid)\n- [.get_flags()](IterableRpcStatus::get_flags)\n- [.get_prog()](IterableRpcStatus::get_prog)\n- [.get_version()](IterableRpcStatus::get_version)\n- [.get_proc()](IterableRpcStatus::get_proc)\n- [.get_service_time()](IterableRpcStatus::get_service_time)\n- [.get_saddr4()](IterableRpcStatus::get_saddr4)\n- [.get_daddr4()](IterableRpcStatus::get_daddr4)\n- [.get_saddr6()](IterableRpcStatus::get_saddr6)\n- [.get_daddr6()](IterableRpcStatus::get_daddr6)\n- [.get_sport()](IterableRpcStatus::get_sport)\n- [.get_dport()](IterableRpcStatus::get_dport)\n- [.get_compound_ops()](IterableRpcStatus::get_compound_ops)\n\n"]
6201 pub fn op_rpc_status_get_dump(self) -> OpRpcStatusGetDump<'buf> {
6202 let mut res = OpRpcStatusGetDump::new(self);
6203 res.request.do_writeback(
6204 res.protocol(),
6205 "op-rpc-status-get-dump",
6206 OpRpcStatusGetDump::lookup,
6207 );
6208 res
6209 }
6210 #[doc = "set the maximum number of running threads\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_threads()](PushServer::push_threads)\n- [.push_gracetime()](PushServer::push_gracetime)\n- [.push_leasetime()](PushServer::push_leasetime)\n- [.push_scope()](PushServer::push_scope)\n- [.push_min_threads()](PushServer::push_min_threads)\n- [.push_fh_key()](PushServer::push_fh_key)\n\n"]
6211 pub fn op_threads_set_do(self) -> OpThreadsSetDo<'buf> {
6212 let mut res = OpThreadsSetDo::new(self);
6213 res.request
6214 .do_writeback(res.protocol(), "op-threads-set-do", OpThreadsSetDo::lookup);
6215 res
6216 }
6217 #[doc = "get the maximum number of running threads\n\nReply attributes:\n- [.get_threads()](IterableServer::get_threads)\n- [.get_gracetime()](IterableServer::get_gracetime)\n- [.get_leasetime()](IterableServer::get_leasetime)\n- [.get_scope()](IterableServer::get_scope)\n- [.get_min_threads()](IterableServer::get_min_threads)\n\n"]
6218 pub fn op_threads_get_do(self) -> OpThreadsGetDo<'buf> {
6219 let mut res = OpThreadsGetDo::new(self);
6220 res.request
6221 .do_writeback(res.protocol(), "op-threads-get-do", OpThreadsGetDo::lookup);
6222 res
6223 }
6224 #[doc = "set nfs enabled versions\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_version()](PushServerProto::nested_version)\n\n"]
6225 pub fn op_version_set_do(self) -> OpVersionSetDo<'buf> {
6226 let mut res = OpVersionSetDo::new(self);
6227 res.request
6228 .do_writeback(res.protocol(), "op-version-set-do", OpVersionSetDo::lookup);
6229 res
6230 }
6231 #[doc = "get nfs enabled versions\n\nReply attributes:\n- [.get_version()](IterableServerProto::get_version)\n\n"]
6232 pub fn op_version_get_do(self) -> OpVersionGetDo<'buf> {
6233 let mut res = OpVersionGetDo::new(self);
6234 res.request
6235 .do_writeback(res.protocol(), "op-version-get-do", OpVersionGetDo::lookup);
6236 res
6237 }
6238 #[doc = "set nfs running sockets\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_addr()](PushServerSock::nested_addr)\n\n"]
6239 pub fn op_listener_set_do(self) -> OpListenerSetDo<'buf> {
6240 let mut res = OpListenerSetDo::new(self);
6241 res.request.do_writeback(
6242 res.protocol(),
6243 "op-listener-set-do",
6244 OpListenerSetDo::lookup,
6245 );
6246 res
6247 }
6248 #[doc = "get nfs running listeners\n\nReply attributes:\n- [.get_addr()](IterableServerSock::get_addr)\n\n"]
6249 pub fn op_listener_get_do(self) -> OpListenerGetDo<'buf> {
6250 let mut res = OpListenerGetDo::new(self);
6251 res.request.do_writeback(
6252 res.protocol(),
6253 "op-listener-get-do",
6254 OpListenerGetDo::lookup,
6255 );
6256 res
6257 }
6258 #[doc = "set the current server pool-mode\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mode()](PushPoolMode::push_mode)\n\n"]
6259 pub fn op_pool_mode_set_do(self) -> OpPoolModeSetDo<'buf> {
6260 let mut res = OpPoolModeSetDo::new(self);
6261 res.request.do_writeback(
6262 res.protocol(),
6263 "op-pool-mode-set-do",
6264 OpPoolModeSetDo::lookup,
6265 );
6266 res
6267 }
6268 #[doc = "get info about server pool-mode\n\nReply attributes:\n- [.get_mode()](IterablePoolMode::get_mode)\n- [.get_npools()](IterablePoolMode::get_npools)\n\n"]
6269 pub fn op_pool_mode_get_do(self) -> OpPoolModeGetDo<'buf> {
6270 let mut res = OpPoolModeGetDo::new(self);
6271 res.request.do_writeback(
6272 res.protocol(),
6273 "op-pool-mode-get-do",
6274 OpPoolModeGetDo::lookup,
6275 );
6276 res
6277 }
6278 #[doc = "Dump all pending svc_export requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableSvcExportReqs::get_requests)\n\n"]
6279 pub fn op_svc_export_get_reqs_dump(self) -> OpSvcExportGetReqsDump<'buf> {
6280 let mut res = OpSvcExportGetReqsDump::new(self);
6281 res.request.do_writeback(
6282 res.protocol(),
6283 "op-svc-export-get-reqs-dump",
6284 OpSvcExportGetReqsDump::lookup,
6285 );
6286 res
6287 }
6288 #[doc = "Respond to one or more svc_export requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushSvcExportReqs::nested_requests)\n\n"]
6289 pub fn op_svc_export_set_reqs_do(self) -> OpSvcExportSetReqsDo<'buf> {
6290 let mut res = OpSvcExportSetReqsDo::new(self);
6291 res.request.do_writeback(
6292 res.protocol(),
6293 "op-svc-export-set-reqs-do",
6294 OpSvcExportSetReqsDo::lookup,
6295 );
6296 res
6297 }
6298 #[doc = "Dump all pending expkey requests\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_requests()](IterableExpkeyReqs::get_requests)\n\n"]
6299 pub fn op_expkey_get_reqs_dump(self) -> OpExpkeyGetReqsDump<'buf> {
6300 let mut res = OpExpkeyGetReqsDump::new(self);
6301 res.request.do_writeback(
6302 res.protocol(),
6303 "op-expkey-get-reqs-dump",
6304 OpExpkeyGetReqsDump::lookup,
6305 );
6306 res
6307 }
6308 #[doc = "Respond to one or more expkey requests\n\nFlags: admin-perm\n\nRequest attributes:\n- [.nested_requests()](PushExpkeyReqs::nested_requests)\n\n"]
6309 pub fn op_expkey_set_reqs_do(self) -> OpExpkeySetReqsDo<'buf> {
6310 let mut res = OpExpkeySetReqsDo::new(self);
6311 res.request.do_writeback(
6312 res.protocol(),
6313 "op-expkey-set-reqs-do",
6314 OpExpkeySetReqsDo::lookup,
6315 );
6316 res
6317 }
6318 #[doc = "Flush nfsd caches (svc_export and/or expkey)\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_mask()](PushCacheFlush::push_mask)\n\n"]
6319 pub fn op_cache_flush_do(self) -> OpCacheFlushDo<'buf> {
6320 let mut res = OpCacheFlushDo::new(self);
6321 res.request
6322 .do_writeback(res.protocol(), "op-cache-flush-do", OpCacheFlushDo::lookup);
6323 res
6324 }
6325 #[doc = "release NLM locks held by an IP address\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_address()](PushUnlockIp::push_address)\n\n"]
6326 pub fn op_unlock_ip_do(self) -> OpUnlockIpDo<'buf> {
6327 let mut res = OpUnlockIpDo::new(self);
6328 res.request
6329 .do_writeback(res.protocol(), "op-unlock-ip-do", OpUnlockIpDo::lookup);
6330 res
6331 }
6332 #[doc = "revoke NFS state under a filesystem path\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_path()](PushUnlockFilesystem::push_path)\n\n"]
6333 pub fn op_unlock_filesystem_do(self) -> OpUnlockFilesystemDo<'buf> {
6334 let mut res = OpUnlockFilesystemDo::new(self);
6335 res.request.do_writeback(
6336 res.protocol(),
6337 "op-unlock-filesystem-do",
6338 OpUnlockFilesystemDo::lookup,
6339 );
6340 res
6341 }
6342 #[doc = "Revoke NFSv4 state acquired through exports of a given path. Unlike\nunlock-filesystem, which operates at superblock granularity, this\ncommand targets only state associated with a specific export path.\nUserspace (exportfs -u) sends this after removing the last client for a\npath so the underlying filesystem can be unmounted.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_path()](PushUnlockExport::push_path)\n\n"]
6343 pub fn op_unlock_export_do(self) -> OpUnlockExportDo<'buf> {
6344 let mut res = OpUnlockExportDo::new(self);
6345 res.request.do_writeback(
6346 res.protocol(),
6347 "op-unlock-export-do",
6348 OpUnlockExportDo::lookup,
6349 );
6350 res
6351 }
6352}
6353#[cfg(test)]
6354mod generated_tests {
6355 use super::*;
6356 #[test]
6357 fn tests() {
6358 let _ = IterableCacheNotify::get_cache_type;
6359 let _ = IterableExpkeyReqs::get_requests;
6360 let _ = IterablePoolMode::get_mode;
6361 let _ = IterablePoolMode::get_npools;
6362 let _ = IterableRpcStatus::get_compound_ops;
6363 let _ = IterableRpcStatus::get_daddr4;
6364 let _ = IterableRpcStatus::get_daddr6;
6365 let _ = IterableRpcStatus::get_dport;
6366 let _ = IterableRpcStatus::get_flags;
6367 let _ = IterableRpcStatus::get_proc;
6368 let _ = IterableRpcStatus::get_prog;
6369 let _ = IterableRpcStatus::get_saddr4;
6370 let _ = IterableRpcStatus::get_saddr6;
6371 let _ = IterableRpcStatus::get_service_time;
6372 let _ = IterableRpcStatus::get_sport;
6373 let _ = IterableRpcStatus::get_version;
6374 let _ = IterableRpcStatus::get_xid;
6375 let _ = IterableServer::get_gracetime;
6376 let _ = IterableServer::get_leasetime;
6377 let _ = IterableServer::get_min_threads;
6378 let _ = IterableServer::get_scope;
6379 let _ = IterableServer::get_threads;
6380 let _ = IterableServerProto::get_version;
6381 let _ = IterableServerSock::get_addr;
6382 let _ = IterableSvcExportReqs::get_requests;
6383 let _ = OpCacheNotifyNotif;
6384 let _ = PushCacheFlush::<&mut Vec<u8>>::push_mask;
6385 let _ = PushExpkeyReqs::<&mut Vec<u8>>::nested_requests;
6386 let _ = PushPoolMode::<&mut Vec<u8>>::push_mode;
6387 let _ = PushServer::<&mut Vec<u8>>::push_fh_key;
6388 let _ = PushServer::<&mut Vec<u8>>::push_gracetime;
6389 let _ = PushServer::<&mut Vec<u8>>::push_leasetime;
6390 let _ = PushServer::<&mut Vec<u8>>::push_min_threads;
6391 let _ = PushServer::<&mut Vec<u8>>::push_scope;
6392 let _ = PushServer::<&mut Vec<u8>>::push_threads;
6393 let _ = PushServerProto::<&mut Vec<u8>>::nested_version;
6394 let _ = PushServerSock::<&mut Vec<u8>>::nested_addr;
6395 let _ = PushSvcExportReqs::<&mut Vec<u8>>::nested_requests;
6396 let _ = PushUnlockExport::<&mut Vec<u8>>::push_path;
6397 let _ = PushUnlockFilesystem::<&mut Vec<u8>>::push_path;
6398 let _ = PushUnlockIp::<&mut Vec<u8>>::push_address;
6399 }
6400}