Packet data can be accessed with the expression rawoffset.size where offset is the integer offset of the field, in bytes, and size is an optional size qualifier. The following qualifiers are supported:
.b | Byte (default) |
.ns | ``Network short'', two bytes in network byte order |
.nl | ``Network long'', four bytes in network byte order |
.ipv4 | IPv4 address, four bytes in network byte order |
.ipv6 | IPv6 address, sixteen bytes in network byte order |
If the offset is zero, the square brackets and the offset expression can be omitted.
raw only provides the basic access mechanism. A more elegant way for using header fields is described in the next section.
Examples:
/* select IPv4 packets without IP options */ class ... if raw[0] == 0x45;
/* select IPv4 packets with the "don't fragment" bit set */ class ... if (raw & 0xf0) == 0x40 && (raw[6].b & 4) == 4;
The choice of expressions is limited by what tcc knows to translate, and by what the respective targets support. There are the following general restrictions:
&
)
&&
, ||
, and !
Examples of basic Boolean expressions:
class ... if ip_proto == 123 if (ip_tos & 0xfc) == 0xb8 if (tcp_sport-4) < 1020;
Combined basic expressions:
class ... if ip_src == 10.0.0.0 || ip_dst == 10.0.0.0 if ip_dst:8 == 9.0.0.0 && (udp_dport == 53 || tcp_dport == 53);
These are not valid expressions:
class ... /* WRONG: result of comparison is not a basic Boolean expression */ if (tcp_dport == 80) == 1 /* WRONG: cannot compare fields with each other */ if ip_src == ip_dst;