GNU Hethereal - Dump and analyze network traffic

Hethereal POST/GET Commands
DESCRIPTION
CAPTURE FILTER SYNTAX
READ FILTER SYNTAX
FILES
INSTALLING
NOTES
AUTHORS

Hethereal does only accept one commandline argument. It was implemented to be a Common Gateway Interface (CGI) and as this, accepts arguments given by a POST or GET command. The only interpreted commandline argument is -G for building the Helpfiles. It can (as other CGI's) be run from a commandline, but its arguments must then be properly encoded:

Hethereal POST/GET Commands

c = [count]
f = [capture filter expression]
F = [file format] - Not yet implemented.
i = [interface]
n = [no nameresolution] - Not yet implemented.
o = [preference setting] - Not yet implemented.
p = [do not capture in promisious mode]
r = [read from infile][filename]
R = [display filter expression]
s = [snaplen] - Not yet implemented.
t = [time stamp format] - Not yet implemented.
V = [print protokoll tree]
w = [capture to savefile][filename]
x = [print hexdata in footer]

Example: If Hethereal runs on the host ABMLinux.org, residing in the /cgi-bin Directory and it should read 3 Packets of tcp traffic for the host bender.abmlinux.de from the file dump, the POST/GET string must be:

http://www.abmlinux.org/cgi-bin/hethereal?r=dump&c=3&f=tcp%20host%20bender.abmlinux.de

DESCRIPTION

Hethereal is a network protocol analyzer. It lets you capture packet data from a live network, or read packets from a previously saved capture file, printing a decoded form of those packets into an HTML Page. Hethereal knows how to read libpcap capture files, including those of tcpdump. In addition, Hethereal can read capture files from snoop (including Shomiti) and atmsnoop, LanAlyzer, Sniffer (compressed or uncompressed), Microsoft Network Monitor, AIX's iptrace, NetXray, Sniffer Pro, RADCOM's WAN/LAN analyzer, Lucent/Ascend router debug output, HP-UX's nettl, the dump output from Toshiba's ISDN routers, the output from i4btrace from the ISDN4BSD project, and output in IPLog format from the Cisco Secure Intrusion Detection System. There is no need to tell Hethereal what type of file you are reading; it will determine the file type by itself. Hethereal is also capable of reading any of these file formats if they are compressed using gzip. Hethereal recognizes this directly from the file; the '.gz' extension is not required for this purpose.

Hethereal is completely controlled trough it's built-in Web-interface. For normal operation you won't need to fiddle around with POST/GET commands. To prevent users from capturing to /etc/passwd for example, which is conceded to be a bad idea, we substitute all occurrencys of \, / and some special characters with '_'. This means, that all capture-files will be kept inside the capture-directory as defined in html_cfg.cfg_path.

If the w=Filename flag is not specified, Hethereal will capture one Packet and display it verbose, including the Hex-Data.

When printing a decoded form of packets, Hethereal prints, by default, a summary line containing the fields specified by the preferences file (which are also the fields displayed in the packet list pane in Ethereal), although if it's printing packets as it captures them, rather than printing packets from a saved capture file, it won't print the "frame number" field. If the V=on flag is specified, it prints instead a protocol tree, which is expandable to show all the fields of all protocols in the packet.

When writing packets to a file, Hethereal, by default, writes the file in libpcap format, and writes all of the packets it sees to the output file. The F=Filter-format flag can be used to specify the format in which to write the file; it can write the file in libpcap format (standard libpcap format, a modified format used by some patched versions of libpcap, or the format used by Red Hat Linux 6.1), snoop format, uncompressed Sniffer format, Microsoft Network Monitor 1.x format, and the format used by Windows-based versions of the Sniffer software.

Read filters in Hethereal, which allow you to select which packets are to be decoded or written to a file, are very powerful; more fields are filterable in Hethereal than in other protocol analyzers, and the syntax you can use to create your filters is richer. As Hethereal progresses, expect more and more protocol fields to be allowed in read filters.

Packet capturing is performed with the pcap library. The capture filter syntax follows the rules of the pcap library. This syntax is different from the read filter syntax. Currently Hethereal only supports capture filter when capturing.

Compressed file support uses (and therefore requires) the zlib library. If the zlib library is not present, Hethereal will compile, but will be unable to read compressed files.

[ c ] Sets the default number of packets to read when capturing live data.

[ f ] Sets the capture filter expression.

[ F ] Sets the file format of the output capture file.

[ i ] Network interface to use for live packet capture.

It should match one of the names listed in "netstat -i" or "ifconfig -a". If no interface is specified, Hethereal searches the list of interfaces, choosing the first non-loopback interface if there are any non-loopback interfaces, and choosing the first loopback interface if there are no non-loopback interfaces; if there are no interfaces, Hethereal reports an error and doesn't start the capture.

[ n ] Disables network object name resolution (such as hostname, TCP and UDP port names).

[ o ] Sets a preference value

This will override the default value and any value read from a preference file. The argument to the flag is a string of the form I:I, where I is the name of the preference (which is the same name that would appear in the preference file), and I is the value to which it should be set.

[ p ] If set to off, don't put the interface into promiscuous mode.

Note that the interface might be in promiscuous mode for some other reason; hence, [ p ] cannot be used to ensure that the only traffic that is captured is traffic sent to or from the machine on which Hethereal is running, broadcast traffic, and multicast traffic to addresses received by that machine.

[ r ] Reads packet data from a file.

[ R ] Read Filter

Causes the specified filter (which uses the syntax of read filters, rather than that of capture filters) to be applied before printing a decoded form of packets or writing packets to a file; packets not matching the filter are discarded rather than being printed or written.

[ s ] Sets the default snapshot length to use when capturing live data. No more than snaplen bytes of each network packet will be read into memory, or saved to disk.

[ t ] Sets the format of the packet timestamp printed in summary lines.

The format can be one of 'r' (relative), 'a' (absolute), 'ad' (absolute with date), or 'd' (delta). The relative time is the time elapsed between the first packet and the current packet. The absolute time is the actual time the packet was captured, with no date displayed; the absolute date and time is the actual time and date the packet was captured. The delta time is the time since the previous packet was captured. The default is relative.

[ V ] Protocoll Tree

If set to on Hethereal will print a protocol tree for each packet rather than a one-line summary of the packet.

[ w ] data savefile.

[ x ] If set to on, a Hexdata Summary will be printed.

Causes Hethereal to print a hex and ASCII dump of the packet data after printing the summary or protocol tree.

CAPTURE FILTER SYNTAX

See manual page of tcpdump(8):

expression selects which packets will be dumped. If no expression is given, all packets on the net will be dumped. Other­ wise, only packets for which expression is `true' will be dumped.

The expression consists of one or more primitives. Primitives usually consist of an id (name or number) preceded by one or more qualifiers. There are three different kinds of qualifier:

type: qualifiers say what kind of thing the id name or number refers to. Possible types are host, net and port. E.g., `host foo', `net 128.3', `port 20'. If there is no type qualifier, host is assumed.

dir: qualifiers specify a particular transfer direction to and/or from id. Possible directions are src, dst, src or dst and src and dst. E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'. If there is no dir qualifier, src or dst is assumed. For `null' link layers (i.e. point to point protocols such as slip) the inbound and outbound qualifiers can be used to specify a desired direction.

proto: qualifiers restrict the match to a particular protocol. Possible protos are: ether, fddi, ip, arp, rarp, decnet, lat, sca, moprc, mopdl, tcp and udp. E.g., `ether src foo', `arp net 128.3', `tcp port 21'. If there is no proto qualifier, all protocols consistent with the type are assumed. E.g., `src foo' means `(ip or arp or rarp) src foo' (except the latter is not legal syntax), `net bar' means `(ip or arp or rarp) net bar' and `port 53' means `(tcp or udp) port 53'.

[`fddi' is actually an alias for `ether'; the parser treats them identically as meaning ``the data link level used on the specified network interface.'' FDDI headers contain Ethernet-like source and destination addresses, and often contain Ethernet-like packet types, so you can filter on these FDDI fields just as with the analogous Ethernet fields. FDDI headers also contain other fields, but you cannot name them explicitly in a filter expres­ sion.]

In addition to the above, there are some special `primitive' keywords that don't follow the pattern: gateway, broadcast, less, greater and arithmetic expressions. All of these are described below.

More complex filter expressions are built up by using the words and, or and not to combine primitives. E.g., `host foo and not port ftp and not port ftp-data'. To save typing, identical qualifier lists can be omitted. E.g., `tcp dst port ftp or ftp-data or domain' is exactly the same as `tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'.

Allowable primitives are:

dst host host
True if the IP destination field of the packet is host, which may be either an address or a name.

src host host
True if the IP source field of the packet is host.

host host
True if either the IP source or destination of the packet is host. Any of the above host expressions can be prepended with the keywords, ip, arp, or rarp as in: ip host host
which is equivalent to: ether proto \ip and host host
If host is a name with multiple IP addresses, each address will be checked for a match.

ether dst ehost
True if the ethernet destination address is ehost. Ehost may be either a name from /etc/ethers or a number (see ethers(3N) for numeric format).

ethr src ehost
True if the ethernet source address is ehost.

ether host ehost
True if either the ethernet source or destination address is ehost.

gateway host
True if the packet used host as a gateway. I.e., the ethernet source or destination address was host but neither the IP source nor the IP destination was host. Host must be a name and must be found in both /etc/hosts and /etc/ethers. (An equivalent expression is ether host ehost and not host host which can be used with either names or numbers for host / ehost.)

dst net net
True if the IP destination address of the packet has a network number of net. Net may be either a name from /etc/networks or a network number (see networks(4) for details).

src net net
True if the IP source address of the packet has a network number of net.

net net
True if either the IP source or destination address of the packet has a network number of net.

net net mask mask
True if the IP address matches net with the specific netmask. May be qualified with src or dst.

net net/len
True if the IP address matches net a netmask len bits wide. May be qualified with src or dst.

dst port port
True if the packet is ip/tcp or ip/udp and has a destination port value of port. The port can be a number or a name used in /etc/services (see tcp(4P) and udp(4P)). If a name is used, both the port number and protocol are checked. If a number or ambiguous name is used, only the port number is checked (e.g., dst port 513 will print both tcp/login traffic and udp/who traffic, and port domain will print both tcp/domain and udp/domain traffic).

src port port
True if the packet has a source port value of port.

port port
True if either the source or destination port of the packet is port. Any of the above port expressions can be prepended with the keywords, tcp or udp, as in: tcp src port port which matches only tcp packets whose source port is port.

less length
True if the packet has a length less than or equal to length. This is equivalent to: len <= length.

greater length
True if the packet has a length greater than or equal to length. This is equivalent to: len >= length.

ip proto protocol
True if the packet is an ip packet (see ip(4P)) of protocol type protocol. Protocol can be a number or one of the names icmp, igrp, udp, nd, or tcp. Note that the identifiers tcp, udp, and icmp are also key­ words and must be escaped via backslash (\), which is \\ in the C-shell.

ether broadcast
True if the packet is an ethernet broadcast packet. The ether keyword is optional.

ip broadcast
True if the packet is an IP broadcast packet. It checks for both the all-zeroes and all-ones broadcast conventions, and looks up the local subnet mask.

ether multicast
True if the packet is an ethernet multicast packet. The ether keyword is optional. This is shorthand for `ether[0] & 1 != 0'.

ip multicast
True if the packet is an IP multicast packet.

ether proto protocol
True if the packet is of ether type protocol. Protocol can be a number or a name like ip, arp, or rarp. Note these identifiers are also keywords and must be escaped via backslash (\). [In the case of FDDI (e.g., `fddi protocol arp'), the protocol identification comes from the 802.2 Logical Link Control (LLC) header, which is usually layered on top of the FDDI header. Tcpdump assumes, when filtering on the proto­ col identifier, that all FDDI packets include an LLC header, and that the LLC header is in so-called SNAP format.]

decnet src host
True if the DECNET source address is host, which may be an address of the form ``10.123'', or a DECNET host name. [DECNET host name support is only available on Ultrix systems that are configured to run DEC­ NET.]

decnet dst host
True if the DECNET destination address is host.

decnet host host
True if either the DECNET source or destination address is host.

ip, arp, rarp, decnet
Abbreviations for: ether proto p
where p is one of the above protocols.

lat, moprc, mopdl
Abbreviations for: ether proto p
where p is one of the above protocols. Note that tcpdump does not currently know how to parse these pro­ tocols.

tcp, udp, icmp
Abbreviations for: ip proto p
where p is one of the above protocols.

expr relop expr
True if the relation holds, where relop is one of >, <, >=, <=, =, !=, and expr is an arithmetic expres­ sion composed of integer constants (expressed in standard C syntax), the normal binary operators [+, -, *, /, &, |], a length operator, and special packet data accessors. To access data inside the packet, use the following syntax:

proto [ expr : size ]

Proto is one of ether, fddi, ip, arp, rarp, tcp, udp, or icmp, and indicates the protocol layer for the index operation. The byte offset, relative to the indicated protocol layer, is given by expr. Size is optional and indicates the number of bytes in the field of interest; it can be either one, two, or four, and defaults to one. The length operator, indicated by the keyword len, gives the length of the packet.

For example, `ether[0] & 1 != 0' catches all multicast traffic. The expression `ip[0] & 0xf != 5' catches all IP packets with options. The expression `ip[6:2] & 0x1fff = 0' catches only unfragmented datagrams and frag zero of fragmented datagrams. This check is implicitly applied to the tcp and udp index operations. For instance, tcp[0] always means the first byte of the TCP header, and never means the first byte of an intervening fragment.

Primitives may be combined using:

A parenthesized group of primitives and operators (parentheses are special to the Shell and must be escaped).

Negation (`!' or `not').

Concatenation (`&&' or `and').

Alternation (`||' or `or').

Negation has highest precedence. Alternation and concatenation have equal precedence and associate left to right. Note that explicit and tokens, not juxtaposition, are now required for concatenation.

If an identifier is given without a keyword, the most recent keyword is assumed. For example, not host vs and ace
is short for
not host vs and host ace
which should not be confused with
not ( host vs or ace )

Expression arguments can be passed to tcpdump as either a single argument or as multiple arguments, whichever is more convenient. Generally, if the expression contains Shell metacharacters, it is easier to pass it as a sin­ gle, quoted argument. Multiple arguments are concatenated with spaces before being parsed.

EXAMPLES

To print all packets arriving at or departing from sundown:
tcpdump host sundown

To print traffic between helios and either hot or ace:
tcpdump host helios and \( hot or ace \)

To print all IP packets between ace and any host except helios:
tcpdump ip host ace and not helios

To print all traffic between local hosts and hosts at Berkeley:
tcpdump net ucb-ether

To print all ftp traffic through internet gateway snup: (note that the expression is quoted to prevent the shell from (mis-)interpreting the parentheses):
tcpdump 'gateway snup and (port ftp or ftp-data)'

To print traffic neither sourced from nor destined for local hosts (if you gateway to one other net, this stuff should never make it onto your local net):
tcpdump ip and not net localnet

To print the start and end packets (the SYN and FIN packets) of each TCP conversation that involves a non-local host:
tcpdump 'tcp[13] & 3 != 0 and not src and dst net localnet'

To print IP packets longer than 576 bytes sent through gateway snup:
tcpdump 'gateway snup and ip[2:2] > 576'

To print IP broadcast or multicast packets that were not sent via ethernet broadcast or multicast:
tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'

To print all ICMP packets that are not echo requests/replies (i.e., not ping packets):
tcpdump 'icmp[0] != 8 and icmp[0] != 0"

READ FILTER SYNTAX

Read filters help you remove the noise from a packet trace and let you see only the packets that interest you. If a packet meets the requirements expressed in your read filter, then it is printed. Read filters let you compare the fields within a protocol against a specific value, compare fields against fields, and to check the existence of specified fields or protocols.

The simplest read filter allows you to check for the existence of a protocol or field. If you want to see all packets which contain the IPX protocol, the filter would be "ipx". (Without the quotation marks) To see all packets that contain a Token-Ring RIF field, use "tr.rif".

Fields can also be compared against values. The comparison operators can be expressed either through C-like symbols, or through English-like abbreviations:

eq, ==    Equal
ne, !=    Not equal
gt, >     Greater than
lt, <     Less Than
ge, >=    Greater than or Equal to
le, <=    Less than or Equal to

Furthermore, each protocol field is typed. The types are:

Unsigned integer (either 8-bit, 16-bit, 24-bit, or 32-bit) Signed integer (either 8-bit, 16-bit, 24-bit, or 32-bit) Boolean Ethernet address (6 bytes) Byte string (n-number of bytes) IPv4 address IPv6 address IPX network number String (text) Double-precision floating point number

An integer may be expressed in decimal, octal, or hexadecimal notation. The following three read filters are equivalent:

frame.pkt_len > 10
frame.pkt_len > 012
frame.pkt_len > 0xa

Boolean values are either true or false. However, a boolean field is present in a protocol decode only if its value is true. If the value is false, the field is not presence. You can therefore check the truth value of a boolean field by simply checking for its existence, that is, by naming the field. For example, a token-ring packet's source route field is boolean. To find any source-routed packets, the read filter is simply:

tr.sr

Non source-routed packets can be found with the negation of that filter:

! tr.sr

Ethernet addresses, as well as a string of bytes, are represented in hex digits. The hex digits may be separated by colons, periods, or hyphens:

fddi.dst eq ff:ff:ff:ff:ff:ff
ipx.srcnode == 0.0.0.0.0.1
eth.src == aa-aa-aa-aa-aa-aa

If a string of bytes contains only one byte, then it is represented as an unsigned integer. That is, if you are testing for hex value 'ff' in a one-byte byte-string, you must compare it agains '0xff' and not 'ff'.

IPv4 addresses can be represented in either dotted decimal notation, or by using the hostname:

ip.dst eq www.mit.edu
ip.src == 192.168.1.1

IPv4 address can be compared with the same logical relations as numbers: eq, ne, gt, ge, lt, and le. The IPv4 address is stored in host order, so you do not have to worry about how the endianness of an IPv4 address when using it in a read filter.

Classless InterDomain Routing (CIDR) notation can be used to test if an IPv4 address is in a certain subnet. For example, this read filter will find all packets in the 129.111 Class-B network:

ip.addr == 129.111.0.0/16

Remember, the number after the slash represents the number of bits used to represent the network. CIDR notation can also be used with hostnames, in this example of finding IP addresses on the same Class C network as 'sneezy':

ip.addr eq sneezy/24

The CIDR notation can only be used on IP addresses or hostnames, not in variable names. So, a read filter like "ip.src/24 == ip.dst/24" is not valid. (yet)

IPX networks are represented by unsigned 32-bit integers. Most likely you will be using hexadecimal when testing for IPX network values:

ipx.srcnet == 0xc0a82c00

A substring operator also exists. You can check the substring (byte-string) of any protocol or field. For example, you can filter on the vendor portion of an ethernet address (the first three bytes) like this:

eth.src[0:3] == 00:00:83

Or more simply, since the number of bytes is inherent in the byte-string you provide, you can provide just the offset. The previous example can be stated like this:

eth.src[0] == 00:00:83

In fact, the only time you need to explicitly provide a length is when you don't provide a byte-string, and are comparing fields against fields:

fddi.src[0:3] == fddi.dst[0:3]

If the length of your byte-string is only one byte, then it must be represented in the same way as an unsigned 8-bit integer:

llc[3] == 0xaa

You can use the substring operator on a protocol name, too. And remember, the "frame" protocol encompasses the entire packet, allowing you to look at the nth byte of a packet regardless of its frame type (Ethernet, token-ring, etc.).

token[0:5] ne 0.0.0.1.1
ipx[0:2] == ff:ff
llc[3:1] eq 0xaa

Offsets for byte-strings can also be negative, in which case the negative number indicates the number of bytes from the end of the field or protocol that you are testing. Here's how to check the last 4 bytes of a frame:

frame[-4] == 0.1.2.3

or

frame[-4:4] == 0.1.2.3

All the above tests can be combined together with logical expressions. These too are expressable in C-like syntax or with English-like abbreviations:

and, &&   Logical AND
or,  ||   Logical OR
xor, ^^   Logical XOR
not, !    Logical NOT

Expressions can be grouped by parentheses as well. The following are all valid read filter expression:

tcp.port == 80 and ip.src == 192.168.2.1
not llc
(ipx.srcnet == 0xbad && ipx.srnode == 0.0.0.0.0.1) || ip
tr.dst[0:3] == 0.6.29 xor tr.src[0:3] == 0.6.29

A special caveat must be given regarding fields that occur more than once per packet. "ip.addr" occurs twice per IP packet, once for the source address, and once for the destination address. Likewise, tr.rif.ring fields can occur more than once per packet. The following two expressions are not equivalent:

ip.addr ne 192.168.4.1
not ip.addr eq 192.168.4.1

The first filter says "show me all packets where an ip.addr exists that does not equal 192.168.4.1". That is, as long as one ip.addr in the packet does not equal 192.168.44.1, the packet passes the display filter. The second filter "don't show me any packets that have at least one ip.addr field equal to 192.168.4.1". If one ip.addr is 192.168.4.1, the packet does not pass. If neither ip.addr fields is 192.168.4.1, then the packet passes.

It is easy to think of the 'ne' and 'eq' operators as having an implict "exists" modifier when dealing with multiply-recurring fields. "ip.addr ne 192.168.4.1" can be thought of as "there exists an ip.addr that does not equal 192.168.4.1".

Be careful with multiply-recurring fields; they can be confusing.

FILES

Currently Hethereal only supports standard ethereal settings in preference files, this may change in future versions. Hethereal needs some images and HTML files accecable by the webserver. See Compilation-parameters in function main() of hethereal.c.

/usr/local/etc/ethereal.conf and $HOME/.ethereal/preferences contain system-wide and personal preference settings, respectively. The file contains preference settings of the form I:I, one per line, where I is the name of the preference (which is the same name that would appear in the preference file), and I is the value to which it should be set; white space is allowed between : and I. A preference setting can be continued on subsequent lines by indenting the continuation lines with white space. A # character starts a comment that runs to the end of the line.

The system-wide preference file is read first, if it exists, overriding Hethereal's default values; the personal preferences file is then read, if it exists, overriding default values and values read from the system-wide preference file.

/etc/ethers is consulted to correlate 6-byte hardware addresses to names. If an address is not found in /etc/ethers, the $HOME/.ethereal/ethers file is consulted next. Each line contains one hardware address and name, separated by whitespace. The digits of the hardware address are separated by either a colon (:), a dash (-), or a period (.). The following three lines are valid lines of an ethers file:

ff:ff:ff:ff:ff:ff          Broadcast
c0-00-ff-ff-ff-ff          TR_broadcast
00.00.00.00.00.00          Zero_broadcast

/usr/local/etc/manuf matches the 3-byte vendor portion of a 6-byte hardware address with the manufacturer's name. The format of the file is the same as the /etc/ethers file, except that each address is three bytes instead of six.

F and $HOME/.ethereal/ipxnets correlate 4-byte IPX network numbers to names. The format is the same as the /etc/ethers file, except that each address if four bytes instead of six. Additionally, the address can be represented a single hexadecimal number, as is more common in the IPX world, rather than four hex octets. For example, these four lines are valid lines of an ipxnets file.

C0.A8.2C.00              HR
c0-a8-1c-00              CEO
00:00:BE:EF              IT_Server1
110f                     FileServer3

INSTALLING

Before compiling, you have to check html_cfg parameters in function main() of hethereal.c. Some parameters's values depend on your Webservers configuration. You can also change Hethereal's look'n'feel there. Hethereal must be installed SUID root and must reside in the CGI-executable directory of your Webserver. Images inside hethereal must reside in a directory relative to DokumentRoot as defined in var html_cfg.base_path. Check appropriate README and source for more details.

NOTES

Hethereal is part of the Ethereal distribution. The latest version of Ethereal can be found at http://www.ethereal.com.

AUTHORS

Hethereal uses the same packet dissection code that Ethereal does, as well as using many other modules from Ethereal; see the list of authors in the Ethereal man page for a list of authors of that code. Hethereal is written by Carsten Buchenau (carsten@ABMLinux.org) and Tim Abenath (tim@ABMLinux.org), University of Applied Science, Dortmund, Germany.