Firewalling and other packet stuff

From Helpful
Revision as of 17:21, 28 January 2011 by Helpful (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

For other network related things, see:


On ports

On port allocation

Short and overly simple summary:

  • The most basic division is 0-to-1024 (for services) and the rest
  • OSes want a range to dynamically allocate to new outgoing connections. That particular subdivision varies per OS - but is often above the range that IANA considers registered(/registerable) ports, which ends at ~50K.

More (and currently messy) detail:

Port 0 through 1023 are generally only used for incoming connections, and can often only be used by superuser processes (partly to avoid random users hosting man-in-the-middle services on ports used for more basic services, such as telnet, ssh, http).

How ports 1024 though 65535 are used (or not used) varies per OS.

Ephemeral ports are those that are allocated to short-lived connections (and forgotten after disconnect), apparently mostly for:

  • outgoing connections (allocated by the OS)
  • incoming connections for services that should not occupy the listening port (notably HTTP)

In practice, ephemeral ports could use all of 1024 and 65535, but many OSes have some split between ephemeral and non-ephemeral.

IANA consider 1024 to 49152 as registered, and suggests 49152 through 65535 as "dynamic and/or private ports" (which only really means these ports cannot be registered with IANA).

In practice, this mostly means 'the OS and/or you can use 49152 through 65535 as you see fit', which may include (and sometimes excludes) ephemeral ports(verify).

Your basic desktop (non-server) needs ephemeral ports only when making outbound connections, of which it usually only needs a few dozen, and perhaps a few hundred at most even with P2P programs.

Most OSes allocate at least 4000 ephemeral ports, so there is usually no need to change this.

Servers may wish to, as 4000 ephemeral ports can mean at most 4000 current or recent connections (see the TIME_WAIT detail/issue of TCP).

You can often extend the ephemeral range to include tens of thousands of ports, though details vary per OS (and different versions of the OS), so it pays to follow real configuration rather than a sort-of-standard.

  • BSD
    • 1024 through 4999
    • freeBSD ≥4.6 uses the IANA range

More of these can be interesting to servers that see a lot of connections, particularly very short-lived ones (partly because of the TIME_WAIT detail of TCP).

In practice, these ranges are not very strict. Various services choose ports in any of these ranges. -->

See also:

Some interesting ports

Arugably more interesting for sniffing than firewalling :)

For longer lists, see:


  • 22:SSH (also SCP, SFTP, also rsync over SSH and others), 23:telnet
  • 513:rlogin, 514:rsh/rcp, 544:rsh/rcp with kerberos

  • 53/UDP:DNS (apparently 53/TCP is used to sync DNS servers), 43: WHOIS

  • 80:HTTP, 443:HTTPS
  • 119:NNTP (news), 563:NNTP/SSL
  • 110:POP3, 995:POP3/SSL, 153:IMAP, 993:IMAP/SSL, 25:SMTP, 465:SMTP/SSL (or cisco)

  • 67 and 68:DHCP/BOOTP server and client, 69:TFTP

  • 21:FTPcommand, 20:FTPdata, 873:rsync (unless over ssh),
  • 137/UDP:NETBIOS nameservice, 138/UDP:NETBIOS datagram, 139/UDP:NETBIOS session, 445/TCP:SMB-over-TCP
  • 1512:WINS
  • 2049:NFS, 111:sunrpc portmapper

  • 524:NCP (Netware Core Protocol)
  • 631:IPP (Internet Printing Protocol)
  • 860:iSCSI
  • 5000:UPnP, 1900:SSDP (UPnP discovery)

  • 5432:PostgreSQL, 1521:OracleSQL, 1433:MSSQL, 3306:MySQL
  • 389:LDAP, 636:LDAP/SSL
  • 1812 and 1813:RADIUS

  • 5222:Jabber-client/server, 5269:Jabber-server/server, 5223:Jabber-secure, 5050:Yahoo, 1863:MSN, 5190:AIM,ICQ, 1550:Gadu-gadu
  • 6667:IRC (but may differ)

  • 177:XDMCP, 6000~:X windows, 5900~:VNC, 5800~:VNC, (~ means 'starts at', and you usually see only a few)

  • 161:SNMP (also 162),
  • 520:RIP, 521:RIPng, 513

  • 1194:OpenVPN, 1723:MS PPTP VPN, 1701:l2tp

