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