1use crate::err::{ParseAttributeError, ParseDeviceError, ParseIpAddrError, ParseSockAddrError};
2use crate::get::{AllowedIp, AllowedIpBuilder, Device, DeviceBuilder, Peer, PeerBuilder};
3use crate::linux::attr::{
4 NlaNested, WgAllowedIpAttribute, WgDeviceAttribute, WgPeerAttribute, NLA_TYPE_MASK,
5};
6use libc::{in6_addr, in_addr, AF_INET, AF_INET6};
7use neli::{
8 attr,
9 genl::Nlattr,
10 types::{Buffer, GenlBuffer},
11};
12use std::convert::TryFrom;
13use std::mem::size_of;
14use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
15use std::time::Duration;
16
17type AttrHandle<'a, T> = attr::AttrHandle<'a, GenlBuffer<T, Buffer>, Nlattr<T, Buffer>>;
18
19impl TryFrom<AttrHandle<'_, WgDeviceAttribute>> for Device {
20 type Error = ParseDeviceError;
21
22 fn try_from(handle: AttrHandle<WgDeviceAttribute>) -> Result<Self, Self::Error> {
23 let mut device_builder = DeviceBuilder::default();
24
25 for attr in handle.iter() {
26 match attr.nla_type.nla_type & NLA_TYPE_MASK {
27 WgDeviceAttribute::Unspec => {
28 }
30 WgDeviceAttribute::Ifindex => {
31 device_builder.ifindex(parse_nla_u32(attr.nla_payload.as_ref())?);
32 }
33 WgDeviceAttribute::Ifname => {
34 device_builder.ifname(parse_nla_nul_string(attr.nla_payload.as_ref())?);
35 }
36 WgDeviceAttribute::PrivateKey => {
37 device_builder.private_key(Some(parse_device_key(attr.nla_payload.as_ref())?));
38 }
39 WgDeviceAttribute::PublicKey => {
40 device_builder.public_key(Some(parse_device_key(attr.nla_payload.as_ref())?));
41 }
42 WgDeviceAttribute::ListenPort => {
43 device_builder.listen_port(parse_nla_u16(attr.nla_payload.as_ref())?);
44 }
45 WgDeviceAttribute::Fwmark => {
46 device_builder.fwmark(parse_nla_u32(attr.nla_payload.as_ref())?);
47 }
48 WgDeviceAttribute::Peers => {
49 device_builder.peers(parse_peers(attr.get_attr_handle::<NlaNested>()?)?);
50 }
51 WgDeviceAttribute::Flags => {
52 }
54 WgDeviceAttribute::UnrecognizedConst(i) => {
55 return Err(ParseDeviceError::UnknownDeviceAttributeError { id: i })
56 }
57 }
58 }
59
60 Ok(device_builder.build()?)
61 }
62}
63
64pub fn extend_device(
65 mut device: Device,
66 handle: AttrHandle<'_, WgDeviceAttribute>,
67) -> Result<Device, ParseDeviceError> {
68 let next_peers = {
69 let peers_attr = handle
70 .iter()
71 .find(|attr| attr.nla_type.nla_type & NLA_TYPE_MASK == WgDeviceAttribute::Peers)
72 .expect("Unable to find additional peers to coalesce.");
73 let handle = peers_attr.get_attr_handle()?;
74
75 handle
76 .iter()
77 .map(Nlattr::<NlaNested, Buffer>::get_attr_handle::<WgPeerAttribute>)
78 .map(|handle| {
79 handle
80 .map_err(|err| err.into())
81 .and_then(parse_peer_builder)
82 })
83 .collect::<Result<Vec<PeerBuilder>, _>>()?
84 };
85
86 for next_peer in next_peers {
87 let matching_last_peer = device
88 .peers
89 .last_mut()
90 .filter(|last_peer| Some(last_peer.public_key) == next_peer.public_key);
91
92 match matching_last_peer {
93 Some(matching_last_peer) => matching_last_peer
94 .allowed_ips
95 .append(&mut next_peer.allowed_ips.unwrap_or_default()),
96 None => device.peers.push(next_peer.build()?),
97 }
98 }
99
100 Ok(device)
101}
102
103pub fn parse_peers(handle: AttrHandle<'_, NlaNested>) -> Result<Vec<Peer>, ParseDeviceError> {
104 let mut peers = vec![];
105
106 for peer in handle.iter() {
107 let handle = peer.get_attr_handle()?;
108 peers.push(Peer::try_from(handle)?);
109 }
110
111 Ok(peers)
112}
113
114pub fn parse_peer_builder(
115 handle: AttrHandle<'_, WgPeerAttribute>,
116) -> Result<PeerBuilder, ParseDeviceError> {
117 let mut peer_builder = PeerBuilder::default();
118
119 for attr in handle.iter() {
120 match attr.nla_type.nla_type & NLA_TYPE_MASK {
121 WgPeerAttribute::Unspec => {}
122 WgPeerAttribute::Flags => {}
123 WgPeerAttribute::PublicKey => {
124 peer_builder.public_key(parse_device_key(attr.nla_payload.as_ref())?);
125 }
126 WgPeerAttribute::PresharedKey => {
127 peer_builder.preshared_key(parse_device_key(attr.nla_payload.as_ref())?);
128 }
129 WgPeerAttribute::Endpoint => {
130 peer_builder.endpoint(Some(parse_sockaddr_in(attr.nla_payload.as_ref())?));
131 }
132 WgPeerAttribute::PersistentKeepaliveInterval => {
133 peer_builder
134 .persistent_keepalive_interval(parse_nla_u16(attr.nla_payload.as_ref())?);
135 }
136 WgPeerAttribute::LastHandshakeTime => {
137 peer_builder
138 .last_handshake_time(parse_last_handshake_time(attr.nla_payload.as_ref())?);
139 }
140 WgPeerAttribute::RxBytes => {
141 peer_builder.rx_bytes(parse_nla_u64(attr.nla_payload.as_ref())?);
142 }
143 WgPeerAttribute::TxBytes => {
144 peer_builder.tx_bytes(parse_nla_u64(attr.nla_payload.as_ref())?);
145 }
146 WgPeerAttribute::AllowedIps => {
147 let handle = attr.get_attr_handle()?;
148 peer_builder.allowed_ips(parse_allowedips(handle)?);
149 }
150 WgPeerAttribute::ProtocolVersion => {
151 peer_builder.protocol_version(parse_nla_u32(attr.nla_payload.as_ref())?);
152 }
153 WgPeerAttribute::UnrecognizedConst(i) => {
154 return Err(ParseDeviceError::UnknownPeerAttributeError { id: i })
155 }
156 }
157 }
158
159 Ok(peer_builder)
160}
161
162impl TryFrom<AttrHandle<'_, WgPeerAttribute>> for Peer {
163 type Error = ParseDeviceError;
164 fn try_from(handle: AttrHandle<'_, WgPeerAttribute>) -> Result<Self, Self::Error> {
165 let peer_builder = parse_peer_builder(handle)?;
166 Ok(peer_builder.build()?)
167 }
168}
169
170pub fn parse_allowedips(
171 handle: AttrHandle<'_, NlaNested>,
172) -> Result<Vec<AllowedIp>, ParseDeviceError> {
173 let mut allowed_ips = vec![];
174
175 for allowed_ip in handle.iter() {
176 allowed_ips.push(AllowedIp::try_from(
177 allowed_ip.get_attr_handle::<WgAllowedIpAttribute>()?,
178 )?);
179 }
180
181 Ok(allowed_ips)
182}
183
184impl TryFrom<AttrHandle<'_, WgAllowedIpAttribute>> for AllowedIp {
185 type Error = ParseDeviceError;
186
187 fn try_from(handle: AttrHandle<'_, WgAllowedIpAttribute>) -> Result<Self, Self::Error> {
188 let mut allowed_ip_builder = AllowedIpBuilder::default();
189
190 for attr in handle.iter() {
191 let payload = attr.nla_payload.as_ref();
192 match attr.nla_type.nla_type {
193 WgAllowedIpAttribute::Unspec => {}
194 WgAllowedIpAttribute::Family => {
195 allowed_ip_builder.family(parse_nla_u16(payload)?);
196 }
197 WgAllowedIpAttribute::IpAddr => {
198 let addr = match payload.len() {
199 len if len == size_of::<in_addr>() => IpAddr::V4(parse_in_addr(payload)?),
200 len if len == size_of::<in6_addr>() => IpAddr::V6(parse_in6_addr(payload)?),
201 len => {
202 return Err(ParseDeviceError::from(ParseAttributeError::from(
203 ParseIpAddrError::InvalidIpAddrLengthError { found: len },
204 )))
205 }
206 };
207 allowed_ip_builder.ipaddr(addr);
208 }
209 WgAllowedIpAttribute::CidrMask => {
210 allowed_ip_builder.cidr_mask(parse_nla_u8(payload)?);
211 }
212 WgAllowedIpAttribute::UnrecognizedConst(i) => {
213 return Err(ParseDeviceError::UnknownAllowedIpAttributeError { id: i })
214 }
215 }
216 }
217
218 Ok(allowed_ip_builder.build()?)
219 }
220}
221
222macro_rules! create_parse_nla_int {
223 ($func_name: ident, $int_type: ident, $bytes: expr) => {
224 pub fn $func_name(buf: &[u8]) -> Result<$int_type, ParseAttributeError> {
225 Some(buf.len())
226 .filter(|&len| len == $bytes)
227 .ok_or_else(|| ParseAttributeError::StaticLengthError {
228 expected: $bytes,
229 found: buf.len(),
230 })?;
231
232 let mut arr = [0u8; $bytes];
233 arr.copy_from_slice(&buf);
234 Ok($int_type::from_ne_bytes(arr))
235 }
236 };
237}
238
239create_parse_nla_int!(parse_nla_u8, u8, size_of::<u8>());
240create_parse_nla_int!(parse_nla_u16, u16, size_of::<u16>());
241create_parse_nla_int!(parse_nla_u32, u32, size_of::<u32>());
242create_parse_nla_int!(parse_nla_u64, u64, size_of::<u64>());
243create_parse_nla_int!(parse_nla_i64, i64, size_of::<i64>());
244
245pub fn parse_nla_u16_be(buf: &[u8]) -> Result<u16, ParseAttributeError> {
246 Some(buf.len()).filter(|&len| len == 2).ok_or({
247 ParseAttributeError::StaticLengthError {
248 expected: 2,
249 found: buf.len(),
250 }
251 })?;
252
253 let mut arr = [0u8; 2];
254 arr.copy_from_slice(buf);
255 Ok(u16::from_be_bytes(arr))
256}
257
258pub fn parse_nla_nul_string(payload: &[u8]) -> Result<String, ParseAttributeError> {
259 let mut payload = payload.to_vec();
263
264 payload
265 .pop()
266 .filter(|char| char == &0)
267 .ok_or(ParseAttributeError::InvalidCStringError)?;
268
269 Ok(String::from_utf8(payload)?)
270}
271
272pub fn parse_device_key(buf: &[u8]) -> Result<[u8; 32], ParseAttributeError> {
273 Some(buf.len()).filter(|&len| len == 32).ok_or({
274 ParseAttributeError::StaticLengthError {
275 expected: 32,
276 found: buf.len(),
277 }
278 })?;
279
280 let mut key = [0u8; 32];
281 key.copy_from_slice(buf);
282 Ok(key)
283}
284
285pub fn parse_sockaddr_in(buf: &[u8]) -> Result<SocketAddr, ParseAttributeError> {
286 let family = parse_nla_u16(&buf[0..2])?;
287
288 let port = parse_nla_u16_be(&buf[2..4])?;
290
291 let addr = match libc::c_int::from(family) {
292 AF_INET => IpAddr::V4(parse_in_addr(&buf[4..8])?),
293 AF_INET6 => IpAddr::V6(parse_in6_addr(&buf[8..24])?),
294 id => return Err(ParseSockAddrError::UnrecognizedAddressFamilyError { id }.into()),
295 };
296
297 Ok(SocketAddr::new(addr, port))
298}
299
300pub fn parse_last_handshake_time(buf: &[u8]) -> Result<Duration, ParseAttributeError> {
301 Some(buf.len()).filter(|&len| len == 16).ok_or({
302 ParseAttributeError::StaticLengthError {
303 expected: 16,
304 found: buf.len(),
305 }
306 })?;
307
308 let secs = parse_nla_i64(&buf[0..8])?;
314 let secs = u64::try_from(secs)?;
315 let nanos = parse_nla_i64(&buf[8..16])?;
316 let nanos = u32::try_from(nanos)?;
317
318 Ok(Duration::new(secs, nanos))
319}
320
321pub fn parse_in_addr(buf: &[u8]) -> Result<Ipv4Addr, ParseAttributeError> {
322 Some(buf.len()).filter(|&len| len == 4).ok_or({
324 ParseAttributeError::StaticLengthError {
325 expected: 4,
326 found: buf.len(),
327 }
328 })?;
329 Ok(Ipv4Addr::new(buf[0], buf[1], buf[2], buf[3]))
330}
331
332pub fn parse_in6_addr(buf: &[u8]) -> Result<Ipv6Addr, ParseAttributeError> {
333 Some(buf.len()).filter(|&len| len == 16).ok_or({
335 ParseAttributeError::StaticLengthError {
336 expected: 16,
337 found: buf.len(),
338 }
339 })?;
340 Ok(Ipv6Addr::new(
341 parse_nla_u16_be(&buf[0..2])?,
342 parse_nla_u16_be(&buf[2..4])?,
343 parse_nla_u16_be(&buf[4..6])?,
344 parse_nla_u16_be(&buf[6..8])?,
345 parse_nla_u16_be(&buf[8..10])?,
346 parse_nla_u16_be(&buf[10..12])?,
347 parse_nla_u16_be(&buf[12..14])?,
348 parse_nla_u16_be(&buf[14..16])?,
349 ))
350}
351
352#[cfg(test)]
353mod tests {
354 use super::*;
355 use crate::linux::cmd::WgCmd;
356 use anyhow::Error;
357 use neli::{err::DeError, genl::Genlmsghdr};
358
359 fn get_device_from_man() -> anyhow::Result<Device> {
363 Ok(Device {
364 ifindex: 6,
365 ifname: "test".to_string(),
366 private_key: Some(parse_device_key(&base64::decode(
367 "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=",
368 )?)?),
369 public_key: Some(parse_device_key(&base64::decode(
370 "HIgo9xNzJMWLKASShiTqIybxZ0U3wGLiUeJ1PKf8ykw=",
371 )?)?),
372 listen_port: 51820,
373 fwmark: 0,
374 peers: vec![
375 Peer {
376 public_key: parse_device_key(&base64::decode(
377 "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg",
378 )?)?,
379 preshared_key: [0u8; 32],
380 endpoint: Some("192.95.5.67:1234".parse()?),
381 persistent_keepalive_interval: 0,
382 last_handshake_time: Duration::new(0, 0),
383 rx_bytes: 0,
384 tx_bytes: 0,
385 allowed_ips: vec![
386 AllowedIp {
387 family: libc::AF_INET as u16,
388 ipaddr: "10.192.122.3".parse()?,
389 cidr_mask: 32,
390 },
391 AllowedIp {
392 family: libc::AF_INET as u16,
393 ipaddr: "10.192.124.0".parse()?,
394 cidr_mask: 24,
395 },
396 ],
397 protocol_version: 1,
398 },
399 Peer {
400 public_key: parse_device_key(&base64::decode(
401 "TrMvSoP4jYQlY6RIzBgbssQqY3vxI2Pi+y71lOWWXX0=",
402 )?)?,
403 preshared_key: [0u8; 32],
404 endpoint: Some("[2607:5300:60:6b0::c05f:543]:2468".parse()?),
405 persistent_keepalive_interval: 0,
406 last_handshake_time: Duration::new(0, 0),
407 rx_bytes: 0,
408 tx_bytes: 0,
409 allowed_ips: vec![
410 AllowedIp {
411 family: libc::AF_INET as u16,
412 ipaddr: "10.192.122.4".parse()?,
413 cidr_mask: 32,
414 },
415 AllowedIp {
416 family: libc::AF_INET as u16,
417 ipaddr: "192.168.0.0".parse()?,
418 cidr_mask: 16,
419 },
420 ],
421 protocol_version: 1,
422 },
423 ],
424 })
425 }
426
427 fn create_test_genlmsghdr(
428 payload: &[u8],
429 ) -> Result<Genlmsghdr<WgCmd, WgDeviceAttribute>, DeError> {
430 use neli::FromBytesWithInput;
431 Genlmsghdr::from_bytes_with_input(&mut std::io::Cursor::new(payload), payload.len())
432 }
433
434 #[test]
435 fn parse_device_example_from_man_page() -> Result<(), Error> {
436 let payload = vec![
437 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x6c, 0xca, 0x00, 0x00, 0x08, 0x00,
438 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00,
439 0x09, 0x00, 0x02, 0x00, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00,
440 0x03, 0x00, 0xc8, 0x09, 0xf3, 0xe5, 0x31, 0x7e, 0x95, 0x75, 0xc9, 0xb5, 0xed, 0x78,
441 0xb6, 0x38, 0xb7, 0xce, 0x53, 0x0d, 0xab, 0xe8, 0x5d, 0xda, 0xb6, 0x14, 0x22, 0x02,
442 0x41, 0x80, 0x1d, 0xdf, 0x06, 0x69, 0x24, 0x00, 0x04, 0x00, 0x1c, 0x88, 0x28, 0xf7,
443 0x13, 0x73, 0x24, 0xc5, 0x8b, 0x28, 0x04, 0x92, 0x86, 0x24, 0xea, 0x23, 0x26, 0xf1,
444 0x67, 0x45, 0x37, 0xc0, 0x62, 0xe2, 0x51, 0xe2, 0x75, 0x3c, 0xa7, 0xfc, 0xca, 0x4c,
445 0xc0, 0x01, 0x08, 0x80, 0xd8, 0x00, 0x00, 0x80, 0x24, 0x00, 0x01, 0x00, 0xc5, 0x32,
446 0x01, 0x03, 0x9a, 0xdb, 0xa1, 0x4b, 0xe7, 0x1f, 0x88, 0x6d, 0xa1, 0xd8, 0xdb, 0xe9,
447 0xee, 0xbd, 0xed, 0x08, 0xcb, 0x11, 0x1b, 0x75, 0x34, 0x00, 0x78, 0x99, 0x9a, 0xa9,
448 0xf0, 0x38, 0x24, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00,
455 0x14, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0xd2, 0xc0, 0x5f, 0x05, 0x43, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x09, 0x80, 0x1c, 0x00, 0x00, 0x80,
457 0x05, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x02, 0x00,
458 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0xc0, 0x7a, 0x03, 0x1c, 0x00, 0x00, 0x80,
459 0x05, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x02, 0x00,
460 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0xc0, 0x7c, 0x00, 0xe4, 0x00, 0x00, 0x80,
461 0x24, 0x00, 0x01, 0x00, 0x4e, 0xb3, 0x2f, 0x4a, 0x83, 0xf8, 0x8d, 0x84, 0x25, 0x63,
462 0xa4, 0x48, 0xcc, 0x18, 0x1b, 0xb2, 0xc4, 0x2a, 0x63, 0x7b, 0xf1, 0x23, 0x63, 0xe2,
463 0xfb, 0x2e, 0xf5, 0x94, 0xe5, 0x96, 0x5d, 0x7d, 0x24, 0x00, 0x02, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x0c, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
470 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x09, 0xa4,
471 0x00, 0x00, 0x00, 0x00, 0x26, 0x07, 0x53, 0x00, 0x00, 0x60, 0x06, 0xb0, 0x00, 0x00,
472 0x00, 0x00, 0xc0, 0x5f, 0x05, 0x43, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x09, 0x80,
473 0x1c, 0x00, 0x00, 0x80, 0x05, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00,
474 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0xc0, 0x7a, 0x04,
475 0x1c, 0x00, 0x00, 0x80, 0x05, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00,
476 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0xc0, 0xa8, 0x00, 0x00,
477 ];
478 let genlmsghdr = create_test_genlmsghdr(&payload)?;
479 let device = Device::try_from(genlmsghdr.get_attr_handle())?;
480
481 assert_eq!(device, get_device_from_man()?);
482
483 Ok(())
484 }
485
486 #[test]
489 fn parse_device_example_from_man_page_pre_five_point_two_kernel() -> Result<(), Error> {
490 let payload = vec![
491 1, 1, 0, 0, 6, 0, 6, 0, 108, 202, 0, 0, 8, 0, 7, 0, 0, 0, 0, 0, 8, 0, 1, 0, 6, 0, 0, 0,
492 9, 0, 2, 0, 116, 101, 115, 116, 0, 0, 0, 0, 36, 0, 3, 0, 200, 9, 243, 229, 49, 126,
493 149, 117, 201, 181, 237, 120, 182, 56, 183, 206, 83, 13, 171, 232, 93, 218, 182, 20,
494 34, 2, 65, 128, 29, 223, 6, 105, 36, 0, 4, 0, 28, 136, 40, 247, 19, 115, 36, 197, 139,
495 40, 4, 146, 134, 36, 234, 35, 38, 241, 103, 69, 55, 192, 98, 226, 81, 226, 117, 60,
496 167, 252, 202, 76, 192, 1, 8, 0, 216, 0, 0, 0, 36, 0, 1, 0, 197, 50, 1, 3, 154, 219,
497 161, 75, 231, 31, 136, 109, 161, 216, 219, 233, 238, 189, 237, 8, 203, 17, 27, 117, 52,
498 0, 120, 153, 154, 169, 240, 56, 36, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
499 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
500 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 5, 0, 0, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
501 12, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 10, 0, 1, 0, 0, 0, 20, 0, 4, 0, 2, 0, 4,
502 210, 192, 95, 5, 67, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 9, 0, 28, 0, 0, 0, 5, 0, 3, 0, 32,
503 0, 0, 0, 6, 0, 1, 0, 2, 0, 0, 0, 8, 0, 2, 0, 10, 192, 122, 3, 28, 0, 0, 0, 5, 0, 3, 0,
504 24, 0, 0, 0, 6, 0, 1, 0, 2, 0, 0, 0, 8, 0, 2, 0, 10, 192, 124, 0, 228, 0, 0, 0, 36, 0,
505 1, 0, 78, 179, 47, 74, 131, 248, 141, 132, 37, 99, 164, 72, 204, 24, 27, 178, 196, 42,
506 99, 123, 241, 35, 99, 226, 251, 46, 245, 148, 229, 150, 93, 125, 36, 0, 2, 0, 0, 0, 0,
507 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
508 20, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 5, 0, 0, 0, 0, 0,
509 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 10, 0,
510 1, 0, 0, 0, 32, 0, 4, 0, 10, 0, 9, 164, 0, 0, 0, 0, 38, 7, 83, 0, 0, 96, 6, 176, 0, 0,
511 0, 0, 192, 95, 5, 67, 0, 0, 0, 0, 60, 0, 9, 0, 28, 0, 0, 0, 5, 0, 3, 0, 32, 0, 0, 0, 6,
512 0, 1, 0, 2, 0, 0, 0, 8, 0, 2, 0, 10, 192, 122, 4, 28, 0, 0, 0, 5, 0, 3, 0, 16, 0, 0, 0,
513 6, 0, 1, 0, 2, 0, 0, 0, 8, 0, 2, 0, 192, 168, 0, 0, 20, 0, 0, 0, 3, 0, 2, 0, 0, 0, 0,
514 0, 250, 117, 199, 159, 0, 0, 0, 0,
515 ];
516 let genlmsghdr = create_test_genlmsghdr(&payload)?;
517 let device = Device::try_from(genlmsghdr.get_attr_handle())?;
518
519 assert_eq!(device, get_device_from_man()?);
520
521 Ok(())
522 }
523
524 #[test]
525 fn parse_device_with_large_peer() -> Result<(), Error> {
526 let first_payload = [
527 0, 1, 0, 0, 6, 0, 6, 0, 108, 202, 0, 0, 8, 0, 7, 0, 0, 0, 0, 0, 8, 0, 1, 0, 6, 0, 0, 0,
528 9, 0, 2, 0, 116, 101, 115, 116, 0, 0, 0, 0, 36, 0, 3, 0, 200, 9, 243, 229, 49, 126,
529 149, 117, 201, 181, 237, 120, 182, 56, 183, 206, 83, 13, 171, 232, 93, 218, 182, 20,
530 34, 2, 65, 128, 29, 223, 6, 105, 36, 0, 4, 0, 28, 136, 40, 247, 19, 115, 36, 197, 139,
531 40, 4, 146, 134, 36, 234, 35, 38, 241, 103, 69, 55, 192, 98, 226, 81, 226, 117, 60,
532 167, 252, 202, 76, 60, 14, 8, 0, 56, 14, 0, 0, 36, 0, 1, 0, 197, 50, 1, 3, 154, 219,
533 161, 75, 231, 31, 136, 109, 161, 216, 219, 233, 238, 189, 237, 8, 203, 17, 27, 117, 52,
534 0, 120, 153, 154, 169, 240, 56, 36, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
535 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
536 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 5, 0, 0, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
537 12, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 10, 0, 1, 0, 0, 0, 20, 0, 4, 0, 2, 0, 4,
538 210, 192, 95, 5, 67, 0, 0, 0, 0, 0, 0, 0, 0, 156, 13, 9, 0, 40, 0, 0, 0, 5, 0, 3, 0,
539 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
540 0, 0, 0, 1, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2,
541 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0,
542 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
543 3, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0,
544 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0,
545 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 40, 0,
546 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0,
547 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
548 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 0, 0, 0, 5, 0,
549 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
550 0, 0, 0, 0, 0, 8, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
551 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 40, 0, 0, 0, 5, 0, 3, 0, 128,
552 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
553 0, 0, 10, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
554 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
555 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
556 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
557 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
558 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 40, 0, 0,
559 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
560 0, 0, 0, 0, 0, 0, 0, 0, 15, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
561 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 40, 0, 0, 0, 5, 0,
562 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563 0, 0, 0, 0, 0, 17, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
564 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 40, 0, 0, 0, 5, 0, 3, 0, 128,
565 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
566 0, 0, 19, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
567 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
568 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21,
569 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
570 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
571 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 40, 0, 0,
572 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
573 0, 0, 0, 0, 0, 0, 0, 0, 24, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
574 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 40, 0, 0, 0, 5, 0,
575 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
576 0, 0, 0, 0, 0, 26, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
577 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 40, 0, 0, 0, 5, 0, 3, 0, 128,
578 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
579 0, 0, 28, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
580 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
581 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
582 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
583 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
584 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 40, 0, 0,
585 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
586 0, 0, 0, 0, 0, 0, 0, 0, 33, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
587 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 40, 0, 0, 0, 5, 0,
588 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
589 0, 0, 0, 0, 0, 35, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
590 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 40, 0, 0, 0, 5, 0, 3, 0, 128,
591 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
592 0, 0, 37, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
593 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
594 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39,
595 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
596 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
597 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 40, 0, 0,
598 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
599 0, 0, 0, 0, 0, 0, 0, 0, 42, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
600 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 40, 0, 0, 0, 5, 0,
601 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
602 0, 0, 0, 0, 0, 44, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
603 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 40, 0, 0, 0, 5, 0, 3, 0, 128,
604 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605 0, 0, 46, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
606 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
607 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,
608 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
609 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
610 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 40, 0, 0,
611 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
612 0, 0, 0, 0, 0, 0, 0, 0, 51, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
613 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 40, 0, 0, 0, 5, 0,
614 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
615 0, 0, 0, 0, 0, 53, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
616 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 40, 0, 0, 0, 5, 0, 3, 0, 128,
617 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
618 0, 0, 55, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
619 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
620 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57,
621 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
622 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
623 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 40, 0, 0,
624 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
625 0, 0, 0, 0, 0, 0, 0, 0, 60, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
626 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 40, 0, 0, 0, 5, 0,
627 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
628 0, 0, 0, 0, 0, 62, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
629 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 40, 0, 0, 0, 5, 0, 3, 0, 128,
630 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
631 0, 0, 64, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
632 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
633 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66,
634 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
635 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
636 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 40, 0, 0,
637 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
638 0, 0, 0, 0, 0, 0, 0, 0, 69, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
639 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 40, 0, 0, 0, 5, 0,
640 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
641 0, 0, 0, 0, 0, 71, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
642 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 40, 0, 0, 0, 5, 0, 3, 0, 128,
643 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
644 0, 0, 73, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
645 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
646 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75,
647 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
648 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
649 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 40, 0, 0,
650 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
651 0, 0, 0, 0, 0, 0, 0, 0, 78, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
652 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 40, 0, 0, 0, 5, 0,
653 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
654 0, 0, 0, 0, 0, 80, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
655 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 40, 0, 0, 0, 5, 0, 3, 0, 128,
656 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
657 0, 0, 82, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0,
658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
659 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,
660 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
661 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1,
662 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 40, 0, 0,
663 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
664 0, 0, 0, 0, 0, 0, 0, 0, 87,
665 ];
666 let second_payload = [
667 0, 1, 0, 0, 6, 0, 6, 0, 108, 202, 0, 0, 8, 0, 7, 0, 0, 0, 0, 0, 8, 0, 1, 0, 6, 0, 0, 0,
668 9, 0, 2, 0, 116, 101, 115, 116, 0, 0, 0, 0, 36, 0, 3, 0, 200, 9, 243, 229, 49, 126,
669 149, 117, 201, 181, 237, 120, 182, 56, 183, 206, 83, 13, 171, 232, 93, 218, 182, 20,
670 34, 2, 65, 128, 29, 223, 6, 105, 36, 0, 4, 0, 28, 136, 40, 247, 19, 115, 36, 197, 139,
671 40, 4, 146, 134, 36, 234, 35, 38, 241, 103, 69, 55, 192, 98, 226, 81, 226, 117, 60,
672 167, 252, 202, 76, 8, 10, 8, 0, 4, 10, 0, 0, 36, 0, 1, 0, 197, 50, 1, 3, 154, 219, 161,
673 75, 231, 31, 136, 109, 161, 216, 219, 233, 238, 189, 237, 8, 203, 17, 27, 117, 52, 0,
674 120, 153, 154, 169, 240, 56, 220, 9, 9, 0, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0,
675 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 40, 0,
676 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0,
677 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10,
678 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 40, 0, 0, 0, 5,
679 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
680 0, 0, 0, 0, 0, 0, 91, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0,
681 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 40, 0, 0, 0, 5, 0, 3, 0,
682 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
683 0, 0, 0, 93, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2,
684 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0,
685 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
686 95, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0,
687 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0,
688 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 40, 0,
689 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0,
690 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10,
691 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 40, 0, 0, 0, 5,
692 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
693 0, 0, 0, 0, 0, 0, 100, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0,
694 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 40, 0, 0, 0, 5, 0, 3, 0,
695 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
696 0, 0, 0, 102, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2,
697 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0,
698 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
699 0, 104, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0,
700 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
701 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106,
702 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
703 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0,
704 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 40,
705 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0,
706 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0,
707 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 40, 0, 0,
708 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
709 0, 0, 0, 0, 0, 0, 0, 0, 111, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
710 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 40, 0, 0, 0, 5, 0,
711 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
712 0, 0, 0, 0, 0, 113, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
713 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 40, 0, 0, 0, 5, 0, 3, 0,
714 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
715 0, 0, 0, 115, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2,
716 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0,
717 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
718 0, 117, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0,
719 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
720 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119,
721 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
722 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0,
723 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 40,
724 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0,
725 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0,
726 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 40, 0, 0,
727 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
728 0, 0, 0, 0, 0, 0, 0, 0, 124, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
729 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 40, 0, 0, 0, 5, 0,
730 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
731 0, 0, 0, 0, 0, 126, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
732 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 40, 0, 0, 0, 5, 0, 3, 0,
733 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
734 0, 0, 0, 128, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2,
735 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0,
736 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
737 0, 130, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0,
738 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
739 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132,
740 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
741 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0,
742 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 40,
743 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0,
744 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0,
745 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 40, 0, 0,
746 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
747 0, 0, 0, 0, 0, 0, 0, 0, 137, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0,
748 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 40, 0, 0, 0, 5, 0,
749 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
750 0, 0, 0, 0, 0, 139, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20,
751 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 40, 0, 0, 0, 5, 0, 3, 0,
752 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
753 0, 0, 0, 141, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2,
754 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0,
755 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
756 0, 143, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0,
757 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0,
758 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145,
759 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0,
760 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0,
761 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 40,
762 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0,
763 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 40, 0, 0, 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0,
764 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 40, 0, 0,
765 0, 5, 0, 3, 0, 128, 0, 0, 0, 6, 0, 1, 0, 10, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
766 0, 0, 0, 0, 0, 0, 0, 0, 150,
767 ];
768
769 let genlmsghdr = create_test_genlmsghdr(&first_payload)?;
770 let device = Device::try_from(genlmsghdr.get_attr_handle())?;
771
772 let genlmsghdr = create_test_genlmsghdr(&second_payload)?;
773 let device = extend_device(device, genlmsghdr.get_attr_handle())?;
774
775 assert_eq!(
776 device,
777 Device {
778 ifindex: 6,
779 ifname: "test".to_string(),
780 private_key: Some(parse_device_key(&base64::decode(
781 "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk="
782 )?)?),
783 public_key: Some(parse_device_key(&base64::decode(
784 "HIgo9xNzJMWLKASShiTqIybxZ0U3wGLiUeJ1PKf8ykw="
785 )?)?),
786 listen_port: 51820,
787 fwmark: 0,
788 peers: vec![Peer {
789 public_key: parse_device_key(&base64::decode(
790 "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="
791 )?)?,
792 preshared_key: [0u8; 32],
793 endpoint: Some("192.95.5.67:1234".parse()?),
794 persistent_keepalive_interval: 0,
795 last_handshake_time: Duration::new(0, 0),
796 rx_bytes: 0,
797 tx_bytes: 0,
798 allowed_ips: (1..=150)
799 .step_by(1)
800 .map(|h| AllowedIp {
801 family: libc::AF_INET6 as u16,
802 ipaddr: IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, h)),
803 cidr_mask: 128,
804 })
805 .collect(),
806 protocol_version: 1,
807 }]
808 }
809 );
810
811 Ok(())
812 }
813}