|
A packet filter consists of the filter command list length (in units
of ushort_ts), and the filter command list itself. (The
priority field mentioned above is ignored in this implementation.) Each filter
command list specifies a sequence of actions that operate on an internal stack
of ushort_ts ("shortwords"). Each shortword
of the command list specifies one of the actions ENF_PUSHLIT, ENF_PUSHZERO, ENF_PUSHONE, ENF_PUSHFFFF, ENF_PUSHFF00, ENF_PUSH00FF,
or ENF_PUSHWORD+n, which respectively
push the next shortword of the command list, zero, one, 0xFFFF, 0xFF00, 0x00FF,
or shortword n of the subject message on the stack,
and a binary operator from the set {ENF_EQ, ENF_NEQ, ENF_LT, ENF_LE, ENF_GT, ENF_GE, ENF_AND, ENF_OR, ENF_XOR} which then operates on the top
two elements of the stack and replaces them with its result. When both an
action and operator are specified in the same shortword, the action is performed
followed by the operation.
The binary operator can also be from the set {ENF_COR, ENF_CAND, ENF_CNOR, ENF_CNAND}.
These are "short-circuit" operators, in that they terminate the
execution of the filter immediately if the condition they are checking for
is found, and continue otherwise. All pop two elements from the stack and
compare them for equality; ENF_CAND
returns false if the result is false; ENF_COR returns true if the result is true; ENF_CNAND returns true if the result is false; ENF_CNOR returns false if the result is true. Unlike the other binary
operators, these four do not leave a result on the stack, even if they continue.
The short-circuit operators should be used when possible, to reduce
the amount of time spent evaluating filters. When they are used, you should
also arrange the order of the tests so that the filter will succeed or fail
as soon as possible; for example, checking the IP
destination field of a UDP packet is more
likely to indicate failure than the packet type field.
The special action ENF_NOPUSH
and the special operator ENF_NOP
can be used to only perform the binary operation or to only push a value on
the stack. Since both are (conveniently) defined to be zero, indicating only
an action actually specifies the action followed by ENF_NOP,
and indicating only an operation actually specifies ENF_NOPUSH followed by the operation.
After executing the filter command list, a non-zero value (true) left
on top of the stack (or an empty stack) causes the incoming packet to be accepted
and a zero value (false) causes the packet to be rejected. (If the filter
exits as the result of a short-circuit operator, the top-of-stack value is
ignored.) Specifying an undefined operation or action in the command list
or performing an illegal operation or action (such as pushing a shortword
offset past the end of the packet or executing a binary operator with fewer
than two shortwords on the stack) causes a filter to reject the packet.
|