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