1// Copyright 2024 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.
45//! Abstractions to expose netstack3 core state to human inspection in bindings.
6//!
7//! This module mostly exists to abstract the dependency to Fuchsia inspect via
8//! a trait, so we don't have to expose all of the internal core types to
9//! bindings for it to perform the inspection.
1011use core::fmt::Display;
1213pub use diagnostics_traits::{Inspectable, InspectableValue, Inspector, InspectorDeviceExt};
14use net_types::ip::IpAddress;
15use net_types::{AddrAndPortFormatter, ZonedAddr};
1617use crate::counters::Counter;
1819/// Extension trait for [`Inspector`] adding support for netstack3-specific
20/// types.
21pub trait InspectorExt: Inspector {
22/// Records a counter.
23fn record_counter(&mut self, name: &str, value: &Counter) {
24self.record_uint(name, value.get())
25 }
2627/// Records a `ZonedAddr` and it's port, mapping the zone into an
28 /// inspectable device identifier.
29fn record_zoned_addr_with_port<I: InspectorDeviceExt<D>, A: IpAddress, D, P: Display>(
30&mut self,
31 name: &str,
32 addr: ZonedAddr<A, D>,
33 port: P,
34 ) {
35self.record_display(
36 name,
37 AddrAndPortFormatter::<_, _, A::Version>::new(
38 addr.map_zone(|device| I::device_identifier_as_address_zone(device)),
39 port,
40 ),
41 )
42 }
4344/// Records the local address of a socket.
45fn record_local_socket_addr<I: InspectorDeviceExt<D>, A: IpAddress, D, P: Display>(
46&mut self,
47 addr_with_port: Option<(ZonedAddr<A, D>, P)>,
48 ) {
49const NAME: &str = "LocalAddress";
50if let Some((addr, port)) = addr_with_port {
51self.record_zoned_addr_with_port::<I, _, _, _>(NAME, addr, port);
52 } else {
53self.record_str(NAME, "[NOT BOUND]")
54 }
55 }
5657/// Records the remote address of a socket.
58fn record_remote_socket_addr<I: InspectorDeviceExt<D>, A: IpAddress, D, P: Display>(
59&mut self,
60 addr_with_port: Option<(ZonedAddr<A, D>, P)>,
61 ) {
62const NAME: &str = "RemoteAddress";
63if let Some((addr, port)) = addr_with_port {
64self.record_zoned_addr_with_port::<I, _, _, _>(NAME, addr, port);
65 } else {
66self.record_str(NAME, "[NOT CONNECTED]")
67 }
68 }
69}
7071impl<T: Inspector> InspectorExt for T {}