Previous: Device Status, Up: Device Interface


10.8 Device Filter

— Function: kern_return_t device_set_filter (device_t device, mach_port_t receive_port, mach_msg_type_name_t receive_port_type, int priority, filter_array_t filter, mach_msg_type_number_t filter_count)

The function device_set_filter makes it possible to filter out selected data arriving at the device and forward it to a port. filter is a list of filter commands, which are applied to incoming data to determine if the data should be sent to receive_port. The IPC type of the send right is specified by receive_port_right, it is either MACH_MSG_TYPE_MAKE_SEND or MACH_MSG_TYPE_MOVE_SEND. The priority value is used to order multiple filters.

There can be up to NET_MAX_FILTER commands in filter. The actual number of commands is passed in filter_count. For the purpose of the filter test, an internal stack is provided. After all commands have been processed, the value on the top of the stack determines if the data is forwarded or the next filter is tried.

Each word of the command list specifies a data (push) operation (high order NETF_NBPO bits) as well as a binary operator (low order NETF_NBPA bits). The value to be pushed onto the stack is chosen as follows.

NETF_PUSHLIT
Use the next short word of the filter as the value.
NETF_PUSHZERO
Use 0 as the value.
NETF_PUSHWORD+N
Use short word N of the “data” portion of the message as the value.
NETF_PUSHHDR+N
Use short word N of the “header” portion of the message as the value.
NETF_PUSHIND+N
Pops the top long word from the stack and then uses short word N of the “data” portion of the message as the value.
NETF_PUSHHDRIND+N
Pops the top long word from the stack and then uses short word N of the “header” portion of the message as the value.
NETF_PUSHSTK+N
Use long word N of the stack (where the top of stack is long word 0) as the value.
NETF_NOPUSH
Don't push a value.

The unsigned value so chosen is promoted to a long word before being pushed. Once a value is pushed (except for the case of NETF_NOPUSH), the top two long words of the stack are popped and a binary operator applied to them (with the old top of stack as the second operand). The result of the operator is pushed on the stack. These operators are:

NETF_NOP
Don't pop off any values and do no operation.
NETF_EQ
Perform an equal comparison.
NETF_LT
Perform a less than comparison.
NETF_LE
Perform a less than or equal comparison.
NETF_GT
Perform a greater than comparison.
NETF_GE
Perform a greater than or equal comparison.
NETF_AND
Perform a bitise boolean AND operation.
NETF_OR
Perform a bitise boolean inclusive OR operation.
NETF_XOR
Perform a bitise boolean exclusive OR operation.
NETF_NEQ
Perform a not equal comparison.
NETF_LSH
Perform a left shift operation.
NETF_RSH
Perform a right shift operation.
NETF_ADD
Perform an addition.
NETF_SUB
Perform a subtraction.
NETF_COR
Perform an equal comparison. If the comparison is TRUE, terminate the filter list. Otherwise, pop the result of the comparison off the stack.
NETF_CAND
Perform an equal comparison. If the comparison is FALSE, terminate the filter list. Otherwise, pop the result of the comparison off the stack.
NETF_CNOR
Perform a not equal comparison. If the comparison is FALSE, terminate the filter list. Otherwise, pop the result of the comparison off the stack.
NETF_CNAND
Perform a not equal comparison. If the comparison is TRUE, terminate the filter list. Otherwise, pop the result of the comparison off the stack. The scan of the filter list terminates when the filter list is emptied, or a NETF_C... operation terminates the list. At this time, if the final value of the top of the stack is TRUE, then the message is accepted for the filter.

The function returns D_SUCCESS if some data was successfully written, D_INVALID_OPERATION if receive_port is not a valid send right, and D_NO_SUCH_DEVICE if device does not denote a device port or the device is dead or not completely open.