OS-specific firewalling

This article is marked 'feel free.' Often because its authors know they won't spend as much time on it as they should. Your help is appreciated.


These are primarily notes
It won't be complete in any sense.
It exists to contain fragments of useful information.

See also Networking notes.

Organization, operation

Packet paths

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)
The short story

Some of us never really need to know more than that packets usually follow one of the following routes:

  • network → PREROUTING → INPUT → local process (data coming in for your apps)
  • local process → OUTPUT → POSTROUTING → network (data going out, from your apps)
  • network → PREROUTING → FORWARD → POSTROUTING → network (data passing through)

This means INPUT, OUTPUT, and FORWARD are usually the interesting chains, while PREROUTING and POSTROUTING are there for doing more complex things than filtering (such as packet alteration for fun, profit, routing, NAT, and other such things).

Networking has to be fast, so rules are actually in very simple to evaluate binary form - they usually consist of little more than a few bitmasks and comparisons. (Speed is also served with a "use only the first thing in the list of rules that applies, nothing else," logic (...that you also see in many ACL systems, and like them, may be simple or used in more convoluted ways))

Some of the more complex rules (e.g. l7 stuff) takes a little longer, so if you care about speed you'll usually place them after simpler rules that are also more likely to apply to more packets.

A slightly longer story; Tables and chains from a few perspectives
This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

When you want to do fancier things, you want to know about the structure of things.

