Changeset 3a14f3b for lib


Ignore:
Timestamp:
09/14/07 16:05:43 (14 years ago)
Author:
Scott Raynel <smr26@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
a81d2fc
Parents:
4c1302b
Message:

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

Location:
lib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • lib/format_linux.c

    r394706e r3a14f3b  
    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
  • lib/format_pcap.c

    r9bc4689 r3a14f3b  
    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) {
  • lib/libtrace.h.in

    r4c1302b r3a14f3b  
    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
  • lib/trace.c

    r9e6b38b r3a14f3b  
    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
Note: See TracChangeset for help on using the changeset viewer.