SNOOPY(8) SNOOPY(8)
NAME
snoopy - spy on network packets
SYNOPSIS
snoopy [ -CDdpst ] [ -M m ] [ -N n ] [ -f filter-expression
] [ -h first-header ] [ packet-source ]
snoopy -? [ proto... ]
DESCRIPTION
Snoopy reads packets from a packet-source (default
/net/ether0), matches them to a filter (by default anything
matches), and writes matching packets to standard output
either in human readable form (default) or in a binary trace
format that can be later read by snoopy. Packet-source can
be the name of an Ethernet (e.g., /net/ether0), an interface
(e.g., /net/ipifc/0), or a file of captured packets.
The human readable format consists of multiple lines per
packet. The first line contains the milliseconds since the
trace was started. Subsequent ones are indented with a tab
and each contains the dump of a single protocol header. The
last line contains the dump of any contained data. For
example, a BOOTP packet would look like:
324389 ms
ether(s=0000929b1b54 d=ffffffffffff pr=0800 ln=342)
ip(s=135.104.9.62 d=255.255.255.255 id=5099 frag=0000...
udp(s=68 d=67 ck=d151 ln= 308)
bootp(t=Req ht=1 hl=16 hp=0 xid=217e5f27 sec=0 fl=800...
dhcp(t=Request clientid=0152415320704e7266238ebf01030...
The binary format consists of:
2 bytes of packet length, msb first
8 bytes of nanosecond time, msb first
the packet
Filters are expressions specifying protocols to be traced
and specific values for fields in the protocol headers. The
grammar is:
expr: protocol
| field '=' value
| field '!=' value
| protocol '(' expr ')'
| '(' expr ')'
| expr '||' expr
Page 1 Plan 9 (printed 10/30/25)
SNOOPY(8) SNOOPY(8)
| expr '&&' expr
| '!' expr
The values for protocol and field can be obtained using the
-? option. With no arguments, it lists the known protocols.
Otherwise it prints, for each protocol specified, which sub-
protocols it can multiplex to, and which fields can be used
for filtering. For example, the listing for ethernet is
currently:
ether's filter attributes:
s - source address
d - destination address
a - source|destination address
sd - source|destination address
t - type
ether's subprotos:
0x0800 ip 0x8863 pppoe_disc
0x0806 arp 0x8864 pppoe_sess
0x0806 rarp 0x888e eapol
0x86dd ip6
The format of value depends on context. In general, ether-
net addresses are entered as a string of hex digits; IP num-
bers in the canonical `.' format for v4 and `:' format for
v6; and ports in decimal.
Snoopy's options are:
-C compute the correct checksum for each packet; on mis-
match, add a field !ck=xxxx where xxxx is the correct
checksum.
-D output will be a binary trace file in Unix pcap format.
-d output will be a binary trace file.
-t input is a binary trace file as generated with the -d
option.
-p do not enter promiscuous mode. Only packets to this
interface will be seen.
-s force one output line per packet. The default is mul-
tiline.
-M discard all but the first m bytes of each packet. The
default is to keep the entire packet. This option is
most useful when writing packets to a file with the -d
option.
-N dump n data bytes per packet. The default is 32.
Page 2 Plan 9 (printed 10/30/25)
SNOOPY(8) SNOOPY(8)
-f use filter-expression to filter the packet stream. The
default is to match all packets.
-h assume the first header per packet to be of the first-
header protocol. The default is `ether'. For packet
interfaces without a media header, use ippkt as the
first-header type to decode ipv4 and ipv6 packets.
EXAMPLES
To display only BOOTP and ARP packets:
% snoopy -f 'arp || bootp'
after optimize: ether(arp || ip(udp(bootp)))
The first line of output shows the completed filter expres-
sion. Snoopy will fill in other protocols as necessary to
complete the filter and then optimize to remove redundant
comparisons.
To save all packets between 135.104.9.2 to 135.104.9.6 and
later display those to/from TCP port 80:
% ramfs
% snoopy -df 'ip(s=135.104.9.2 && d=135.104.9.6) ||\
ip(s=135.104.9.6 && d=135.104.9.2)' > /tmp/quux
<interrupt from the keyboard>
% snoopy -tf 'tcp(sd=80)' /tmp/quux
FILES
/net/ether0
Ethernet device
SOURCE
/sys/src/cmd/ip/snoopy
Page 3 Plan 9 (printed 10/30/25)