1#![doc = "Address configuration over rtnetlink."]
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::{PushBuiltinBitfield32, PushBuiltinNfgenmsg, PushDummy, PushNlmsghdr};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &CStr = c"rt-addr";
17pub const PROTONUM: u16 = 0u16;
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 IfaFlags {
21 Secondary = 1 << 0,
22 Nodad = 1 << 1,
23 Optimistic = 1 << 2,
24 Dadfailed = 1 << 3,
25 Homeaddress = 1 << 4,
26 Deprecated = 1 << 5,
27 Tentative = 1 << 6,
28 Permanent = 1 << 7,
29 Managetempaddr = 1 << 8,
30 Noprefixroute = 1 << 9,
31 Mcautojoin = 1 << 10,
32 StablePrivacy = 1 << 11,
33}
34impl IfaFlags {
35 pub fn from_value(value: u64) -> Option<Self> {
36 Some(match value {
37 n if n == 1 << 0 => Self::Secondary,
38 n if n == 1 << 1 => Self::Nodad,
39 n if n == 1 << 2 => Self::Optimistic,
40 n if n == 1 << 3 => Self::Dadfailed,
41 n if n == 1 << 4 => Self::Homeaddress,
42 n if n == 1 << 5 => Self::Deprecated,
43 n if n == 1 << 6 => Self::Tentative,
44 n if n == 1 << 7 => Self::Permanent,
45 n if n == 1 << 8 => Self::Managetempaddr,
46 n if n == 1 << 9 => Self::Noprefixroute,
47 n if n == 1 << 10 => Self::Mcautojoin,
48 n if n == 1 << 11 => Self::StablePrivacy,
49 _ => return None,
50 })
51 }
52}
53#[derive(Clone)]
54pub enum AddrAttrs<'a> {
55 Address(std::net::IpAddr),
56 Local(std::net::IpAddr),
57 Label(&'a CStr),
58 Broadcast(std::net::IpAddr),
59 Anycast(&'a [u8]),
60 Cacheinfo(PushIfaCacheinfo),
61 Multicast(&'a [u8]),
62 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
63 Flags(u32),
64 RtPriority(u32),
65 TargetNetnsid(&'a [u8]),
66 Proto(u8),
67}
68impl<'a> IterableAddrAttrs<'a> {
69 pub fn get_address(&self) -> Result<std::net::IpAddr, ErrorContext> {
70 let mut iter = self.clone();
71 iter.pos = 0;
72 for attr in iter {
73 if let AddrAttrs::Address(val) = attr? {
74 return Ok(val);
75 }
76 }
77 Err(ErrorContext::new_missing(
78 "AddrAttrs",
79 "Address",
80 self.orig_loc,
81 self.buf.as_ptr() as usize,
82 ))
83 }
84 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
85 let mut iter = self.clone();
86 iter.pos = 0;
87 for attr in iter {
88 if let AddrAttrs::Local(val) = attr? {
89 return Ok(val);
90 }
91 }
92 Err(ErrorContext::new_missing(
93 "AddrAttrs",
94 "Local",
95 self.orig_loc,
96 self.buf.as_ptr() as usize,
97 ))
98 }
99 pub fn get_label(&self) -> Result<&'a CStr, ErrorContext> {
100 let mut iter = self.clone();
101 iter.pos = 0;
102 for attr in iter {
103 if let AddrAttrs::Label(val) = attr? {
104 return Ok(val);
105 }
106 }
107 Err(ErrorContext::new_missing(
108 "AddrAttrs",
109 "Label",
110 self.orig_loc,
111 self.buf.as_ptr() as usize,
112 ))
113 }
114 pub fn get_broadcast(&self) -> Result<std::net::IpAddr, ErrorContext> {
115 let mut iter = self.clone();
116 iter.pos = 0;
117 for attr in iter {
118 if let AddrAttrs::Broadcast(val) = attr? {
119 return Ok(val);
120 }
121 }
122 Err(ErrorContext::new_missing(
123 "AddrAttrs",
124 "Broadcast",
125 self.orig_loc,
126 self.buf.as_ptr() as usize,
127 ))
128 }
129 pub fn get_anycast(&self) -> Result<&'a [u8], ErrorContext> {
130 let mut iter = self.clone();
131 iter.pos = 0;
132 for attr in iter {
133 if let AddrAttrs::Anycast(val) = attr? {
134 return Ok(val);
135 }
136 }
137 Err(ErrorContext::new_missing(
138 "AddrAttrs",
139 "Anycast",
140 self.orig_loc,
141 self.buf.as_ptr() as usize,
142 ))
143 }
144 pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
145 let mut iter = self.clone();
146 iter.pos = 0;
147 for attr in iter {
148 if let AddrAttrs::Cacheinfo(val) = attr? {
149 return Ok(val);
150 }
151 }
152 Err(ErrorContext::new_missing(
153 "AddrAttrs",
154 "Cacheinfo",
155 self.orig_loc,
156 self.buf.as_ptr() as usize,
157 ))
158 }
159 pub fn get_multicast(&self) -> Result<&'a [u8], ErrorContext> {
160 let mut iter = self.clone();
161 iter.pos = 0;
162 for attr in iter {
163 if let AddrAttrs::Multicast(val) = attr? {
164 return Ok(val);
165 }
166 }
167 Err(ErrorContext::new_missing(
168 "AddrAttrs",
169 "Multicast",
170 self.orig_loc,
171 self.buf.as_ptr() as usize,
172 ))
173 }
174 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
175 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
176 let mut iter = self.clone();
177 iter.pos = 0;
178 for attr in iter {
179 if let AddrAttrs::Flags(val) = attr? {
180 return Ok(val);
181 }
182 }
183 Err(ErrorContext::new_missing(
184 "AddrAttrs",
185 "Flags",
186 self.orig_loc,
187 self.buf.as_ptr() as usize,
188 ))
189 }
190 pub fn get_rt_priority(&self) -> Result<u32, ErrorContext> {
191 let mut iter = self.clone();
192 iter.pos = 0;
193 for attr in iter {
194 if let AddrAttrs::RtPriority(val) = attr? {
195 return Ok(val);
196 }
197 }
198 Err(ErrorContext::new_missing(
199 "AddrAttrs",
200 "RtPriority",
201 self.orig_loc,
202 self.buf.as_ptr() as usize,
203 ))
204 }
205 pub fn get_target_netnsid(&self) -> Result<&'a [u8], ErrorContext> {
206 let mut iter = self.clone();
207 iter.pos = 0;
208 for attr in iter {
209 if let AddrAttrs::TargetNetnsid(val) = attr? {
210 return Ok(val);
211 }
212 }
213 Err(ErrorContext::new_missing(
214 "AddrAttrs",
215 "TargetNetnsid",
216 self.orig_loc,
217 self.buf.as_ptr() as usize,
218 ))
219 }
220 pub fn get_proto(&self) -> Result<u8, ErrorContext> {
221 let mut iter = self.clone();
222 iter.pos = 0;
223 for attr in iter {
224 if let AddrAttrs::Proto(val) = attr? {
225 return Ok(val);
226 }
227 }
228 Err(ErrorContext::new_missing(
229 "AddrAttrs",
230 "Proto",
231 self.orig_loc,
232 self.buf.as_ptr() as usize,
233 ))
234 }
235}
236impl AddrAttrs<'_> {
237 pub fn new<'a>(buf: &'a [u8]) -> IterableAddrAttrs<'a> {
238 IterableAddrAttrs::with_loc(buf, buf.as_ptr() as usize)
239 }
240 fn attr_from_type(r#type: u16) -> Option<&'static str> {
241 let res = match r#type {
242 1u16 => "Address",
243 2u16 => "Local",
244 3u16 => "Label",
245 4u16 => "Broadcast",
246 5u16 => "Anycast",
247 6u16 => "Cacheinfo",
248 7u16 => "Multicast",
249 8u16 => "Flags",
250 9u16 => "RtPriority",
251 10u16 => "TargetNetnsid",
252 11u16 => "Proto",
253 _ => return None,
254 };
255 Some(res)
256 }
257}
258#[derive(Clone, Copy, Default)]
259pub struct IterableAddrAttrs<'a> {
260 buf: &'a [u8],
261 pos: usize,
262 orig_loc: usize,
263}
264impl<'a> IterableAddrAttrs<'a> {
265 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
266 Self {
267 buf,
268 pos: 0,
269 orig_loc,
270 }
271 }
272 pub fn get_buf(&self) -> &'a [u8] {
273 self.buf
274 }
275}
276impl<'a> Iterator for IterableAddrAttrs<'a> {
277 type Item = Result<AddrAttrs<'a>, ErrorContext>;
278 fn next(&mut self) -> Option<Self::Item> {
279 let pos = self.pos;
280 let mut r#type;
281 loop {
282 r#type = None;
283 if self.buf.len() == self.pos {
284 return None;
285 }
286 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
287 break;
288 };
289 r#type = Some(header.r#type);
290 let res = match header.r#type {
291 1u16 => AddrAttrs::Address({
292 let res = parse_ip(next);
293 let Some(val) = res else { break };
294 val
295 }),
296 2u16 => AddrAttrs::Local({
297 let res = parse_ip(next);
298 let Some(val) = res else { break };
299 val
300 }),
301 3u16 => AddrAttrs::Label({
302 let res = CStr::from_bytes_with_nul(next).ok();
303 let Some(val) = res else { break };
304 val
305 }),
306 4u16 => AddrAttrs::Broadcast({
307 let res = parse_ip(next);
308 let Some(val) = res else { break };
309 val
310 }),
311 5u16 => AddrAttrs::Anycast({
312 let res = Some(next);
313 let Some(val) = res else { break };
314 val
315 }),
316 6u16 => AddrAttrs::Cacheinfo({
317 let res = PushIfaCacheinfo::new_from_slice(next);
318 let Some(val) = res else { break };
319 val
320 }),
321 7u16 => AddrAttrs::Multicast({
322 let res = Some(next);
323 let Some(val) = res else { break };
324 val
325 }),
326 8u16 => AddrAttrs::Flags({
327 let res = parse_u32(next);
328 let Some(val) = res else { break };
329 val
330 }),
331 9u16 => AddrAttrs::RtPriority({
332 let res = parse_u32(next);
333 let Some(val) = res else { break };
334 val
335 }),
336 10u16 => AddrAttrs::TargetNetnsid({
337 let res = Some(next);
338 let Some(val) = res else { break };
339 val
340 }),
341 11u16 => AddrAttrs::Proto({
342 let res = parse_u8(next);
343 let Some(val) = res else { break };
344 val
345 }),
346 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
347 n => continue,
348 };
349 return Some(Ok(res));
350 }
351 Some(Err(ErrorContext::new(
352 "AddrAttrs",
353 r#type.and_then(|t| AddrAttrs::attr_from_type(t)),
354 self.orig_loc,
355 self.buf.as_ptr().wrapping_add(pos) as usize,
356 )))
357 }
358}
359impl<'a> std::fmt::Debug for IterableAddrAttrs<'_> {
360 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
361 let mut fmt = f.debug_struct("AddrAttrs");
362 for attr in self.clone() {
363 let attr = match attr {
364 Ok(a) => a,
365 Err(err) => {
366 fmt.finish()?;
367 f.write_str("Err(")?;
368 err.fmt(f)?;
369 return f.write_str(")");
370 }
371 };
372 match attr {
373 AddrAttrs::Address(val) => fmt.field("Address", &val),
374 AddrAttrs::Local(val) => fmt.field("Local", &val),
375 AddrAttrs::Label(val) => fmt.field("Label", &val),
376 AddrAttrs::Broadcast(val) => fmt.field("Broadcast", &val),
377 AddrAttrs::Anycast(val) => fmt.field("Anycast", &val),
378 AddrAttrs::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
379 AddrAttrs::Multicast(val) => fmt.field("Multicast", &val),
380 AddrAttrs::Flags(val) => {
381 fmt.field("Flags", &FormatFlags(val.into(), IfaFlags::from_value))
382 }
383 AddrAttrs::RtPriority(val) => fmt.field("RtPriority", &val),
384 AddrAttrs::TargetNetnsid(val) => fmt.field("TargetNetnsid", &val),
385 AddrAttrs::Proto(val) => fmt.field("Proto", &val),
386 };
387 }
388 fmt.finish()
389 }
390}
391impl IterableAddrAttrs<'_> {
392 pub fn lookup_attr(
393 &self,
394 offset: usize,
395 missing_type: Option<u16>,
396 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
397 let mut stack = Vec::new();
398 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
399 if cur == offset {
400 stack.push(("AddrAttrs", offset));
401 return (
402 stack,
403 missing_type.and_then(|t| AddrAttrs::attr_from_type(t)),
404 );
405 }
406 if cur > offset || cur + self.buf.len() < offset {
407 return (stack, None);
408 }
409 let mut attrs = self.clone();
410 let mut last_off = cur + attrs.pos;
411 while let Some(attr) = attrs.next() {
412 let Ok(attr) = attr else { break };
413 match attr {
414 AddrAttrs::Address(val) => {
415 if last_off == offset {
416 stack.push(("Address", last_off));
417 break;
418 }
419 }
420 AddrAttrs::Local(val) => {
421 if last_off == offset {
422 stack.push(("Local", last_off));
423 break;
424 }
425 }
426 AddrAttrs::Label(val) => {
427 if last_off == offset {
428 stack.push(("Label", last_off));
429 break;
430 }
431 }
432 AddrAttrs::Broadcast(val) => {
433 if last_off == offset {
434 stack.push(("Broadcast", last_off));
435 break;
436 }
437 }
438 AddrAttrs::Anycast(val) => {
439 if last_off == offset {
440 stack.push(("Anycast", last_off));
441 break;
442 }
443 }
444 AddrAttrs::Cacheinfo(val) => {
445 if last_off == offset {
446 stack.push(("Cacheinfo", last_off));
447 break;
448 }
449 }
450 AddrAttrs::Multicast(val) => {
451 if last_off == offset {
452 stack.push(("Multicast", last_off));
453 break;
454 }
455 }
456 AddrAttrs::Flags(val) => {
457 if last_off == offset {
458 stack.push(("Flags", last_off));
459 break;
460 }
461 }
462 AddrAttrs::RtPriority(val) => {
463 if last_off == offset {
464 stack.push(("RtPriority", last_off));
465 break;
466 }
467 }
468 AddrAttrs::TargetNetnsid(val) => {
469 if last_off == offset {
470 stack.push(("TargetNetnsid", last_off));
471 break;
472 }
473 }
474 AddrAttrs::Proto(val) => {
475 if last_off == offset {
476 stack.push(("Proto", last_off));
477 break;
478 }
479 }
480 _ => {}
481 };
482 last_off = cur + attrs.pos;
483 }
484 if !stack.is_empty() {
485 stack.push(("AddrAttrs", cur));
486 }
487 (stack, None)
488 }
489}
490pub struct PushAddrAttrs<Prev: Rec> {
491 pub(crate) prev: Option<Prev>,
492 pub(crate) header_offset: Option<usize>,
493}
494impl<Prev: Rec> Rec for PushAddrAttrs<Prev> {
495 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
496 self.prev.as_mut().unwrap().as_rec_mut()
497 }
498 fn as_rec(&self) -> &Vec<u8> {
499 self.prev.as_ref().unwrap().as_rec()
500 }
501}
502impl<Prev: Rec> PushAddrAttrs<Prev> {
503 pub fn new(prev: Prev) -> Self {
504 Self {
505 prev: Some(prev),
506 header_offset: None,
507 }
508 }
509 pub fn end_nested(mut self) -> Prev {
510 let mut prev = self.prev.take().unwrap();
511 if let Some(header_offset) = &self.header_offset {
512 finalize_nested_header(prev.as_rec_mut(), *header_offset);
513 }
514 prev
515 }
516 pub fn push_address(mut self, value: std::net::IpAddr) -> Self {
517 push_header(self.as_rec_mut(), 1u16, {
518 match &value {
519 IpAddr::V4(_) => 4,
520 IpAddr::V6(_) => 16,
521 }
522 } as u16);
523 encode_ip(self.as_rec_mut(), value);
524 self
525 }
526 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
527 push_header(self.as_rec_mut(), 2u16, {
528 match &value {
529 IpAddr::V4(_) => 4,
530 IpAddr::V6(_) => 16,
531 }
532 } as u16);
533 encode_ip(self.as_rec_mut(), value);
534 self
535 }
536 pub fn push_label(mut self, value: &CStr) -> Self {
537 push_header(
538 self.as_rec_mut(),
539 3u16,
540 value.to_bytes_with_nul().len() as u16,
541 );
542 self.as_rec_mut().extend(value.to_bytes_with_nul());
543 self
544 }
545 pub fn push_label_bytes(mut self, value: &[u8]) -> Self {
546 push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
547 self.as_rec_mut().extend(value);
548 self.as_rec_mut().push(0);
549 self
550 }
551 pub fn push_broadcast(mut self, value: std::net::IpAddr) -> Self {
552 push_header(self.as_rec_mut(), 4u16, {
553 match &value {
554 IpAddr::V4(_) => 4,
555 IpAddr::V6(_) => 16,
556 }
557 } as u16);
558 encode_ip(self.as_rec_mut(), value);
559 self
560 }
561 pub fn push_anycast(mut self, value: &[u8]) -> Self {
562 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
563 self.as_rec_mut().extend(value);
564 self
565 }
566 pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
567 push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
568 self.as_rec_mut().extend(value.as_slice());
569 self
570 }
571 pub fn push_multicast(mut self, value: &[u8]) -> Self {
572 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
573 self.as_rec_mut().extend(value);
574 self
575 }
576 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
577 pub fn push_flags(mut self, value: u32) -> Self {
578 push_header(self.as_rec_mut(), 8u16, 4 as u16);
579 self.as_rec_mut().extend(value.to_ne_bytes());
580 self
581 }
582 pub fn push_rt_priority(mut self, value: u32) -> Self {
583 push_header(self.as_rec_mut(), 9u16, 4 as u16);
584 self.as_rec_mut().extend(value.to_ne_bytes());
585 self
586 }
587 pub fn push_target_netnsid(mut self, value: &[u8]) -> Self {
588 push_header(self.as_rec_mut(), 10u16, value.len() as u16);
589 self.as_rec_mut().extend(value);
590 self
591 }
592 pub fn push_proto(mut self, value: u8) -> Self {
593 push_header(self.as_rec_mut(), 11u16, 1 as u16);
594 self.as_rec_mut().extend(value.to_ne_bytes());
595 self
596 }
597}
598impl<Prev: Rec> Drop for PushAddrAttrs<Prev> {
599 fn drop(&mut self) {
600 if let Some(prev) = &mut self.prev {
601 if let Some(header_offset) = &self.header_offset {
602 finalize_nested_header(prev.as_rec_mut(), *header_offset);
603 }
604 }
605 }
606}
607#[derive(Clone)]
608pub struct PushIfaddrmsg {
609 pub(crate) buf: [u8; 8usize],
610}
611#[doc = "Create zero-initialized struct"]
612impl Default for PushIfaddrmsg {
613 fn default() -> Self {
614 Self { buf: [0u8; 8usize] }
615 }
616}
617impl PushIfaddrmsg {
618 #[doc = "Create zero-initialized struct"]
619 pub fn new() -> Self {
620 Default::default()
621 }
622 #[doc = "Copy from contents from other slice"]
623 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
624 if other.len() != Self::len() {
625 return None;
626 }
627 let mut buf = [0u8; Self::len()];
628 buf.clone_from_slice(other);
629 Some(Self { buf })
630 }
631 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
632 pub fn new_from_zeroed(other: &[u8]) -> Self {
633 let mut buf = [0u8; Self::len()];
634 let len = buf.len().min(other.len());
635 buf[..len].clone_from_slice(&other[..len]);
636 Self { buf }
637 }
638 pub fn as_slice(&self) -> &[u8] {
639 &self.buf
640 }
641 pub fn as_mut_slice(&mut self) -> &mut [u8] {
642 &mut self.buf
643 }
644 pub const fn len() -> usize {
645 8usize
646 }
647 pub fn ifa_family(&self) -> u8 {
648 parse_u8(&self.buf[0usize..1usize]).unwrap()
649 }
650 pub fn set_ifa_family(&mut self, value: u8) {
651 self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
652 }
653 pub fn ifa_prefixlen(&self) -> u8 {
654 parse_u8(&self.buf[1usize..2usize]).unwrap()
655 }
656 pub fn set_ifa_prefixlen(&mut self, value: u8) {
657 self.buf[1usize..2usize].copy_from_slice(&value.to_ne_bytes())
658 }
659 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
660 pub fn ifa_flags(&self) -> u8 {
661 parse_u8(&self.buf[2usize..3usize]).unwrap()
662 }
663 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
664 pub fn set_ifa_flags(&mut self, value: u8) {
665 self.buf[2usize..3usize].copy_from_slice(&value.to_ne_bytes())
666 }
667 pub fn ifa_scope(&self) -> u8 {
668 parse_u8(&self.buf[3usize..4usize]).unwrap()
669 }
670 pub fn set_ifa_scope(&mut self, value: u8) {
671 self.buf[3usize..4usize].copy_from_slice(&value.to_ne_bytes())
672 }
673 pub fn ifa_index(&self) -> u32 {
674 parse_u32(&self.buf[4usize..8usize]).unwrap()
675 }
676 pub fn set_ifa_index(&mut self, value: u32) {
677 self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
678 }
679}
680impl std::fmt::Debug for PushIfaddrmsg {
681 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
682 fmt.debug_struct("Ifaddrmsg")
683 .field("ifa_family", &self.ifa_family())
684 .field("ifa_prefixlen", &self.ifa_prefixlen())
685 .field(
686 "ifa_flags",
687 &FormatFlags(self.ifa_flags().into(), IfaFlags::from_value),
688 )
689 .field("ifa_scope", &self.ifa_scope())
690 .field("ifa_index", &self.ifa_index())
691 .finish()
692 }
693}
694#[derive(Clone)]
695pub struct PushIfaCacheinfo {
696 pub(crate) buf: [u8; 16usize],
697}
698#[doc = "Create zero-initialized struct"]
699impl Default for PushIfaCacheinfo {
700 fn default() -> Self {
701 Self {
702 buf: [0u8; 16usize],
703 }
704 }
705}
706impl PushIfaCacheinfo {
707 #[doc = "Create zero-initialized struct"]
708 pub fn new() -> Self {
709 Default::default()
710 }
711 #[doc = "Copy from contents from other slice"]
712 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
713 if other.len() != Self::len() {
714 return None;
715 }
716 let mut buf = [0u8; Self::len()];
717 buf.clone_from_slice(other);
718 Some(Self { buf })
719 }
720 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
721 pub fn new_from_zeroed(other: &[u8]) -> Self {
722 let mut buf = [0u8; Self::len()];
723 let len = buf.len().min(other.len());
724 buf[..len].clone_from_slice(&other[..len]);
725 Self { buf }
726 }
727 pub fn as_slice(&self) -> &[u8] {
728 &self.buf
729 }
730 pub fn as_mut_slice(&mut self) -> &mut [u8] {
731 &mut self.buf
732 }
733 pub const fn len() -> usize {
734 16usize
735 }
736 pub fn ifa_prefered(&self) -> u32 {
737 parse_u32(&self.buf[0usize..4usize]).unwrap()
738 }
739 pub fn set_ifa_prefered(&mut self, value: u32) {
740 self.buf[0usize..4usize].copy_from_slice(&value.to_ne_bytes())
741 }
742 pub fn ifa_valid(&self) -> u32 {
743 parse_u32(&self.buf[4usize..8usize]).unwrap()
744 }
745 pub fn set_ifa_valid(&mut self, value: u32) {
746 self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
747 }
748 pub fn cstamp(&self) -> u32 {
749 parse_u32(&self.buf[8usize..12usize]).unwrap()
750 }
751 pub fn set_cstamp(&mut self, value: u32) {
752 self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
753 }
754 pub fn tstamp(&self) -> u32 {
755 parse_u32(&self.buf[12usize..16usize]).unwrap()
756 }
757 pub fn set_tstamp(&mut self, value: u32) {
758 self.buf[12usize..16usize].copy_from_slice(&value.to_ne_bytes())
759 }
760}
761impl std::fmt::Debug for PushIfaCacheinfo {
762 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
763 fmt.debug_struct("IfaCacheinfo")
764 .field("ifa_prefered", &self.ifa_prefered())
765 .field("ifa_valid", &self.ifa_valid())
766 .field("cstamp", &self.cstamp())
767 .field("tstamp", &self.tstamp())
768 .finish()
769 }
770}
771#[doc = "Add new address"]
772pub struct PushOpNewaddrDoRequest<Prev: Rec> {
773 pub(crate) prev: Option<Prev>,
774 pub(crate) header_offset: Option<usize>,
775}
776impl<Prev: Rec> Rec for PushOpNewaddrDoRequest<Prev> {
777 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
778 self.prev.as_mut().unwrap().as_rec_mut()
779 }
780 fn as_rec(&self) -> &Vec<u8> {
781 self.prev.as_ref().unwrap().as_rec()
782 }
783}
784impl<Prev: Rec> PushOpNewaddrDoRequest<Prev> {
785 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
786 Self::write_header(&mut prev, header);
787 Self::new_without_header(prev)
788 }
789 fn new_without_header(prev: Prev) -> Self {
790 Self {
791 prev: Some(prev),
792 header_offset: None,
793 }
794 }
795 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
796 prev.as_rec_mut().extend(header.as_slice());
797 }
798 pub fn end_nested(mut self) -> Prev {
799 let mut prev = self.prev.take().unwrap();
800 if let Some(header_offset) = &self.header_offset {
801 finalize_nested_header(prev.as_rec_mut(), *header_offset);
802 }
803 prev
804 }
805 pub fn push_address(mut self, value: std::net::IpAddr) -> Self {
806 push_header(self.as_rec_mut(), 1u16, {
807 match &value {
808 IpAddr::V4(_) => 4,
809 IpAddr::V6(_) => 16,
810 }
811 } as u16);
812 encode_ip(self.as_rec_mut(), value);
813 self
814 }
815 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
816 push_header(self.as_rec_mut(), 2u16, {
817 match &value {
818 IpAddr::V4(_) => 4,
819 IpAddr::V6(_) => 16,
820 }
821 } as u16);
822 encode_ip(self.as_rec_mut(), value);
823 self
824 }
825 pub fn push_label(mut self, value: &CStr) -> Self {
826 push_header(
827 self.as_rec_mut(),
828 3u16,
829 value.to_bytes_with_nul().len() as u16,
830 );
831 self.as_rec_mut().extend(value.to_bytes_with_nul());
832 self
833 }
834 pub fn push_label_bytes(mut self, value: &[u8]) -> Self {
835 push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
836 self.as_rec_mut().extend(value);
837 self.as_rec_mut().push(0);
838 self
839 }
840 pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
841 push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
842 self.as_rec_mut().extend(value.as_slice());
843 self
844 }
845 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
846 pub fn push_flags(mut self, value: u32) -> Self {
847 push_header(self.as_rec_mut(), 8u16, 4 as u16);
848 self.as_rec_mut().extend(value.to_ne_bytes());
849 self
850 }
851}
852impl<Prev: Rec> Drop for PushOpNewaddrDoRequest<Prev> {
853 fn drop(&mut self) {
854 if let Some(prev) = &mut self.prev {
855 if let Some(header_offset) = &self.header_offset {
856 finalize_nested_header(prev.as_rec_mut(), *header_offset);
857 }
858 }
859 }
860}
861#[doc = "Add new address"]
862#[derive(Clone)]
863pub enum OpNewaddrDoRequest<'a> {
864 Address(std::net::IpAddr),
865 Local(std::net::IpAddr),
866 Label(&'a CStr),
867 Cacheinfo(PushIfaCacheinfo),
868 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
869 Flags(u32),
870}
871impl<'a> IterableOpNewaddrDoRequest<'a> {
872 pub fn get_address(&self) -> Result<std::net::IpAddr, ErrorContext> {
873 let mut iter = self.clone();
874 iter.pos = 0;
875 for attr in iter {
876 if let OpNewaddrDoRequest::Address(val) = attr? {
877 return Ok(val);
878 }
879 }
880 Err(ErrorContext::new_missing(
881 "OpNewaddrDoRequest",
882 "Address",
883 self.orig_loc,
884 self.buf.as_ptr() as usize,
885 ))
886 }
887 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
888 let mut iter = self.clone();
889 iter.pos = 0;
890 for attr in iter {
891 if let OpNewaddrDoRequest::Local(val) = attr? {
892 return Ok(val);
893 }
894 }
895 Err(ErrorContext::new_missing(
896 "OpNewaddrDoRequest",
897 "Local",
898 self.orig_loc,
899 self.buf.as_ptr() as usize,
900 ))
901 }
902 pub fn get_label(&self) -> Result<&'a CStr, ErrorContext> {
903 let mut iter = self.clone();
904 iter.pos = 0;
905 for attr in iter {
906 if let OpNewaddrDoRequest::Label(val) = attr? {
907 return Ok(val);
908 }
909 }
910 Err(ErrorContext::new_missing(
911 "OpNewaddrDoRequest",
912 "Label",
913 self.orig_loc,
914 self.buf.as_ptr() as usize,
915 ))
916 }
917 pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
918 let mut iter = self.clone();
919 iter.pos = 0;
920 for attr in iter {
921 if let OpNewaddrDoRequest::Cacheinfo(val) = attr? {
922 return Ok(val);
923 }
924 }
925 Err(ErrorContext::new_missing(
926 "OpNewaddrDoRequest",
927 "Cacheinfo",
928 self.orig_loc,
929 self.buf.as_ptr() as usize,
930 ))
931 }
932 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
933 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
934 let mut iter = self.clone();
935 iter.pos = 0;
936 for attr in iter {
937 if let OpNewaddrDoRequest::Flags(val) = attr? {
938 return Ok(val);
939 }
940 }
941 Err(ErrorContext::new_missing(
942 "OpNewaddrDoRequest",
943 "Flags",
944 self.orig_loc,
945 self.buf.as_ptr() as usize,
946 ))
947 }
948}
949impl OpNewaddrDoRequest<'_> {
950 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpNewaddrDoRequest<'a>) {
951 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
952 (
953 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
954 IterableOpNewaddrDoRequest::with_loc(attrs, buf.as_ptr() as usize),
955 )
956 }
957 fn attr_from_type(r#type: u16) -> Option<&'static str> {
958 AddrAttrs::attr_from_type(r#type)
959 }
960}
961#[derive(Clone, Copy, Default)]
962pub struct IterableOpNewaddrDoRequest<'a> {
963 buf: &'a [u8],
964 pos: usize,
965 orig_loc: usize,
966}
967impl<'a> IterableOpNewaddrDoRequest<'a> {
968 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
969 Self {
970 buf,
971 pos: 0,
972 orig_loc,
973 }
974 }
975 pub fn get_buf(&self) -> &'a [u8] {
976 self.buf
977 }
978}
979impl<'a> Iterator for IterableOpNewaddrDoRequest<'a> {
980 type Item = Result<OpNewaddrDoRequest<'a>, ErrorContext>;
981 fn next(&mut self) -> Option<Self::Item> {
982 let pos = self.pos;
983 let mut r#type;
984 loop {
985 r#type = None;
986 if self.buf.len() == self.pos {
987 return None;
988 }
989 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
990 break;
991 };
992 r#type = Some(header.r#type);
993 let res = match header.r#type {
994 1u16 => OpNewaddrDoRequest::Address({
995 let res = parse_ip(next);
996 let Some(val) = res else { break };
997 val
998 }),
999 2u16 => OpNewaddrDoRequest::Local({
1000 let res = parse_ip(next);
1001 let Some(val) = res else { break };
1002 val
1003 }),
1004 3u16 => OpNewaddrDoRequest::Label({
1005 let res = CStr::from_bytes_with_nul(next).ok();
1006 let Some(val) = res else { break };
1007 val
1008 }),
1009 6u16 => OpNewaddrDoRequest::Cacheinfo({
1010 let res = PushIfaCacheinfo::new_from_slice(next);
1011 let Some(val) = res else { break };
1012 val
1013 }),
1014 8u16 => OpNewaddrDoRequest::Flags({
1015 let res = parse_u32(next);
1016 let Some(val) = res else { break };
1017 val
1018 }),
1019 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1020 n => continue,
1021 };
1022 return Some(Ok(res));
1023 }
1024 Some(Err(ErrorContext::new(
1025 "OpNewaddrDoRequest",
1026 r#type.and_then(|t| OpNewaddrDoRequest::attr_from_type(t)),
1027 self.orig_loc,
1028 self.buf.as_ptr().wrapping_add(pos) as usize,
1029 )))
1030 }
1031}
1032impl<'a> std::fmt::Debug for IterableOpNewaddrDoRequest<'_> {
1033 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1034 let mut fmt = f.debug_struct("OpNewaddrDoRequest");
1035 for attr in self.clone() {
1036 let attr = match attr {
1037 Ok(a) => a,
1038 Err(err) => {
1039 fmt.finish()?;
1040 f.write_str("Err(")?;
1041 err.fmt(f)?;
1042 return f.write_str(")");
1043 }
1044 };
1045 match attr {
1046 OpNewaddrDoRequest::Address(val) => fmt.field("Address", &val),
1047 OpNewaddrDoRequest::Local(val) => fmt.field("Local", &val),
1048 OpNewaddrDoRequest::Label(val) => fmt.field("Label", &val),
1049 OpNewaddrDoRequest::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
1050 OpNewaddrDoRequest::Flags(val) => {
1051 fmt.field("Flags", &FormatFlags(val.into(), IfaFlags::from_value))
1052 }
1053 };
1054 }
1055 fmt.finish()
1056 }
1057}
1058impl IterableOpNewaddrDoRequest<'_> {
1059 pub fn lookup_attr(
1060 &self,
1061 offset: usize,
1062 missing_type: Option<u16>,
1063 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1064 let mut stack = Vec::new();
1065 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1066 if cur == offset + PushIfaddrmsg::len() {
1067 stack.push(("OpNewaddrDoRequest", offset));
1068 return (
1069 stack,
1070 missing_type.and_then(|t| OpNewaddrDoRequest::attr_from_type(t)),
1071 );
1072 }
1073 if cur > offset || cur + self.buf.len() < offset {
1074 return (stack, None);
1075 }
1076 let mut attrs = self.clone();
1077 let mut last_off = cur + attrs.pos;
1078 while let Some(attr) = attrs.next() {
1079 let Ok(attr) = attr else { break };
1080 match attr {
1081 OpNewaddrDoRequest::Address(val) => {
1082 if last_off == offset {
1083 stack.push(("Address", last_off));
1084 break;
1085 }
1086 }
1087 OpNewaddrDoRequest::Local(val) => {
1088 if last_off == offset {
1089 stack.push(("Local", last_off));
1090 break;
1091 }
1092 }
1093 OpNewaddrDoRequest::Label(val) => {
1094 if last_off == offset {
1095 stack.push(("Label", last_off));
1096 break;
1097 }
1098 }
1099 OpNewaddrDoRequest::Cacheinfo(val) => {
1100 if last_off == offset {
1101 stack.push(("Cacheinfo", last_off));
1102 break;
1103 }
1104 }
1105 OpNewaddrDoRequest::Flags(val) => {
1106 if last_off == offset {
1107 stack.push(("Flags", last_off));
1108 break;
1109 }
1110 }
1111 _ => {}
1112 };
1113 last_off = cur + attrs.pos;
1114 }
1115 if !stack.is_empty() {
1116 stack.push(("OpNewaddrDoRequest", cur));
1117 }
1118 (stack, None)
1119 }
1120}
1121#[doc = "Add new address"]
1122pub struct PushOpNewaddrDoReply<Prev: Rec> {
1123 pub(crate) prev: Option<Prev>,
1124 pub(crate) header_offset: Option<usize>,
1125}
1126impl<Prev: Rec> Rec for PushOpNewaddrDoReply<Prev> {
1127 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1128 self.prev.as_mut().unwrap().as_rec_mut()
1129 }
1130 fn as_rec(&self) -> &Vec<u8> {
1131 self.prev.as_ref().unwrap().as_rec()
1132 }
1133}
1134impl<Prev: Rec> PushOpNewaddrDoReply<Prev> {
1135 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1136 Self::write_header(&mut prev, header);
1137 Self::new_without_header(prev)
1138 }
1139 fn new_without_header(prev: Prev) -> Self {
1140 Self {
1141 prev: Some(prev),
1142 header_offset: None,
1143 }
1144 }
1145 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1146 prev.as_rec_mut().extend(header.as_slice());
1147 }
1148 pub fn end_nested(mut self) -> Prev {
1149 let mut prev = self.prev.take().unwrap();
1150 if let Some(header_offset) = &self.header_offset {
1151 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1152 }
1153 prev
1154 }
1155}
1156impl<Prev: Rec> Drop for PushOpNewaddrDoReply<Prev> {
1157 fn drop(&mut self) {
1158 if let Some(prev) = &mut self.prev {
1159 if let Some(header_offset) = &self.header_offset {
1160 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1161 }
1162 }
1163 }
1164}
1165#[doc = "Add new address"]
1166#[derive(Clone)]
1167pub enum OpNewaddrDoReply {}
1168impl<'a> IterableOpNewaddrDoReply<'a> {}
1169impl OpNewaddrDoReply {
1170 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpNewaddrDoReply<'a>) {
1171 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
1172 (
1173 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
1174 IterableOpNewaddrDoReply::with_loc(attrs, buf.as_ptr() as usize),
1175 )
1176 }
1177 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1178 AddrAttrs::attr_from_type(r#type)
1179 }
1180}
1181#[derive(Clone, Copy, Default)]
1182pub struct IterableOpNewaddrDoReply<'a> {
1183 buf: &'a [u8],
1184 pos: usize,
1185 orig_loc: usize,
1186}
1187impl<'a> IterableOpNewaddrDoReply<'a> {
1188 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1189 Self {
1190 buf,
1191 pos: 0,
1192 orig_loc,
1193 }
1194 }
1195 pub fn get_buf(&self) -> &'a [u8] {
1196 self.buf
1197 }
1198}
1199impl<'a> Iterator for IterableOpNewaddrDoReply<'a> {
1200 type Item = Result<OpNewaddrDoReply, ErrorContext>;
1201 fn next(&mut self) -> Option<Self::Item> {
1202 let pos = self.pos;
1203 let mut r#type;
1204 loop {
1205 r#type = None;
1206 if self.buf.len() == self.pos {
1207 return None;
1208 }
1209 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1210 break;
1211 };
1212 r#type = Some(header.r#type);
1213 let res = match header.r#type {
1214 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1215 n => continue,
1216 };
1217 return Some(Ok(res));
1218 }
1219 Some(Err(ErrorContext::new(
1220 "OpNewaddrDoReply",
1221 r#type.and_then(|t| OpNewaddrDoReply::attr_from_type(t)),
1222 self.orig_loc,
1223 self.buf.as_ptr().wrapping_add(pos) as usize,
1224 )))
1225 }
1226}
1227impl std::fmt::Debug for IterableOpNewaddrDoReply<'_> {
1228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1229 let mut fmt = f.debug_struct("OpNewaddrDoReply");
1230 for attr in self.clone() {
1231 let attr = match attr {
1232 Ok(a) => a,
1233 Err(err) => {
1234 fmt.finish()?;
1235 f.write_str("Err(")?;
1236 err.fmt(f)?;
1237 return f.write_str(")");
1238 }
1239 };
1240 match attr {};
1241 }
1242 fmt.finish()
1243 }
1244}
1245impl IterableOpNewaddrDoReply<'_> {
1246 pub fn lookup_attr(
1247 &self,
1248 offset: usize,
1249 missing_type: Option<u16>,
1250 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1251 let mut stack = Vec::new();
1252 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1253 if cur == offset + PushIfaddrmsg::len() {
1254 stack.push(("OpNewaddrDoReply", offset));
1255 return (
1256 stack,
1257 missing_type.and_then(|t| OpNewaddrDoReply::attr_from_type(t)),
1258 );
1259 }
1260 (stack, None)
1261 }
1262}
1263#[derive(Debug)]
1264pub struct RequestOpNewaddrDoRequest<'r> {
1265 request: Request<'r>,
1266}
1267impl<'r> RequestOpNewaddrDoRequest<'r> {
1268 pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
1269 PushOpNewaddrDoRequest::write_header(&mut request.buf_mut(), header);
1270 Self { request: request }
1271 }
1272 pub fn encode(&mut self) -> PushOpNewaddrDoRequest<&mut Vec<u8>> {
1273 PushOpNewaddrDoRequest::new_without_header(self.request.buf_mut())
1274 }
1275 pub fn into_encoder(self) -> PushOpNewaddrDoRequest<RequestBuf<'r>> {
1276 PushOpNewaddrDoRequest::new_without_header(self.request.buf)
1277 }
1278 pub fn decode_request<'buf>(
1279 buf: &'buf [u8],
1280 ) -> (PushIfaddrmsg, IterableOpNewaddrDoRequest<'buf>) {
1281 OpNewaddrDoRequest::new(buf)
1282 }
1283}
1284impl NetlinkRequest for RequestOpNewaddrDoRequest<'_> {
1285 fn protocol(&self) -> Protocol {
1286 Protocol::Raw {
1287 protonum: 0u16,
1288 request_type: 20u16,
1289 }
1290 }
1291 fn flags(&self) -> u16 {
1292 self.request.flags
1293 }
1294 fn payload(&self) -> &[u8] {
1295 self.request.buf()
1296 }
1297 type ReplyType<'buf> = (PushIfaddrmsg, IterableOpNewaddrDoReply<'buf>);
1298 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1299 OpNewaddrDoReply::new(buf)
1300 }
1301 fn lookup(
1302 buf: &[u8],
1303 offset: usize,
1304 missing_type: Option<u16>,
1305 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1306 OpNewaddrDoRequest::new(buf)
1307 .1
1308 .lookup_attr(offset, missing_type)
1309 }
1310}
1311#[doc = "Remove address"]
1312pub struct PushOpDeladdrDoRequest<Prev: Rec> {
1313 pub(crate) prev: Option<Prev>,
1314 pub(crate) header_offset: Option<usize>,
1315}
1316impl<Prev: Rec> Rec for PushOpDeladdrDoRequest<Prev> {
1317 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1318 self.prev.as_mut().unwrap().as_rec_mut()
1319 }
1320 fn as_rec(&self) -> &Vec<u8> {
1321 self.prev.as_ref().unwrap().as_rec()
1322 }
1323}
1324impl<Prev: Rec> PushOpDeladdrDoRequest<Prev> {
1325 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1326 Self::write_header(&mut prev, header);
1327 Self::new_without_header(prev)
1328 }
1329 fn new_without_header(prev: Prev) -> Self {
1330 Self {
1331 prev: Some(prev),
1332 header_offset: None,
1333 }
1334 }
1335 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1336 prev.as_rec_mut().extend(header.as_slice());
1337 }
1338 pub fn end_nested(mut self) -> Prev {
1339 let mut prev = self.prev.take().unwrap();
1340 if let Some(header_offset) = &self.header_offset {
1341 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1342 }
1343 prev
1344 }
1345 pub fn push_address(mut self, value: std::net::IpAddr) -> Self {
1346 push_header(self.as_rec_mut(), 1u16, {
1347 match &value {
1348 IpAddr::V4(_) => 4,
1349 IpAddr::V6(_) => 16,
1350 }
1351 } as u16);
1352 encode_ip(self.as_rec_mut(), value);
1353 self
1354 }
1355 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
1356 push_header(self.as_rec_mut(), 2u16, {
1357 match &value {
1358 IpAddr::V4(_) => 4,
1359 IpAddr::V6(_) => 16,
1360 }
1361 } as u16);
1362 encode_ip(self.as_rec_mut(), value);
1363 self
1364 }
1365}
1366impl<Prev: Rec> Drop for PushOpDeladdrDoRequest<Prev> {
1367 fn drop(&mut self) {
1368 if let Some(prev) = &mut self.prev {
1369 if let Some(header_offset) = &self.header_offset {
1370 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1371 }
1372 }
1373 }
1374}
1375#[doc = "Remove address"]
1376#[derive(Clone)]
1377pub enum OpDeladdrDoRequest {
1378 Address(std::net::IpAddr),
1379 Local(std::net::IpAddr),
1380}
1381impl<'a> IterableOpDeladdrDoRequest<'a> {
1382 pub fn get_address(&self) -> Result<std::net::IpAddr, ErrorContext> {
1383 let mut iter = self.clone();
1384 iter.pos = 0;
1385 for attr in iter {
1386 if let OpDeladdrDoRequest::Address(val) = attr? {
1387 return Ok(val);
1388 }
1389 }
1390 Err(ErrorContext::new_missing(
1391 "OpDeladdrDoRequest",
1392 "Address",
1393 self.orig_loc,
1394 self.buf.as_ptr() as usize,
1395 ))
1396 }
1397 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
1398 let mut iter = self.clone();
1399 iter.pos = 0;
1400 for attr in iter {
1401 if let OpDeladdrDoRequest::Local(val) = attr? {
1402 return Ok(val);
1403 }
1404 }
1405 Err(ErrorContext::new_missing(
1406 "OpDeladdrDoRequest",
1407 "Local",
1408 self.orig_loc,
1409 self.buf.as_ptr() as usize,
1410 ))
1411 }
1412}
1413impl OpDeladdrDoRequest {
1414 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpDeladdrDoRequest<'a>) {
1415 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
1416 (
1417 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
1418 IterableOpDeladdrDoRequest::with_loc(attrs, buf.as_ptr() as usize),
1419 )
1420 }
1421 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1422 AddrAttrs::attr_from_type(r#type)
1423 }
1424}
1425#[derive(Clone, Copy, Default)]
1426pub struct IterableOpDeladdrDoRequest<'a> {
1427 buf: &'a [u8],
1428 pos: usize,
1429 orig_loc: usize,
1430}
1431impl<'a> IterableOpDeladdrDoRequest<'a> {
1432 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1433 Self {
1434 buf,
1435 pos: 0,
1436 orig_loc,
1437 }
1438 }
1439 pub fn get_buf(&self) -> &'a [u8] {
1440 self.buf
1441 }
1442}
1443impl<'a> Iterator for IterableOpDeladdrDoRequest<'a> {
1444 type Item = Result<OpDeladdrDoRequest, ErrorContext>;
1445 fn next(&mut self) -> Option<Self::Item> {
1446 let pos = self.pos;
1447 let mut r#type;
1448 loop {
1449 r#type = None;
1450 if self.buf.len() == self.pos {
1451 return None;
1452 }
1453 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1454 break;
1455 };
1456 r#type = Some(header.r#type);
1457 let res = match header.r#type {
1458 1u16 => OpDeladdrDoRequest::Address({
1459 let res = parse_ip(next);
1460 let Some(val) = res else { break };
1461 val
1462 }),
1463 2u16 => OpDeladdrDoRequest::Local({
1464 let res = parse_ip(next);
1465 let Some(val) = res else { break };
1466 val
1467 }),
1468 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1469 n => continue,
1470 };
1471 return Some(Ok(res));
1472 }
1473 Some(Err(ErrorContext::new(
1474 "OpDeladdrDoRequest",
1475 r#type.and_then(|t| OpDeladdrDoRequest::attr_from_type(t)),
1476 self.orig_loc,
1477 self.buf.as_ptr().wrapping_add(pos) as usize,
1478 )))
1479 }
1480}
1481impl std::fmt::Debug for IterableOpDeladdrDoRequest<'_> {
1482 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1483 let mut fmt = f.debug_struct("OpDeladdrDoRequest");
1484 for attr in self.clone() {
1485 let attr = match attr {
1486 Ok(a) => a,
1487 Err(err) => {
1488 fmt.finish()?;
1489 f.write_str("Err(")?;
1490 err.fmt(f)?;
1491 return f.write_str(")");
1492 }
1493 };
1494 match attr {
1495 OpDeladdrDoRequest::Address(val) => fmt.field("Address", &val),
1496 OpDeladdrDoRequest::Local(val) => fmt.field("Local", &val),
1497 };
1498 }
1499 fmt.finish()
1500 }
1501}
1502impl IterableOpDeladdrDoRequest<'_> {
1503 pub fn lookup_attr(
1504 &self,
1505 offset: usize,
1506 missing_type: Option<u16>,
1507 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1508 let mut stack = Vec::new();
1509 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1510 if cur == offset + PushIfaddrmsg::len() {
1511 stack.push(("OpDeladdrDoRequest", offset));
1512 return (
1513 stack,
1514 missing_type.and_then(|t| OpDeladdrDoRequest::attr_from_type(t)),
1515 );
1516 }
1517 if cur > offset || cur + self.buf.len() < offset {
1518 return (stack, None);
1519 }
1520 let mut attrs = self.clone();
1521 let mut last_off = cur + attrs.pos;
1522 while let Some(attr) = attrs.next() {
1523 let Ok(attr) = attr else { break };
1524 match attr {
1525 OpDeladdrDoRequest::Address(val) => {
1526 if last_off == offset {
1527 stack.push(("Address", last_off));
1528 break;
1529 }
1530 }
1531 OpDeladdrDoRequest::Local(val) => {
1532 if last_off == offset {
1533 stack.push(("Local", last_off));
1534 break;
1535 }
1536 }
1537 _ => {}
1538 };
1539 last_off = cur + attrs.pos;
1540 }
1541 if !stack.is_empty() {
1542 stack.push(("OpDeladdrDoRequest", cur));
1543 }
1544 (stack, None)
1545 }
1546}
1547#[doc = "Remove address"]
1548pub struct PushOpDeladdrDoReply<Prev: Rec> {
1549 pub(crate) prev: Option<Prev>,
1550 pub(crate) header_offset: Option<usize>,
1551}
1552impl<Prev: Rec> Rec for PushOpDeladdrDoReply<Prev> {
1553 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1554 self.prev.as_mut().unwrap().as_rec_mut()
1555 }
1556 fn as_rec(&self) -> &Vec<u8> {
1557 self.prev.as_ref().unwrap().as_rec()
1558 }
1559}
1560impl<Prev: Rec> PushOpDeladdrDoReply<Prev> {
1561 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1562 Self::write_header(&mut prev, header);
1563 Self::new_without_header(prev)
1564 }
1565 fn new_without_header(prev: Prev) -> Self {
1566 Self {
1567 prev: Some(prev),
1568 header_offset: None,
1569 }
1570 }
1571 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1572 prev.as_rec_mut().extend(header.as_slice());
1573 }
1574 pub fn end_nested(mut self) -> Prev {
1575 let mut prev = self.prev.take().unwrap();
1576 if let Some(header_offset) = &self.header_offset {
1577 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1578 }
1579 prev
1580 }
1581}
1582impl<Prev: Rec> Drop for PushOpDeladdrDoReply<Prev> {
1583 fn drop(&mut self) {
1584 if let Some(prev) = &mut self.prev {
1585 if let Some(header_offset) = &self.header_offset {
1586 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1587 }
1588 }
1589 }
1590}
1591#[doc = "Remove address"]
1592#[derive(Clone)]
1593pub enum OpDeladdrDoReply {}
1594impl<'a> IterableOpDeladdrDoReply<'a> {}
1595impl OpDeladdrDoReply {
1596 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpDeladdrDoReply<'a>) {
1597 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
1598 (
1599 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
1600 IterableOpDeladdrDoReply::with_loc(attrs, buf.as_ptr() as usize),
1601 )
1602 }
1603 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1604 AddrAttrs::attr_from_type(r#type)
1605 }
1606}
1607#[derive(Clone, Copy, Default)]
1608pub struct IterableOpDeladdrDoReply<'a> {
1609 buf: &'a [u8],
1610 pos: usize,
1611 orig_loc: usize,
1612}
1613impl<'a> IterableOpDeladdrDoReply<'a> {
1614 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1615 Self {
1616 buf,
1617 pos: 0,
1618 orig_loc,
1619 }
1620 }
1621 pub fn get_buf(&self) -> &'a [u8] {
1622 self.buf
1623 }
1624}
1625impl<'a> Iterator for IterableOpDeladdrDoReply<'a> {
1626 type Item = Result<OpDeladdrDoReply, ErrorContext>;
1627 fn next(&mut self) -> Option<Self::Item> {
1628 let pos = self.pos;
1629 let mut r#type;
1630 loop {
1631 r#type = None;
1632 if self.buf.len() == self.pos {
1633 return None;
1634 }
1635 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1636 break;
1637 };
1638 r#type = Some(header.r#type);
1639 let res = match header.r#type {
1640 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1641 n => continue,
1642 };
1643 return Some(Ok(res));
1644 }
1645 Some(Err(ErrorContext::new(
1646 "OpDeladdrDoReply",
1647 r#type.and_then(|t| OpDeladdrDoReply::attr_from_type(t)),
1648 self.orig_loc,
1649 self.buf.as_ptr().wrapping_add(pos) as usize,
1650 )))
1651 }
1652}
1653impl std::fmt::Debug for IterableOpDeladdrDoReply<'_> {
1654 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1655 let mut fmt = f.debug_struct("OpDeladdrDoReply");
1656 for attr in self.clone() {
1657 let attr = match attr {
1658 Ok(a) => a,
1659 Err(err) => {
1660 fmt.finish()?;
1661 f.write_str("Err(")?;
1662 err.fmt(f)?;
1663 return f.write_str(")");
1664 }
1665 };
1666 match attr {};
1667 }
1668 fmt.finish()
1669 }
1670}
1671impl IterableOpDeladdrDoReply<'_> {
1672 pub fn lookup_attr(
1673 &self,
1674 offset: usize,
1675 missing_type: Option<u16>,
1676 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1677 let mut stack = Vec::new();
1678 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1679 if cur == offset + PushIfaddrmsg::len() {
1680 stack.push(("OpDeladdrDoReply", offset));
1681 return (
1682 stack,
1683 missing_type.and_then(|t| OpDeladdrDoReply::attr_from_type(t)),
1684 );
1685 }
1686 (stack, None)
1687 }
1688}
1689#[derive(Debug)]
1690pub struct RequestOpDeladdrDoRequest<'r> {
1691 request: Request<'r>,
1692}
1693impl<'r> RequestOpDeladdrDoRequest<'r> {
1694 pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
1695 PushOpDeladdrDoRequest::write_header(&mut request.buf_mut(), header);
1696 Self { request: request }
1697 }
1698 pub fn encode(&mut self) -> PushOpDeladdrDoRequest<&mut Vec<u8>> {
1699 PushOpDeladdrDoRequest::new_without_header(self.request.buf_mut())
1700 }
1701 pub fn into_encoder(self) -> PushOpDeladdrDoRequest<RequestBuf<'r>> {
1702 PushOpDeladdrDoRequest::new_without_header(self.request.buf)
1703 }
1704 pub fn decode_request<'buf>(
1705 buf: &'buf [u8],
1706 ) -> (PushIfaddrmsg, IterableOpDeladdrDoRequest<'buf>) {
1707 OpDeladdrDoRequest::new(buf)
1708 }
1709}
1710impl NetlinkRequest for RequestOpDeladdrDoRequest<'_> {
1711 fn protocol(&self) -> Protocol {
1712 Protocol::Raw {
1713 protonum: 0u16,
1714 request_type: 21u16,
1715 }
1716 }
1717 fn flags(&self) -> u16 {
1718 self.request.flags
1719 }
1720 fn payload(&self) -> &[u8] {
1721 self.request.buf()
1722 }
1723 type ReplyType<'buf> = (PushIfaddrmsg, IterableOpDeladdrDoReply<'buf>);
1724 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1725 OpDeladdrDoReply::new(buf)
1726 }
1727 fn lookup(
1728 buf: &[u8],
1729 offset: usize,
1730 missing_type: Option<u16>,
1731 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1732 OpDeladdrDoRequest::new(buf)
1733 .1
1734 .lookup_attr(offset, missing_type)
1735 }
1736}
1737#[doc = "Dump address information."]
1738pub struct PushOpGetaddrDumpRequest<Prev: Rec> {
1739 pub(crate) prev: Option<Prev>,
1740 pub(crate) header_offset: Option<usize>,
1741}
1742impl<Prev: Rec> Rec for PushOpGetaddrDumpRequest<Prev> {
1743 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1744 self.prev.as_mut().unwrap().as_rec_mut()
1745 }
1746 fn as_rec(&self) -> &Vec<u8> {
1747 self.prev.as_ref().unwrap().as_rec()
1748 }
1749}
1750impl<Prev: Rec> PushOpGetaddrDumpRequest<Prev> {
1751 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1752 Self::write_header(&mut prev, header);
1753 Self::new_without_header(prev)
1754 }
1755 fn new_without_header(prev: Prev) -> Self {
1756 Self {
1757 prev: Some(prev),
1758 header_offset: None,
1759 }
1760 }
1761 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1762 prev.as_rec_mut().extend(header.as_slice());
1763 }
1764 pub fn end_nested(mut self) -> Prev {
1765 let mut prev = self.prev.take().unwrap();
1766 if let Some(header_offset) = &self.header_offset {
1767 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1768 }
1769 prev
1770 }
1771}
1772impl<Prev: Rec> Drop for PushOpGetaddrDumpRequest<Prev> {
1773 fn drop(&mut self) {
1774 if let Some(prev) = &mut self.prev {
1775 if let Some(header_offset) = &self.header_offset {
1776 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1777 }
1778 }
1779 }
1780}
1781#[doc = "Dump address information."]
1782#[derive(Clone)]
1783pub enum OpGetaddrDumpRequest {}
1784impl<'a> IterableOpGetaddrDumpRequest<'a> {}
1785impl OpGetaddrDumpRequest {
1786 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetaddrDumpRequest<'a>) {
1787 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
1788 (
1789 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
1790 IterableOpGetaddrDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
1791 )
1792 }
1793 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1794 AddrAttrs::attr_from_type(r#type)
1795 }
1796}
1797#[derive(Clone, Copy, Default)]
1798pub struct IterableOpGetaddrDumpRequest<'a> {
1799 buf: &'a [u8],
1800 pos: usize,
1801 orig_loc: usize,
1802}
1803impl<'a> IterableOpGetaddrDumpRequest<'a> {
1804 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1805 Self {
1806 buf,
1807 pos: 0,
1808 orig_loc,
1809 }
1810 }
1811 pub fn get_buf(&self) -> &'a [u8] {
1812 self.buf
1813 }
1814}
1815impl<'a> Iterator for IterableOpGetaddrDumpRequest<'a> {
1816 type Item = Result<OpGetaddrDumpRequest, ErrorContext>;
1817 fn next(&mut self) -> Option<Self::Item> {
1818 let pos = self.pos;
1819 let mut r#type;
1820 loop {
1821 r#type = None;
1822 if self.buf.len() == self.pos {
1823 return None;
1824 }
1825 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1826 break;
1827 };
1828 r#type = Some(header.r#type);
1829 let res = match header.r#type {
1830 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1831 n => continue,
1832 };
1833 return Some(Ok(res));
1834 }
1835 Some(Err(ErrorContext::new(
1836 "OpGetaddrDumpRequest",
1837 r#type.and_then(|t| OpGetaddrDumpRequest::attr_from_type(t)),
1838 self.orig_loc,
1839 self.buf.as_ptr().wrapping_add(pos) as usize,
1840 )))
1841 }
1842}
1843impl std::fmt::Debug for IterableOpGetaddrDumpRequest<'_> {
1844 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1845 let mut fmt = f.debug_struct("OpGetaddrDumpRequest");
1846 for attr in self.clone() {
1847 let attr = match attr {
1848 Ok(a) => a,
1849 Err(err) => {
1850 fmt.finish()?;
1851 f.write_str("Err(")?;
1852 err.fmt(f)?;
1853 return f.write_str(")");
1854 }
1855 };
1856 match attr {};
1857 }
1858 fmt.finish()
1859 }
1860}
1861impl IterableOpGetaddrDumpRequest<'_> {
1862 pub fn lookup_attr(
1863 &self,
1864 offset: usize,
1865 missing_type: Option<u16>,
1866 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1867 let mut stack = Vec::new();
1868 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1869 if cur == offset + PushIfaddrmsg::len() {
1870 stack.push(("OpGetaddrDumpRequest", offset));
1871 return (
1872 stack,
1873 missing_type.and_then(|t| OpGetaddrDumpRequest::attr_from_type(t)),
1874 );
1875 }
1876 (stack, None)
1877 }
1878}
1879#[doc = "Dump address information."]
1880pub struct PushOpGetaddrDumpReply<Prev: Rec> {
1881 pub(crate) prev: Option<Prev>,
1882 pub(crate) header_offset: Option<usize>,
1883}
1884impl<Prev: Rec> Rec for PushOpGetaddrDumpReply<Prev> {
1885 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1886 self.prev.as_mut().unwrap().as_rec_mut()
1887 }
1888 fn as_rec(&self) -> &Vec<u8> {
1889 self.prev.as_ref().unwrap().as_rec()
1890 }
1891}
1892impl<Prev: Rec> PushOpGetaddrDumpReply<Prev> {
1893 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
1894 Self::write_header(&mut prev, header);
1895 Self::new_without_header(prev)
1896 }
1897 fn new_without_header(prev: Prev) -> Self {
1898 Self {
1899 prev: Some(prev),
1900 header_offset: None,
1901 }
1902 }
1903 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
1904 prev.as_rec_mut().extend(header.as_slice());
1905 }
1906 pub fn end_nested(mut self) -> Prev {
1907 let mut prev = self.prev.take().unwrap();
1908 if let Some(header_offset) = &self.header_offset {
1909 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1910 }
1911 prev
1912 }
1913 pub fn push_address(mut self, value: std::net::IpAddr) -> Self {
1914 push_header(self.as_rec_mut(), 1u16, {
1915 match &value {
1916 IpAddr::V4(_) => 4,
1917 IpAddr::V6(_) => 16,
1918 }
1919 } as u16);
1920 encode_ip(self.as_rec_mut(), value);
1921 self
1922 }
1923 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
1924 push_header(self.as_rec_mut(), 2u16, {
1925 match &value {
1926 IpAddr::V4(_) => 4,
1927 IpAddr::V6(_) => 16,
1928 }
1929 } as u16);
1930 encode_ip(self.as_rec_mut(), value);
1931 self
1932 }
1933 pub fn push_label(mut self, value: &CStr) -> Self {
1934 push_header(
1935 self.as_rec_mut(),
1936 3u16,
1937 value.to_bytes_with_nul().len() as u16,
1938 );
1939 self.as_rec_mut().extend(value.to_bytes_with_nul());
1940 self
1941 }
1942 pub fn push_label_bytes(mut self, value: &[u8]) -> Self {
1943 push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
1944 self.as_rec_mut().extend(value);
1945 self.as_rec_mut().push(0);
1946 self
1947 }
1948 pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
1949 push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
1950 self.as_rec_mut().extend(value.as_slice());
1951 self
1952 }
1953 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
1954 pub fn push_flags(mut self, value: u32) -> Self {
1955 push_header(self.as_rec_mut(), 8u16, 4 as u16);
1956 self.as_rec_mut().extend(value.to_ne_bytes());
1957 self
1958 }
1959}
1960impl<Prev: Rec> Drop for PushOpGetaddrDumpReply<Prev> {
1961 fn drop(&mut self) {
1962 if let Some(prev) = &mut self.prev {
1963 if let Some(header_offset) = &self.header_offset {
1964 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1965 }
1966 }
1967 }
1968}
1969#[doc = "Dump address information."]
1970#[derive(Clone)]
1971pub enum OpGetaddrDumpReply<'a> {
1972 Address(std::net::IpAddr),
1973 Local(std::net::IpAddr),
1974 Label(&'a CStr),
1975 Cacheinfo(PushIfaCacheinfo),
1976 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
1977 Flags(u32),
1978}
1979impl<'a> IterableOpGetaddrDumpReply<'a> {
1980 pub fn get_address(&self) -> Result<std::net::IpAddr, ErrorContext> {
1981 let mut iter = self.clone();
1982 iter.pos = 0;
1983 for attr in iter {
1984 if let OpGetaddrDumpReply::Address(val) = attr? {
1985 return Ok(val);
1986 }
1987 }
1988 Err(ErrorContext::new_missing(
1989 "OpGetaddrDumpReply",
1990 "Address",
1991 self.orig_loc,
1992 self.buf.as_ptr() as usize,
1993 ))
1994 }
1995 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
1996 let mut iter = self.clone();
1997 iter.pos = 0;
1998 for attr in iter {
1999 if let OpGetaddrDumpReply::Local(val) = attr? {
2000 return Ok(val);
2001 }
2002 }
2003 Err(ErrorContext::new_missing(
2004 "OpGetaddrDumpReply",
2005 "Local",
2006 self.orig_loc,
2007 self.buf.as_ptr() as usize,
2008 ))
2009 }
2010 pub fn get_label(&self) -> Result<&'a CStr, ErrorContext> {
2011 let mut iter = self.clone();
2012 iter.pos = 0;
2013 for attr in iter {
2014 if let OpGetaddrDumpReply::Label(val) = attr? {
2015 return Ok(val);
2016 }
2017 }
2018 Err(ErrorContext::new_missing(
2019 "OpGetaddrDumpReply",
2020 "Label",
2021 self.orig_loc,
2022 self.buf.as_ptr() as usize,
2023 ))
2024 }
2025 pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
2026 let mut iter = self.clone();
2027 iter.pos = 0;
2028 for attr in iter {
2029 if let OpGetaddrDumpReply::Cacheinfo(val) = attr? {
2030 return Ok(val);
2031 }
2032 }
2033 Err(ErrorContext::new_missing(
2034 "OpGetaddrDumpReply",
2035 "Cacheinfo",
2036 self.orig_loc,
2037 self.buf.as_ptr() as usize,
2038 ))
2039 }
2040 #[doc = "Associated type: \"IfaFlags\" (1 bit per enumeration)"]
2041 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
2042 let mut iter = self.clone();
2043 iter.pos = 0;
2044 for attr in iter {
2045 if let OpGetaddrDumpReply::Flags(val) = attr? {
2046 return Ok(val);
2047 }
2048 }
2049 Err(ErrorContext::new_missing(
2050 "OpGetaddrDumpReply",
2051 "Flags",
2052 self.orig_loc,
2053 self.buf.as_ptr() as usize,
2054 ))
2055 }
2056}
2057impl OpGetaddrDumpReply<'_> {
2058 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetaddrDumpReply<'a>) {
2059 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2060 (
2061 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2062 IterableOpGetaddrDumpReply::with_loc(attrs, buf.as_ptr() as usize),
2063 )
2064 }
2065 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2066 AddrAttrs::attr_from_type(r#type)
2067 }
2068}
2069#[derive(Clone, Copy, Default)]
2070pub struct IterableOpGetaddrDumpReply<'a> {
2071 buf: &'a [u8],
2072 pos: usize,
2073 orig_loc: usize,
2074}
2075impl<'a> IterableOpGetaddrDumpReply<'a> {
2076 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2077 Self {
2078 buf,
2079 pos: 0,
2080 orig_loc,
2081 }
2082 }
2083 pub fn get_buf(&self) -> &'a [u8] {
2084 self.buf
2085 }
2086}
2087impl<'a> Iterator for IterableOpGetaddrDumpReply<'a> {
2088 type Item = Result<OpGetaddrDumpReply<'a>, ErrorContext>;
2089 fn next(&mut self) -> Option<Self::Item> {
2090 let pos = self.pos;
2091 let mut r#type;
2092 loop {
2093 r#type = None;
2094 if self.buf.len() == self.pos {
2095 return None;
2096 }
2097 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2098 break;
2099 };
2100 r#type = Some(header.r#type);
2101 let res = match header.r#type {
2102 1u16 => OpGetaddrDumpReply::Address({
2103 let res = parse_ip(next);
2104 let Some(val) = res else { break };
2105 val
2106 }),
2107 2u16 => OpGetaddrDumpReply::Local({
2108 let res = parse_ip(next);
2109 let Some(val) = res else { break };
2110 val
2111 }),
2112 3u16 => OpGetaddrDumpReply::Label({
2113 let res = CStr::from_bytes_with_nul(next).ok();
2114 let Some(val) = res else { break };
2115 val
2116 }),
2117 6u16 => OpGetaddrDumpReply::Cacheinfo({
2118 let res = PushIfaCacheinfo::new_from_slice(next);
2119 let Some(val) = res else { break };
2120 val
2121 }),
2122 8u16 => OpGetaddrDumpReply::Flags({
2123 let res = parse_u32(next);
2124 let Some(val) = res else { break };
2125 val
2126 }),
2127 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2128 n => continue,
2129 };
2130 return Some(Ok(res));
2131 }
2132 Some(Err(ErrorContext::new(
2133 "OpGetaddrDumpReply",
2134 r#type.and_then(|t| OpGetaddrDumpReply::attr_from_type(t)),
2135 self.orig_loc,
2136 self.buf.as_ptr().wrapping_add(pos) as usize,
2137 )))
2138 }
2139}
2140impl<'a> std::fmt::Debug for IterableOpGetaddrDumpReply<'_> {
2141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2142 let mut fmt = f.debug_struct("OpGetaddrDumpReply");
2143 for attr in self.clone() {
2144 let attr = match attr {
2145 Ok(a) => a,
2146 Err(err) => {
2147 fmt.finish()?;
2148 f.write_str("Err(")?;
2149 err.fmt(f)?;
2150 return f.write_str(")");
2151 }
2152 };
2153 match attr {
2154 OpGetaddrDumpReply::Address(val) => fmt.field("Address", &val),
2155 OpGetaddrDumpReply::Local(val) => fmt.field("Local", &val),
2156 OpGetaddrDumpReply::Label(val) => fmt.field("Label", &val),
2157 OpGetaddrDumpReply::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
2158 OpGetaddrDumpReply::Flags(val) => {
2159 fmt.field("Flags", &FormatFlags(val.into(), IfaFlags::from_value))
2160 }
2161 };
2162 }
2163 fmt.finish()
2164 }
2165}
2166impl IterableOpGetaddrDumpReply<'_> {
2167 pub fn lookup_attr(
2168 &self,
2169 offset: usize,
2170 missing_type: Option<u16>,
2171 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2172 let mut stack = Vec::new();
2173 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2174 if cur == offset + PushIfaddrmsg::len() {
2175 stack.push(("OpGetaddrDumpReply", offset));
2176 return (
2177 stack,
2178 missing_type.and_then(|t| OpGetaddrDumpReply::attr_from_type(t)),
2179 );
2180 }
2181 if cur > offset || cur + self.buf.len() < offset {
2182 return (stack, None);
2183 }
2184 let mut attrs = self.clone();
2185 let mut last_off = cur + attrs.pos;
2186 while let Some(attr) = attrs.next() {
2187 let Ok(attr) = attr else { break };
2188 match attr {
2189 OpGetaddrDumpReply::Address(val) => {
2190 if last_off == offset {
2191 stack.push(("Address", last_off));
2192 break;
2193 }
2194 }
2195 OpGetaddrDumpReply::Local(val) => {
2196 if last_off == offset {
2197 stack.push(("Local", last_off));
2198 break;
2199 }
2200 }
2201 OpGetaddrDumpReply::Label(val) => {
2202 if last_off == offset {
2203 stack.push(("Label", last_off));
2204 break;
2205 }
2206 }
2207 OpGetaddrDumpReply::Cacheinfo(val) => {
2208 if last_off == offset {
2209 stack.push(("Cacheinfo", last_off));
2210 break;
2211 }
2212 }
2213 OpGetaddrDumpReply::Flags(val) => {
2214 if last_off == offset {
2215 stack.push(("Flags", last_off));
2216 break;
2217 }
2218 }
2219 _ => {}
2220 };
2221 last_off = cur + attrs.pos;
2222 }
2223 if !stack.is_empty() {
2224 stack.push(("OpGetaddrDumpReply", cur));
2225 }
2226 (stack, None)
2227 }
2228}
2229#[derive(Debug)]
2230pub struct RequestOpGetaddrDumpRequest<'r> {
2231 request: Request<'r>,
2232}
2233impl<'r> RequestOpGetaddrDumpRequest<'r> {
2234 pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
2235 PushOpGetaddrDumpRequest::write_header(&mut request.buf_mut(), header);
2236 Self {
2237 request: request.set_dump(),
2238 }
2239 }
2240 pub fn encode(&mut self) -> PushOpGetaddrDumpRequest<&mut Vec<u8>> {
2241 PushOpGetaddrDumpRequest::new_without_header(self.request.buf_mut())
2242 }
2243 pub fn into_encoder(self) -> PushOpGetaddrDumpRequest<RequestBuf<'r>> {
2244 PushOpGetaddrDumpRequest::new_without_header(self.request.buf)
2245 }
2246 pub fn decode_request<'buf>(
2247 buf: &'buf [u8],
2248 ) -> (PushIfaddrmsg, IterableOpGetaddrDumpRequest<'buf>) {
2249 OpGetaddrDumpRequest::new(buf)
2250 }
2251}
2252impl NetlinkRequest for RequestOpGetaddrDumpRequest<'_> {
2253 fn protocol(&self) -> Protocol {
2254 Protocol::Raw {
2255 protonum: 0u16,
2256 request_type: 22u16,
2257 }
2258 }
2259 fn flags(&self) -> u16 {
2260 self.request.flags
2261 }
2262 fn payload(&self) -> &[u8] {
2263 self.request.buf()
2264 }
2265 type ReplyType<'buf> = (PushIfaddrmsg, IterableOpGetaddrDumpReply<'buf>);
2266 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2267 OpGetaddrDumpReply::new(buf)
2268 }
2269 fn lookup(
2270 buf: &[u8],
2271 offset: usize,
2272 missing_type: Option<u16>,
2273 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2274 OpGetaddrDumpRequest::new(buf)
2275 .1
2276 .lookup_attr(offset, missing_type)
2277 }
2278}
2279#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2280pub struct PushOpGetmulticastDumpRequest<Prev: Rec> {
2281 pub(crate) prev: Option<Prev>,
2282 pub(crate) header_offset: Option<usize>,
2283}
2284impl<Prev: Rec> Rec for PushOpGetmulticastDumpRequest<Prev> {
2285 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2286 self.prev.as_mut().unwrap().as_rec_mut()
2287 }
2288 fn as_rec(&self) -> &Vec<u8> {
2289 self.prev.as_ref().unwrap().as_rec()
2290 }
2291}
2292impl<Prev: Rec> PushOpGetmulticastDumpRequest<Prev> {
2293 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
2294 Self::write_header(&mut prev, header);
2295 Self::new_without_header(prev)
2296 }
2297 fn new_without_header(prev: Prev) -> Self {
2298 Self {
2299 prev: Some(prev),
2300 header_offset: None,
2301 }
2302 }
2303 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
2304 prev.as_rec_mut().extend(header.as_slice());
2305 }
2306 pub fn end_nested(mut self) -> Prev {
2307 let mut prev = self.prev.take().unwrap();
2308 if let Some(header_offset) = &self.header_offset {
2309 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2310 }
2311 prev
2312 }
2313}
2314impl<Prev: Rec> Drop for PushOpGetmulticastDumpRequest<Prev> {
2315 fn drop(&mut self) {
2316 if let Some(prev) = &mut self.prev {
2317 if let Some(header_offset) = &self.header_offset {
2318 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2319 }
2320 }
2321 }
2322}
2323#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2324#[derive(Clone)]
2325pub enum OpGetmulticastDumpRequest {}
2326impl<'a> IterableOpGetmulticastDumpRequest<'a> {}
2327impl OpGetmulticastDumpRequest {
2328 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetmulticastDumpRequest<'a>) {
2329 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2330 (
2331 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2332 IterableOpGetmulticastDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
2333 )
2334 }
2335 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2336 AddrAttrs::attr_from_type(r#type)
2337 }
2338}
2339#[derive(Clone, Copy, Default)]
2340pub struct IterableOpGetmulticastDumpRequest<'a> {
2341 buf: &'a [u8],
2342 pos: usize,
2343 orig_loc: usize,
2344}
2345impl<'a> IterableOpGetmulticastDumpRequest<'a> {
2346 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2347 Self {
2348 buf,
2349 pos: 0,
2350 orig_loc,
2351 }
2352 }
2353 pub fn get_buf(&self) -> &'a [u8] {
2354 self.buf
2355 }
2356}
2357impl<'a> Iterator for IterableOpGetmulticastDumpRequest<'a> {
2358 type Item = Result<OpGetmulticastDumpRequest, ErrorContext>;
2359 fn next(&mut self) -> Option<Self::Item> {
2360 let pos = self.pos;
2361 let mut r#type;
2362 loop {
2363 r#type = None;
2364 if self.buf.len() == self.pos {
2365 return None;
2366 }
2367 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2368 break;
2369 };
2370 r#type = Some(header.r#type);
2371 let res = match header.r#type {
2372 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2373 n => continue,
2374 };
2375 return Some(Ok(res));
2376 }
2377 Some(Err(ErrorContext::new(
2378 "OpGetmulticastDumpRequest",
2379 r#type.and_then(|t| OpGetmulticastDumpRequest::attr_from_type(t)),
2380 self.orig_loc,
2381 self.buf.as_ptr().wrapping_add(pos) as usize,
2382 )))
2383 }
2384}
2385impl std::fmt::Debug for IterableOpGetmulticastDumpRequest<'_> {
2386 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2387 let mut fmt = f.debug_struct("OpGetmulticastDumpRequest");
2388 for attr in self.clone() {
2389 let attr = match attr {
2390 Ok(a) => a,
2391 Err(err) => {
2392 fmt.finish()?;
2393 f.write_str("Err(")?;
2394 err.fmt(f)?;
2395 return f.write_str(")");
2396 }
2397 };
2398 match attr {};
2399 }
2400 fmt.finish()
2401 }
2402}
2403impl IterableOpGetmulticastDumpRequest<'_> {
2404 pub fn lookup_attr(
2405 &self,
2406 offset: usize,
2407 missing_type: Option<u16>,
2408 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2409 let mut stack = Vec::new();
2410 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2411 if cur == offset + PushIfaddrmsg::len() {
2412 stack.push(("OpGetmulticastDumpRequest", offset));
2413 return (
2414 stack,
2415 missing_type.and_then(|t| OpGetmulticastDumpRequest::attr_from_type(t)),
2416 );
2417 }
2418 (stack, None)
2419 }
2420}
2421#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2422pub struct PushOpGetmulticastDumpReply<Prev: Rec> {
2423 pub(crate) prev: Option<Prev>,
2424 pub(crate) header_offset: Option<usize>,
2425}
2426impl<Prev: Rec> Rec for PushOpGetmulticastDumpReply<Prev> {
2427 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2428 self.prev.as_mut().unwrap().as_rec_mut()
2429 }
2430 fn as_rec(&self) -> &Vec<u8> {
2431 self.prev.as_ref().unwrap().as_rec()
2432 }
2433}
2434impl<Prev: Rec> PushOpGetmulticastDumpReply<Prev> {
2435 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
2436 Self::write_header(&mut prev, header);
2437 Self::new_without_header(prev)
2438 }
2439 fn new_without_header(prev: Prev) -> Self {
2440 Self {
2441 prev: Some(prev),
2442 header_offset: None,
2443 }
2444 }
2445 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
2446 prev.as_rec_mut().extend(header.as_slice());
2447 }
2448 pub fn end_nested(mut self) -> Prev {
2449 let mut prev = self.prev.take().unwrap();
2450 if let Some(header_offset) = &self.header_offset {
2451 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2452 }
2453 prev
2454 }
2455 pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
2456 push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
2457 self.as_rec_mut().extend(value.as_slice());
2458 self
2459 }
2460 pub fn push_multicast(mut self, value: &[u8]) -> Self {
2461 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
2462 self.as_rec_mut().extend(value);
2463 self
2464 }
2465}
2466impl<Prev: Rec> Drop for PushOpGetmulticastDumpReply<Prev> {
2467 fn drop(&mut self) {
2468 if let Some(prev) = &mut self.prev {
2469 if let Some(header_offset) = &self.header_offset {
2470 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2471 }
2472 }
2473 }
2474}
2475#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2476#[derive(Clone)]
2477pub enum OpGetmulticastDumpReply<'a> {
2478 Cacheinfo(PushIfaCacheinfo),
2479 Multicast(&'a [u8]),
2480}
2481impl<'a> IterableOpGetmulticastDumpReply<'a> {
2482 pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
2483 let mut iter = self.clone();
2484 iter.pos = 0;
2485 for attr in iter {
2486 if let OpGetmulticastDumpReply::Cacheinfo(val) = attr? {
2487 return Ok(val);
2488 }
2489 }
2490 Err(ErrorContext::new_missing(
2491 "OpGetmulticastDumpReply",
2492 "Cacheinfo",
2493 self.orig_loc,
2494 self.buf.as_ptr() as usize,
2495 ))
2496 }
2497 pub fn get_multicast(&self) -> Result<&'a [u8], ErrorContext> {
2498 let mut iter = self.clone();
2499 iter.pos = 0;
2500 for attr in iter {
2501 if let OpGetmulticastDumpReply::Multicast(val) = attr? {
2502 return Ok(val);
2503 }
2504 }
2505 Err(ErrorContext::new_missing(
2506 "OpGetmulticastDumpReply",
2507 "Multicast",
2508 self.orig_loc,
2509 self.buf.as_ptr() as usize,
2510 ))
2511 }
2512}
2513impl OpGetmulticastDumpReply<'_> {
2514 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetmulticastDumpReply<'a>) {
2515 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2516 (
2517 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2518 IterableOpGetmulticastDumpReply::with_loc(attrs, buf.as_ptr() as usize),
2519 )
2520 }
2521 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2522 AddrAttrs::attr_from_type(r#type)
2523 }
2524}
2525#[derive(Clone, Copy, Default)]
2526pub struct IterableOpGetmulticastDumpReply<'a> {
2527 buf: &'a [u8],
2528 pos: usize,
2529 orig_loc: usize,
2530}
2531impl<'a> IterableOpGetmulticastDumpReply<'a> {
2532 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2533 Self {
2534 buf,
2535 pos: 0,
2536 orig_loc,
2537 }
2538 }
2539 pub fn get_buf(&self) -> &'a [u8] {
2540 self.buf
2541 }
2542}
2543impl<'a> Iterator for IterableOpGetmulticastDumpReply<'a> {
2544 type Item = Result<OpGetmulticastDumpReply<'a>, ErrorContext>;
2545 fn next(&mut self) -> Option<Self::Item> {
2546 let pos = self.pos;
2547 let mut r#type;
2548 loop {
2549 r#type = None;
2550 if self.buf.len() == self.pos {
2551 return None;
2552 }
2553 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2554 break;
2555 };
2556 r#type = Some(header.r#type);
2557 let res = match header.r#type {
2558 6u16 => OpGetmulticastDumpReply::Cacheinfo({
2559 let res = PushIfaCacheinfo::new_from_slice(next);
2560 let Some(val) = res else { break };
2561 val
2562 }),
2563 7u16 => OpGetmulticastDumpReply::Multicast({
2564 let res = Some(next);
2565 let Some(val) = res else { break };
2566 val
2567 }),
2568 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2569 n => continue,
2570 };
2571 return Some(Ok(res));
2572 }
2573 Some(Err(ErrorContext::new(
2574 "OpGetmulticastDumpReply",
2575 r#type.and_then(|t| OpGetmulticastDumpReply::attr_from_type(t)),
2576 self.orig_loc,
2577 self.buf.as_ptr().wrapping_add(pos) as usize,
2578 )))
2579 }
2580}
2581impl<'a> std::fmt::Debug for IterableOpGetmulticastDumpReply<'_> {
2582 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2583 let mut fmt = f.debug_struct("OpGetmulticastDumpReply");
2584 for attr in self.clone() {
2585 let attr = match attr {
2586 Ok(a) => a,
2587 Err(err) => {
2588 fmt.finish()?;
2589 f.write_str("Err(")?;
2590 err.fmt(f)?;
2591 return f.write_str(")");
2592 }
2593 };
2594 match attr {
2595 OpGetmulticastDumpReply::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
2596 OpGetmulticastDumpReply::Multicast(val) => fmt.field("Multicast", &val),
2597 };
2598 }
2599 fmt.finish()
2600 }
2601}
2602impl IterableOpGetmulticastDumpReply<'_> {
2603 pub fn lookup_attr(
2604 &self,
2605 offset: usize,
2606 missing_type: Option<u16>,
2607 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2608 let mut stack = Vec::new();
2609 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2610 if cur == offset + PushIfaddrmsg::len() {
2611 stack.push(("OpGetmulticastDumpReply", offset));
2612 return (
2613 stack,
2614 missing_type.and_then(|t| OpGetmulticastDumpReply::attr_from_type(t)),
2615 );
2616 }
2617 if cur > offset || cur + self.buf.len() < offset {
2618 return (stack, None);
2619 }
2620 let mut attrs = self.clone();
2621 let mut last_off = cur + attrs.pos;
2622 while let Some(attr) = attrs.next() {
2623 let Ok(attr) = attr else { break };
2624 match attr {
2625 OpGetmulticastDumpReply::Cacheinfo(val) => {
2626 if last_off == offset {
2627 stack.push(("Cacheinfo", last_off));
2628 break;
2629 }
2630 }
2631 OpGetmulticastDumpReply::Multicast(val) => {
2632 if last_off == offset {
2633 stack.push(("Multicast", last_off));
2634 break;
2635 }
2636 }
2637 _ => {}
2638 };
2639 last_off = cur + attrs.pos;
2640 }
2641 if !stack.is_empty() {
2642 stack.push(("OpGetmulticastDumpReply", cur));
2643 }
2644 (stack, None)
2645 }
2646}
2647#[derive(Debug)]
2648pub struct RequestOpGetmulticastDumpRequest<'r> {
2649 request: Request<'r>,
2650}
2651impl<'r> RequestOpGetmulticastDumpRequest<'r> {
2652 pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
2653 PushOpGetmulticastDumpRequest::write_header(&mut request.buf_mut(), header);
2654 Self {
2655 request: request.set_dump(),
2656 }
2657 }
2658 pub fn encode(&mut self) -> PushOpGetmulticastDumpRequest<&mut Vec<u8>> {
2659 PushOpGetmulticastDumpRequest::new_without_header(self.request.buf_mut())
2660 }
2661 pub fn into_encoder(self) -> PushOpGetmulticastDumpRequest<RequestBuf<'r>> {
2662 PushOpGetmulticastDumpRequest::new_without_header(self.request.buf)
2663 }
2664 pub fn decode_request<'buf>(
2665 buf: &'buf [u8],
2666 ) -> (PushIfaddrmsg, IterableOpGetmulticastDumpRequest<'buf>) {
2667 OpGetmulticastDumpRequest::new(buf)
2668 }
2669}
2670impl NetlinkRequest for RequestOpGetmulticastDumpRequest<'_> {
2671 fn protocol(&self) -> Protocol {
2672 Protocol::Raw {
2673 protonum: 0u16,
2674 request_type: 58u16,
2675 }
2676 }
2677 fn flags(&self) -> u16 {
2678 self.request.flags
2679 }
2680 fn payload(&self) -> &[u8] {
2681 self.request.buf()
2682 }
2683 type ReplyType<'buf> = (PushIfaddrmsg, IterableOpGetmulticastDumpReply<'buf>);
2684 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2685 OpGetmulticastDumpReply::new(buf)
2686 }
2687 fn lookup(
2688 buf: &[u8],
2689 offset: usize,
2690 missing_type: Option<u16>,
2691 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2692 OpGetmulticastDumpRequest::new(buf)
2693 .1
2694 .lookup_attr(offset, missing_type)
2695 }
2696}
2697#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2698pub struct PushOpGetmulticastDoRequest<Prev: Rec> {
2699 pub(crate) prev: Option<Prev>,
2700 pub(crate) header_offset: Option<usize>,
2701}
2702impl<Prev: Rec> Rec for PushOpGetmulticastDoRequest<Prev> {
2703 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2704 self.prev.as_mut().unwrap().as_rec_mut()
2705 }
2706 fn as_rec(&self) -> &Vec<u8> {
2707 self.prev.as_ref().unwrap().as_rec()
2708 }
2709}
2710impl<Prev: Rec> PushOpGetmulticastDoRequest<Prev> {
2711 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
2712 Self::write_header(&mut prev, header);
2713 Self::new_without_header(prev)
2714 }
2715 fn new_without_header(prev: Prev) -> Self {
2716 Self {
2717 prev: Some(prev),
2718 header_offset: None,
2719 }
2720 }
2721 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
2722 prev.as_rec_mut().extend(header.as_slice());
2723 }
2724 pub fn end_nested(mut self) -> Prev {
2725 let mut prev = self.prev.take().unwrap();
2726 if let Some(header_offset) = &self.header_offset {
2727 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2728 }
2729 prev
2730 }
2731}
2732impl<Prev: Rec> Drop for PushOpGetmulticastDoRequest<Prev> {
2733 fn drop(&mut self) {
2734 if let Some(prev) = &mut self.prev {
2735 if let Some(header_offset) = &self.header_offset {
2736 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2737 }
2738 }
2739 }
2740}
2741#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2742#[derive(Clone)]
2743pub enum OpGetmulticastDoRequest {}
2744impl<'a> IterableOpGetmulticastDoRequest<'a> {}
2745impl OpGetmulticastDoRequest {
2746 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetmulticastDoRequest<'a>) {
2747 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2748 (
2749 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2750 IterableOpGetmulticastDoRequest::with_loc(attrs, buf.as_ptr() as usize),
2751 )
2752 }
2753 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2754 AddrAttrs::attr_from_type(r#type)
2755 }
2756}
2757#[derive(Clone, Copy, Default)]
2758pub struct IterableOpGetmulticastDoRequest<'a> {
2759 buf: &'a [u8],
2760 pos: usize,
2761 orig_loc: usize,
2762}
2763impl<'a> IterableOpGetmulticastDoRequest<'a> {
2764 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2765 Self {
2766 buf,
2767 pos: 0,
2768 orig_loc,
2769 }
2770 }
2771 pub fn get_buf(&self) -> &'a [u8] {
2772 self.buf
2773 }
2774}
2775impl<'a> Iterator for IterableOpGetmulticastDoRequest<'a> {
2776 type Item = Result<OpGetmulticastDoRequest, ErrorContext>;
2777 fn next(&mut self) -> Option<Self::Item> {
2778 let pos = self.pos;
2779 let mut r#type;
2780 loop {
2781 r#type = None;
2782 if self.buf.len() == self.pos {
2783 return None;
2784 }
2785 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2786 break;
2787 };
2788 r#type = Some(header.r#type);
2789 let res = match header.r#type {
2790 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2791 n => continue,
2792 };
2793 return Some(Ok(res));
2794 }
2795 Some(Err(ErrorContext::new(
2796 "OpGetmulticastDoRequest",
2797 r#type.and_then(|t| OpGetmulticastDoRequest::attr_from_type(t)),
2798 self.orig_loc,
2799 self.buf.as_ptr().wrapping_add(pos) as usize,
2800 )))
2801 }
2802}
2803impl std::fmt::Debug for IterableOpGetmulticastDoRequest<'_> {
2804 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2805 let mut fmt = f.debug_struct("OpGetmulticastDoRequest");
2806 for attr in self.clone() {
2807 let attr = match attr {
2808 Ok(a) => a,
2809 Err(err) => {
2810 fmt.finish()?;
2811 f.write_str("Err(")?;
2812 err.fmt(f)?;
2813 return f.write_str(")");
2814 }
2815 };
2816 match attr {};
2817 }
2818 fmt.finish()
2819 }
2820}
2821impl IterableOpGetmulticastDoRequest<'_> {
2822 pub fn lookup_attr(
2823 &self,
2824 offset: usize,
2825 missing_type: Option<u16>,
2826 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2827 let mut stack = Vec::new();
2828 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2829 if cur == offset + PushIfaddrmsg::len() {
2830 stack.push(("OpGetmulticastDoRequest", offset));
2831 return (
2832 stack,
2833 missing_type.and_then(|t| OpGetmulticastDoRequest::attr_from_type(t)),
2834 );
2835 }
2836 (stack, None)
2837 }
2838}
2839#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2840pub struct PushOpGetmulticastDoReply<Prev: Rec> {
2841 pub(crate) prev: Option<Prev>,
2842 pub(crate) header_offset: Option<usize>,
2843}
2844impl<Prev: Rec> Rec for PushOpGetmulticastDoReply<Prev> {
2845 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2846 self.prev.as_mut().unwrap().as_rec_mut()
2847 }
2848 fn as_rec(&self) -> &Vec<u8> {
2849 self.prev.as_ref().unwrap().as_rec()
2850 }
2851}
2852impl<Prev: Rec> PushOpGetmulticastDoReply<Prev> {
2853 pub fn new(mut prev: Prev, header: &PushIfaddrmsg) -> Self {
2854 Self::write_header(&mut prev, header);
2855 Self::new_without_header(prev)
2856 }
2857 fn new_without_header(prev: Prev) -> Self {
2858 Self {
2859 prev: Some(prev),
2860 header_offset: None,
2861 }
2862 }
2863 fn write_header(prev: &mut Prev, header: &PushIfaddrmsg) {
2864 prev.as_rec_mut().extend(header.as_slice());
2865 }
2866 pub fn end_nested(mut self) -> Prev {
2867 let mut prev = self.prev.take().unwrap();
2868 if let Some(header_offset) = &self.header_offset {
2869 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2870 }
2871 prev
2872 }
2873 pub fn push_cacheinfo(mut self, value: PushIfaCacheinfo) -> Self {
2874 push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
2875 self.as_rec_mut().extend(value.as_slice());
2876 self
2877 }
2878 pub fn push_multicast(mut self, value: &[u8]) -> Self {
2879 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
2880 self.as_rec_mut().extend(value);
2881 self
2882 }
2883}
2884impl<Prev: Rec> Drop for PushOpGetmulticastDoReply<Prev> {
2885 fn drop(&mut self) {
2886 if let Some(prev) = &mut self.prev {
2887 if let Some(header_offset) = &self.header_offset {
2888 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2889 }
2890 }
2891 }
2892}
2893#[doc = "Get / dump IPv4/IPv6 multicast addresses."]
2894#[derive(Clone)]
2895pub enum OpGetmulticastDoReply<'a> {
2896 Cacheinfo(PushIfaCacheinfo),
2897 Multicast(&'a [u8]),
2898}
2899impl<'a> IterableOpGetmulticastDoReply<'a> {
2900 pub fn get_cacheinfo(&self) -> Result<PushIfaCacheinfo, ErrorContext> {
2901 let mut iter = self.clone();
2902 iter.pos = 0;
2903 for attr in iter {
2904 if let OpGetmulticastDoReply::Cacheinfo(val) = attr? {
2905 return Ok(val);
2906 }
2907 }
2908 Err(ErrorContext::new_missing(
2909 "OpGetmulticastDoReply",
2910 "Cacheinfo",
2911 self.orig_loc,
2912 self.buf.as_ptr() as usize,
2913 ))
2914 }
2915 pub fn get_multicast(&self) -> Result<&'a [u8], ErrorContext> {
2916 let mut iter = self.clone();
2917 iter.pos = 0;
2918 for attr in iter {
2919 if let OpGetmulticastDoReply::Multicast(val) = attr? {
2920 return Ok(val);
2921 }
2922 }
2923 Err(ErrorContext::new_missing(
2924 "OpGetmulticastDoReply",
2925 "Multicast",
2926 self.orig_loc,
2927 self.buf.as_ptr() as usize,
2928 ))
2929 }
2930}
2931impl OpGetmulticastDoReply<'_> {
2932 pub fn new<'a>(buf: &'a [u8]) -> (PushIfaddrmsg, IterableOpGetmulticastDoReply<'a>) {
2933 let (header, attrs) = buf.split_at(buf.len().min(PushIfaddrmsg::len()));
2934 (
2935 PushIfaddrmsg::new_from_slice(header).unwrap_or_default(),
2936 IterableOpGetmulticastDoReply::with_loc(attrs, buf.as_ptr() as usize),
2937 )
2938 }
2939 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2940 AddrAttrs::attr_from_type(r#type)
2941 }
2942}
2943#[derive(Clone, Copy, Default)]
2944pub struct IterableOpGetmulticastDoReply<'a> {
2945 buf: &'a [u8],
2946 pos: usize,
2947 orig_loc: usize,
2948}
2949impl<'a> IterableOpGetmulticastDoReply<'a> {
2950 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2951 Self {
2952 buf,
2953 pos: 0,
2954 orig_loc,
2955 }
2956 }
2957 pub fn get_buf(&self) -> &'a [u8] {
2958 self.buf
2959 }
2960}
2961impl<'a> Iterator for IterableOpGetmulticastDoReply<'a> {
2962 type Item = Result<OpGetmulticastDoReply<'a>, ErrorContext>;
2963 fn next(&mut self) -> Option<Self::Item> {
2964 let pos = self.pos;
2965 let mut r#type;
2966 loop {
2967 r#type = None;
2968 if self.buf.len() == self.pos {
2969 return None;
2970 }
2971 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2972 break;
2973 };
2974 r#type = Some(header.r#type);
2975 let res = match header.r#type {
2976 6u16 => OpGetmulticastDoReply::Cacheinfo({
2977 let res = PushIfaCacheinfo::new_from_slice(next);
2978 let Some(val) = res else { break };
2979 val
2980 }),
2981 7u16 => OpGetmulticastDoReply::Multicast({
2982 let res = Some(next);
2983 let Some(val) = res else { break };
2984 val
2985 }),
2986 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2987 n => continue,
2988 };
2989 return Some(Ok(res));
2990 }
2991 Some(Err(ErrorContext::new(
2992 "OpGetmulticastDoReply",
2993 r#type.and_then(|t| OpGetmulticastDoReply::attr_from_type(t)),
2994 self.orig_loc,
2995 self.buf.as_ptr().wrapping_add(pos) as usize,
2996 )))
2997 }
2998}
2999impl<'a> std::fmt::Debug for IterableOpGetmulticastDoReply<'_> {
3000 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3001 let mut fmt = f.debug_struct("OpGetmulticastDoReply");
3002 for attr in self.clone() {
3003 let attr = match attr {
3004 Ok(a) => a,
3005 Err(err) => {
3006 fmt.finish()?;
3007 f.write_str("Err(")?;
3008 err.fmt(f)?;
3009 return f.write_str(")");
3010 }
3011 };
3012 match attr {
3013 OpGetmulticastDoReply::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
3014 OpGetmulticastDoReply::Multicast(val) => fmt.field("Multicast", &val),
3015 };
3016 }
3017 fmt.finish()
3018 }
3019}
3020impl IterableOpGetmulticastDoReply<'_> {
3021 pub fn lookup_attr(
3022 &self,
3023 offset: usize,
3024 missing_type: Option<u16>,
3025 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3026 let mut stack = Vec::new();
3027 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3028 if cur == offset + PushIfaddrmsg::len() {
3029 stack.push(("OpGetmulticastDoReply", offset));
3030 return (
3031 stack,
3032 missing_type.and_then(|t| OpGetmulticastDoReply::attr_from_type(t)),
3033 );
3034 }
3035 if cur > offset || cur + self.buf.len() < offset {
3036 return (stack, None);
3037 }
3038 let mut attrs = self.clone();
3039 let mut last_off = cur + attrs.pos;
3040 while let Some(attr) = attrs.next() {
3041 let Ok(attr) = attr else { break };
3042 match attr {
3043 OpGetmulticastDoReply::Cacheinfo(val) => {
3044 if last_off == offset {
3045 stack.push(("Cacheinfo", last_off));
3046 break;
3047 }
3048 }
3049 OpGetmulticastDoReply::Multicast(val) => {
3050 if last_off == offset {
3051 stack.push(("Multicast", last_off));
3052 break;
3053 }
3054 }
3055 _ => {}
3056 };
3057 last_off = cur + attrs.pos;
3058 }
3059 if !stack.is_empty() {
3060 stack.push(("OpGetmulticastDoReply", cur));
3061 }
3062 (stack, None)
3063 }
3064}
3065#[derive(Debug)]
3066pub struct RequestOpGetmulticastDoRequest<'r> {
3067 request: Request<'r>,
3068}
3069impl<'r> RequestOpGetmulticastDoRequest<'r> {
3070 pub fn new(mut request: Request<'r>, header: &PushIfaddrmsg) -> Self {
3071 PushOpGetmulticastDoRequest::write_header(&mut request.buf_mut(), header);
3072 Self { request: request }
3073 }
3074 pub fn encode(&mut self) -> PushOpGetmulticastDoRequest<&mut Vec<u8>> {
3075 PushOpGetmulticastDoRequest::new_without_header(self.request.buf_mut())
3076 }
3077 pub fn into_encoder(self) -> PushOpGetmulticastDoRequest<RequestBuf<'r>> {
3078 PushOpGetmulticastDoRequest::new_without_header(self.request.buf)
3079 }
3080 pub fn decode_request<'buf>(
3081 buf: &'buf [u8],
3082 ) -> (PushIfaddrmsg, IterableOpGetmulticastDoRequest<'buf>) {
3083 OpGetmulticastDoRequest::new(buf)
3084 }
3085}
3086impl NetlinkRequest for RequestOpGetmulticastDoRequest<'_> {
3087 fn protocol(&self) -> Protocol {
3088 Protocol::Raw {
3089 protonum: 0u16,
3090 request_type: 58u16,
3091 }
3092 }
3093 fn flags(&self) -> u16 {
3094 self.request.flags
3095 }
3096 fn payload(&self) -> &[u8] {
3097 self.request.buf()
3098 }
3099 type ReplyType<'buf> = (PushIfaddrmsg, IterableOpGetmulticastDoReply<'buf>);
3100 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
3101 OpGetmulticastDoReply::new(buf)
3102 }
3103 fn lookup(
3104 buf: &[u8],
3105 offset: usize,
3106 missing_type: Option<u16>,
3107 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3108 OpGetmulticastDoRequest::new(buf)
3109 .1
3110 .lookup_attr(offset, missing_type)
3111 }
3112}
3113#[derive(Debug)]
3114pub struct ChainedFinal<'a> {
3115 inner: Chained<'a>,
3116}
3117#[derive(Debug)]
3118pub struct Chained<'a> {
3119 buf: RequestBuf<'a>,
3120 first_seq: u32,
3121 lookups: Vec<(&'static str, LookupFn)>,
3122 last_header_offset: usize,
3123 last_kind: Option<RequestInfo>,
3124}
3125impl<'a> ChainedFinal<'a> {
3126 pub fn into_chained(self) -> Chained<'a> {
3127 self.inner
3128 }
3129 pub fn buf(&self) -> &Vec<u8> {
3130 self.inner.buf()
3131 }
3132 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
3133 self.inner.buf_mut()
3134 }
3135 fn get_index(&self, seq: u32) -> Option<u32> {
3136 let min = self.inner.first_seq;
3137 let max = min.wrapping_add(self.inner.lookups.len() as u32);
3138 return if min <= max {
3139 (min..max).contains(&seq).then(|| seq - min)
3140 } else if min <= seq {
3141 Some(seq - min)
3142 } else if seq < max {
3143 Some(u32::MAX - min + seq)
3144 } else {
3145 None
3146 };
3147 }
3148}
3149impl crate::traits::NetlinkChained for ChainedFinal<'_> {
3150 fn protonum(&self) -> u16 {
3151 PROTONUM
3152 }
3153 fn payload(&self) -> &[u8] {
3154 self.buf()
3155 }
3156 fn chain_len(&self) -> usize {
3157 self.inner.lookups.len()
3158 }
3159 fn get_index(&self, seq: u32) -> Option<usize> {
3160 self.get_index(seq).map(|n| n as usize)
3161 }
3162 fn name(&self, index: usize) -> &'static str {
3163 self.inner.lookups[index].0
3164 }
3165 fn lookup(&self, index: usize) -> LookupFn {
3166 self.inner.lookups[index].1
3167 }
3168}
3169impl Chained<'static> {
3170 pub fn new(first_seq: u32) -> Self {
3171 Self::new_from_buf(Vec::new(), first_seq)
3172 }
3173 pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
3174 Self {
3175 buf: RequestBuf::Own(buf),
3176 first_seq,
3177 lookups: Vec::new(),
3178 last_header_offset: 0,
3179 last_kind: None,
3180 }
3181 }
3182 pub fn into_buf(self) -> Vec<u8> {
3183 match self.buf {
3184 RequestBuf::Own(buf) => buf,
3185 _ => unreachable!(),
3186 }
3187 }
3188}
3189impl<'a> Chained<'a> {
3190 pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
3191 Self {
3192 buf: RequestBuf::Ref(buf),
3193 first_seq,
3194 lookups: Vec::new(),
3195 last_header_offset: 0,
3196 last_kind: None,
3197 }
3198 }
3199 pub fn finalize(mut self) -> ChainedFinal<'a> {
3200 self.update_header();
3201 ChainedFinal { inner: self }
3202 }
3203 pub fn request(&mut self) -> Request<'_> {
3204 self.update_header();
3205 self.last_header_offset = self.buf().len();
3206 self.buf_mut()
3207 .extend_from_slice(PushNlmsghdr::new().as_slice());
3208 let mut request = Request::new_extend(self.buf.buf_mut());
3209 self.last_kind = None;
3210 request.writeback = Some(&mut self.last_kind);
3211 request
3212 }
3213 pub fn buf(&self) -> &Vec<u8> {
3214 self.buf.buf()
3215 }
3216 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
3217 self.buf.buf_mut()
3218 }
3219 fn update_header(&mut self) {
3220 let Some(RequestInfo {
3221 protocol,
3222 flags,
3223 name,
3224 lookup,
3225 }) = self.last_kind
3226 else {
3227 if !self.buf().is_empty() {
3228 assert_eq!(
3229 self.last_header_offset + PushNlmsghdr::len(),
3230 self.buf().len()
3231 );
3232 self.buf.buf_mut().truncate(self.last_header_offset);
3233 }
3234 return;
3235 };
3236 let header_offset = self.last_header_offset;
3237 let request_type = match protocol {
3238 Protocol::Raw { request_type, .. } => request_type,
3239 Protocol::Generic(_) => unreachable!(),
3240 };
3241 let index = self.lookups.len();
3242 let seq = self.first_seq.wrapping_add(index as u32);
3243 self.lookups.push((name, lookup));
3244 let buf = self.buf_mut();
3245 align(buf);
3246 let mut header = PushNlmsghdr::new();
3247 header.set_len((buf.len() - header_offset) as u32);
3248 header.set_type(request_type);
3249 header.set_flags(flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16);
3250 header.set_seq(seq);
3251 buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
3252 }
3253}
3254use crate::traits::LookupFn;
3255use crate::utils::RequestBuf;
3256#[derive(Debug)]
3257pub struct Request<'buf> {
3258 buf: RequestBuf<'buf>,
3259 flags: u16,
3260 writeback: Option<&'buf mut Option<RequestInfo>>,
3261}
3262#[allow(unused)]
3263#[derive(Debug, Clone)]
3264pub struct RequestInfo {
3265 protocol: Protocol,
3266 flags: u16,
3267 name: &'static str,
3268 lookup: LookupFn,
3269}
3270impl Request<'static> {
3271 pub fn new() -> Self {
3272 Self::new_from_buf(Vec::new())
3273 }
3274 pub fn new_from_buf(buf: Vec<u8>) -> Self {
3275 Self {
3276 flags: 0,
3277 buf: RequestBuf::Own(buf),
3278 writeback: None,
3279 }
3280 }
3281 pub fn into_buf(self) -> Vec<u8> {
3282 match self.buf {
3283 RequestBuf::Own(buf) => buf,
3284 _ => unreachable!(),
3285 }
3286 }
3287}
3288impl<'buf> Request<'buf> {
3289 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
3290 buf.clear();
3291 Self::new_extend(buf)
3292 }
3293 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
3294 Self {
3295 flags: 0,
3296 buf: RequestBuf::Ref(buf),
3297 writeback: None,
3298 }
3299 }
3300 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
3301 let Some(writeback) = &mut self.writeback else {
3302 return;
3303 };
3304 **writeback = Some(RequestInfo {
3305 protocol,
3306 flags: self.flags,
3307 name,
3308 lookup,
3309 })
3310 }
3311 pub fn buf(&self) -> &Vec<u8> {
3312 self.buf.buf()
3313 }
3314 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
3315 self.buf.buf_mut()
3316 }
3317 #[doc = "Set `NLM_F_CREATE` flag"]
3318 pub fn set_create(mut self) -> Self {
3319 self.flags |= consts::NLM_F_CREATE as u16;
3320 self
3321 }
3322 #[doc = "Set `NLM_F_EXCL` flag"]
3323 pub fn set_excl(mut self) -> Self {
3324 self.flags |= consts::NLM_F_EXCL as u16;
3325 self
3326 }
3327 #[doc = "Set `NLM_F_REPLACE` flag"]
3328 pub fn set_replace(mut self) -> Self {
3329 self.flags |= consts::NLM_F_REPLACE as u16;
3330 self
3331 }
3332 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
3333 pub fn set_change(self) -> Self {
3334 self.set_create().set_replace()
3335 }
3336 #[doc = "Set `NLM_F_APPEND` flag"]
3337 pub fn set_append(mut self) -> Self {
3338 self.flags |= consts::NLM_F_APPEND as u16;
3339 self
3340 }
3341 #[doc = "Set `NLM_F_DUMP` flag"]
3342 fn set_dump(mut self) -> Self {
3343 self.flags |= consts::NLM_F_DUMP as u16;
3344 self
3345 }
3346 pub fn op_newaddr_do_request(self, header: &PushIfaddrmsg) -> RequestOpNewaddrDoRequest<'buf> {
3347 let mut res = RequestOpNewaddrDoRequest::new(self, header);
3348 res.request.do_writeback(
3349 res.protocol(),
3350 "op-newaddr-do-request",
3351 RequestOpNewaddrDoRequest::lookup,
3352 );
3353 res
3354 }
3355 pub fn op_deladdr_do_request(self, header: &PushIfaddrmsg) -> RequestOpDeladdrDoRequest<'buf> {
3356 let mut res = RequestOpDeladdrDoRequest::new(self, header);
3357 res.request.do_writeback(
3358 res.protocol(),
3359 "op-deladdr-do-request",
3360 RequestOpDeladdrDoRequest::lookup,
3361 );
3362 res
3363 }
3364 pub fn op_getaddr_dump_request(
3365 self,
3366 header: &PushIfaddrmsg,
3367 ) -> RequestOpGetaddrDumpRequest<'buf> {
3368 let mut res = RequestOpGetaddrDumpRequest::new(self, header);
3369 res.request.do_writeback(
3370 res.protocol(),
3371 "op-getaddr-dump-request",
3372 RequestOpGetaddrDumpRequest::lookup,
3373 );
3374 res
3375 }
3376 pub fn op_getmulticast_dump_request(
3377 self,
3378 header: &PushIfaddrmsg,
3379 ) -> RequestOpGetmulticastDumpRequest<'buf> {
3380 let mut res = RequestOpGetmulticastDumpRequest::new(self, header);
3381 res.request.do_writeback(
3382 res.protocol(),
3383 "op-getmulticast-dump-request",
3384 RequestOpGetmulticastDumpRequest::lookup,
3385 );
3386 res
3387 }
3388 pub fn op_getmulticast_do_request(
3389 self,
3390 header: &PushIfaddrmsg,
3391 ) -> RequestOpGetmulticastDoRequest<'buf> {
3392 let mut res = RequestOpGetmulticastDoRequest::new(self, header);
3393 res.request.do_writeback(
3394 res.protocol(),
3395 "op-getmulticast-do-request",
3396 RequestOpGetmulticastDoRequest::lookup,
3397 );
3398 res
3399 }
3400}