1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//! [`StreamCapture`] — sealed trait giving async stream types
//! uniform read-access to their underlying capture.
//!
//! Implemented for [`FlowStream`](super::flow_stream::FlowStream),
//! [`SessionStream`](super::session_stream::SessionStream),
//! [`DatagramStream`](super::datagram_stream::DatagramStream),
//! and [`DedupStream`](super::dedup_stream::DedupStream). External
//! crates cannot implement this trait — adding new stream
//! adapters is netring's concern.
//!
//! # Why it exists
//!
//! Once a stream is built (`cap.flow_stream(...)`, etc.) the
//! underlying [`AsyncCapture`] moves into the stream. Without
//! this trait, kernel-ring statistics, BPF filter swap, and other
//! capture-level operations become unreachable. The accessor lets
//! callers reach back through:
//!
//! ```no_run
//! # use netring::{AsyncCapture, Dedup, StreamCapture};
//! # async fn _ex() -> Result<(), netring::Error> {
//! let cap = AsyncCapture::open("eth0")?;
//! let stream = cap.dedup_stream(Dedup::loopback());
//!
//! // Poll kernel ring stats while the stream is running:
//! let stats = stream.capture_stats()?;
//! eprintln!("ring drops: {}", stats.drops);
//!
//! // Or reach the AsyncCapture directly for richer operations:
//! let _fd = stream.capture();
//! # Ok(()) }
//! ```
//!
//! The trait's default methods cover the common cases
//! ([`capture_stats`](StreamCapture::capture_stats),
//! [`capture_cumulative_stats`](StreamCapture::capture_cumulative_stats));
//! impls supply only the [`capture`](StreamCapture::capture) hook.
use AsRawFd;
use crateAsyncCapture;
use crateBpfFilter;
use crateDedup;
use crateError;
use crateCaptureStats;
use crate;
/// Sealing module — keeps external crates from implementing
/// [`StreamCapture`] on their own types.
pub use Sealed;
/// Uniform read-access to the underlying [`AsyncCapture`] for an
/// async stream adapter. Sealed — implemented only by netring's
/// own stream types.
///
/// See the module-level docs for rationale and examples.
/// Atomically replace the BPF filter on the underlying capture
/// from a built stream. Sub-trait of [`StreamCapture`], gated on
/// the source supporting [`PacketSetFilter`] (AF_PACKET only —
/// `AsyncCapture<XdpSocket>`-backed streams don't expose it).
///
/// Auto-implemented for every [`StreamCapture`] whose source
/// satisfies the bound. Use via:
///
/// ```no_run
/// # use netring::{AsyncCapture, BpfFilter, Dedup, StreamSetFilter};
/// # async fn _ex() -> Result<(), netring::Error> {
/// let cap = AsyncCapture::open("eth0")?;
/// let stream = cap.dedup_stream(Dedup::loopback());
///
/// let new_filter = BpfFilter::builder().tcp().dst_port(443).build()?;
/// stream.set_filter(&new_filter)?;
/// # Ok(()) }
/// ```
///
/// **Caveat**: in-flight packets in the kernel ring at swap time
/// were captured under the *old* filter. Drain a couple of polls
/// if a clean cutover is needed.