netlink_packet_route/rtnl/link/nlas/
af_spec_inet.rs1use 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}