Skip to main content

net_declare/
lib.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Macros for constructing networking address types from the standard library,
6//! FIDL, and [`net_types`] from human-readable representations.
7
8#![no_std]
9
10pub use fidl_fuchsia_net_common as fnet_common;
11
12/// Declares an [`std::net::IpAddr`] from a parsable IP address (either V4 or
13/// V6) string.
14pub use net_declare_macros::std_ip;
15/// Declares an [`std::net::Ipv4Addr`] from a parsable IPv4 address string.
16pub use net_declare_macros::std_ip_v4;
17/// Declares an [`std::net::Ipv6Addr`] from a parsable IPv6 address string.
18pub use net_declare_macros::std_ip_v6;
19/// Declares an [`std::net::SocketAddr`] from a parsable IP address + port
20/// string (either V4 or V6).
21///
22/// NOTE: `std::net::SocketAddrV6` does not support parsing scope_id from
23/// strings, meaning the generated IPv6 socket address will always have
24/// `scope_id=0`. See [Rust issue 1992].
25///
26/// [Rust issue 1992]: https://github.com/rust-lang/rfcs/issues/1992
27pub use net_declare_macros::std_socket_addr;
28/// Declares an [`std::net::SocketAddrV4`] from a parsable IPv4 address + port
29/// in the form `addr:port`.
30pub use net_declare_macros::std_socket_addr_v4;
31/// Declares an [`std::net::SocketAddrV6`] from a parsable IPv6 address + port
32/// in the form `[addr]:port`.
33///
34/// NOTE: `std::net::SocketAddrV6` does not support parsing scope_id from
35/// strings, meaning the generated IPv6 socket address will always have
36/// `scope_id=0`. See [Rust issue 1992].
37///
38/// [Rust issue 1992]: https://github.com/rust-lang/rfcs/issues/1992
39pub use net_declare_macros::std_socket_addr_v6;
40
41/// Declares a [`fidl_fuchsia_net::IpAddress`] from a parsable IP address
42/// (either V4 or V6) string.
43pub use net_declare_macros::fidl_ip;
44/// Declares a [`fidl_fuchsia_net::Ipv4Address`] from a parsable IPv4 address
45/// string.
46pub use net_declare_macros::fidl_ip_v4;
47/// Declares a [`fidl_fuchsia_net::Ipv4AddressWithPrefix`] from a parsable IPv4
48/// + prefix length string, e.g. `192.168.0.1/24`.
49pub use net_declare_macros::fidl_ip_v4_with_prefix;
50/// Declares a [`fidl_fuchsia_net::Ipv6Address`] from a parsable IPv6 address
51/// string.
52pub use net_declare_macros::fidl_ip_v6;
53/// Declares a [`fidl_fuchsia_net::Ipv6AddressWithPrefix`] from a parsable IPv6
54/// + prefix length string, e.g. `ff08::1/88`.
55pub use net_declare_macros::fidl_ip_v6_with_prefix;
56/// Declares a [`fidl_fuchsia_net::MacAddress`] from a parsable MAC address in
57/// the form `aa:bb:cc:dd:ee:ff`.
58pub use net_declare_macros::fidl_mac;
59/// Declares an [`fidl_fuchsia_net::SocketAddress`] from a parsable IP address +
60/// port string (either V4 or V6).
61///
62/// NOTE: `std::net::SocketAddrV6` does not support parsing scope_id from
63/// strings, meaning the generated IPv6 socket address will always have
64/// `zone_index=0`. See [Rust issue 1992].
65///
66/// [Rust issue 1992]: https://github.com/rust-lang/rfcs/issues/1992
67pub use net_declare_macros::fidl_socket_addr;
68/// Declares a [`fidl_fuchsia_net::Ipv4SocketAddress`] from a parsable IPv4
69/// address + port in the form `addr:port`.
70pub use net_declare_macros::fidl_socket_addr_v4;
71/// Declares a [`fidl_fuchsia_net::Ipv6SocketAddress`] from a parsable IPv6
72/// address + port in the form `[addr]:port`.
73///
74/// NOTE: `std::net::SocketAddrV6` does not support parsing scope_id from
75/// strings, meaning the generated IPv6 socket address will always have
76/// `scope_id=0`. See [Rust issue 1992].
77///
78/// [Rust issue 1992]: https://github.com/rust-lang/rfcs/issues/1992
79pub use net_declare_macros::fidl_socket_addr_v6;
80/// Declares a [`fidl_fuchsia_net::Subnet`] from a parsable CIDR address string
81/// in the form `addr/prefix`, e.g. `192.168.0.1/24` or `ff08::1/64`.
82pub use net_declare_macros::fidl_subnet;
83
84/// Declares a [`net_types::ip::AddrSubnetEither`] from a parsable IP address +
85/// prefix length string.
86pub use net_declare_macros::net_addr_subnet;
87/// Declares a [`net_types::ip::AddrSubnet<Ipv4Addr>`] from a parsable IPv4
88/// address + prefix length string.
89pub use net_declare_macros::net_addr_subnet_v4;
90/// Declares a [`net_types::ip::AddrSubnet<Ipv6Addr>`] from a parsable IPv6
91/// address + prefix length string.
92pub use net_declare_macros::net_addr_subnet_v6;
93/// Declares a [`net_types::ip::IpAddr`] from a parsable IP address (either V4
94/// or V6) string.
95pub use net_declare_macros::net_ip;
96/// Declares a [`net_types::ip::Ipv4Addr`] from a parsable IPv4 address string.
97pub use net_declare_macros::net_ip_v4;
98/// Declares a [`net_types::ip::Ipv6Addr`] from a parsable IPv6 address string.
99pub use net_declare_macros::net_ip_v6;
100/// Declares a [`net_types::ethernet::Mac`] from a parsable MAC address in
101/// the form `aa:bb:cc:dd:ee:ff`.
102pub use net_declare_macros::net_mac;
103/// Declares a [`net_types::ip::Subnet<Ipv4Addr>`] from a parsable IPv4 CIDR
104/// address string.
105pub use net_declare_macros::net_subnet_v4;
106/// Declares a [`net_types::ip::Subnet<Ipv6Addr>`] from a parsable IPv6 CIDR
107/// address string.
108pub use net_declare_macros::net_subnet_v6;
109
110/// Declares a [`net_types::ip::PrefixLength<Ipv4>`] from an integer literal.
111pub use net_declare_macros::net_prefix_length_v4;
112
113/// Declares a [`net_types::ip::PrefixLength<Ipv6>`] from an integer literal.
114pub use net_declare_macros::net_prefix_length_v6;
115
116/// Redeclaration of macros to generate `std` types.
117pub mod std {
118    pub use super::{
119        std_ip as ip, std_ip_v4 as ip_v4, std_ip_v6 as ip_v6, std_socket_addr as socket_addr,
120        std_socket_addr_v4 as socket_addr_v4, std_socket_addr_v6 as socket_addr_v6,
121    };
122}
123
124/// Redeclaration of macros to generate `fidl` types.
125pub mod fidl {
126    pub use super::{
127        fidl_ip as ip, fidl_ip_v4 as ip_v4, fidl_ip_v6 as ip_v6, fidl_mac as mac,
128        fidl_socket_addr as socket_addr, fidl_socket_addr_v4 as socket_addr_v4,
129        fidl_socket_addr_v6 as socket_addr_v6, fidl_subnet as subnet,
130    };
131}
132
133/// Redeclaration of macros to generate `net_types` types.
134pub mod net {
135    pub use super::{
136        net_ip as ip, net_ip_v4 as ip_v4, net_ip_v6 as ip_v6, net_mac as mac,
137        net_prefix_length_v4 as prefix_length_v4, net_prefix_length_v6 as prefix_length_v6,
138        net_subnet_v4 as subnet_v4, net_subnet_v6 as subnet_v6,
139    };
140}
141
142#[cfg(test)]
143mod tests {
144    extern crate self as net_declare;
145    extern crate std;
146    use super::*;
147    use fidl_fuchsia_net_common as fidl;
148    use net_declare_macros::net_prefix_length_v4;
149
150    #[test]
151    fn test_std_ip() {
152        assert_eq!(
153            std::net::IpAddr::V4(std::net::Ipv4Addr::new(192, 168, 0, 1)),
154            std_ip!("192.168.0.1")
155        );
156        assert_eq!(
157            std::net::IpAddr::V6(std::net::Ipv6Addr::new(0xFF01, 0, 0, 0, 0, 0, 0, 0x0102)),
158            std_ip!("ff01::0102")
159        );
160    }
161
162    #[test]
163    fn test_std_ip_v4() {
164        assert_eq!(std::net::Ipv4Addr::new(192, 168, 0, 1), std_ip_v4!("192.168.0.1"));
165    }
166
167    #[test]
168    fn test_std_ip_v6() {
169        assert_eq!(
170            std::net::Ipv6Addr::new(0xFF01, 0, 0, 0, 0, 0, 0, 0x0102),
171            std_ip_v6!("ff01::0102")
172        );
173    }
174
175    #[test]
176    fn test_std_socket_addr() {
177        assert_eq!(
178            std::net::SocketAddr::V4(std::net::SocketAddrV4::new(
179                std::net::Ipv4Addr::new(192, 168, 0, 1),
180                8080
181            )),
182            std_socket_addr!("192.168.0.1:8080")
183        );
184        assert_eq!(
185            std::net::SocketAddr::V6(std::net::SocketAddrV6::new(
186                std::net::Ipv6Addr::new(0xFF01, 0, 0, 0, 0, 0, 0, 0x0102),
187                8080,
188                0,
189                0
190            )),
191            std_socket_addr!("[ff01::0102]:8080")
192        );
193    }
194
195    #[test]
196    fn test_std_socket_addr_v4() {
197        assert_eq!(
198            std::net::SocketAddrV4::new(std::net::Ipv4Addr::new(192, 168, 0, 1), 8080),
199            std_socket_addr_v4!("192.168.0.1:8080")
200        );
201    }
202
203    #[test]
204    fn test_std_socket_addr_v6() {
205        assert_eq!(
206            std::net::SocketAddrV6::new(
207                std::net::Ipv6Addr::new(0xFF01, 0, 0, 0, 0, 0, 0, 0x0102),
208                8080,
209                0,
210                0
211            ),
212            std_socket_addr_v6!("[ff01::0102]:8080")
213        );
214    }
215
216    #[test]
217    fn test_fidl_ip() {
218        assert_eq!(
219            fidl::IpAddress::Ipv4(fidl::Ipv4Address { addr: [192, 168, 0, 1] }),
220            fidl_ip!("192.168.0.1")
221        );
222
223        assert_eq!(
224            fidl::IpAddress::Ipv6(fidl::Ipv6Address {
225                addr: [0xFF, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x02]
226            }),
227            fidl_ip!("ff01::0102")
228        );
229    }
230
231    #[test]
232    fn test_fidl_ip_v4() {
233        assert_eq!(fidl::Ipv4Address { addr: [192, 168, 0, 1] }, fidl_ip_v4!("192.168.0.1"));
234    }
235
236    #[test]
237    fn test_fidl_ip_v6() {
238        assert_eq!(
239            fidl::Ipv6Address {
240                addr: [0xFF, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x02]
241            },
242            fidl_ip_v6!("ff01::0102")
243        );
244    }
245
246    #[test]
247    fn test_fidl_ip_v6_v4_mapped() {
248        assert_eq!(
249            fidl::Ipv6Address { addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 192, 168, 0, 1] },
250            fidl_ip_v6!("::ffff:192.168.0.1")
251        );
252    }
253
254    #[test]
255    fn test_fidl_socket_addr() {
256        assert_eq!(
257            fidl::SocketAddress::Ipv4(fidl::Ipv4SocketAddress {
258                address: fidl::Ipv4Address { addr: [192, 168, 0, 1] },
259                port: 8080
260            }),
261            fidl_socket_addr!("192.168.0.1:8080")
262        );
263
264        assert_eq!(
265            fidl::SocketAddress::Ipv6(fidl::Ipv6SocketAddress {
266                address: fidl::Ipv6Address {
267                    addr: [0xFF, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x02]
268                },
269                port: 8080,
270                zone_index: 0,
271            }),
272            fidl_socket_addr!("[ff01::0102]:8080")
273        );
274    }
275
276    #[test]
277    fn test_fidl_socket_addr_v4() {
278        assert_eq!(
279            fidl::Ipv4SocketAddress {
280                address: fidl::Ipv4Address { addr: [192, 168, 0, 1] },
281                port: 8080
282            },
283            fidl_socket_addr_v4!("192.168.0.1:8080")
284        );
285    }
286
287    #[test]
288    fn test_fidl_socket_addr_v6() {
289        assert_eq!(
290            fidl::Ipv6SocketAddress {
291                address: fidl::Ipv6Address {
292                    addr: [0xFF, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x02]
293                },
294                port: 8080,
295                zone_index: 0,
296            },
297            fidl_socket_addr_v6!("[ff01::0102]:8080")
298        );
299    }
300
301    #[test]
302    fn test_fidl_mac() {
303        assert_eq!(fidl::MacAddress { octets: [0, 1, 2, 3, 4, 5] }, fidl_mac!("00:01:02:03:04:05"));
304    }
305
306    #[test]
307    fn test_accept_quotes() {
308        // Rustfmt gets confused with this syntax sometimes, so we allow macros
309        // to receive what looks like a string literal as well.
310        assert_eq!(
311            fidl::MacAddress { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] },
312            fidl_mac!("AA:BB:CC:DD:EE:FF")
313        );
314    }
315
316    #[test]
317    fn test_fidl_ip_v4_with_prefix() {
318        assert_eq!(
319            fidl::Ipv4AddressWithPrefix {
320                addr: fidl::Ipv4Address { addr: [192, 168, 0, 1] },
321                prefix_len: 24
322            },
323            fidl_ip_v4_with_prefix!("192.168.0.1/24")
324        );
325    }
326
327    #[test]
328    fn test_fidl_ip_v6_with_prefix() {
329        assert_eq!(
330            fidl::Ipv6AddressWithPrefix {
331                addr: fidl::Ipv6Address {
332                    addr: [0xFF, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x02]
333                },
334                prefix_len: 64
335            },
336            fidl_ip_v6_with_prefix!("ff01::0102/64")
337        );
338    }
339
340    #[test]
341    fn test_fidl_subnet_v4() {
342        assert_eq!(
343            fidl::Subnet {
344                addr: fidl::IpAddress::Ipv4(fidl::Ipv4Address { addr: [192, 168, 0, 1] }),
345                prefix_len: 24
346            },
347            fidl_subnet!("192.168.0.1/24")
348        );
349    }
350
351    #[test]
352    fn test_fidl_subnet_v6() {
353        assert_eq!(
354            fidl::Subnet {
355                addr: fidl::IpAddress::Ipv6(fidl::Ipv6Address {
356                    addr: [0xFF, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x02]
357                }),
358                prefix_len: 64
359            },
360            fidl_subnet!("ff01::0102/64")
361        );
362    }
363
364    #[test]
365    fn test_net_ip() {
366        assert_eq!(
367            net_types::ip::IpAddr::from(net_types::ip::Ipv4Addr::new([192, 168, 0, 1])),
368            net_ip!("192.168.0.1")
369        );
370
371        assert_eq!(
372            net_types::ip::IpAddr::from(net_types::ip::Ipv6Addr::new([
373                0xFF01, 0, 0, 0, 0, 0, 0, 0x0102
374            ])),
375            net_ip!("ff01::0102"),
376        );
377    }
378
379    #[test]
380    fn test_net_ip_v4() {
381        assert_eq!(net_types::ip::Ipv4Addr::new([192, 168, 0, 1]), net_ip_v4!("192.168.0.1"),);
382    }
383
384    #[test]
385    fn test_net_ip_v6() {
386        assert_eq!(
387            net_types::ip::Ipv6Addr::new([0xFF01, 0, 0, 0, 0, 0, 0, 0x0102]),
388            net_ip_v6!("ff01::0102"),
389        );
390    }
391
392    #[test]
393    fn test_net_ip_v6_v4_mapped() {
394        assert_eq!(
395            net_types::ip::Ipv6Addr::from_bytes([
396                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 192, 168, 0, 1
397            ]),
398            net_ip_v6!("::ffff:192.168.0.1"),
399        )
400    }
401
402    #[test]
403    fn test_net_mac() {
404        assert_eq!(
405            net_types::ethernet::Mac::new([0, 1, 2, 3, 4, 5]),
406            net_mac!("00:01:02:03:04:05")
407        );
408    }
409
410    #[test]
411    fn test_net_subnet_v4() {
412        assert_eq!(
413            net_types::ip::Subnet::new(net_types::ip::Ipv4Addr::new([18, 6, 0, 0]), 15).unwrap(),
414            net_subnet_v4!("18.6.0.0/15")
415        )
416    }
417
418    #[test]
419    fn test_net_subnet_v6() {
420        assert_eq!(
421            net_types::ip::Subnet::new(
422                net_types::ip::Ipv6Addr::new([0xff80, 0, 0, 0, 0, 0, 0, 0]),
423                12
424            )
425            .unwrap(),
426            net_subnet_v6!("ff80::/12")
427        )
428    }
429
430    #[test]
431    fn test_net_prefix_length_v4() {
432        assert_eq!(
433            net_types::ip::PrefixLength::<net_types::ip::Ipv4>::new(23).unwrap(),
434            net_prefix_length_v4!(23)
435        )
436    }
437
438    #[test]
439    fn test_net_prefix_length_v6() {
440        assert_eq!(
441            net_types::ip::PrefixLength::<net_types::ip::Ipv6>::new(125).unwrap(),
442            net_prefix_length_v6!(125)
443        )
444    }
445
446    #[test]
447    fn test_net_addr_subnet_v4() {
448        assert_eq!(
449            net_types::ip::AddrSubnet::new(net_types::ip::Ipv4Addr::new([192, 168, 0, 1]), 24)
450                .unwrap(),
451            net_addr_subnet_v4!("192.168.0.1/24")
452        );
453    }
454
455    #[test]
456    fn test_net_addr_subnet_v6() {
457        assert_eq!(
458            net_types::ip::AddrSubnet::new(
459                net_types::ip::Ipv6Addr::new([0xfe80, 0, 0, 0, 0, 0, 0, 1]),
460                64
461            )
462            .unwrap(),
463            net_addr_subnet_v6!("fe80::1/64")
464        );
465    }
466
467    #[test]
468    fn test_net_addr_subnet() {
469        assert_eq!(
470            net_types::ip::AddrSubnetEither::<
471                net_types::SpecifiedAddr<net_types::ip::IpAddr>,
472            >::new(
473                net_types::ip::IpAddr::V4(net_types::ip::Ipv4Addr::new([192, 168, 0, 1])),
474                24
475            )
476            .unwrap(),
477            net_addr_subnet!("192.168.0.1/24")
478        );
479        assert_eq!(
480            net_types::ip::AddrSubnetEither::<
481                net_types::SpecifiedAddr<net_types::ip::IpAddr>,
482            >::new(
483                net_types::ip::IpAddr::V6(net_types::ip::Ipv6Addr::new([
484                    0xfe80, 0, 0, 0, 0, 0, 0, 1
485                ])),
486                64
487            )
488            .unwrap(),
489            net_addr_subnet!("fe80::1/64")
490        );
491    }
492}