Blame bootstrap_ver/extensions/libxt_u32.man

Packit Service dd8e2b
U32 tests whether quantities of up to 4 bytes extracted from a packet have
Packit Service dd8e2b
specified values. The specification of what to extract is general enough to
Packit Service dd8e2b
find data at given offsets from tcp headers or payloads.
Packit Service dd8e2b
.TP
Packit Service dd8e2b
[\fB!\fP] \fB\-\-u32\fP \fItests\fP
Packit Service dd8e2b
The argument amounts to a program in a small language described below.
Packit Service dd8e2b
.IP
Packit Service dd8e2b
tests := location "=" value | tests "&&" location "=" value
Packit Service dd8e2b
.IP
Packit Service dd8e2b
value := range | value "," range
Packit Service dd8e2b
.IP
Packit Service dd8e2b
range := number | number ":" number
Packit Service dd8e2b
.PP
Packit Service dd8e2b
a single number, \fIn\fP, is interpreted the same as \fIn:n\fP. \fIn:m\fP is
Packit Service dd8e2b
interpreted as the range of numbers \fB>=n\fP and \fB<=m\fP.
Packit Service dd8e2b
.IP "" 4
Packit Service dd8e2b
location := number | location operator number
Packit Service dd8e2b
.IP "" 4
Packit Service dd8e2b
operator := "&" | "<<" | ">>" | "@"
Packit Service dd8e2b
.PP
Packit Service dd8e2b
The operators \fB&\fP, \fB<<\fP, \fB>>\fP and \fB&&\fP mean the same as in C.
Packit Service dd8e2b
The \fB=\fP is really a set membership operator and the value syntax describes
Packit Service dd8e2b
a set. The \fB@\fP operator is what allows moving to the next header and is
Packit Service dd8e2b
described further below.
Packit Service dd8e2b
.PP
Packit Service dd8e2b
There are currently some artificial implementation limits on the size of the
Packit Service dd8e2b
tests:
Packit Service dd8e2b
.IP "    *"
Packit Service dd8e2b
no more than 10 of "\fB=\fP" (and 9 "\fB&&\fP"s) in the u32 argument
Packit Service dd8e2b
.IP "    *"
Packit Service dd8e2b
no more than 10 ranges (and 9 commas) per value
Packit Service dd8e2b
.IP "    *"
Packit Service dd8e2b
no more than 10 numbers (and 9 operators) per location
Packit Service dd8e2b
.PP
Packit Service dd8e2b
To describe the meaning of location, imagine the following machine that
Packit Service dd8e2b
interprets it. There are three registers:
Packit Service dd8e2b
.IP
Packit Service dd8e2b
A is of type \fBchar *\fP, initially the address of the IP header
Packit Service dd8e2b
.IP
Packit Service dd8e2b
B and C are unsigned 32 bit integers, initially zero
Packit Service dd8e2b
.PP
Packit Service dd8e2b
The instructions are:
Packit Service dd8e2b
.TP
Packit Service dd8e2b
.B number
Packit Service dd8e2b
B = number;
Packit Service dd8e2b
.IP
Packit Service dd8e2b
C = (*(A+B)<<24) + (*(A+B+1)<<16) + (*(A+B+2)<<8) + *(A+B+3)
Packit Service dd8e2b
.TP
Packit Service dd8e2b
.B &number
Packit Service dd8e2b
C = C & number
Packit Service dd8e2b
.TP
Packit Service dd8e2b
.B << number
Packit Service dd8e2b
C = C << number
Packit Service dd8e2b
.TP
Packit Service dd8e2b
.B >> number
Packit Service dd8e2b
C = C >> number
Packit Service dd8e2b
.TP
Packit Service dd8e2b
.B @number
Packit Service dd8e2b
A = A + C; then do the instruction number
Packit Service dd8e2b
.PP
Packit Service dd8e2b
Any access of memory outside [skb\->data,skb\->end] causes the match to fail.
Packit Service dd8e2b
Otherwise the result of the computation is the final value of C.
Packit Service dd8e2b
.PP
Packit Service dd8e2b
Whitespace is allowed but not required in the tests. However, the characters
Packit Service dd8e2b
that do occur there are likely to require shell quoting, so it is a good idea
Packit Service dd8e2b
to enclose the arguments in quotes.
Packit Service dd8e2b
.PP
Packit Service dd8e2b
Example:
Packit Service dd8e2b
.IP
Packit Service dd8e2b
match IP packets with total length >= 256
Packit Service dd8e2b
.IP
Packit Service dd8e2b
The IP header contains a total length field in bytes 2-3.
Packit Service dd8e2b
.IP
Packit Service dd8e2b
\-\-u32 "\fB0 & 0xFFFF = 0x100:0xFFFF\fP"
Packit Service dd8e2b
.IP
Packit Service dd8e2b
read bytes 0-3
Packit Service dd8e2b
.IP
Packit Service dd8e2b
AND that with 0xFFFF (giving bytes 2-3), and test whether that is in the range
Packit Service dd8e2b
[0x100:0xFFFF]
Packit Service dd8e2b
.PP
Packit Service dd8e2b
Example: (more realistic, hence more complicated)
Packit Service dd8e2b
.IP
Packit Service dd8e2b
match ICMP packets with icmp type 0
Packit Service dd8e2b
.IP
Packit Service dd8e2b
First test that it is an ICMP packet, true iff byte 9 (protocol) = 1
Packit Service dd8e2b
.IP
Packit Service dd8e2b
\-\-u32 "\fB6 & 0xFF = 1 &&\fP ...
Packit Service dd8e2b
.IP
Packit Service dd8e2b
read bytes 6-9, use \fB&\fP to throw away bytes 6-8 and compare the result to
Packit Service dd8e2b
1. Next test that it is not a fragment. (If so, it might be part of such a
Packit Service dd8e2b
packet but we cannot always tell.) N.B.: This test is generally needed if you
Packit Service dd8e2b
want to match anything beyond the IP header. The last 6 bits of byte 6 and all
Packit Service dd8e2b
of byte 7 are 0 iff this is a complete packet (not a fragment). Alternatively,
Packit Service dd8e2b
you can allow first fragments by only testing the last 5 bits of byte 6.
Packit Service dd8e2b
.IP
Packit Service dd8e2b
 ... \fB4 & 0x3FFF = 0 &&\fP ...
