Changeset c0506ea


Ignore:
Timestamp:
09/20/11 14:21:53 (9 years ago)
Author:
Shane Alcock <salcock@…>
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:
c0ccccd
Parents:
2cf2c2d
Message:
  • We now use pcap_create and pcap_activate for pcap interfaces if libpcap 1.0 or later is available. This doesn't seem to make much of a difference performance-wise, as pcap_open_live was updated to use these functions anyway. This means if mmapped packet capture is available, we would have used it via pcap_open_live anyway.
  • Added a new function (trace_interrupt). Calling this function will set an internal variable which can be used to cause any blocking read_packet function to exit with an EOF. Useful for programs that are handling signals themselves and need a way to tell libtrace to stop. Prior to this, programs like tracestats would not exit on Ctrl-C if reading from a pcap interface which was not receiving any packets.
  • Updated pcap interface format to respond to trace_interrupt.
  • Optimising trace_apply_filter to minimise calls to trace_get_link_type and trace_get_packet_buffer.
  • Removed unused extern variable "form" from libtrace_int.h
  • Fixed bug with filters in the pcap interface format which would result in "invalid BPF program" error message when filter was definitely legit.
  • Updated version number to 3.0.13
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • README

    r33e8f4d rc0506ea  
    1 libtrace 3.0.12
     1libtrace 3.0.13
    22
    33---------------------------------------------------------------------------
  • configure.in

    r33e8f4d rc0506ea  
    44# and in the README
    55
    6 AC_INIT([libtrace],[3.0.12],[contact@wand.net.nz],[libtrace])
     6AC_INIT([libtrace],[3.0.13],[contact@wand.net.nz],[libtrace])
    77
    88LIBTRACE_MAJOR=3
    99LIBTRACE_MID=0
    10 LIBTRACE_MINOR=12
     10LIBTRACE_MINOR=13
    1111
    1212# OpenSolaris hides libraries like libncurses in /usr/gnu/lib, which is not
     
    221221# Check for libpcap
    222222AC_CHECK_LIB(pcap,pcap_next_ex,pcapfound=1,pcapfound=0)
     223AC_CHECK_LIB(pcap,pcap_create,pcapcreate=1,pcapcreate=0)
    223224AC_CHECK_FUNCS(pcap_inject pcap_sendpacket pcap_setnonblock)
    224225AC_CHECK_DECLS([BIOCSETIF],,,[
     
    248249        AC_DEFINE([HAVE_LIBPCAP],1,[compile with libpcap support])
    249250        AC_DEFINE([HAVE_BPF_FILTER],1,[compile with bpf filter support])
     251fi
     252
     253if test "$pcapcreate" = 1; then
     254        AC_DEFINE([HAVE_PCAP_CREATE],1,[compile with libpcap 1.0 support])
    250255fi
    251256
     
    542547echo
    543548AC_MSG_NOTICE([Libtrace version $PACKAGE_VERSION])
    544 reportopt "Compiled with PCAP 0.8 support" $ac_cv_lib_pcap_pcap_next_ex
     549if test "$pcapcreate" = 1; then
     550        AC_MSG_NOTICE([Compiled with PCAP support: >= 1.0])
     551else
     552        AC_MSG_NOTICE([Compiled with PCAP support: < 1.0])
     553fi
     554
    545555reportopt "Compiled with compressed trace (zlib) support" $ac_cv_lib_z_deflate
    546556reportopt "Compiled with compressed trace (bz2) support" $ac_cv_lib_bz2_BZ2_bzDecompressInit
  • lib/format_pcap.c

    r5f329ab rc0506ea  
    243243static int pcapint_start_input(libtrace_t *libtrace) {
    244244        char errbuf[PCAP_ERRBUF_SIZE];
     245
     246#ifdef HAVE_PCAP_CREATE
     247        int ret = 0;
    245248       
     249        if ((INPUT.pcap = pcap_create(libtrace->uridata, errbuf)) == NULL) {
     250                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
     251                return -1; /* failure */
     252        }
     253        if ((pcap_set_snaplen(INPUT.pcap, DATA(libtrace)->snaplen) ==
     254                                PCAP_ERROR_ACTIVATED)) {
     255                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
     256                return -1; /* failure */
     257        }
     258
     259        if ((pcap_set_promisc(INPUT.pcap, DATA(libtrace)->promisc) ==
     260                                PCAP_ERROR_ACTIVATED)) {
     261                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
     262                return -1; /* failure */
     263        }
     264       
     265        if ((pcap_set_timeout(INPUT.pcap, 1) == PCAP_ERROR_ACTIVATED)) {
     266                trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",errbuf);
     267                return -1; /* failure */
     268        }
     269
     270        if ((ret = pcap_activate(INPUT.pcap)) != 0) {
     271                if (ret == PCAP_WARNING_PROMISC_NOTSUP) {
     272                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,"Promiscuous mode unsupported");
     273                        return -1;
     274                }
     275                if (ret == PCAP_WARNING) {
     276                        pcap_perror(INPUT.pcap, "Pcap Warning:");
     277                } else {
     278                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"%s",
     279                                        pcap_geterr(INPUT.pcap));
     280                        return -1;
     281                }
     282        }
     283                         
     284#else   
     285
    246286        /* Open the live device */
    247287        if ((INPUT.pcap =
     
    254294                return -1; /* failure */
    255295        }
     296#endif
    256297        /* Set a filter if one is defined */
    257298        if (DATA(libtrace)->filter) {
     299                if (DATA(libtrace)->filter->flag == 0) {
     300                        pcap_compile(INPUT.pcap,
     301                                        &DATA(libtrace)->filter->filter,
     302                                        DATA(libtrace)->filter->filterstring,
     303                                        1, 0);
     304                        DATA(libtrace)->filter->flag = 1;
     305                }
    258306                if (pcap_setfilter(INPUT.pcap,&DATA(libtrace)->filter->filter)
    259307                        == -1) {
     
    370418                switch(ret) {
    371419                        case 1: break; /* no error */
    372                         case 0: continue; /* timeout expired */
     420                        case 0:
     421                                if (libtrace_halt)
     422                                        return 0;
     423                                continue; /* timeout expired */
    373424                        case -1:
    374425                                trace_set_err(libtrace,TRACE_ERR_BAD_PACKET,
  • lib/libtrace.h.in

    ree58d0d rc0506ea  
    775775DLLEXPORT void trace_help(void);
    776776
     777/** Causes a libtrace reader to stop blocking whilst waiting on new packets
     778 * and immediately return EOF.
     779 *
     780 * This function is useful if you are handling signals within your libtrace
     781 * program. If a live source is not receiving any packets (or they are being
     782 * filtered), a call to trace_read_packet will result in an infinite loop as
     783 * it will block until a packet is received. Normally, a SIGINT would cause the
     784 * program to end and thus break the loop, but if you are handling the signal
     785 * yourself then that signal will never reach libtrace.
     786 *
     787 * Instead this function sets a global variable within libtrace that will
     788 * cause a blocking live capture to break on the next internal timeout,
     789 * allowing control to be returned to the user and their own signal handling
     790 * to kick in.
     791 */
     792DLLEXPORT void trace_interrupt(void);
     793
    777794/** @name Trace management
    778795 * These members deal with creating, configuring, starting, pausing and
  • lib/libtrace_int.h

    r9cc1266 rc0506ea  
    762762
    763763/** The list of registered capture formats */
    764 extern struct libtrace_format_t *form;
     764//extern struct libtrace_format_t *form;
     765
     766/** Specifies whether any blocking packet readers should cease reading
     767 * immediately
     768 */
     769extern int libtrace_halt;
    765770
    766771/** Registers a new capture format module.
  • lib/trace.c

    ree58d0d rc0506ea  
    103103
    104104static struct libtrace_format_t *formats_list = NULL;
     105
     106int libtrace_halt = 0;
    105107
    106108/* strncpy is not assured to copy the final \0, so we
     
    11841186 */
    11851187static int trace_bpf_compile(libtrace_filter_t *filter,
    1186                 const libtrace_packet_t *packet ) {
     1188                const libtrace_packet_t *packet,
     1189                void *linkptr,
     1190                libtrace_linktype_t linktype    ) {
    11871191#ifdef HAVE_BPF_FILTER
    1188         void *linkptr = 0;
    1189         libtrace_linktype_t linktype;
    11901192        assert(filter);
    11911193
    11921194        /* If this isn't a real packet, then fail */
    1193         linkptr = trace_get_packet_buffer(packet,&linktype,NULL);
    11941195        if (!linkptr) {
    11951196                trace_set_err(packet->trace,
     
    12441245        bool free_packet_needed = false;
    12451246        int ret;
     1247        libtrace_linktype_t linktype;
    12461248        libtrace_packet_t *packet_copy = (libtrace_packet_t*)packet;
    12471249
     
    12511253        /* Match all non-data packets as we probably want them to pass
    12521254         * through to the caller */
    1253         if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)
     1255        linktype = trace_get_link_type(packet);
     1256
     1257        if (linktype == TRACE_TYPE_NONDATA)
    12541258                return 1;       
    12551259
    1256         if (libtrace_to_pcap_dlt(trace_get_link_type(packet))==~0U) {
     1260        if (libtrace_to_pcap_dlt(linktype)==~0U) {
    12571261               
    12581262                /* If we cannot get a suitable DLT for the packet, it may
     
    12671271                free_packet_needed=true;
    12681272
    1269                 while (libtrace_to_pcap_dlt(trace_get_link_type(packet_copy))==
    1270                                 ~0U) {
     1273                while (libtrace_to_pcap_dlt(linktype) == ~0U) {
    12711274                        if (!demote_packet(packet_copy)) {
    12721275                                trace_set_err(packet->trace,
     
    12781281                                return -1;
    12791282                        }
    1280                 }
     1283                        linktype = trace_get_link_type(packet_copy);
     1284                }
     1285
    12811286        }
    12821287       
     
    12921297         * what the link type was
    12931298         */
    1294         if (trace_bpf_compile(filter,packet_copy)==-1) {
     1299        if (trace_bpf_compile(filter,packet_copy,linkptr,linktype)==-1) {
    12951300                if (free_packet_needed) {
    12961301                        trace_destroy_packet(packet_copy);
     
    18341839        packet->l4_remaining = 0;
    18351840
     1841}
     1842
     1843void trace_interrupt(void) {
     1844        libtrace_halt = 1;
    18361845}
    18371846
Note: See TracChangeset for help on using the changeset viewer.