Pflua implements "pflang", the language that libpcap uses to express packet filters. Pflua also optionally provides some experimental extensions to pflang. These extensions are experimental, and naturally are not supported by the libpcap pipeline. Please let us know if you find them to be useful to you.
The address-of operator:
By default, this operator is enabled. To disable, include this code somewhere in your app before parsing:
require('pf.parse').allow_address_of = false
An AddressExpression is a new kind of arithmetic expression. The grammar is as follows:
AddressExpression := '&' Addressable Addressable := PayloadAccessor '[' ArithmeticExpression [ ':' (1|2|4) ] ']' PayloadAccessor := 'ip' | 'ip6' | 'tcp' | 'udp' | 'icmp' | 'arp' | 'rarp' | 'wlan' | 'ether' | 'fddi' | 'tr' | 'ppp' | 'slip' | 'link' | 'radio' | 'ip' | 'ip6' | 'tcp' | 'udp' | 'igmp' | 'pim' | 'igrp' | 'vrrp' | 'sctp'
The semantics are that
&foo returns the address of
foo, as a byte
offset from the beginning of the packet. Therefore if a packet is TCP
and the first byte of the packet is the first byte of the ethernet
ether[&tcp] = tcp will always be true.
If the packet is not of the correct kind, then the comparison in which
the AddressExpression is embedded fails to match. This would be the
case, for example, if you asked for
&udp but the packet isn't UDP.
Likewise, if the address isn't within the packet, the containing
comparison will fail to match. An example would be
&udp on a UDP
packet whose size, including the UDP header but excluding the IP or
other L2 header is less than 64 bytes. Note that this behavior differs
udp on a short packet; such an access causes the whole filter
to abort (see the
The pfmatch language
See the pfmatch page, for more.