Netfilter/iptables largely consists of:

  • tables
    • mostly for organization.
    • Within each chain in a path, each table could apply. That is, any table may have that chain, and if it does, it will be used. (in a predefined order, apparently conntrack, mangle, nat, filter (unsure -- (verify)))
    • May use some (or all) of the commonly predefined chains - see the common capitalized names below. May introduce new chains, but rarely do.
    • On the common tables:
      • filter
        • you can assume you have this. It's all you need for an incoming-stuff firewall. Also the default table for iptables commands.
        • mostly used to filter out packets in the stages INPUT, FORWARD, and/or OUTPUT. (You can do it in other tables, but this tends to be unnecessary)
      • mangle
        • frequently present
        • often empty if you're not a router or fancy server
        • supports MARK, TOS, TTL targets
        • mangle/PREROUTING is used for things like altering TOS
        • mangle/INPUT is for mangling the packet just before it goes to the process -- not often a critical feature.
      • nat
        • often empty if you're not a router or fancy server
        • often for DNAT (in PREROUTING), SNAT (in POSTROUTING)
      • conntrack
        • less usually present
        • often empty if you're not a router or fancy server
        • only applies in PREROUTING and OUTPUT, and can't really be controlled directly (verify)
  • chains (and targets)
    • Predefined ones: {{comment|(PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING. These are created when modules are loaded.
    • can additionally define your own, usually for clarity of management or reuse (example: a chain containing trusted IPs, which you would probably unconditionally jump to at the start of filter's INPUT)
    • Chains mostly consist mostly of a list of rules
  • rules
    • ...that sit in specific chains. Each rule tends to represent a single case of filtering, alteration or such. Many have the function of throwing a packet over to another chain.

Also interesting but not part of the most central terminology:

  • Modules
    • ...refer to the fact that things can be loaded/added at runtime (as well as be compiled in).
    • usually add tables (usually what they're for)
    • may add new chains
    • may have specific targets (for example, mangle supports/adds MARK, TOS, TTL)
  • targets
    • can be jumped to (just like chain names), but represent behaviour (more specific than jumping around).
    • ACCEPT, REJECT, DROP, LOG, QUEUE, and RETURN are common targets,

The predefined chains (and other predefined names) are usually the most useful/important ones to getting packets in, out, and past, and doing so in an understandable way.

While you can customize it (for organization, a sort of conditional logic on streams of packets), in practice people rarely deviate from the images you see around various explanations, like:

first version; probably contains mistakes

There are some limitations of what type of rules are accepted in specific chains and specific tables - though you're still allowed to do a lot of things that make little sense you probably wouldn't think of, are impossible to predict the behaviour of, or are an unnecessarily complex method.

The previously mentioned three common paths mentioned before in a little more detail:

  • packets generated by a local process go via OUTPUT to POSTROUTING, often:
    • mangle/OUTPUT (often unused)
    • nat/OUTPUT
    • filter/OUTPUT (if you think this useful)
    • mangle/POSTROUTING
    • nat/POSTROUTING (mostly for SNAT, MASQUARADE)

  • packets destined for a local process go via PREROUTING and INPUT to that process
    • mangle/PREROUTING
    • nat/PREROUTING (mostly for DNAT)
    • mangle/INPUT
    • filter/INPUT (the place where most firewalling for this node happens)
  • packets routed through this node go from PREROUTING to FORWARD to POSTROUTING and onto some network again, often specifically:
    • mangle/PREROUTING
    • nat/PREROUTING (mostly for DNAT)
    • mangle/FORWARD (only necessary if you want to mangle in a way that affects routing decisions in the path -- otherwise it can go into another mangle step)
    • filter/FORWARD
    • mangle/POSTROUTING
    • nat/POSTROUTING (mostly for SNAT, MASQUARADE)

(note that PREROUTING can divert a packet to FORWARD through DNATting, in which case it's actually the next case...). As such, there is only a difference after PREROUTING -- there is a routing decision there that checks whether the packet is targeted at this node or not, and sends it to to INPUT or FORWARD accordingly.

Note also that in promiscuous mode, all packets are received, not just those for us or passing through us.

Managing rules

Useful command types:

  • -I: Insert on top of list
  • -F: flush all, or flush a specific chain
  • -A: Append to end of list
  • -D: Delete rule by rule number (1-based counting) in a specific chain, or by repeating the exact rule, so e.g.:
    • iptables -D INPUT 7
    • iptables -D INPUT -s -p udp -m udp -m multiport --dports 135,137,138,139,445 -j ACCEPT
  • -L: list chain contets (you may need to specify a table too(verify))

Most operating systems will do some work around shutdown and bootup so that rules persist over reboots. They usually use iptables-save and iptables-restore, which serializes and overwrites the current state of the tables.

I personally prefer doing the same thing over worrying over -I and -A. After one

iptables-save > /etc/savetable

...I have the convenience of, whenever I want to change the firewall, editing that file and running

iptables-restore /etc/temptable

to make the rules current. (The tables are (by default) flushed by iptables-restore before inserting the rules, so this is an idempotent thing. The -A lines are more or less stuck on iptables verbatim, while the other lines are organisation, the bracketed numbers seem to be packet and byte counters - I'm not sure whether they're restored.

The handy side effect is that you always have a record of it in case your system gets forgetful, or for when you quickly want to pick out rules for another firewalls on.

Note that your distribution may have some automatic, easily configurable firewalling program - that may also overwrite whatever you just changed whenever it wants to and may or may not consider its own rules to be the master set. If so, use that instead - in general, change the rules at the easiest-to-administer and most auhoritative place.

Rule format (the intersting bit)

Rules look something like like:

iptables -A INPUT -i eth0 -j ACCEPT
iptables -A INPUT -s -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 6001 -j ACCEPT
iptables -t nat -A POSTROUTING -s -o eth0 -j SNAT --to-source
iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --sport 21 -j MARK --set-mark 0x4

The first three are filtering rules (the first two of which are very similar in effect), the last two are more complex.

In simple firewalls it's fairly common to match on the fact that something is a tcp or udp packet, often in combination with the ports involved. In an INPUT rule, destination means us, and dport indicates the local service the connection is trying to access, so source address and destination is what you most commonly filter on.

Anyway, let's pick apart the rule structure and list common components.

When creating chain contents, each rule has:

  • -t table. It's 'filter' by default, so can be omitted on firewall rules
  • -A chain to append to a chain (or -I to insert, possibly -R to replace)
  • -j: what target to jump the packet to. (There is also -g for goto, ((verify) the difference)

It quite likely has one of the general match options

  • -s and/or -d: source and destination address or network, specifically for IP (any subprotocol)
  • -p protocol: ommited means 'all'; the other options are tcp, udp, and icmp.
  • -i interface: incoming interface (optional; default is all. Note that you can do things like eth+ to match eth0, eth1, etc.).
  • (-o interface analogously, for outgoing packets)

Most other options are arguments to a specific alterntive match type (-m matchtype ) you decide to use. (These rules can also contain , of course)

Match types are usually a specific type of filter. You can use more than one match in a rule. They can of course be combined with the general match options.

They are pluggable at kernel/kernel-module level, so may or may not be available to you without some kernel compiling fun (though central things like tcp and udp), or without getting a cutting-edge kernel or patch.

The common match types that you can count on are tcp and udp, and also mport or multiport - these will serve all your port filtering needs.

Since you can construct illogical match combinations, there is the occasionaly apparent redundancy, and there may be dependencies. For example, when using -m tcp (or udp, mport, multiport(verify)), you also have to specify -p tcp or -p udp.

A not commonly seen but still interesting detail is that you can use ! directly before many parameter values (sometimes the entire parameter), where sensible, to invert its sense.

match types

Specified with -m. Many of these have to be compiled into the kernel and some are OS-specific. The most useful are:

  • tcp, udp: all packets of respective transport protocol
  • mport, multiport, in case you want ranges or lists of ports at a time
  • state: NEW, ESTABLISHED, RELATED, INVALID, useful to blindly allow packets belonging to connections which we scrutinized at establish time

Some of the following are generally interesting, a few depends on extra services, and you'll probably never use most:

  • recent: automatically maintain a blacklist. For example allows blockign people that try many connections in a short amount of time (e.g. to avoid being brute forced)
  • connbytes, connrate, limit, dstlimit, connlimit, hashlimit: allows matching/limiting of total connection trasfer, byte/packet rate/size or connection count, per service/net/etc.
  • psd: attempts to match on packets coming from portscans

  • iprange, mac: IP ranges, source MAC address. Mostly useful for filtering.
  • tcpmss, tos, ttl, conntrack, length, mark, connmark, pkttype: various packet property matches, including the MARK (see mangling). pkttype is link-layer type: unicast, broadcast, or multicast
  • u32: u32 matches up to 4-byte values in a packet, which is useful to pick out packet details without specific support

  • time: time-of-day, on weekdays, 'inside date range'.
  • random, nth: probability-based packet matcher, or every-n packet matcher
  • osf: passive OS fingerprinting
  • account, quota: packet counters, either for feedback via proc or for a quota system
  • owner: match uid, gid, command of locally generated packets



Targets can be basic chains: (or custom ones)


...special targets (common policies):

  • ACCEPT basically means "Sure, right. Just let it through to the next chain in line"
  • DROP is a packet trash can. It will make the client wait for a response, slowing it down. Used to be called DENY
  • REJECT: (common extension) respond with an ICMP-based rejection / problem signal packet
  • RETURN returns the packet to the previous chain it came from (allows complex as well as confusing logic)
  • QUEUE is a pass to userspace


  • SNAT (in nat-postrouting): Source Network Address Translation: source IP is changed, source port can be.
  • DNAT (in nat-postrouting): Destinaton Network Address Transation
  • MASQUERADE: dynamic version of the above
  • BALANCE: round-robin DNATting over a range of target IPs

(fancy stuff you'll probably never use)

...and others, various of which may need kernel support.

  • LOG, ULOG: Log to syslogd/syslog-ng/otehers, or a socket-based logger like ulogd (useful to e.g. redirect into a database). There are analysis tools for some of these targers (like there are for webserver logs)
  • TARPIT: accepts the initial connection, but no data. This slows down certain types of scans.
  • TOS, TTL, TCPMSS, MARK, CONNMARK, IPMARK: Alter packet details
  • REDIRECT, NETMAP, SAME, MIRROR: More packet mangling, mostly IP address/net-related
  • ROUTE: override routing decision details
  • ...and more.

Note: Some of these have the effect of doing -j RETURN themselves. For example, you can -j LOG and it will continue processing in the chain that -j LOG is in.(verify)

Simple firewall

(Glossing over a lot of details...)

A simple and common approach is to whitelist things you want to allow, and deny everything else, for example:

Allow packets from previously approved connections
Allow everything for localhost
Allow ssh from anywhere
Allow web requests from anywhere (assuming this computer has a web server)
Allow anything from my workstation, by IP address
Allow SMB file sharing for my housemates (on
Allow ICMP traffic  (Ping and such)
Allow anything from my handheld device, by MAC address 01:23:45:67:89:ab
Deny everything else (could also be set as a table's default policy instead of an explicit last rule)

...which translated to iptables rules would look something like:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -s -j ACCEPT
iptables -A INPUT -m tcp -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m tcp -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -s -j ACCEPT
iptables -A INPUT -m tcp -p tcp -s -m multiport --dports 139,445 -j ACCEPT
iptables -A INPUT -m udp -p udp -s -m multiport --dports 137,138 -j ACCEPT
iptables -A INPUT -m icmp -p icmp -j ACCEPT
iptables -A INPUT -m mac --mac-source 01:23:45:67:89:ab -j ACCEPT
iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable


  • Multiport is vaguely recent; if you don't have it you may need to write multiple rules to the same effect.
  • Ports 137/udp, 138/udp, 139/tcp, 445/tcp (and arguably 135/tcp) are ports for SMB file sharing
  • Rejecting is usually done for all protocols (including the potentially useful ICMP, for pinging), or done per-protocol. The above allows all ICMP, some TCP and UDP ports, and rejects everything else (including protocols other than icmp, tcp, and udp, if you get/use any)
  • REJECT tells off the other end, DROP means no response is sent at all (meaning the connection has to time out on the client side, which will will slow down scanners a bit, but also honestly misguided connections)


This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

When you log from your firewall, you are probably also going for an analyzer, which probably means you want to redirect this output to a log made for only this purpose.

How to configure that depends on which logger you use (system log (LOG) or a userspace logger (ULOG), whether you want to dump into one or more files, and other preferences, but often comes down to a simple string match.

You may want to look for fishing expeditions too, such as connections to port 8080 and other common ports (e.g. P2P you do not use) when there has never been anything there.

LOG (syslog)

Logs to whatever you're using for your syslogs.

For example, when I add:

-A INPUT -j LOG --log-prefix "iptables_INPUT "

...just before the final reject, I get packet reports in my syslog, where iptables_INPUT is a nice and specific thing I can test for.

Since I have metalog installed, I added:

Firewall log : 
  regex    = "iptables_INPUT"
  logdir   = "/var/log/firewall" /etc/metalog.conf. I also made a script that parses these log lines and reports semi-nicely.

You may want to filter this out of the general kernel log, using neg_regex.

ULOG (userspace log)

Instead of using the syslog calls, ULOG multicasts the messages on a netlink socket, and most likely use ulogd to receive this. That daemon can decide to do one of various things, including storing the packet reports in a big database (ULOG log analysers often expect that)

ULOG can store the entire packet rather than just print a summary as LOG does.

On the iptables side, you use this much likg LOG, though options, if you used any, are different. Example:


Related software

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

Log analysis:

See also

Windows XP's basic firewalling

Windows XP comes with basic firewalling - that is, 'deny incoming connections except the ones I want' which is the most useful rule of thumb in practice anyhow, but the few neater features are hidden behind a one-click interface.

Opening ports / allowing programs

Assuming you keep your XP updated, windows will pop up for new programs asking you whether you want it to allow communication. The general, good, idea is to deny everything that's not allowed by you or windows policies.

If you need to allow things later, usually because they don't seem to work, you need to figure out what ports a program expects connections on. (every now and then an ISP may be trying to discourage certain programs or services, either for legal or security reasons, by firewalling them on your connection, which is usually solvable by changing the port number)

To allow incoming connections to ports, Go into the properties (of any one of them), 'Advanced' tab, Settings (in the Windows Firewall part), its 'Exceptions' tab, 'Add port', and give it the port number and protocol type (TCP or UDP). You can name it anything.

As you can see from the dialog, you can also allow programs. This works by checking the executable path-and-filename for a running program, and allowing it based on that. I vaguely remember problems with it (This may be related to disallowals and rule ordering), but if they have been fixed, this is more flexible as it would mean not having to deal with ports.


This may not be relevant for most, but you can enable and disable the firewall per interface (as would seem logical to me, but it en-/disables it for all) If you want this, instead of enabling/disabling from the right-click menu in the network control panel you should:

Go into any network interface's properties, 'Advanced' tab, 'Settings' in the Windows Firewall part, its 'Advanced' tab, and check only the interfaces you want protected.

"Windows cannot display Windows Firewall settings"

Diagnosis: (Windows XP)

  • Windows complains you have the firewall disabled
  • Trying to enable it yields something like ("Due to an unidentified problem,") "Windows cannot display Windows Firewall Settings."

In my case (and apparently many others), this was because spyware disabled the windows firewall, removing XP's "Windows Firewall/Internet Connection Sharing (ICS)" service. To verify this, see the windows service list and look for an entry called that.

If it is entirely missing, remove the spyware and try:

rundll32 setupapi,InstallHinfSection Ndi-Steelhead 132 %windir%\inf\netrass.inf

This installs the firewall service. It likely also resets some things(verify).

After you do that, you may also need to do:

NETSH FIREWALL RESET set the firewall back to default settings, you should have a working firewall again, though you may want configure and lock it down a little again.

See also:

Tool notes

See also Network tools

tcpdump notes

This article is marked 'feel free.' Often because its authors know they won't spend as much time on it as they should. Your help is appreciated.

TCPdump snoops network traffic going getting to this host. It can summarize the traffic on-screen (the default) or write it to the fairly common pcap-style files. It can also filter what packets it shows/writes.

The 'tcp' in the name is misleading, because it suggests it captures at the network layer, and then specifically TCP. Actually, it captures at link layer, so you can get all the interesting stuff: ethernet, wifi, and more.

Wireshark (previously Ethereal) serves much the same purpose. It has a GUI, more protocol decoding, a more advanced filter language that includes substring and regexp content filtering.

Usage notes

Usually, the filter expression is enclosed in single quotes. This is not necessary, but is simpler than dealing with than various types of shell escaping.

If the line reporting "packets dropped by kernel" doesn't say 0: This refers to to the packet capture interface (a kernel feature) and doesn't mean the kernel is screwing up your networking, nor does it refer to firewall drops.

The network is moving packets faster than the capturing program is reading them from the capture interface. That is, the kernel isn't waiting around for the capturer (tcpdump) to catch up, it's removing the packets exposed to the capturing.

It seems one reason is that tcpdump is waiting on its own DNS lookups - try tcpdump -n (numeric, no names) to see if that helps.

Interesting command line options

  • -n: don't resolve hostnames (faster)
  • -i interfacename: listen on a specific interface. Default is the first it can find. ("-i any" will capture from all interfaces but ''not'' be promiscuous)

  • -s 0: capture the whole packet instead of the first 68 bytes, which is faster and enough for the scrolling screen summary, but little else. You probably want the whole packets when inspecing packets in detail and writing them to a file.

  • -w filename: dump packet data to a file, instead of decoding and printing (tcpdump -r and other utilities take this)

  • -t: don't show timetamps (less clutter, though also not as informative)

Print packet as

  • -A: ASCII (safe to print; command characters are removed)
  • -x: hex
  • -X: hex and ASCII
  • (-xx and -XX are variations that also show the link-level header)


Host, net, port

As to filters: Avoid shell interpretation of filter string by using single quotes. Also: note that the predefined primitives require a backslash before them.

Probably the most directly interesting types filters are things like:

  • port 53 (matches tcp and udp; "udp port 53" and "tcp port 53" are shorthands that imply the respective protos)
  • portrange 1024-65535
  • host (shorthand for "ether proto \ip and host ...")
  • net 192.168 (shorthand for "ip net ..."), and also:
    • net 192.168.5 mask
    • net 192.168.5/24
When not mentioning src or dst, you accept an address, net, port or such if it appears as either source or destination. So:
port 80
would capture your surfing and people connecting to your web server, while
src port 80
dst port 80
look at direction.

If you add a named hosts it is looked up, but redirects and round robin DNS resolving may throw you off (both may happen in the case of

Protocol constants

  • "ether proto" things
    • ip (shorthand for "ether proto \ip", and actual value is 0x0800)
    • arp (shorthand for "ether proto \arp", value is 0x0806)
    • rarp ("ether proto \rarp")
    • ip6, tr, fddi, decnet
    • Others, e.g. 0x8863 for PPPoE Discovery, 0x8864 for PPPoE Session


  • ICMP that isn't pinging:
    tcpdump 'icmp[icmptype]!=icmp-echo and icmp[icmptype]!=icmp-echoreply'
  • "ip proto" things:
    • tcp (shorthand for "ip proto \tcp")
    • udp (shorthand for "ip proto \udp")
    • icmp (shorthand for "ip proto \icmp")
    • Also: ipx, decnet

(note the absence of backslashes in shorthands)

Logic in filters

Logical booleans:

  • and, &&
  • or, ||
  • not, !


  • 'not arp and not port 67' (show all except arp and dhcp)
  • 'net 192.168 && !host' (all traffic on this net not related to this specific host)
  • 'net 192.168 || net 145.99' (traffic on my private and public IP net)


  • eq, == and =
  • ne, !=
  • gt, >
  • lt, <
  • ge, >=
  • le, <=

Repetition and omission: lists and short forms

If the predicate is missing, the last is assumed. For example:

net 10 or 192

...does the same as

net 10 or net 192

Lists are supported through a similar sort of expansion:

host ourrouter and not \( ourmailserver or ourwebserver \)

Raw bit/byte testing, and bitwise operations

You can get at packet data, with decimal (or hexadecimal) offsets for a frame/packet at apparently any layer/decoded protocol, including things like ether[], link[], ip[], tcp[], udp[], and icmp[]. Some examples:

  • ip[8] = 1 (picks out a byte. This tests for TTL being 1)
  • tcp[0:2] = 80 (picks out a word using [start offset:length]. This one is equivalent to "src port 80")
  • tcp[20:4] = 0x48454C4F (one page's example; those are ASCII bytes for HELO, part of SMTP mail sending)
  • icmp[0]==8 || icmp[0]==0, ICMP packets that are either echo request or echo reply. Note that there are readable constants for these, used in an example somewhere above.

See links below for header references, and for further examples using this sort of test.

Value/bitwise operations that may be useful:

  • +, -, /, and *: integer math
  • & and |: bitwise and and or
  • <<, >>: bitshifts

Note that you only ever deal with whatever endianness is defined for the protocol. IP, TCP and UDP are always big-endian.


Also interesting in this context is len, the packet packet length. I'm not sure at which level -- it seems that filtering for 1514 gives results and not 1500 or 1518, which would suggest it's counting at link level, except it's NOT counting ethernet's CRC.

Copy-paste examples

  • ICMP packets:
    tcpdump icmp
    (ping and ICMP portscans)
  • non-ping ICMP:
    tcpdump 'icmp[0]!=8 && icmp[0]!=0'
    (often mostly 'port unreachable' replies)
  • ARP packets:
    tcpdump arp
  • ARP and DHCP:
    tcpdump 'udp port 67 or udp port 68 or arp'
  • SYN packets:
    tcpdump '(tcp[13]&0x2)!=0 and (tcp[13]&0x10)==0'
    (initial establishment of TCP connections, SYN portscans) (Specifically packets with SYN set, ACK not set, and ignoring the other flags)

  • MAC filter:
    tcpdump 'ether host 00:0B:6A:11:22:33'
    (also see ether src and ether dst)
  • Ethernet broadcasts:
    tcpdump 'ether broadcast'
    (shows ARP requests and more)
  • Small data packets:
    tcpdump '(tcp or udp) and len<100'
  • IPv6:
    tcpdump ip6

There are various tricks you can pull when you combine other networking tools, or even general tools. For example, you can add pv to see how much data of a specific type (say HTTP) is being moved (at ethernet level):

tcpdump 'tcp port 80' -s 0 -w - | pv > /dev/null


Various wireless-related utilities dump or read the pcap format, so you can use tcpdump to read the results.

BSSIDs act as MACs, so you can filter for traffic to and from an AP using:

ether host 00:12:34:66:22:12

Tcpdump knows how to decode the 802.11 (WiFi) basics, but there seem to be no handy aliases yet. Since 801.11 is a different type of ethernet frame (the aliases seem for ethernetII), most of the interesting filters have to come from accessing the packet's link level data. See also wireless.

Interesting tests include

  • link[0]==0x80: Beacon
  • link[0]&0x0c==0x08: Data packets
    • link[0:2]&0x0c02==0x0802: WEP-encrypted data packets

See also

  • tcpslice, which manipulates dump files


Header reference / byte/bit-tests