Changeset 1278

Show
Ignore:
Timestamp:
14/09/07 16:05:43 (1 year ago)
Author:
smr26
Message:

Allow libtrace applications to create filters based on pre-compiled BPF
bytecode as well as filterstrings. See trace_create_filter_from_bytecode()

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib/format_linux.c

    r1275 r1278  
    5151#include <errno.h> 
    5252 
     53#include <assert.h> 
    5354 
    5455struct libtrace_format_data_t { 
     
    161162        } 
    162163 
    163         /* Push BPF filter into the kernel. 
     164        /* Push BPF filter into the kernel. At this stage we can safely assume 
     165         * that the filterstring has been compiled, or the filter was supplied 
     166         * pre-compiled. 
    164167         */ 
    165168        if (filter != NULL) { 
     169                assert(filter->flag == 1); 
    166170                if (setsockopt(FORMAT(libtrace->format_data)->fd, 
    167171                                        SOL_SOCKET, 
     
    234238        pcap_t *pcap; 
    235239 
    236         /* We've been passed a filter, which hasn't been compiled yet. We need 
    237          * to figure out the linktype of the socket, compile the filter, check 
    238          * to make sure it's sane, then save it for trace_start() to push down 
    239          * into the kernel. 
    240          */ 
    241         sock = socket(PF_INET, SOCK_STREAM, 0); 
    242         memset(&ifr, 0, sizeof(struct ifreq)); 
    243         strncpy(ifr.ifr_name, libtrace->uridata, IF_NAMESIZE); 
    244         if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) { 
    245                 perror("Can't get HWADDR for interface"); 
    246                 return -1; 
    247         } 
    248         close(socket); 
    249  
    250         arphrd = ifr.ifr_hwaddr.sa_family; 
    251         dlt = libtrace_to_pcap_dlt(arphrd_type_to_libtrace(arphrd)); 
    252  
     240        /* Take a copy of the filter object as it was passed in */ 
    253241        f = (libtrace_filter_t *) malloc(sizeof(libtrace_filter_t)); 
    254242        memcpy(f, filter, sizeof(libtrace_filter_t)); 
    255  
    256         pcap = pcap_open_dead(dlt, FORMAT(libtrace->format_data)->snaplen); 
    257243         
    258         if (pcap_compile(pcap, &f->filter, f->filterstring, 0, 0) == -1) { 
    259                 perror("PCAP failed to compile the filterstring"); 
    260                 return -1; 
    261         } 
    262  
    263         pcap_close(pcap); 
    264  
     244        /* If we are passed a filter with "flag" set to zero, then we must 
     245         * compile the filterstring before continuing. This involves 
     246         * determining the linktype, passing the filterstring to libpcap to 
     247         * compile, and saving the result for trace_start() to push into the 
     248         * kernel. 
     249         * If flag is set to one, then the filter was probably generated using 
     250         * trace_create_filter_from_bytecode() and so we don't need to do 
     251         * anything (we've just copied it above). 
     252         */ 
     253        if (f->flag == 0) { 
     254                sock = socket(PF_INET, SOCK_STREAM, 0); 
     255                memset(&ifr, 0, sizeof(struct ifreq)); 
     256                strncpy(ifr.ifr_name, libtrace->uridata, IF_NAMESIZE); 
     257                if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) { 
     258                        perror("Can't get HWADDR for interface"); 
     259                        return -1; 
     260                } 
     261                close(socket); 
     262 
     263                arphrd = ifr.ifr_hwaddr.sa_family; 
     264                dlt = libtrace_to_pcap_dlt(arphrd_type_to_libtrace(arphrd)); 
     265 
     266                pcap = pcap_open_dead(dlt,  
     267                                FORMAT(libtrace->format_data)->snaplen); 
     268 
     269                if (pcap_compile(pcap, &f->filter, f->filterstring, 0, 0) == -1) { 
     270                        perror("PCAP failed to compile the filterstring"); 
     271                        return -1; 
     272                } 
     273 
     274                pcap_close(pcap); 
     275                 
     276                /* Set the "flag" to indicate that the filterstring has been 
     277                 * compiled 
     278                 */ 
     279                f->flag = 1; 
     280        } 
     281         
    265282        if (FORMAT(libtrace->format_data)->filter != NULL) 
    266283                free(FORMAT(libtrace->format_data)->filter); 
    267284         
    268285        FORMAT(libtrace->format_data)->filter = f; 
     286         
    269287        return 0; 
    270288#else 
  • trunk/lib/format_pcap.c

    r1269 r1278  
    104104        } 
    105105        if (DATA(libtrace)->filter) { 
    106                 pcap_compile(INPUT.pcap, &DATA(libtrace)->filter->filter, 
    107                                 DATA(libtrace)->filter->filterstring, 1, 0); 
     106                if (DATA(libtrace)->filter->flag == 0) { 
     107                        pcap_compile(INPUT.pcap,  
     108                                        &DATA(libtrace)->filter->filter, 
     109                                        DATA(libtrace)->filter->filterstring,  
     110                                        1, 0); 
     111                        DATA(libtrace)->filter->flag = 1; 
     112                } 
    108113                if (pcap_setfilter(INPUT.pcap,&DATA(libtrace)->filter->filter)  
    109114                                == -1) { 
  • trunk/lib/libtrace.h.in

    r1277 r1278  
    15281528libtrace_filter_t *trace_create_filter(const char *filterstring); 
    15291529 
    1530 /** apply a BPF filter 
     1530/** Setup a BPF filter based on pre-compiled byte-code. 
     1531 * @param bf_insns      A pointer to the start of the byte-code 
     1532 * @param bf_len        The number of BPF instructions   
     1533 * @returns             an opaque pointer to a libtrace_filter_t object 
     1534 * @note                The supplied byte-code is not checked for correctness. 
     1535 * @author              Scott Raynel 
     1536 */ 
     1537DLLEXPORT libtrace_filter_t * 
     1538trace_create_filter_from_bytecode(void *bf_insns, unsigned int bf_len); 
     1539 
     1540/** Apply a BPF filter to a packet 
    15311541 * @param filter        the filter opaque pointer 
    15321542 * @param packet        the packet opaque pointer 
     
    15411551                const libtrace_packet_t *packet); 
    15421552 
    1543 /** destory of BPF filter 
     1553/** Destroy a BPF filter 
    15441554 * @param filter        the filter opaque pointer 
    15451555 * Deallocate all the resources associated with a BPF filter 
  • trunk/lib/trace.c

    r1274 r1278  
    964964} 
    965965 
     966/** Setup a BPF filter based on pre-compiled byte-code. 
     967 * @param bf_insns      A pointer to the start of the byte-code 
     968 * @param bf_len        The number of BPF instructions 
     969 * @returns             an opaque pointer to a libtrace_filter_t object 
     970 * @note                The supplied byte-code is not checked for correctness. 
     971 * @author              Scott Raynel 
     972 */ 
     973DLLEXPORT libtrace_filter_t * 
     974trace_create_filter_from_bytecode(void *bf_insns, unsigned int bf_len) 
     975{ 
     976#ifndef HAVE_BPF 
     977        fprintf(stderr, "This version of libtrace does not have BPF support\n"); 
     978        return NULL; 
     979#else 
     980        struct libtrace_filter_t *filter = (struct libtrace_filter_t *) 
     981                malloc(sizeof(struct libtrace_filter_t)); 
     982        filter->filter.bf_insns = (struct bpf_insn *) 
     983                malloc(sizeof(struct bpf_insn) * bf_len); 
     984         
     985        memcpy(filter->filter.bf_insns, bf_insns, 
     986                        bf_len * sizeof(struct bpf_insn)); 
     987         
     988        filter->filter.bf_len = bf_len; 
     989        filter->filterstring = NULL; 
     990        /* "flag" indicates that the filter member is valid */ 
     991        filter->flag = 1;  
     992         
     993        return filter; 
     994#endif 
     995} 
     996 
    966997/* setup a BPF filter 
    967998 * @param filterstring a char * containing the bpf filter string