aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/bpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'wiretap/bpf.c')
-rw-r--r--wiretap/bpf.c373
1 files changed, 0 insertions, 373 deletions
diff --git a/wiretap/bpf.c b/wiretap/bpf.c
deleted file mode 100644
index 3f02859d13..0000000000
--- a/wiretap/bpf.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * bpf.c
- * -----
- * Creates and handles the BPF code produced by wiretap.
- *
- * Gilbert Ramirez
- */
-
-#ifndef __G_LIB_H__
-#include <glib.h>
-#endif
-
-#include <sys/types.h>
-#include <netinet/in.h>
-
-#include "wtap.h"
-#include "rt-compile.h"
-#include "rt-global.h"
-#include "bpf-engine.h"
-#include "bpf.h"
-
-
-static GList *bpf_code_just_parsed = NULL;
-static struct bpf_instruction *bpf_record = NULL;
-
-static int
-bpf_clean_jump(GList *L, int i_this, int jmp, int num_bpf_instructions,
- int i_ret_success, int i_ret_failure);
-static void
-bpf_pass1(GList *L);
-
-static GList*
-bpf_mk_bytecmp(int ftype, int rel_opcode, guint8 *bytes);
-
-static void
-bpf_optimize(GList *L);
-
-static int
-bpf_attach(wtap *wth);
-
-static void
-bpf_attach_record(gpointer bpf_code, gpointer junk);
-
-static int
-offline_attach(wtap *wth);
-
-
-/* sets function pointers in rt-grammar.y to point to the BPF-related
- * functions */
-void
-wtap_filter_bpf_init(void)
-{
- mk_bytecmp = bpf_mk_bytecmp;
- mk_optimize = bpf_optimize;
- mk_attach = bpf_attach;
-}
-
-/* almost the same as bpf_init... */
-void
-wtap_filter_offline_init(wtap *wth)
-{
- int fi; /* filter index */
-
- mk_bytecmp = bpf_mk_bytecmp;
- mk_optimize = bpf_optimize;
- mk_attach = offline_attach;
-
- wtap_filter_offline_clear(wth);
-
- /* make the offline filter array */
- wth->filter.offline = g_malloc(sizeof(int*) * WTAP_NUM_ENCAP_TYPES);
- wth->filter_type = WTAP_FILTER_OFFLINE;
- wth->offline_filter_lengths = g_malloc(sizeof(int) * WTAP_NUM_ENCAP_TYPES);
-
- for (fi = 0; fi < WTAP_NUM_ENCAP_TYPES; fi++) {
- wth->filter.offline[fi] = NULL;
- }
-}
-
-/* Removes an offline filter from a wtap struct, and frees memory used
- * by that filter */
-void
-wtap_filter_offline_clear(wtap *wth)
-{
- int fi; /* filter index */
-
- if (wth->filter.offline) {
- for (fi = 0; fi < WTAP_NUM_ENCAP_TYPES; fi++) {
- if (wth->filter.offline[fi])
- g_free(wth->filter.offline[fi]);
- }
- g_free(wth->filter.offline);
- g_free(wth->offline_filter_lengths);
- }
- wth->filter_type = WTAP_FILTER_NONE;
-}
-
-/* Allocate a new bpf_code_unit structure and initialize the BPF instruction
- * codes to the values passed by the caller. */
-static struct bpf_code_unit *
-bpf_code_unit_alloc(guint8 label, guint16 code, guint8 jt, guint8 jf, guint32 k)
-{
- struct bpf_code_unit *bpf;
-
- bpf = g_malloc(sizeof(struct bpf_code_unit));
- bpf->line_label = label;
- bpf->bpf.code = code;
- bpf->bpf.jt = jt;
- bpf->bpf.jf = jf;
- bpf->bpf.k = k;
-
- /*g_print("{ %d { 0x%02x, %d, %d, 0x%08x }},\n",
- label, code, jt, jf, k);*/
- return bpf;
-}
-
-
-/* Finds ftype in the bytecmp_table, the relation, and the n-string
-byte array, and creates BPF that will check those bytes */
-static GList*
-bpf_mk_bytecmp(int ftype, int rel_opcode, guint8 *bytes)
-{
- GList *L;
- struct bpf_code_unit *bpf;
- int len_to_cmp, offset, endpoint, label;
- bytecmp_info *b;
-
- L = g_list_alloc();
-
- /* find the field in the table */
- b = lookup_bytecmp(ftype);
-
- /* How many bytes do we have to compare, and where? */
- len_to_cmp = b->length;
- offset = b->offset;
- endpoint = len_to_cmp + offset;
- /*g_print("len_to_cmp=%d, offset=%d, endpoint=%d\n",
- len_to_cmp, offset, endpoint);
- g_print("bytes: (%d) %02X:%02X:%02X\n",
- bytes[0], bytes[1], bytes[2], bytes[3]);*/
-
- label = NEXT_BLOCK;
- /* loop until we have written instructions to compare
- all bytes */
- while (len_to_cmp) {
-
- if (len_to_cmp >= 4) {
- bpf = bpf_code_unit_alloc(label,
- BPF_LD|BPF_W|BPF_ABS,
- 0, 0, endpoint - 4);
- g_list_append(L, bpf);
- label = NO_LABEL;
-
- endpoint -= 4;
- bpf = bpf_code_unit_alloc(NO_LABEL,
- BPF_JMP|BPF_JEQ,
- (len_to_cmp == 4 ? END_OF_PROGRAM_SUCCESS : 0),
- NEXT_BLOCK,
- phtonl(&bytes[len_to_cmp-3]));
- g_list_append(L, bpf);
-
- len_to_cmp -= 4;
- }
- else if (len_to_cmp == 3) {
- bpf = bpf_code_unit_alloc(label,
- BPF_LD|BPF_W|BPF_ABS,
- 0, 0, endpoint - 3);
- g_list_append(L, bpf);
- label = NO_LABEL;
- endpoint -= 3;
-
- bpf = bpf_code_unit_alloc(NO_LABEL,
- BPF_ALU|BPF_AND,
- 0, 0, 0xffffff);
- /*htonl(0xffffff));*/
- g_list_append(L, bpf);
-
- bpf = bpf_code_unit_alloc(NO_LABEL,
- BPF_JMP|BPF_JEQ,
- (len_to_cmp == 3 ? END_OF_PROGRAM_SUCCESS : 0),
- NEXT_BLOCK,
- phtonl(&bytes[len_to_cmp-2]) & 0xffffff00);
- g_list_append(L, bpf);
-
- len_to_cmp -= 3;
- }
- else if (len_to_cmp == 2) {
- bpf = bpf_code_unit_alloc(label,
- BPF_LD|BPF_H|BPF_ABS,
- 0, 0, endpoint - 2);
- g_list_append(L, bpf);
- label = NO_LABEL;
-
- endpoint -= 2;
- bpf = bpf_code_unit_alloc(NO_LABEL,
- BPF_JMP|BPF_JEQ,
- (len_to_cmp == 2 ? END_OF_PROGRAM_SUCCESS : 0),
- NEXT_BLOCK,
- (guint32)phtons(&bytes[len_to_cmp-1]));
- g_list_append(L, bpf);
-
- len_to_cmp -= 2;
- }
- else if (len_to_cmp == 1) {
- bpf = bpf_code_unit_alloc(label,
- BPF_LD|BPF_B|BPF_ABS,
- 0, 0, endpoint - 1);
- g_list_append(L, bpf);
- label = NO_LABEL;
-
- endpoint--;
- bpf = bpf_code_unit_alloc(NO_LABEL,
- BPF_JMP|BPF_JEQ,
- END_OF_PROGRAM_SUCCESS, NEXT_BLOCK,
- bytes[len_to_cmp]);
- g_list_append(L, bpf);
- len_to_cmp--;
- }
- }
-
-
- L = g_list_remove(L, 0);
- return L;
-}
-
-
-static void
-bpf_optimize(GList *L)
-{
- bpf_pass1(L);
- bpf_code_just_parsed = L;
-}
-
-/* after the BPF code is constructed from the parser, this step is run. During
- * pass1 we:
- *
- * 1. Clean up the jump variables
- */
-static void
-bpf_pass1(GList *L)
-{
- struct bpf_code_unit *bpf;
- int num_bpf_instructions;
- int i_ret_success;
- int i_ret_failure;
- int i;
-
- /* Attach a SUCCESS return to the end of the BPF code */
- bpf = bpf_code_unit_alloc(END_OF_PROGRAM_SUCCESS, BPF_RET, 0, 0, 0xffff);
- g_list_append(L, bpf);
-
- /* Attach a FAILURE return to the end of the BPF code */
- bpf = bpf_code_unit_alloc(END_OF_PROGRAM_FAILURE, BPF_RET, 0, 0, 0);
- g_list_append(L, bpf);
-
- num_bpf_instructions = g_list_length(L);
- i_ret_success = num_bpf_instructions - 2;
- i_ret_failure = num_bpf_instructions - 1;
-
- for(i = 0; i < num_bpf_instructions; i++) {
- bpf = (struct bpf_code_unit*) g_list_nth_data(L, i);
- if (!bpf)
- continue;
-
- /* Check for Jump to end failure/success */
- if (bpf->bpf.code & BPF_JMP) {
-
- bpf->bpf.jt = bpf_clean_jump(L, i, bpf->bpf.jt, num_bpf_instructions,
- i_ret_success, i_ret_failure);
-
- bpf->bpf.jf = bpf_clean_jump(L, i, bpf->bpf.jf, num_bpf_instructions,
- i_ret_success, i_ret_failure);
- }
- }
-}
-
-static int
-bpf_clean_jump(GList *L, int i_this, int jmp, int num_bpf_instructions,
- int i_ret_success, int i_ret_failure)
-{
- int i;
- struct bpf_code_unit *bpf;
-
- switch(jmp) {
- case END_OF_PROGRAM_SUCCESS:
- return i_ret_success - i_this - 1;
-
- case END_OF_PROGRAM_FAILURE:
- return i_ret_failure - i_this - 1;
-
- case NEXT_BLOCK:
- for (i = i_this + 1; i < num_bpf_instructions; i++) {
- bpf = (struct bpf_code_unit*) g_list_nth_data(L, i);
- if (!bpf)
- continue;
- if (bpf->line_label == NEXT_BLOCK) {
- return i - i_this - 1;
- }
- }
- /* failed to find NEXT_BLOCK.... chose FAILURE */
- return i_ret_failure - i_this - 1;
-
- /* default: nothing */
- }
- return jmp;
-}
-
-
-
-/* Takes code from bpf_code_just_parsed and attaches it to wth
- * returns 1 if sucessfull, 0 if not */
-static int bpf_attach(wtap *wth)
-{
- if (wth->filter.bpf)
- g_free(wth->filter.bpf);
-
- /* filter_length will be number of bpf_block records */
- wth->filter_length = g_list_length(bpf_code_just_parsed) - 1;
-
- wth->filter.bpf = g_malloc(wth->filter_length *
- sizeof(struct bpf_instruction));
- wth->filter_type = WTAP_FILTER_BPF;
-
- bpf_record = wth->filter.bpf;
-
- g_list_foreach(bpf_code_just_parsed, bpf_attach_record, NULL);
-
- if (bpf_chk_filter(wth->filter.bpf, wth->filter_length) == 0)
- return 1;
- else
- return 0;
-
-}
-
-void bpf_attach_record(gpointer bpf_code, gpointer junk)
-{
- struct bpf_code_unit *bpf_c = (struct bpf_code_unit*) bpf_code;
-
- struct bpf_instruction *bpf_i;
-
- if (!bpf_c)
- return;
-
- bpf_i = &(bpf_c->bpf);
- memcpy(bpf_record, bpf_i, sizeof(struct bpf_instruction));
- bpf_record++;
-}
-
-
-/* Takes code from bpf_code_just_parsed and attachs it to wth.
- * returns 1 if sucessfull, 0 if not */
-static int offline_attach(wtap *wth)
-{
- /* filter_length will be number of bpf_instruction records */
- wth->offline_filter_lengths[comp_encap_type] =
- g_list_length(bpf_code_just_parsed);
-
- /* Make space for this filter */
- wth->filter.offline[comp_encap_type] =
- g_malloc(wth->offline_filter_lengths[comp_encap_type]
- * sizeof(struct bpf_instruction));
-
- bpf_record = wth->filter.offline[comp_encap_type];
-
- g_list_foreach(bpf_code_just_parsed, bpf_attach_record, NULL);
-
- if (bpf_chk_filter(wth->filter.offline[comp_encap_type],
- wth->offline_filter_lengths[comp_encap_type]) == 0)
- return 1;
- else
- return 0;
-}
-