Browse Source

Reorganize the code to build the filter

develop
Damien Goutte-Gattat 9 years ago
parent
commit
eab71a01ac
  1. 48
      src/wait4pid.c

48
src/wait4pid.c

@ -141,9 +141,20 @@ struct __attribute__ ((__packed__)) cn_proc_msg {
static int
set_filter(int sock, pid_t *pids, size_t len)
{
int i;
struct sock_fprog flt;
struct sock_filter filter[256]; /* Max steps in a filter program. */
int i, j = 0;
struct sock_filter filter[256] = {
/* Load event type. */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
NLMSG_LENGTH(0) + offsetof(struct cn_proc_msg, evt.what)),
/* If this is a PROC_EVENT_EXIT, continue to the next step;
* otherwise go to the "block" step at the end of the filter. */
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, htonl(PROC_EVENT_EXIT), 0, 1 + len),
/* Load the process identifier. */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
NLMSG_LENGTH(0) +
offsetof(struct cn_proc_msg, evt.event_data.exit.process_pid))
};
if ( len > 251 ) {
errno = EINVAL;
@ -153,35 +164,22 @@ set_filter(int sock, pid_t *pids, size_t len)
flt.len = 5 + len;
flt.filter = filter;
/* Block the packet if proc_event.what != PROC_EVENT_EXIT */
flt.filter[j].code = BPF_LD+BPF_W+BPF_ABS;
flt.filter[j++].k = NLMSG_LENGTH(0)
+ offsetof(struct cn_proc_msg, evt.what);
flt.filter[j].code = BPF_JMP+BPF_JEQ+BPF_K;
flt.filter[j].k = htonl(PROC_EVENT_EXIT);
flt.filter[j].jt = 0; /* continue */
flt.filter[j++].jf = 1 + len; /* jump to the "block" instruction */
/* Get the process identifier */
flt.filter[j].code = BPF_LD+BPF_W+BPF_ABS;
flt.filter[j++].k = NLMSG_LENGTH(0)
+ offsetof(struct cn_proc_msg, evt.event_data.exit.process_pid);
for ( i = 0; i < len; i++ ) {
/* Accept the packet if its pid matches pids[i]. */
flt.filter[j].code = BPF_JMP+BPF_JEQ+BPF_K;
flt.filter[j].k = htonl(pids[i]);
flt.filter[j].jt = len - i; /* jump to the "accept" instruction */
flt.filter[j++].jf = 0; /* continue */
/* If the loaded PID matches pids[i], go to the "accept" step
* at the end of the filter; otherwise continue to the next step. */
filter[i+3].code = BPF_JMP+BPF_JEQ+BPF_K;
filter[i+3].k = htonl(pids[i]);
filter[i+3].jt = len - i;
filter[i+3].jf = 0;
}
/* No match, block the packet. */
flt.filter[j].code = BPF_RET+BPF_K;
flt.filter[j++].k = 0;
filter[len+3].code = BPF_RET+BPF_K;
filter[len+3].k = 0;
/* Accept the packet. */
flt.filter[j].code = BPF_RET+BPF_K;
flt.filter[j++].k = (uint)-1;
filter[len+4].code = BPF_RET+BPF_K;
filter[len+4].k = (uint)-1;
return setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &flt, sizeof(flt));
}

Loading…
Cancel
Save