size_t bpf_arg_comp(struct sock_filter **pfilter, int op, int argidx, unsigned long c, unsigned int label_id) { struct sock_filter *filter = calloc(BPF_ARG_COMP_LEN + 1, sizeof(struct sock_filter)); struct sock_filter *curr_block = filter; size_t (*comp_function)(struct sock_filter *filter, unsigned long k, unsigned char jt, unsigned char jf); int flip = 0; /* Load arg */ curr_block += bpf_load_arg(curr_block, argidx); /* Jump type */ switch (op) { case EQ: comp_function = bpf_comp_jeq; flip = 0; break; case NE: comp_function = bpf_comp_jeq; flip = 1; break; case SET: comp_function = bpf_comp_jset; flip = 0; break; default: *pfilter = NULL; return 0; } /* * It's easier for the rest of the code to have the true branch * skip and the false branch fall through. */ unsigned char jt = flip ? NEXT : SKIP; unsigned char jf = flip ? SKIP : NEXT; curr_block += comp_function(curr_block, c, jt, jf); curr_block += set_bpf_jump_lbl(curr_block, label_id); *pfilter = filter; return curr_block - filter; }
/* Binary search with compare function - comp_function. If search_ptr is found in the container, it will return its position in the container. Otherwise, it will return -1 and set insertion_position to the position search_ptr can be inserted into the container*/ int OC_binary_search(const struct Ordered_container* c_ptr, const void* search_ptr, int *insertion_position, int (*comp_function) (const void* arg1, const void* arg2)) { int low, high, mid, comp_result; low = 0; high = c_ptr->size-1; while(low <= high) { mid = (low+high) / 2; comp_result = comp_function(search_ptr, c_ptr->array[mid]); if(comp_result < 0) high = mid - 1; else if(comp_result > 0) low = mid + 1; else return mid; /*found match*/ } *insertion_position = high + 1; /*no match, set the insertion position */ return -1; /*no match */ }