1#![doc = "Auxilary types not porovided by any particular family\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)]
10#[cfg(test)]
11mod tests;
12use crate::{
13 consts,
14 traits::{NetlinkRequest, Protocol},
15 utils::*,
16};
17pub const PROTONAME: &str = "builtin";
18pub const PROTONAME_CSTR: &CStr = c"builtin";
19#[derive(Debug)]
20#[doc = "Generic family header\n"]
21#[repr(C, packed(4))]
22pub struct BuiltinNfgenmsg {
23 pub cmd: u8,
24 pub version: u8,
25 pub reserved: u16,
26}
27impl Clone for BuiltinNfgenmsg {
28 fn clone(&self) -> Self {
29 Self::new_from_array(*self.as_array())
30 }
31}
32#[doc = "Create zero-initialized struct"]
33impl Default for BuiltinNfgenmsg {
34 fn default() -> Self {
35 Self::new()
36 }
37}
38impl BuiltinNfgenmsg {
39 #[doc = "Create zero-initialized struct"]
40 pub fn new() -> Self {
41 Self::new_from_array([0u8; Self::len()])
42 }
43 #[doc = "Copy from contents from slice"]
44 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
45 if other.len() != Self::len() {
46 return None;
47 }
48 let mut buf = [0u8; Self::len()];
49 buf.clone_from_slice(other);
50 Some(Self::new_from_array(buf))
51 }
52 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
53 pub fn new_from_zeroed(other: &[u8]) -> Self {
54 let mut buf = [0u8; Self::len()];
55 let len = buf.len().min(other.len());
56 buf[..len].clone_from_slice(&other[..len]);
57 Self::new_from_array(buf)
58 }
59 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
60 unsafe { std::mem::transmute(buf) }
61 }
62 pub fn as_slice(&self) -> &[u8] {
63 unsafe {
64 let ptr: *const u8 = std::mem::transmute(self as *const Self);
65 std::slice::from_raw_parts(ptr, Self::len())
66 }
67 }
68 pub fn from_slice(buf: &[u8]) -> &Self {
69 assert!(buf.len() >= Self::len());
70 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
71 unsafe { std::mem::transmute(buf.as_ptr()) }
72 }
73 pub fn as_array(&self) -> &[u8; 4usize] {
74 unsafe { std::mem::transmute(self) }
75 }
76 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
77 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
78 unsafe { std::mem::transmute(buf) }
79 }
80 pub fn into_array(self) -> [u8; 4usize] {
81 unsafe { std::mem::transmute(self) }
82 }
83 pub const fn len() -> usize {
84 const _: () = assert!(std::mem::size_of::<BuiltinNfgenmsg>() == 4usize);
85 4usize
86 }
87}
88#[derive(Debug)]
89#[doc = "Wrapper for bitfield32 type\n"]
90#[repr(C, packed(4))]
91pub struct BuiltinBitfield32 {
92 pub value: u32,
93 pub selector: u32,
94}
95impl Clone for BuiltinBitfield32 {
96 fn clone(&self) -> Self {
97 Self::new_from_array(*self.as_array())
98 }
99}
100#[doc = "Create zero-initialized struct"]
101impl Default for BuiltinBitfield32 {
102 fn default() -> Self {
103 Self::new()
104 }
105}
106impl BuiltinBitfield32 {
107 #[doc = "Create zero-initialized struct"]
108 pub fn new() -> Self {
109 Self::new_from_array([0u8; Self::len()])
110 }
111 #[doc = "Copy from contents from slice"]
112 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
113 if other.len() != Self::len() {
114 return None;
115 }
116 let mut buf = [0u8; Self::len()];
117 buf.clone_from_slice(other);
118 Some(Self::new_from_array(buf))
119 }
120 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
121 pub fn new_from_zeroed(other: &[u8]) -> Self {
122 let mut buf = [0u8; Self::len()];
123 let len = buf.len().min(other.len());
124 buf[..len].clone_from_slice(&other[..len]);
125 Self::new_from_array(buf)
126 }
127 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
128 unsafe { std::mem::transmute(buf) }
129 }
130 pub fn as_slice(&self) -> &[u8] {
131 unsafe {
132 let ptr: *const u8 = std::mem::transmute(self as *const Self);
133 std::slice::from_raw_parts(ptr, Self::len())
134 }
135 }
136 pub fn from_slice(buf: &[u8]) -> &Self {
137 assert!(buf.len() >= Self::len());
138 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
139 unsafe { std::mem::transmute(buf.as_ptr()) }
140 }
141 pub fn as_array(&self) -> &[u8; 8usize] {
142 unsafe { std::mem::transmute(self) }
143 }
144 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
145 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
146 unsafe { std::mem::transmute(buf) }
147 }
148 pub fn into_array(self) -> [u8; 8usize] {
149 unsafe { std::mem::transmute(self) }
150 }
151 pub const fn len() -> usize {
152 const _: () = assert!(std::mem::size_of::<BuiltinBitfield32>() == 8usize);
153 8usize
154 }
155}
156#[derive(Debug)]
157#[doc = "Header of a Netlink message\n"]
158#[repr(C, packed(4))]
159pub struct Nlmsghdr {
160 pub len: u32,
161 pub r#type: u16,
162 pub flags: u16,
163 pub seq: u32,
164 pub pid: u32,
165}
166impl Clone for Nlmsghdr {
167 fn clone(&self) -> Self {
168 Self::new_from_array(*self.as_array())
169 }
170}
171#[doc = "Create zero-initialized struct"]
172impl Default for Nlmsghdr {
173 fn default() -> Self {
174 Self::new()
175 }
176}
177impl Nlmsghdr {
178 #[doc = "Create zero-initialized struct"]
179 pub fn new() -> Self {
180 Self::new_from_array([0u8; Self::len()])
181 }
182 #[doc = "Copy from contents from slice"]
183 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
184 if other.len() != Self::len() {
185 return None;
186 }
187 let mut buf = [0u8; Self::len()];
188 buf.clone_from_slice(other);
189 Some(Self::new_from_array(buf))
190 }
191 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
192 pub fn new_from_zeroed(other: &[u8]) -> Self {
193 let mut buf = [0u8; Self::len()];
194 let len = buf.len().min(other.len());
195 buf[..len].clone_from_slice(&other[..len]);
196 Self::new_from_array(buf)
197 }
198 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
199 unsafe { std::mem::transmute(buf) }
200 }
201 pub fn as_slice(&self) -> &[u8] {
202 unsafe {
203 let ptr: *const u8 = std::mem::transmute(self as *const Self);
204 std::slice::from_raw_parts(ptr, Self::len())
205 }
206 }
207 pub fn from_slice(buf: &[u8]) -> &Self {
208 assert!(buf.len() >= Self::len());
209 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
210 unsafe { std::mem::transmute(buf.as_ptr()) }
211 }
212 pub fn as_array(&self) -> &[u8; 16usize] {
213 unsafe { std::mem::transmute(self) }
214 }
215 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
216 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
217 unsafe { std::mem::transmute(buf) }
218 }
219 pub fn into_array(self) -> [u8; 16usize] {
220 unsafe { std::mem::transmute(self) }
221 }
222 pub const fn len() -> usize {
223 const _: () = assert!(std::mem::size_of::<Nlmsghdr>() == 16usize);
224 16usize
225 }
226}
227#[derive(Clone)]
228pub enum Dummy {}
229impl<'a> IterableDummy<'a> {}
230impl Dummy {
231 pub fn new<'a>(buf: &'a [u8]) -> IterableDummy<'a> {
232 IterableDummy::with_loc(buf, buf.as_ptr() as usize)
233 }
234 fn attr_from_type(r#type: u16) -> Option<&'static str> {
235 None
236 }
237}
238#[derive(Clone, Copy, Default)]
239pub struct IterableDummy<'a> {
240 buf: &'a [u8],
241 pos: usize,
242 orig_loc: usize,
243}
244impl<'a> IterableDummy<'a> {
245 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
246 Self {
247 buf,
248 pos: 0,
249 orig_loc,
250 }
251 }
252 pub fn get_buf(&self) -> &'a [u8] {
253 self.buf
254 }
255}
256impl<'a> Iterator for IterableDummy<'a> {
257 type Item = Result<Dummy, ErrorContext>;
258 fn next(&mut self) -> Option<Self::Item> {
259 let mut pos;
260 let mut r#type;
261 loop {
262 pos = self.pos;
263 r#type = None;
264 if self.buf.len() == self.pos {
265 return None;
266 }
267 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
268 self.pos = self.buf.len();
269 break;
270 };
271 r#type = Some(header.r#type);
272 let res = match header.r#type {
273 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
274 n => continue,
275 };
276 return Some(Ok(res));
277 }
278 Some(Err(ErrorContext::new(
279 "Dummy",
280 r#type.and_then(|t| Dummy::attr_from_type(t)),
281 self.orig_loc,
282 self.buf.as_ptr().wrapping_add(pos) as usize,
283 )))
284 }
285}
286impl std::fmt::Debug for IterableDummy<'_> {
287 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
288 let mut fmt = f.debug_struct("Dummy");
289 for attr in self.clone() {
290 let attr = match attr {
291 Ok(a) => a,
292 Err(err) => {
293 fmt.finish()?;
294 f.write_str("Err(")?;
295 err.fmt(f)?;
296 return f.write_str(")");
297 }
298 };
299 match attr {};
300 }
301 fmt.finish()
302 }
303}
304impl IterableDummy<'_> {
305 pub fn lookup_attr(
306 &self,
307 offset: usize,
308 missing_type: Option<u16>,
309 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
310 let mut stack = Vec::new();
311 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
312 if missing_type.is_some() && cur == offset {
313 stack.push(("Dummy", offset));
314 return (stack, missing_type.and_then(|t| Dummy::attr_from_type(t)));
315 }
316 (stack, None)
317 }
318}
319#[derive(Clone)]
320pub enum NlmsgerrAttrs<'a> {
321 #[doc = "error message string (string)\n"]
322 Msg(&'a CStr),
323 #[doc = "offset of the invalid attribute in the original message, counting from\nthe beginning of the header (u32)\n"]
324 Offset(u32),
325 #[doc = "arbitrary subsystem specific cookie to be used - in the success case -\nto identify a created object or operation or similar (binary)\n"]
326 Cookie(&'a [u8]),
327 #[doc = "policy for a rejected attribute\n"]
328 Policy(IterablePolicyTypeAttrs<'a>),
329 #[doc = "type of a missing required attribute, NLMSGERR_ATTR_MISS_NEST will not\nbe present if the attribute was missing at the message level\n"]
330 MissingType(u16),
331 #[doc = "offset of the nest where attribute was missing\n"]
332 MissingNest(u32),
333}
334impl<'a> IterableNlmsgerrAttrs<'a> {
335 #[doc = "error message string (string)\n"]
336 pub fn get_msg(&self) -> Result<&'a CStr, ErrorContext> {
337 let mut iter = self.clone();
338 iter.pos = 0;
339 for attr in iter {
340 if let Ok(NlmsgerrAttrs::Msg(val)) = attr {
341 return Ok(val);
342 }
343 }
344 Err(ErrorContext::new_missing(
345 "NlmsgerrAttrs",
346 "Msg",
347 self.orig_loc,
348 self.buf.as_ptr() as usize,
349 ))
350 }
351 #[doc = "offset of the invalid attribute in the original message, counting from\nthe beginning of the header (u32)\n"]
352 pub fn get_offset(&self) -> Result<u32, ErrorContext> {
353 let mut iter = self.clone();
354 iter.pos = 0;
355 for attr in iter {
356 if let Ok(NlmsgerrAttrs::Offset(val)) = attr {
357 return Ok(val);
358 }
359 }
360 Err(ErrorContext::new_missing(
361 "NlmsgerrAttrs",
362 "Offset",
363 self.orig_loc,
364 self.buf.as_ptr() as usize,
365 ))
366 }
367 #[doc = "arbitrary subsystem specific cookie to be used - in the success case -\nto identify a created object or operation or similar (binary)\n"]
368 pub fn get_cookie(&self) -> Result<&'a [u8], ErrorContext> {
369 let mut iter = self.clone();
370 iter.pos = 0;
371 for attr in iter {
372 if let Ok(NlmsgerrAttrs::Cookie(val)) = attr {
373 return Ok(val);
374 }
375 }
376 Err(ErrorContext::new_missing(
377 "NlmsgerrAttrs",
378 "Cookie",
379 self.orig_loc,
380 self.buf.as_ptr() as usize,
381 ))
382 }
383 #[doc = "policy for a rejected attribute\n"]
384 pub fn get_policy(&self) -> Result<IterablePolicyTypeAttrs<'a>, ErrorContext> {
385 let mut iter = self.clone();
386 iter.pos = 0;
387 for attr in iter {
388 if let Ok(NlmsgerrAttrs::Policy(val)) = attr {
389 return Ok(val);
390 }
391 }
392 Err(ErrorContext::new_missing(
393 "NlmsgerrAttrs",
394 "Policy",
395 self.orig_loc,
396 self.buf.as_ptr() as usize,
397 ))
398 }
399 #[doc = "type of a missing required attribute, NLMSGERR_ATTR_MISS_NEST will not\nbe present if the attribute was missing at the message level\n"]
400 pub fn get_missing_type(&self) -> Result<u16, ErrorContext> {
401 let mut iter = self.clone();
402 iter.pos = 0;
403 for attr in iter {
404 if let Ok(NlmsgerrAttrs::MissingType(val)) = attr {
405 return Ok(val);
406 }
407 }
408 Err(ErrorContext::new_missing(
409 "NlmsgerrAttrs",
410 "MissingType",
411 self.orig_loc,
412 self.buf.as_ptr() as usize,
413 ))
414 }
415 #[doc = "offset of the nest where attribute was missing\n"]
416 pub fn get_missing_nest(&self) -> Result<u32, ErrorContext> {
417 let mut iter = self.clone();
418 iter.pos = 0;
419 for attr in iter {
420 if let Ok(NlmsgerrAttrs::MissingNest(val)) = attr {
421 return Ok(val);
422 }
423 }
424 Err(ErrorContext::new_missing(
425 "NlmsgerrAttrs",
426 "MissingNest",
427 self.orig_loc,
428 self.buf.as_ptr() as usize,
429 ))
430 }
431}
432impl NlmsgerrAttrs<'_> {
433 pub fn new<'a>(buf: &'a [u8]) -> IterableNlmsgerrAttrs<'a> {
434 IterableNlmsgerrAttrs::with_loc(buf, buf.as_ptr() as usize)
435 }
436 fn attr_from_type(r#type: u16) -> Option<&'static str> {
437 let res = match r#type {
438 0u16 => "Unused",
439 1u16 => "Msg",
440 2u16 => "Offset",
441 3u16 => "Cookie",
442 4u16 => "Policy",
443 5u16 => "MissingType",
444 6u16 => "MissingNest",
445 _ => return None,
446 };
447 Some(res)
448 }
449}
450#[derive(Clone, Copy, Default)]
451pub struct IterableNlmsgerrAttrs<'a> {
452 buf: &'a [u8],
453 pos: usize,
454 orig_loc: usize,
455}
456impl<'a> IterableNlmsgerrAttrs<'a> {
457 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
458 Self {
459 buf,
460 pos: 0,
461 orig_loc,
462 }
463 }
464 pub fn get_buf(&self) -> &'a [u8] {
465 self.buf
466 }
467}
468impl<'a> Iterator for IterableNlmsgerrAttrs<'a> {
469 type Item = Result<NlmsgerrAttrs<'a>, ErrorContext>;
470 fn next(&mut self) -> Option<Self::Item> {
471 let mut pos;
472 let mut r#type;
473 loop {
474 pos = self.pos;
475 r#type = None;
476 if self.buf.len() == self.pos {
477 return None;
478 }
479 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
480 self.pos = self.buf.len();
481 break;
482 };
483 r#type = Some(header.r#type);
484 let res = match header.r#type {
485 1u16 => NlmsgerrAttrs::Msg({
486 let res = CStr::from_bytes_with_nul(next).ok();
487 let Some(val) = res else { break };
488 val
489 }),
490 2u16 => NlmsgerrAttrs::Offset({
491 let res = parse_u32(next);
492 let Some(val) = res else { break };
493 val
494 }),
495 3u16 => NlmsgerrAttrs::Cookie({
496 let res = Some(next);
497 let Some(val) = res else { break };
498 val
499 }),
500 4u16 => NlmsgerrAttrs::Policy({
501 let res = Some(IterablePolicyTypeAttrs::with_loc(next, self.orig_loc));
502 let Some(val) = res else { break };
503 val
504 }),
505 5u16 => NlmsgerrAttrs::MissingType({
506 let res = parse_u16(next);
507 let Some(val) = res else { break };
508 val
509 }),
510 6u16 => NlmsgerrAttrs::MissingNest({
511 let res = parse_u32(next);
512 let Some(val) = res else { break };
513 val
514 }),
515 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
516 n => continue,
517 };
518 return Some(Ok(res));
519 }
520 Some(Err(ErrorContext::new(
521 "NlmsgerrAttrs",
522 r#type.and_then(|t| NlmsgerrAttrs::attr_from_type(t)),
523 self.orig_loc,
524 self.buf.as_ptr().wrapping_add(pos) as usize,
525 )))
526 }
527}
528impl<'a> std::fmt::Debug for IterableNlmsgerrAttrs<'_> {
529 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
530 let mut fmt = f.debug_struct("NlmsgerrAttrs");
531 for attr in self.clone() {
532 let attr = match attr {
533 Ok(a) => a,
534 Err(err) => {
535 fmt.finish()?;
536 f.write_str("Err(")?;
537 err.fmt(f)?;
538 return f.write_str(")");
539 }
540 };
541 match attr {
542 NlmsgerrAttrs::Msg(val) => fmt.field("Msg", &val),
543 NlmsgerrAttrs::Offset(val) => fmt.field("Offset", &val),
544 NlmsgerrAttrs::Cookie(val) => fmt.field("Cookie", &val),
545 NlmsgerrAttrs::Policy(val) => fmt.field("Policy", &val),
546 NlmsgerrAttrs::MissingType(val) => fmt.field("MissingType", &val),
547 NlmsgerrAttrs::MissingNest(val) => fmt.field("MissingNest", &val),
548 };
549 }
550 fmt.finish()
551 }
552}
553impl IterableNlmsgerrAttrs<'_> {
554 pub fn lookup_attr(
555 &self,
556 offset: usize,
557 missing_type: Option<u16>,
558 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
559 let mut stack = Vec::new();
560 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
561 if missing_type.is_some() && cur == offset {
562 stack.push(("NlmsgerrAttrs", offset));
563 return (
564 stack,
565 missing_type.and_then(|t| NlmsgerrAttrs::attr_from_type(t)),
566 );
567 }
568 if cur > offset || cur + self.buf.len() < offset {
569 return (stack, None);
570 }
571 let mut attrs = self.clone();
572 let mut last_off = cur + attrs.pos;
573 let mut missing = None;
574 while let Some(attr) = attrs.next() {
575 let Ok(attr) = attr else { break };
576 match attr {
577 NlmsgerrAttrs::Msg(val) => {
578 if last_off == offset {
579 stack.push(("Msg", last_off));
580 break;
581 }
582 }
583 NlmsgerrAttrs::Offset(val) => {
584 if last_off == offset {
585 stack.push(("Offset", last_off));
586 break;
587 }
588 }
589 NlmsgerrAttrs::Cookie(val) => {
590 if last_off == offset {
591 stack.push(("Cookie", last_off));
592 break;
593 }
594 }
595 NlmsgerrAttrs::Policy(val) => {
596 (stack, missing) = val.lookup_attr(offset, missing_type);
597 if !stack.is_empty() {
598 break;
599 }
600 }
601 NlmsgerrAttrs::MissingType(val) => {
602 if last_off == offset {
603 stack.push(("MissingType", last_off));
604 break;
605 }
606 }
607 NlmsgerrAttrs::MissingNest(val) => {
608 if last_off == offset {
609 stack.push(("MissingNest", last_off));
610 break;
611 }
612 }
613 _ => {}
614 };
615 last_off = cur + attrs.pos;
616 }
617 if !stack.is_empty() {
618 stack.push(("NlmsgerrAttrs", cur));
619 }
620 (stack, missing)
621 }
622}
623#[derive(Clone)]
624pub enum PolicyTypeAttrs<'a> {
625 #[doc = "type of the attribute, enum netlink_attribute_type (U32)\n"]
626 Type(u32),
627 #[doc = "minimum value for signed integers (S64)\n"]
628 MinValueSigned(i64),
629 #[doc = "maximum value for signed integers (S64)\n"]
630 MaxValueSigned(i64),
631 #[doc = "minimum value for unsigned integers (U64)\n"]
632 MinValueU(u64),
633 #[doc = "maximum value for unsigned integers (U64)\n"]
634 MaxValueU(u64),
635 #[doc = "minimum length for binary attributes, no minimum if not given (U32)\n"]
636 MinLength(u32),
637 #[doc = "maximum length for binary attributes, no maximum if not given (U32)\n"]
638 MaxLength(u32),
639 #[doc = "sub policy for nested and nested array types (U32)\n"]
640 PolicyIdx(u32),
641 #[doc = "maximum sub policy attribute for nested and nested array types, this can\nin theory be \\< the size of the policy pointed to by the index, if\nlimited inside the nesting (U32)\n"]
642 PolicyMaxtype(u32),
643 #[doc = "valid mask for the bitfield32 type (U32)\n"]
644 Bitfield32Mask(u32),
645 #[doc = "pad attribute for 64-bit alignment\n"]
646 Pad(&'a [u8]),
647 #[doc = "mask of valid bits for unsigned integers (U64)\n"]
648 Mask(u64),
649}
650impl<'a> IterablePolicyTypeAttrs<'a> {
651 #[doc = "type of the attribute, enum netlink_attribute_type (U32)\n"]
652 pub fn get_type(&self) -> Result<u32, ErrorContext> {
653 let mut iter = self.clone();
654 iter.pos = 0;
655 for attr in iter {
656 if let Ok(PolicyTypeAttrs::Type(val)) = attr {
657 return Ok(val);
658 }
659 }
660 Err(ErrorContext::new_missing(
661 "PolicyTypeAttrs",
662 "Type",
663 self.orig_loc,
664 self.buf.as_ptr() as usize,
665 ))
666 }
667 #[doc = "minimum value for signed integers (S64)\n"]
668 pub fn get_min_value_signed(&self) -> Result<i64, ErrorContext> {
669 let mut iter = self.clone();
670 iter.pos = 0;
671 for attr in iter {
672 if let Ok(PolicyTypeAttrs::MinValueSigned(val)) = attr {
673 return Ok(val);
674 }
675 }
676 Err(ErrorContext::new_missing(
677 "PolicyTypeAttrs",
678 "MinValueSigned",
679 self.orig_loc,
680 self.buf.as_ptr() as usize,
681 ))
682 }
683 #[doc = "maximum value for signed integers (S64)\n"]
684 pub fn get_max_value_signed(&self) -> Result<i64, ErrorContext> {
685 let mut iter = self.clone();
686 iter.pos = 0;
687 for attr in iter {
688 if let Ok(PolicyTypeAttrs::MaxValueSigned(val)) = attr {
689 return Ok(val);
690 }
691 }
692 Err(ErrorContext::new_missing(
693 "PolicyTypeAttrs",
694 "MaxValueSigned",
695 self.orig_loc,
696 self.buf.as_ptr() as usize,
697 ))
698 }
699 #[doc = "minimum value for unsigned integers (U64)\n"]
700 pub fn get_min_value_u(&self) -> Result<u64, ErrorContext> {
701 let mut iter = self.clone();
702 iter.pos = 0;
703 for attr in iter {
704 if let Ok(PolicyTypeAttrs::MinValueU(val)) = attr {
705 return Ok(val);
706 }
707 }
708 Err(ErrorContext::new_missing(
709 "PolicyTypeAttrs",
710 "MinValueU",
711 self.orig_loc,
712 self.buf.as_ptr() as usize,
713 ))
714 }
715 #[doc = "maximum value for unsigned integers (U64)\n"]
716 pub fn get_max_value_u(&self) -> Result<u64, ErrorContext> {
717 let mut iter = self.clone();
718 iter.pos = 0;
719 for attr in iter {
720 if let Ok(PolicyTypeAttrs::MaxValueU(val)) = attr {
721 return Ok(val);
722 }
723 }
724 Err(ErrorContext::new_missing(
725 "PolicyTypeAttrs",
726 "MaxValueU",
727 self.orig_loc,
728 self.buf.as_ptr() as usize,
729 ))
730 }
731 #[doc = "minimum length for binary attributes, no minimum if not given (U32)\n"]
732 pub fn get_min_length(&self) -> Result<u32, ErrorContext> {
733 let mut iter = self.clone();
734 iter.pos = 0;
735 for attr in iter {
736 if let Ok(PolicyTypeAttrs::MinLength(val)) = attr {
737 return Ok(val);
738 }
739 }
740 Err(ErrorContext::new_missing(
741 "PolicyTypeAttrs",
742 "MinLength",
743 self.orig_loc,
744 self.buf.as_ptr() as usize,
745 ))
746 }
747 #[doc = "maximum length for binary attributes, no maximum if not given (U32)\n"]
748 pub fn get_max_length(&self) -> Result<u32, ErrorContext> {
749 let mut iter = self.clone();
750 iter.pos = 0;
751 for attr in iter {
752 if let Ok(PolicyTypeAttrs::MaxLength(val)) = attr {
753 return Ok(val);
754 }
755 }
756 Err(ErrorContext::new_missing(
757 "PolicyTypeAttrs",
758 "MaxLength",
759 self.orig_loc,
760 self.buf.as_ptr() as usize,
761 ))
762 }
763 #[doc = "sub policy for nested and nested array types (U32)\n"]
764 pub fn get_policy_idx(&self) -> Result<u32, ErrorContext> {
765 let mut iter = self.clone();
766 iter.pos = 0;
767 for attr in iter {
768 if let Ok(PolicyTypeAttrs::PolicyIdx(val)) = attr {
769 return Ok(val);
770 }
771 }
772 Err(ErrorContext::new_missing(
773 "PolicyTypeAttrs",
774 "PolicyIdx",
775 self.orig_loc,
776 self.buf.as_ptr() as usize,
777 ))
778 }
779 #[doc = "maximum sub policy attribute for nested and nested array types, this can\nin theory be \\< the size of the policy pointed to by the index, if\nlimited inside the nesting (U32)\n"]
780 pub fn get_policy_maxtype(&self) -> Result<u32, ErrorContext> {
781 let mut iter = self.clone();
782 iter.pos = 0;
783 for attr in iter {
784 if let Ok(PolicyTypeAttrs::PolicyMaxtype(val)) = attr {
785 return Ok(val);
786 }
787 }
788 Err(ErrorContext::new_missing(
789 "PolicyTypeAttrs",
790 "PolicyMaxtype",
791 self.orig_loc,
792 self.buf.as_ptr() as usize,
793 ))
794 }
795 #[doc = "valid mask for the bitfield32 type (U32)\n"]
796 pub fn get_bitfield32_mask(&self) -> Result<u32, ErrorContext> {
797 let mut iter = self.clone();
798 iter.pos = 0;
799 for attr in iter {
800 if let Ok(PolicyTypeAttrs::Bitfield32Mask(val)) = attr {
801 return Ok(val);
802 }
803 }
804 Err(ErrorContext::new_missing(
805 "PolicyTypeAttrs",
806 "Bitfield32Mask",
807 self.orig_loc,
808 self.buf.as_ptr() as usize,
809 ))
810 }
811 #[doc = "pad attribute for 64-bit alignment\n"]
812 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
813 let mut iter = self.clone();
814 iter.pos = 0;
815 for attr in iter {
816 if let Ok(PolicyTypeAttrs::Pad(val)) = attr {
817 return Ok(val);
818 }
819 }
820 Err(ErrorContext::new_missing(
821 "PolicyTypeAttrs",
822 "Pad",
823 self.orig_loc,
824 self.buf.as_ptr() as usize,
825 ))
826 }
827 #[doc = "mask of valid bits for unsigned integers (U64)\n"]
828 pub fn get_mask(&self) -> Result<u64, ErrorContext> {
829 let mut iter = self.clone();
830 iter.pos = 0;
831 for attr in iter {
832 if let Ok(PolicyTypeAttrs::Mask(val)) = attr {
833 return Ok(val);
834 }
835 }
836 Err(ErrorContext::new_missing(
837 "PolicyTypeAttrs",
838 "Mask",
839 self.orig_loc,
840 self.buf.as_ptr() as usize,
841 ))
842 }
843}
844impl PolicyTypeAttrs<'_> {
845 pub fn new<'a>(buf: &'a [u8]) -> IterablePolicyTypeAttrs<'a> {
846 IterablePolicyTypeAttrs::with_loc(buf, buf.as_ptr() as usize)
847 }
848 fn attr_from_type(r#type: u16) -> Option<&'static str> {
849 let res = match r#type {
850 0u16 => "Unspec",
851 1u16 => "Type",
852 2u16 => "MinValueSigned",
853 3u16 => "MaxValueSigned",
854 4u16 => "MinValueU",
855 5u16 => "MaxValueU",
856 6u16 => "MinLength",
857 7u16 => "MaxLength",
858 8u16 => "PolicyIdx",
859 9u16 => "PolicyMaxtype",
860 10u16 => "Bitfield32Mask",
861 11u16 => "Pad",
862 12u16 => "Mask",
863 _ => return None,
864 };
865 Some(res)
866 }
867}
868#[derive(Clone, Copy, Default)]
869pub struct IterablePolicyTypeAttrs<'a> {
870 buf: &'a [u8],
871 pos: usize,
872 orig_loc: usize,
873}
874impl<'a> IterablePolicyTypeAttrs<'a> {
875 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
876 Self {
877 buf,
878 pos: 0,
879 orig_loc,
880 }
881 }
882 pub fn get_buf(&self) -> &'a [u8] {
883 self.buf
884 }
885}
886impl<'a> Iterator for IterablePolicyTypeAttrs<'a> {
887 type Item = Result<PolicyTypeAttrs<'a>, ErrorContext>;
888 fn next(&mut self) -> Option<Self::Item> {
889 let mut pos;
890 let mut r#type;
891 loop {
892 pos = self.pos;
893 r#type = None;
894 if self.buf.len() == self.pos {
895 return None;
896 }
897 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
898 self.pos = self.buf.len();
899 break;
900 };
901 r#type = Some(header.r#type);
902 let res = match header.r#type {
903 1u16 => PolicyTypeAttrs::Type({
904 let res = parse_u32(next);
905 let Some(val) = res else { break };
906 val
907 }),
908 2u16 => PolicyTypeAttrs::MinValueSigned({
909 let res = parse_i64(next);
910 let Some(val) = res else { break };
911 val
912 }),
913 3u16 => PolicyTypeAttrs::MaxValueSigned({
914 let res = parse_i64(next);
915 let Some(val) = res else { break };
916 val
917 }),
918 4u16 => PolicyTypeAttrs::MinValueU({
919 let res = parse_u64(next);
920 let Some(val) = res else { break };
921 val
922 }),
923 5u16 => PolicyTypeAttrs::MaxValueU({
924 let res = parse_u64(next);
925 let Some(val) = res else { break };
926 val
927 }),
928 6u16 => PolicyTypeAttrs::MinLength({
929 let res = parse_u32(next);
930 let Some(val) = res else { break };
931 val
932 }),
933 7u16 => PolicyTypeAttrs::MaxLength({
934 let res = parse_u32(next);
935 let Some(val) = res else { break };
936 val
937 }),
938 8u16 => PolicyTypeAttrs::PolicyIdx({
939 let res = parse_u32(next);
940 let Some(val) = res else { break };
941 val
942 }),
943 9u16 => PolicyTypeAttrs::PolicyMaxtype({
944 let res = parse_u32(next);
945 let Some(val) = res else { break };
946 val
947 }),
948 10u16 => PolicyTypeAttrs::Bitfield32Mask({
949 let res = parse_u32(next);
950 let Some(val) = res else { break };
951 val
952 }),
953 11u16 => PolicyTypeAttrs::Pad({
954 let res = Some(next);
955 let Some(val) = res else { break };
956 val
957 }),
958 12u16 => PolicyTypeAttrs::Mask({
959 let res = parse_u64(next);
960 let Some(val) = res else { break };
961 val
962 }),
963 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
964 n => continue,
965 };
966 return Some(Ok(res));
967 }
968 Some(Err(ErrorContext::new(
969 "PolicyTypeAttrs",
970 r#type.and_then(|t| PolicyTypeAttrs::attr_from_type(t)),
971 self.orig_loc,
972 self.buf.as_ptr().wrapping_add(pos) as usize,
973 )))
974 }
975}
976impl<'a> std::fmt::Debug for IterablePolicyTypeAttrs<'_> {
977 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
978 let mut fmt = f.debug_struct("PolicyTypeAttrs");
979 for attr in self.clone() {
980 let attr = match attr {
981 Ok(a) => a,
982 Err(err) => {
983 fmt.finish()?;
984 f.write_str("Err(")?;
985 err.fmt(f)?;
986 return f.write_str(")");
987 }
988 };
989 match attr {
990 PolicyTypeAttrs::Type(val) => fmt.field("Type", &val),
991 PolicyTypeAttrs::MinValueSigned(val) => fmt.field("MinValueSigned", &val),
992 PolicyTypeAttrs::MaxValueSigned(val) => fmt.field("MaxValueSigned", &val),
993 PolicyTypeAttrs::MinValueU(val) => fmt.field("MinValueU", &val),
994 PolicyTypeAttrs::MaxValueU(val) => fmt.field("MaxValueU", &val),
995 PolicyTypeAttrs::MinLength(val) => fmt.field("MinLength", &val),
996 PolicyTypeAttrs::MaxLength(val) => fmt.field("MaxLength", &val),
997 PolicyTypeAttrs::PolicyIdx(val) => fmt.field("PolicyIdx", &val),
998 PolicyTypeAttrs::PolicyMaxtype(val) => fmt.field("PolicyMaxtype", &val),
999 PolicyTypeAttrs::Bitfield32Mask(val) => fmt.field("Bitfield32Mask", &val),
1000 PolicyTypeAttrs::Pad(val) => fmt.field("Pad", &val),
1001 PolicyTypeAttrs::Mask(val) => fmt.field("Mask", &val),
1002 };
1003 }
1004 fmt.finish()
1005 }
1006}
1007impl IterablePolicyTypeAttrs<'_> {
1008 pub fn lookup_attr(
1009 &self,
1010 offset: usize,
1011 missing_type: Option<u16>,
1012 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1013 let mut stack = Vec::new();
1014 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1015 if missing_type.is_some() && cur == offset {
1016 stack.push(("PolicyTypeAttrs", offset));
1017 return (
1018 stack,
1019 missing_type.and_then(|t| PolicyTypeAttrs::attr_from_type(t)),
1020 );
1021 }
1022 if cur > offset || cur + self.buf.len() < offset {
1023 return (stack, None);
1024 }
1025 let mut attrs = self.clone();
1026 let mut last_off = cur + attrs.pos;
1027 while let Some(attr) = attrs.next() {
1028 let Ok(attr) = attr else { break };
1029 match attr {
1030 PolicyTypeAttrs::Type(val) => {
1031 if last_off == offset {
1032 stack.push(("Type", last_off));
1033 break;
1034 }
1035 }
1036 PolicyTypeAttrs::MinValueSigned(val) => {
1037 if last_off == offset {
1038 stack.push(("MinValueSigned", last_off));
1039 break;
1040 }
1041 }
1042 PolicyTypeAttrs::MaxValueSigned(val) => {
1043 if last_off == offset {
1044 stack.push(("MaxValueSigned", last_off));
1045 break;
1046 }
1047 }
1048 PolicyTypeAttrs::MinValueU(val) => {
1049 if last_off == offset {
1050 stack.push(("MinValueU", last_off));
1051 break;
1052 }
1053 }
1054 PolicyTypeAttrs::MaxValueU(val) => {
1055 if last_off == offset {
1056 stack.push(("MaxValueU", last_off));
1057 break;
1058 }
1059 }
1060 PolicyTypeAttrs::MinLength(val) => {
1061 if last_off == offset {
1062 stack.push(("MinLength", last_off));
1063 break;
1064 }
1065 }
1066 PolicyTypeAttrs::MaxLength(val) => {
1067 if last_off == offset {
1068 stack.push(("MaxLength", last_off));
1069 break;
1070 }
1071 }
1072 PolicyTypeAttrs::PolicyIdx(val) => {
1073 if last_off == offset {
1074 stack.push(("PolicyIdx", last_off));
1075 break;
1076 }
1077 }
1078 PolicyTypeAttrs::PolicyMaxtype(val) => {
1079 if last_off == offset {
1080 stack.push(("PolicyMaxtype", last_off));
1081 break;
1082 }
1083 }
1084 PolicyTypeAttrs::Bitfield32Mask(val) => {
1085 if last_off == offset {
1086 stack.push(("Bitfield32Mask", last_off));
1087 break;
1088 }
1089 }
1090 PolicyTypeAttrs::Pad(val) => {
1091 if last_off == offset {
1092 stack.push(("Pad", last_off));
1093 break;
1094 }
1095 }
1096 PolicyTypeAttrs::Mask(val) => {
1097 if last_off == offset {
1098 stack.push(("Mask", last_off));
1099 break;
1100 }
1101 }
1102 _ => {}
1103 };
1104 last_off = cur + attrs.pos;
1105 }
1106 if !stack.is_empty() {
1107 stack.push(("PolicyTypeAttrs", cur));
1108 }
1109 (stack, None)
1110 }
1111}
1112pub struct PushDummy<Prev: Pusher> {
1113 pub(crate) prev: Option<Prev>,
1114 pub(crate) header_offset: Option<usize>,
1115}
1116impl<Prev: Pusher> Pusher for PushDummy<Prev> {
1117 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1118 self.prev.as_mut().unwrap().as_vec_mut()
1119 }
1120 fn as_vec(&self) -> &Vec<u8> {
1121 self.prev.as_ref().unwrap().as_vec()
1122 }
1123}
1124impl<Prev: Pusher> PushDummy<Prev> {
1125 pub fn new(prev: Prev) -> Self {
1126 Self {
1127 prev: Some(prev),
1128 header_offset: None,
1129 }
1130 }
1131 pub fn end_nested(mut self) -> Prev {
1132 let mut prev = self.prev.take().unwrap();
1133 if let Some(header_offset) = &self.header_offset {
1134 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1135 }
1136 prev
1137 }
1138}
1139impl<Prev: Pusher> Drop for PushDummy<Prev> {
1140 fn drop(&mut self) {
1141 if let Some(prev) = &mut self.prev {
1142 if let Some(header_offset) = &self.header_offset {
1143 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1144 }
1145 }
1146 }
1147}
1148pub struct PushNlmsgerrAttrs<Prev: Pusher> {
1149 pub(crate) prev: Option<Prev>,
1150 pub(crate) header_offset: Option<usize>,
1151}
1152impl<Prev: Pusher> Pusher for PushNlmsgerrAttrs<Prev> {
1153 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1154 self.prev.as_mut().unwrap().as_vec_mut()
1155 }
1156 fn as_vec(&self) -> &Vec<u8> {
1157 self.prev.as_ref().unwrap().as_vec()
1158 }
1159}
1160impl<Prev: Pusher> PushNlmsgerrAttrs<Prev> {
1161 pub fn new(prev: Prev) -> Self {
1162 Self {
1163 prev: Some(prev),
1164 header_offset: None,
1165 }
1166 }
1167 pub fn end_nested(mut self) -> Prev {
1168 let mut prev = self.prev.take().unwrap();
1169 if let Some(header_offset) = &self.header_offset {
1170 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1171 }
1172 prev
1173 }
1174 #[doc = "error message string (string)\n"]
1175 pub fn push_msg(mut self, value: &CStr) -> Self {
1176 push_header(
1177 self.as_vec_mut(),
1178 1u16,
1179 value.to_bytes_with_nul().len() as u16,
1180 );
1181 self.as_vec_mut().extend(value.to_bytes_with_nul());
1182 self
1183 }
1184 #[doc = "error message string (string)\n"]
1185 pub fn push_msg_bytes(mut self, value: &[u8]) -> Self {
1186 push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
1187 self.as_vec_mut().extend(value);
1188 self.as_vec_mut().push(0);
1189 self
1190 }
1191 #[doc = "offset of the invalid attribute in the original message, counting from\nthe beginning of the header (u32)\n"]
1192 pub fn push_offset(mut self, value: u32) -> Self {
1193 push_header(self.as_vec_mut(), 2u16, 4 as u16);
1194 self.as_vec_mut().extend(value.to_ne_bytes());
1195 self
1196 }
1197 #[doc = "arbitrary subsystem specific cookie to be used - in the success case -\nto identify a created object or operation or similar (binary)\n"]
1198 pub fn push_cookie(mut self, value: &[u8]) -> Self {
1199 push_header(self.as_vec_mut(), 3u16, value.len() as u16);
1200 self.as_vec_mut().extend(value);
1201 self
1202 }
1203 #[doc = "policy for a rejected attribute\n"]
1204 pub fn nested_policy(mut self) -> PushPolicyTypeAttrs<Self> {
1205 let header_offset = push_nested_header(self.as_vec_mut(), 4u16);
1206 PushPolicyTypeAttrs {
1207 prev: Some(self),
1208 header_offset: Some(header_offset),
1209 }
1210 }
1211 #[doc = "type of a missing required attribute, NLMSGERR_ATTR_MISS_NEST will not\nbe present if the attribute was missing at the message level\n"]
1212 pub fn push_missing_type(mut self, value: u16) -> Self {
1213 push_header(self.as_vec_mut(), 5u16, 2 as u16);
1214 self.as_vec_mut().extend(value.to_ne_bytes());
1215 self
1216 }
1217 #[doc = "offset of the nest where attribute was missing\n"]
1218 pub fn push_missing_nest(mut self, value: u32) -> Self {
1219 push_header(self.as_vec_mut(), 6u16, 4 as u16);
1220 self.as_vec_mut().extend(value.to_ne_bytes());
1221 self
1222 }
1223}
1224impl<Prev: Pusher> Drop for PushNlmsgerrAttrs<Prev> {
1225 fn drop(&mut self) {
1226 if let Some(prev) = &mut self.prev {
1227 if let Some(header_offset) = &self.header_offset {
1228 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1229 }
1230 }
1231 }
1232}
1233pub struct PushPolicyTypeAttrs<Prev: Pusher> {
1234 pub(crate) prev: Option<Prev>,
1235 pub(crate) header_offset: Option<usize>,
1236}
1237impl<Prev: Pusher> Pusher for PushPolicyTypeAttrs<Prev> {
1238 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1239 self.prev.as_mut().unwrap().as_vec_mut()
1240 }
1241 fn as_vec(&self) -> &Vec<u8> {
1242 self.prev.as_ref().unwrap().as_vec()
1243 }
1244}
1245impl<Prev: Pusher> PushPolicyTypeAttrs<Prev> {
1246 pub fn new(prev: Prev) -> Self {
1247 Self {
1248 prev: Some(prev),
1249 header_offset: None,
1250 }
1251 }
1252 pub fn end_nested(mut self) -> Prev {
1253 let mut prev = self.prev.take().unwrap();
1254 if let Some(header_offset) = &self.header_offset {
1255 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1256 }
1257 prev
1258 }
1259 #[doc = "type of the attribute, enum netlink_attribute_type (U32)\n"]
1260 pub fn push_type(mut self, value: u32) -> Self {
1261 push_header(self.as_vec_mut(), 1u16, 4 as u16);
1262 self.as_vec_mut().extend(value.to_ne_bytes());
1263 self
1264 }
1265 #[doc = "minimum value for signed integers (S64)\n"]
1266 pub fn push_min_value_signed(mut self, value: i64) -> Self {
1267 push_header(self.as_vec_mut(), 2u16, 8 as u16);
1268 self.as_vec_mut().extend(value.to_ne_bytes());
1269 self
1270 }
1271 #[doc = "maximum value for signed integers (S64)\n"]
1272 pub fn push_max_value_signed(mut self, value: i64) -> Self {
1273 push_header(self.as_vec_mut(), 3u16, 8 as u16);
1274 self.as_vec_mut().extend(value.to_ne_bytes());
1275 self
1276 }
1277 #[doc = "minimum value for unsigned integers (U64)\n"]
1278 pub fn push_min_value_u(mut self, value: u64) -> Self {
1279 push_header(self.as_vec_mut(), 4u16, 8 as u16);
1280 self.as_vec_mut().extend(value.to_ne_bytes());
1281 self
1282 }
1283 #[doc = "maximum value for unsigned integers (U64)\n"]
1284 pub fn push_max_value_u(mut self, value: u64) -> Self {
1285 push_header(self.as_vec_mut(), 5u16, 8 as u16);
1286 self.as_vec_mut().extend(value.to_ne_bytes());
1287 self
1288 }
1289 #[doc = "minimum length for binary attributes, no minimum if not given (U32)\n"]
1290 pub fn push_min_length(mut self, value: u32) -> Self {
1291 push_header(self.as_vec_mut(), 6u16, 4 as u16);
1292 self.as_vec_mut().extend(value.to_ne_bytes());
1293 self
1294 }
1295 #[doc = "maximum length for binary attributes, no maximum if not given (U32)\n"]
1296 pub fn push_max_length(mut self, value: u32) -> Self {
1297 push_header(self.as_vec_mut(), 7u16, 4 as u16);
1298 self.as_vec_mut().extend(value.to_ne_bytes());
1299 self
1300 }
1301 #[doc = "sub policy for nested and nested array types (U32)\n"]
1302 pub fn push_policy_idx(mut self, value: u32) -> Self {
1303 push_header(self.as_vec_mut(), 8u16, 4 as u16);
1304 self.as_vec_mut().extend(value.to_ne_bytes());
1305 self
1306 }
1307 #[doc = "maximum sub policy attribute for nested and nested array types, this can\nin theory be \\< the size of the policy pointed to by the index, if\nlimited inside the nesting (U32)\n"]
1308 pub fn push_policy_maxtype(mut self, value: u32) -> Self {
1309 push_header(self.as_vec_mut(), 9u16, 4 as u16);
1310 self.as_vec_mut().extend(value.to_ne_bytes());
1311 self
1312 }
1313 #[doc = "valid mask for the bitfield32 type (U32)\n"]
1314 pub fn push_bitfield32_mask(mut self, value: u32) -> Self {
1315 push_header(self.as_vec_mut(), 10u16, 4 as u16);
1316 self.as_vec_mut().extend(value.to_ne_bytes());
1317 self
1318 }
1319 #[doc = "pad attribute for 64-bit alignment\n"]
1320 pub fn push_pad(mut self, value: &[u8]) -> Self {
1321 push_header(self.as_vec_mut(), 11u16, value.len() as u16);
1322 self.as_vec_mut().extend(value);
1323 self
1324 }
1325 #[doc = "mask of valid bits for unsigned integers (U64)\n"]
1326 pub fn push_mask(mut self, value: u64) -> Self {
1327 push_header(self.as_vec_mut(), 12u16, 8 as u16);
1328 self.as_vec_mut().extend(value.to_ne_bytes());
1329 self
1330 }
1331}
1332impl<Prev: Pusher> Drop for PushPolicyTypeAttrs<Prev> {
1333 fn drop(&mut self) {
1334 if let Some(prev) = &mut self.prev {
1335 if let Some(header_offset) = &self.header_offset {
1336 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1337 }
1338 }
1339 }
1340}