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