netlink_packet_route/rtnl/link/nlas/
af_spec_inet.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4use netlink_packet_utils::{
5    nla::{self, DefaultNla, NlaBuffer, NlasIterator},
6    traits::{Emitable, Parseable},
7    DecodeError,
8};
9
10use super::{inet, inet6};
11use crate::constants::*;
12
13#[derive(Clone, Eq, PartialEq, Debug)]
14#[non_exhaustive]
15pub enum AfSpecInet {
16    Unspec(Vec<u8>),
17    Unix(Vec<u8>),
18    Ax25(Vec<u8>),
19    Ipx(Vec<u8>),
20    AppleTalk(Vec<u8>),
21    Netrom(Vec<u8>),
22    Bridge(Vec<u8>),
23    AtmPvc(Vec<u8>),
24    X25(Vec<u8>),
25    Inet(Vec<inet::Inet>),
26    Inet6(Vec<inet6::Inet6>),
27    Rose(Vec<u8>),
28    DecNet(Vec<u8>),
29    NetbEui(Vec<u8>),
30    Security(Vec<u8>),
31    Key(Vec<u8>),
32    Netlink(Vec<u8>),
33    Packet(Vec<u8>),
34    Ash(Vec<u8>),
35    EcoNet(Vec<u8>),
36    AtmSvc(Vec<u8>),
37    Rds(Vec<u8>),
38    Sna(Vec<u8>),
39    Irda(Vec<u8>),
40    Pppox(Vec<u8>),
41    WanPipe(Vec<u8>),
42    Llc(Vec<u8>),
43    Can(Vec<u8>),
44    Tipc(Vec<u8>),
45    Bluetooth(Vec<u8>),
46    Iucv(Vec<u8>),
47    RxRpc(Vec<u8>),
48    Isdn(Vec<u8>),
49    Phonet(Vec<u8>),
50    Ieee802154(Vec<u8>),
51    Caif(Vec<u8>),
52    Alg(Vec<u8>),
53    Other(DefaultNla),
54}
55
56impl nla::Nla for AfSpecInet {
57    #[rustfmt::skip]
58    fn value_len(&self) -> usize {
59        use self::AfSpecInet::*;
60        match *self {
61            Unspec(ref bytes)
62                | Unix(ref bytes)
63                | Ax25(ref bytes)
64                | Ipx(ref bytes)
65                | AppleTalk(ref bytes)
66                | Netrom(ref bytes)
67                | Bridge(ref bytes)
68                | AtmPvc(ref bytes)
69                | X25(ref bytes)
70                | Rose(ref bytes)
71                | DecNet(ref bytes)
72                | NetbEui(ref bytes)
73                | Security(ref bytes)
74                | Key(ref bytes)
75                | Netlink(ref bytes)
76                | Packet(ref bytes)
77                | Ash(ref bytes)
78                | EcoNet(ref bytes)
79                | AtmSvc(ref bytes)
80                | Rds(ref bytes)
81                | Sna(ref bytes)
82                | Irda(ref bytes)
83                | Pppox(ref bytes)
84                | WanPipe(ref bytes)
85                | Llc(ref bytes)
86                | Can(ref bytes)
87                | Tipc(ref bytes)
88                | Bluetooth(ref bytes)
89                | Iucv(ref bytes)
90                | RxRpc(ref bytes)
91                | Isdn(ref bytes)
92                | Phonet(ref bytes)
93                | Ieee802154(ref bytes)
94                | Caif(ref bytes)
95                | Alg(ref bytes)
96                => bytes.len(),
97            Inet6(ref nlas) => nlas.as_slice().buffer_len(),
98            Inet(ref nlas) =>  nlas.as_slice().buffer_len(),
99            Other(ref nla) => nla.value_len(),
100        }
101    }
102
103    #[rustfmt::skip]
104    fn emit_value(&self, buffer: &mut [u8]) {
105        use self::AfSpecInet::*;
106        match *self {
107            Unspec(ref bytes)
108                | Unix(ref bytes)
109                | Ax25(ref bytes)
110                | Ipx(ref bytes)
111                | AppleTalk(ref bytes)
112                | Netrom(ref bytes)
113                | Bridge(ref bytes)
114                | AtmPvc(ref bytes)
115                | X25(ref bytes)
116                | Rose(ref bytes)
117                | DecNet(ref bytes)
118                | NetbEui(ref bytes)
119                | Security(ref bytes)
120                | Key(ref bytes)
121                | Netlink(ref bytes)
122                | Packet(ref bytes)
123                | Ash(ref bytes)
124                | EcoNet(ref bytes)
125                | AtmSvc(ref bytes)
126                | Rds(ref bytes)
127                | Sna(ref bytes)
128                | Irda(ref bytes)
129                | Pppox(ref bytes)
130                | WanPipe(ref bytes)
131                | Llc(ref bytes)
132                | Can(ref bytes)
133                | Tipc(ref bytes)
134                | Bluetooth(ref bytes)
135                | Iucv(ref bytes)
136                | RxRpc(ref bytes)
137                | Isdn(ref bytes)
138                | Phonet(ref bytes)
139                | Ieee802154(ref bytes)
140                | Caif(ref bytes)
141                | Alg(ref bytes)
142                => buffer[..bytes.len()].copy_from_slice(bytes.as_slice()),
143            Inet6(ref nlas) => nlas.as_slice().emit(buffer),
144            Inet(ref nlas) => nlas.as_slice().emit(buffer),
145            Other(ref nla)  => nla.emit_value(buffer),
146        }
147    }
148
149    fn kind(&self) -> u16 {
150        use self::AfSpecInet::*;
151        match *self {
152            Inet(_) => AF_INET,
153            Unspec(_) => AF_UNSPEC,
154            Unix(_) => AF_UNIX,
155            Ax25(_) => AF_AX25,
156            Ipx(_) => AF_IPX,
157            AppleTalk(_) => AF_APPLETALK,
158            Netrom(_) => AF_NETROM,
159            Bridge(_) => AF_BRIDGE,
160            AtmPvc(_) => AF_ATMPVC,
161            X25(_) => AF_X25,
162            Inet6(_) => AF_INET6,
163            Rose(_) => AF_ROSE,
164            DecNet(_) => AF_DECNET,
165            NetbEui(_) => AF_NETBEUI,
166            Security(_) => AF_SECURITY,
167            Key(_) => AF_KEY,
168            Netlink(_) => AF_NETLINK,
169            Packet(_) => AF_PACKET,
170            Ash(_) => AF_ASH,
171            EcoNet(_) => AF_ECONET,
172            AtmSvc(_) => AF_ATMSVC,
173            Rds(_) => AF_RDS,
174            Sna(_) => AF_SNA,
175            Irda(_) => AF_IRDA,
176            Pppox(_) => AF_PPPOX,
177            WanPipe(_) => AF_WANPIPE,
178            Llc(_) => AF_LLC,
179            Can(_) => AF_CAN,
180            Tipc(_) => AF_TIPC,
181            Bluetooth(_) => AF_BLUETOOTH,
182            Iucv(_) => AF_IUCV,
183            RxRpc(_) => AF_RXRPC,
184            Isdn(_) => AF_ISDN,
185            Phonet(_) => AF_PHONET,
186            Ieee802154(_) => AF_IEEE802154,
187            Caif(_) => AF_CAIF,
188            Alg(_) => AF_ALG,
189            Other(ref nla) => nla.kind(),
190        }
191    }
192}
193
194impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for AfSpecInet {
195    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
196        use self::AfSpecInet::*;
197
198        let payload = buf.value();
199        Ok(match buf.kind() {
200            AF_UNSPEC => Unspec(payload.to_vec()),
201            AF_INET => {
202                let mut nlas = vec![];
203                for nla in NlasIterator::new(payload) {
204                    let nla = nla.context("invalid AF_INET value")?;
205                    nlas.push(
206                        inet::Inet::parse(&nla)
207                            .context("invalid AF_INET value")?,
208                    );
209                }
210                Inet(nlas)
211            }
212            AF_INET6 => {
213                let mut nlas = vec![];
214                for nla in NlasIterator::new(payload) {
215                    let nla = nla.context("invalid AF_INET6 value")?;
216                    nlas.push(
217                        inet6::Inet6::parse(&nla)
218                            .context("invalid AF_INET6 value")?,
219                    );
220                }
221                Inet6(nlas)
222            }
223            AF_UNIX => Unix(payload.to_vec()),
224            AF_AX25 => Ax25(payload.to_vec()),
225            AF_IPX => Ipx(payload.to_vec()),
226            AF_APPLETALK => AppleTalk(payload.to_vec()),
227            AF_NETROM => Netrom(payload.to_vec()),
228            AF_BRIDGE => Bridge(payload.to_vec()),
229            AF_ATMPVC => AtmPvc(payload.to_vec()),
230            AF_X25 => X25(payload.to_vec()),
231            AF_ROSE => Rose(payload.to_vec()),
232            AF_DECNET => DecNet(payload.to_vec()),
233            AF_NETBEUI => NetbEui(payload.to_vec()),
234            AF_SECURITY => Security(payload.to_vec()),
235            AF_KEY => Key(payload.to_vec()),
236            AF_NETLINK => Netlink(payload.to_vec()),
237            AF_PACKET => Packet(payload.to_vec()),
238            AF_ASH => Ash(payload.to_vec()),
239            AF_ECONET => EcoNet(payload.to_vec()),
240            AF_ATMSVC => AtmSvc(payload.to_vec()),
241            AF_RDS => Rds(payload.to_vec()),
242            AF_SNA => Sna(payload.to_vec()),
243            AF_IRDA => Irda(payload.to_vec()),
244            AF_PPPOX => Pppox(payload.to_vec()),
245            AF_WANPIPE => WanPipe(payload.to_vec()),
246            AF_LLC => Llc(payload.to_vec()),
247            AF_CAN => Can(payload.to_vec()),
248            AF_TIPC => Tipc(payload.to_vec()),
249            AF_BLUETOOTH => Bluetooth(payload.to_vec()),
250            AF_IUCV => Iucv(payload.to_vec()),
251            AF_RXRPC => RxRpc(payload.to_vec()),
252            AF_ISDN => Isdn(payload.to_vec()),
253            AF_PHONET => Phonet(payload.to_vec()),
254            AF_IEEE802154 => Ieee802154(payload.to_vec()),
255            AF_CAIF => Caif(payload.to_vec()),
256            AF_ALG => Alg(payload.to_vec()),
257            kind => Other(
258                DefaultNla::parse(buf)
259                    .context(format!("Unknown NLA type {kind}"))?,
260            ),
261        })
262    }
263}