1.. _network_monitoring:
2
3Monitor Network Traffic
4#######################
5
6.. contents::
7    :local:
8    :depth: 2
9
10It is useful to be able to monitor the network traffic especially when
11debugging a connectivity issues or when developing new protocol support in
12Zephyr. This page describes how to set up a way to capture network traffic so
13that user is able to use Wireshark or similar tool in remote host to see the
14network packets sent or received by a Zephyr device.
15
16See also the :zephyr:code-sample:`net-capture` sample application from the Zephyr
17source distribution for configuration options that need to be enabled.
18
19Host Configuration
20******************
21
22The instructions here describe how to setup a Linux host to capture Zephyr
23network RX and TX traffic. Similar instructions should work also in other
24operating systems.
25On the Linux Host, fetch the Zephyr ``net-tools`` project, which is located
26in a separate Git repository:
27
28.. code-block:: console
29
30   git clone https://github.com/zephyrproject-rtos/net-tools
31
32The ``net-tools`` project provides a configure file to setup IP-to-IP tunnel
33interface so that we can transfer monitoring data from Zephyr to host.
34
35In terminal #1, type:
36
37.. code-block:: console
38
39   ./net-setup.sh -c zeth-tunnel.conf
40
41This script will create following IPIP tunnel interfaces:
42
43.. csv-table::
44   :header: "Interface name", "Description"
45   :widths: auto
46
47   "``zeth-ip6ip``", "IPv6-over-IPv4 tunnel"
48   "``zeth-ipip``", "IPv4-over-IPv4 tunnel"
49   "``zeth-ipip6``", "IPv4-over-IPv6 tunnel"
50   "``zeth-ip6ip6``", "IPv6-over-IPv6 tunnel"
51
52Zephyr will send captured network packets to one of these interfaces.
53The actual interface will depend on how the capturing is configured.
54You can then use Wireshark to monitor the proper network interface.
55
56After the tunneling interfaces have been created, you can use for example
57``net-capture.py`` script from ``net-tools`` project to print or save the
58captured network packets. The ``net-capture.py`` provides an UDP listener,
59it can print the captured data to screen and optionally can also save the
60data to a pcap file.
61
62.. code-block:: console
63
64   $ ./net-capture.py -i zeth-ip6ip -w capture.pcap
65   [20210408Z14:33:08.959589] Ether / IP / ICMP 192.0.2.1 > 192.0.2.2 echo-request 0 / Raw
66   [20210408Z14:33:08.976178] Ether / IP / ICMP 192.0.2.2 > 192.0.2.1 echo-reply 0 / Raw
67   [20210408Z14:33:16.176303] Ether / IPv6 / ICMPv6 Echo Request (id: 0x9feb seq: 0x0)
68   [20210408Z14:33:16.195326] Ether / IPv6 / ICMPv6 Echo Reply (id: 0x9feb seq: 0x0)
69   [20210408Z14:33:21.194979] Ether / IPv6 / ICMPv6ND_NS / ICMPv6 Neighbor Discovery Option - Source Link-Layer Address 02:00:5e:00:53:3b
70   [20210408Z14:33:21.217528] Ether / IPv6 / ICMPv6ND_NA / ICMPv6 Neighbor Discovery Option - Destination Link-Layer Address 00:00:5e:00:53:ff
71   [20210408Z14:34:10.245408] Ether / IPv6 / UDP 2001:db8::2:47319 > 2001:db8::1:4242 / Raw
72   [20210408Z14:34:10.266542] Ether / IPv6 / UDP 2001:db8::1:4242 > 2001:db8::2:47319 / Raw
73
74The ``net-capture.py`` has following command line options:
75
76.. code-block:: console
77
78   Listen captured network data from Zephyr and save it optionally to pcap file.
79   ./net-capture.py \
80	-i | --interface <network interface>
81		Listen this interface for the data
82	[-p | --port <UDP port>]
83		UDP port (default is 4242) where the capture data is received
84	[-q | --quiet]
85		Do not print packet information
86	[-t | --type <L2 type of the data>]
87		Scapy L2 type name of the UDP payload, default is Ether
88	[-w | --write <pcap file name>]
89		Write the received data to file in PCAP format
90
91Instead of the ``net-capture.py`` script, you can for example use ``netcat``
92to provide an UDP listener so that the host will not send port unreachable
93message to Zephyr:
94
95.. code-block:: console
96
97   nc -l -u 2001:db8:200::2 4242 > /dev/null
98
99The IP address above is the inner tunnel endpoint, and can be changed and
100it depends on how the Zephyr is configured. Zephyr will send UDP packets
101containing the captured network packets to the configured IP tunnel, so we
102need to terminate the network connection like this.
103
104Zephyr Configuration
105********************
106
107In this example, we use ``native_posix`` board. You can also use any other board
108that supports networking.
109
110In terminal #3, type:
111
112.. zephyr-app-commands::
113   :zephyr-app: samples/net/capture
114   :host-os: unix
115   :board: native_posix
116   :gen-args: -DCONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD=\""gnome-terminal -- screen %s"\"
117   :goals: build
118   :compact:
119
120To see the Zephyr console and shell, start Zephyr instance like this:
121
122.. code-block:: console
123
124   build/zephyr/zephyr.exe -attach_uart
125
126Any other application can be used too, just make sure that suitable
127configuration options are enabled (see ``samples/net/capture/prj.conf`` file
128for examples).
129
130The network capture can be configured automatically if needed, but
131currently the ``capture`` sample application does not do that. User has to use
132``net-shell`` to setup and enable the monitoring.
133
134The network packet monitoring needs to be setup first. The ``net-shell`` has
135``net capture setup`` command for doing that. The command syntax is
136
137.. code-block:: console
138
139   net capture setup <remote-ip-addr> <local-ip-addr> <peer-ip-addr>
140        <remote> is the (outer) endpoint IP address
141        <local> is the (inner) local IP address
142        <peer> is the (inner) peer IP address
143        Local and Peer IP addresses can have UDP port number in them (optional)
144        like 198.0.51.2:9000 or [2001:db8:100::2]:4242
145
146In Zephyr console, type:
147
148.. code-block:: console
149
150   net capture setup 192.0.2.2 2001:db8:200::1 2001:db8:200::2
151
152This command will create the tunneling interface. The ``192.0.2.2`` is the
153remote host where the tunnel is terminated. The address is used to select
154the local network interface where the tunneling interface is attached to.
155The ``2001:db8:200::1`` tells the local IP address for the tunnel,
156the ``2001:db8:200::2`` is the peer IP address where the captured network
157packets are sent. The port numbers for UDP packet can be given in the
158setup command like this for IPv6-over-IPv4 tunnel
159
160.. code-block:: console
161
162   net capture setup 192.0.2.2 [2001:db8:200::1]:9999 [2001:db8:200::2]:9998
163
164and like this for IPv4-over-IPv4 tunnel
165
166.. code-block:: console
167
168   net capture setup 192.0.2.2 198.51.100.1:9999 198.51.100.2:9998
169
170If the port number is omitted, then ``4242`` UDP port is used as a default.
171
172The current monitoring configuration can be checked like this:
173
174.. code-block:: console
175
176   uart:~$ net capture
177   Network packet capture disabled
178                   Capture  Tunnel
179   Device          iface    iface   Local                  Peer
180   NET_CAPTURE0    -        1      [2001:db8:200::1]:4242  [2001:db8:200::2]:4242
181
182which will print the current configuration. As we have not yet enabled
183monitoring, the ``Capture iface`` is not set.
184
185Then we need to enable the network packet monitoring like this:
186
187.. code-block:: console
188
189   net capture enable 2
190
191The ``2`` tells the network interface which traffic we want to capture. In
192this example, the ``2`` is the ``native_posix`` board Ethernet interface.
193Note that we send the network traffic to the same interface that we are
194monitoring in this example. The monitoring system avoids to capture already
195captured network traffic as that would lead to recursion.
196You can use ``net iface`` command to see what network interfaces are available.
197Note that you cannot capture traffic from the tunnel interface as that would
198cause recursion loop.
199The captured network traffic can be sent to some other network interface
200if configured so. Just set the ``<remote-ip-addr>`` option properly in
201``net capture setup`` so that the IP tunnel is attached to desired network
202interface.
203The capture status can be checked again like this:
204
205.. code-block:: console
206
207   uart:~$ net capture
208   Network packet capture enabled
209                   Capture  Tunnel
210   Device          iface    iface   Local                  Peer
211   NET_CAPTURE0    2        1      [2001:db8:200::1]:4242  [2001:db8:200::2]:4242
212
213After enabling the monitoring, the system will send captured (either received
214or sent) network packets to the tunnel interface for further processing.
215
216The monitoring can be disabled like this:
217
218.. code-block:: console
219
220   net capture disable
221
222which will turn currently running monitoring off. The monitoring setup can
223be cleared like this:
224
225.. code-block:: console
226
227   net capture cleanup
228
229It is not necessary to use ``net-shell`` for configuring the monitoring.
230The :ref:`network capture API <net_capture_interface>` functions can be called
231by the application if needed.
232
233Wireshark Configuration
234***********************
235
236The `Wireshark <https://www.wireshark.org/>`_ tool can be used to monitor the
237captured network traffic in a useful way.
238
239You can monitor either the tunnel interfaces or the ``zeth`` interface.
240In order to see the actual captured data inside an UDP packet,
241see `Wireshark decapsulate UDP`_ document for instructions.
242
243.. _Wireshark decapsulate UDP:
244   https://osqa-ask.wireshark.org/questions/28138/decoding-ethernet-encapsulated-in-tcp-or-udp/
245