Packet Capture on Fuchsia

Packet capture is a fundamental tool for developing, debugging, and testing networking.

fx sniff is a development host command that:

  • Runs the packet capture on the Fuchsia target device.
  • Stores the packets in PCAPNG format on the Fuchsia development host.
  • Streams out to a graphical user interface such as Wireshark.

netdump is a packet capturer with rich capture filter support. fx sniff internally invokes netdump with predefined capture filters that are necessary for Fuchsia's developer workflow. For use cases where fx sniff is not viable (e.g. when you have serial console access but without dev host connected), use netdump directly.

Prepare the image

netdump is part of the universe dependency list of the core product. If a package server is available, there is no extra step to prepare the image. Just running netdump will fetch the binary.

If the package server is not available, make sure to bundle netdump into your set of base packages.

$ fx set core.x64 --with-base //src/connectivity/network/netdump
$ fx build

How-to (On Host)

Capture packets over WLAN interface

[host] $ fx sniff wlan

By default, this command captures packets for 30 seconds. To configure the duration, add the --time {sec} or -t {sec} option.

If you don't know the network interface name, run fx sniff without options. The error message shows you what interfaces are available. Alternatively, run:

[host] $ fx shell net if list       # Take note of `filepath` in output

Show the hexdump of packets over the ethernet interface

[host] $ fx sniff --view hex eth

Capture WLAN packets and store them in a file

[host] $ fx sniff --file my_packets wlan

The captured packets are first stored in the target's /tmp/ directory. After the capture is complete, the files are moved to //out/my_packets.pcapng automatically.

Stream out to Wireshark in realtime

NOTE: Linux only.

[host] $ fx sniff --view wireshark wlan

How-to (on target device)

Use netdump for debugging

fx sniff requires working ssh connectivity from the host to the target, which means that networking must be working to some degree. In some cases, networking might not be working at all. If you have access to the serial console while networking, including ssh, is not working, you must run netdump directly on the target. netdump provides a richer set of features than fx sniff.

Prerequisites

Before you use netdump, you must get the file path for the network interface. This is an example for WLAN interface (assuming your target device has one and only one WLAN interface - which is a typical case).

[target] $ iface_filepath=$(net if list wlan | grep filepath | while read c1 c2; do echo $c2; done)

Capture packets over the WLAN interface

[target] $ netdump -t 30 "$iface_filepath"

Show the hexdump of packets over the ethernet interface

[target] $ netdump --raw "$iface_filepath"

Stream out the binary dump in PCAPNG format

[target] $ netdump --pcapdump ${iface_filepath}

Capture packets and store them in a file

[target] $ netdump -t 30 -w /tmp/my_packets.pcapng "$iface_filepath"

Copy the dump file to the host

[host] $ cd ${FUCHSIA_OUT_DIR} && fx scp "[$(fx get-device-addr)]:/tmp/my_precious_packets.pcapng" .

netdump help

[target] $ netdump --help

Only Watch ARP, DHCP, and DNS packets

[target] $ netdump -t 10 -f "arp or port dns,dhcp" "$iface_filepath"

Full syntax for filters

The packet filter language syntax is as follows. Keywords are in bold. Optional terms are in [square brackets]. Placeholders for literals are in <angle brackets>. Binary logical operators associate to the left. All keywords and port aliases should be in lower case.


       expr ::= ( expr )
              | not expr  | expr and expr | expr or expr
              | eth_expr  | host_expr     | trans_expr
length_expr ::= greater <len> | less <len>
       type ::= src | dst
   eth_expr ::= length_expr
              | ether [type] host <mac_addr>
              | [ether proto] net_expr
   net_expr ::= arp
              | vlan
              | ip  [length_expr | host_expr | trans_expr]
              | ip6 [length_expr | host_expr | trans_expr]
  host_expr ::= [type] host <ip_addr>
 trans_expr ::= [proto] icmp
              | [proto] tcp [port_expr]
              | [proto] udp [port_expr]
              | port_expr
  port_expr ::= [type] port <port_lst>
  • <len>: Packet length in bytes. Greater or less comparison is inclusive of len.
  • <mac_addr>: MAC address, e.g. DE:AD:BE:EF:D0:0D. Hex digits are case-insensitive.
  • <ip_addr>: IP address consistent with the IP version specified previously. E.g. 192.168.1.10, 2001:4860:4860::8888.
  • <port_lst>: List of ports or port ranges separated by commas, e.g. 13,ssh,6000-7000,20. The following aliases for defined ports and port ranges can be used as items in the list, but not as part of a range (3,dhcp,12 is allowed, http-100 is not):

    Alias Port(s)
    dhcp 67-68
    dns 53
    echo 7
    ftpxfer 20
    ftpctl 21
    http 80
    https 443
    irc 194
    ntp 123
    sftp 115
    ssh 22
    telnet 23
    tftp 69
    dbglog Netboot debug log port
    dbgack Netboot debug log ack port

Synonyms

The following aliases may be used instead of the keywords listed in the syntax:

Keyword Alias
ip ip4
port portrange

Reference: fx workflow packet signatures

There are many different kinds of services running between the Fuchsia development host and the target. Those are usually invoked by fx commands. Most of times, you are not interested in those packets generated by the fx workflows. The following table lists noteworthy signatures.

Use Signature Reference
Logger port 33337 DEBUGLOG_PORT
Logger port 33338 DEBUGLOG_ACK_PORT
Bootserver port 33330 NB_SERVER_PORT
Bootserver port 33331 NB_ADVERT_PORT
Bootserver port 33332 NB_CMD_PORT_START
Bootserver port 33339 NB_CMD_PORT_END
Bootserver port 33340 NB_TFTP_OUTGOING_PORT
Bootserver port 33341 NB_TFTP_INCOMING_PORT
Package Server port 8083 docs/packages.md
fx shell port 22 devshell/shell
target addr fe80::xxxx:xx4d:fexx:xxxx%XX fx netaddr
target addr fe80::xxxx:xxff:fexx:xxxx%XX fx netaddr --local
target addr fe80::xxxx:xxff:fexx:xxxx%XX fx netaddr --fuchsia
zxdb port 2345 devshell/contrib/debug
- port 65026
- port 65268
- 1900

How do I test if netdump is broken?

You can run some sanity checks locally.

[host] $ fx set core.x64 --with //src/connectivity:tests,//src/connectivity/network/netdump:netdump_unit_tests
# (After running your target)
[host] $ fx run-test netdump_unit_test          # unit test
[host] $ fx run-test netdump_integration_tests  # integration test

Troubleshooting

Q fx sniff commands give me the error env: python3: No such file or directory

A Please install Python 3 in your environment. Fuchsia is in the middle of migrating from Python 2.7 to Python 3.

Q I get the error /boot/bin/sh: netdump not found

A The netdump package is not prepared. Make sure to bundle netdump in the image. See prepare the image.