Packit Service dd8e2b
.IP
Packit Service dd8e2b
Last test: the first byte past the IP header (the type) is 0. This is where we
Packit Service dd8e2b
have to use the @syntax. The length of the IP header (IHL) in 32 bit words is
Packit Service dd8e2b
stored in the right half of byte 0 of the IP header itself.
Packit Service dd8e2b
.IP
Packit Service dd8e2b
 ... \fB0 >> 22 & 0x3C @ 0 >> 24 = 0\fP"
Packit Service dd8e2b
.IP
Packit Service dd8e2b
The first 0 means read bytes 0-3, \fB>>22\fP means shift that 22 bits to the
Packit Service dd8e2b
right. Shifting 24 bits would give the first byte, so only 22 bits is four
Packit Service dd8e2b
times that plus a few more bits. \fB&3C\fP then eliminates the two extra bits
Packit Service dd8e2b
on the right and the first four bits of the first byte. For instance, if IHL=5,
Packit Service dd8e2b
then the IP header is 20 (4 x 5) bytes long. In this case, bytes 0-1 are (in
Packit Service dd8e2b
binary) xxxx0101 yyzzzzzz, \fB>>22\fP gives the 10 bit value xxxx0101yy and
Packit Service dd8e2b
\fB&3C\fP gives 010100. \fB@\fP means to use this number as a new offset into
Packit Service dd8e2b
the packet, and read four bytes starting from there. This is the first 4 bytes
Packit Service dd8e2b
of the ICMP payload, of which byte 0 is the ICMP type. Therefore, we simply
Packit Service dd8e2b
shift the value 24 to the right to throw out all but the first byte and compare
Packit Service dd8e2b
the result with 0.
Packit Service dd8e2b
.PP
Packit Service dd8e2b
Example:
Packit Service dd8e2b
.IP
Packit Service dd8e2b
TCP payload bytes 8-12 is any of 1, 2, 5 or 8
Packit Service dd8e2b
.IP
Packit Service dd8e2b
First we test that the packet is a tcp packet (similar to ICMP).
Packit Service dd8e2b
.IP
Packit Service dd8e2b
\-\-u32 "\fB6 & 0xFF = 6 &&\fP ...
Packit Service dd8e2b
.IP
Packit Service dd8e2b
Next, test that it is not a fragment (same as above).
Packit Service dd8e2b
.IP
Packit Service dd8e2b
 ... \fB0 >> 22 & 0x3C @ 12 >> 26 & 0x3C @ 8 = 1,2,5,8\fP"
Packit Service dd8e2b
.IP
Packit Service dd8e2b
\fB0>>22&3C\fP as above computes the number of bytes in the IP header. \fB@\fP
Packit Service dd8e2b
makes this the new offset into the packet, which is the start of the TCP
Packit Service dd8e2b
header. The length of the TCP header (again in 32 bit words) is the left half
Packit Service dd8e2b
of byte 12 of the TCP header. The \fB12>>26&3C\fP computes this length in bytes
Packit Service dd8e2b
(similar to the IP header before). "@" makes this the new offset, which is the
Packit Service dd8e2b
start of the TCP payload. Finally, 8 reads bytes 8-12 of the payload and
Packit Service dd8e2b
\fB=\fP checks whether the result is any of 1, 2, 5 or 8.