Changeset 1691


Ignore:
Timestamp:
02/22/11 10:01:08 (2 years ago)
Author:
salcock
Message:
  • Fixed poor performance of the event API by greatly reducing the amount of packets created, copied and freed
  • We now cache the transport header and payload length for each packet
  • We now deal with Linux SLL Ethernet captures taken using tcpdump with -i any correctly.
  • Changed parameters for internal function trace_get_payload_from_sll - it now sets both the arphrd type and the next protocol
  • Moved ARPHRD definitions into a separate header file, as they come in handy anywhere we deal with SLL headers
Location:
trunk/lib
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/Makefile.am

    r1633 r1691  
    11lib_LTLIBRARIES = libtrace.la 
    2 include_HEADERS = libtrace.h dagformat.h lt_inttypes.h daglegacy.h rt_protocol.h erftypes.h wandio.h 
     2include_HEADERS = libtrace.h dagformat.h lt_inttypes.h daglegacy.h rt_protocol.h erftypes.h wandio.h  
    33 
    44AM_CFLAGS=@LIBCFLAGS@ 
     
    6868                ior-peek.c ior-stdio.c ior-thread.c \ 
    6969                iow-stdio.c iow-thread.c wandio.c \ 
    70                 wandio.h 
     70                wandio.h arphrd.h 
    7171 
    7272if DAG2_4 
  • trunk/lib/format_helper.c

    r1556 r1691  
    143143 
    144144        if (!trace->event.packet) { 
     145                trace->event.packet = trace_create_packet(); 
     146        } 
     147 
     148        if (!trace->event.waiting) { 
    145149                /* There is no packet event waiting for us, so create a new 
    146150                 * libtrace packet in the event structure and read the next 
     
    151155                 * function is called. */ 
    152156 
    153                 trace->event.packet = trace_create_packet(); 
    154157                trace->event.psize= 
    155158                        trace_read_packet(trace,trace->event.packet); 
     
    195198                                trace->event.trace_last_ts; 
    196199                        event.type = TRACE_EVENT_SLEEP; 
     200                        trace->event.waiting = true; 
    197201                        return event; 
    198202                } 
     
    214218        /* We do a lot of freeing and creating of packet buffers with this 
    215219         * method, but at least it works unlike what was here previously */ 
    216         if (packet->buf_control == TRACE_CTRL_PACKET) { 
    217                 free(packet->buffer); 
    218         } 
     220        //if (packet->buf_control == TRACE_CTRL_PACKET) { 
     221        //      free(packet->buffer); 
     222        //} 
    219223         
    220224        /* The packet that we had read earlier is now ready to be returned 
     
    228232        packet->buf_control = trace->event.packet->buf_control; 
    229233 
    230         trace->event.packet->buffer = NULL; 
    231         trace->event.packet->buf_control = TRACE_CTRL_EXTERNAL; 
    232          
    233         trace_destroy_packet(trace->event.packet); 
    234         trace->event.packet = NULL; 
     234        //trace->event.packet->buffer = NULL; 
     235        //trace->event.packet->buf_control = TRACE_CTRL_EXTERNAL; 
     236         
     237        //trace_destroy_packet(trace->event.packet); 
     238        //trace->event.packet = NULL; 
    235239 
    236240        event.type = TRACE_EVENT_PACKET; 
    237241 
    238242        trace->event.trace_last_ts = ts; 
     243        trace->event.waiting = false; 
    239244 
    240245        return event; 
  • trunk/lib/libtrace.h.in

    r1665 r1691  
    420420        buf_control_t buf_control;      /**< Describes memory ownership */ 
    421421        int capture_length;             /**< Cached capture length */ 
     422        int payload_length;             /**< Cached payload length */ 
    422423        void *l3_header;                /**< Cached l3 header */ 
    423424        uint16_t l3_ethertype;          /**< Cached l3 ethertype */ 
     425        void *l4_header;                /**< Cached transport header */ 
     426        uint8_t transport_proto;        /**< Cached transport protocol */ 
    424427} libtrace_packet_t; 
    425428 
  • trunk/lib/libtrace_int.h

    r1668 r1691  
    160160        /** The size of the current PACKET event */ 
    161161        int psize; 
     162        /** Whether there is a packet stored in *packet above waiting for an 
     163         * event to occur */ 
     164        bool waiting; 
    162165}; 
    163166 
     
    226229                                                                PRINTF(3,4); 
    227230 
     231/** Clears the cached values for a libtrace packet 
     232 * 
     233 * @param packet        The libtrace packet that requires a cache reset 
     234 */ 
     235void trace_clear_cache(libtrace_packet_t *packet); 
    228236 
    229237/** Converts the data provided in buffer into a valid libtrace packet 
     
    857865 * 
    858866 * @param link          A pointer to the Linux SLL header to be skipped 
    859  * @param[out] type     The ethertype of the next header 
     867 * @param[out] arphrd_type      The arp hardware type of the packet 
     868 * @param[out] next_header      The ethertype of the next header 
    860869 * @param[in,out] remaining     Updated with the number of captured bytes 
    861870 *                              remaining 
     
    874883 * calling this function. 
    875884 */      
    876 void *trace_get_payload_from_linux_sll(const void *link, uint16_t *type,  
     885void *trace_get_payload_from_linux_sll(const void *link, 
     886                uint16_t *arphrd_type,  
     887                uint16_t *next_header,  
    877888                uint32_t *remaining); 
    878889 
  • trunk/lib/link_wireless.c

    r1646 r1691  
    188188                        } else break; 
    189189                case TRACE_TYPE_LINUX_SLL: 
    190                         l = trace_get_payload_from_linux_sll(link, &type, NULL ); 
     190                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL ); 
    191191                        return trace_get_wireless_tsft(l, arphrd_type_to_libtrace(type), tsft); 
    192192 
     
    223223                        } else break; 
    224224                case TRACE_TYPE_LINUX_SLL: 
    225                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     225                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    226226                        return trace_get_wireless_flags(l, arphrd_type_to_libtrace(type), flags); 
    227227                default: 
     
    247247                        } else break; 
    248248                case TRACE_TYPE_LINUX_SLL: 
    249                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     249                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    250250                        return trace_get_wireless_rate(l, arphrd_type_to_libtrace(type), rate); 
    251251                default: 
     
    275275                        } else break; 
    276276                case TRACE_TYPE_LINUX_SLL: 
    277                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     277                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    278278                        return trace_get_wireless_freq(l, arphrd_type_to_libtrace(type), freq); 
    279279                default: 
     
    311311                        } else break; 
    312312                case TRACE_TYPE_LINUX_SLL: 
    313                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     313                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    314314                        return trace_get_wireless_channel_flags(l, arphrd_type_to_libtrace(type), flags); 
    315315                default: 
     
    342342                        } else break; 
    343343                case TRACE_TYPE_LINUX_SLL: 
    344                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     344                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    345345                        return trace_get_wireless_fhss_hopset(l, arphrd_type_to_libtrace(type), hopset); 
    346346                default: 
     
    369369                        } else break; 
    370370                case TRACE_TYPE_LINUX_SLL: 
    371                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     371                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    372372                        return trace_get_wireless_fhss_hoppattern(l, arphrd_type_to_libtrace(type), hoppattern); 
    373373                default: 
     
    395395                        } else break; 
    396396                case TRACE_TYPE_LINUX_SLL: 
    397                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     397                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    398398                        return trace_get_wireless_signal_strength_dbm(l, arphrd_type_to_libtrace(type), strength); 
    399399                default: 
     
    419419                        } else break; 
    420420                case TRACE_TYPE_LINUX_SLL: 
    421                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     421                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    422422                        return trace_get_wireless_noise_strength_dbm(l, arphrd_type_to_libtrace(type), strength); 
    423423                default: 
     
    443443                        } else break; 
    444444                case TRACE_TYPE_LINUX_SLL: 
    445                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     445                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    446446                        return trace_get_wireless_signal_strength_db(l, arphrd_type_to_libtrace(type), strength); 
    447447                default: 
     
    467467                        } else break; 
    468468                case TRACE_TYPE_LINUX_SLL: 
    469                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     469                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    470470                        return trace_get_wireless_noise_strength_db(l, arphrd_type_to_libtrace(type), strength); 
    471471                default: 
     
    497497                        } else break; 
    498498                case TRACE_TYPE_LINUX_SLL: 
    499                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     499                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    500500                        return trace_get_wireless_lock_quality(l, arphrd_type_to_libtrace(type), quality); 
    501501                default: 
     
    523523                        } else break; 
    524524                case TRACE_TYPE_LINUX_SLL: 
    525                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     525                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    526526                        return trace_get_wireless_tx_attenuation(l, arphrd_type_to_libtrace(type), attenuation); 
    527527                default: 
     
    547547                        } else break; 
    548548                case TRACE_TYPE_LINUX_SLL: 
    549                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     549                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    550550                        return trace_get_wireless_tx_attenuation_db(l, arphrd_type_to_libtrace(type), attenuation); 
    551551                default: 
     
    571571                        } else break; 
    572572                case TRACE_TYPE_LINUX_SLL: 
    573                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     573                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    574574                        return trace_get_wireless_tx_power_dbm(l, arphrd_type_to_libtrace(type), txpower); 
    575575                default: 
     
    596596                        } else break; 
    597597                case TRACE_TYPE_LINUX_SLL: 
    598                         l = trace_get_payload_from_linux_sll(link, &type, NULL); 
     598                        l = trace_get_payload_from_linux_sll(link, &type, NULL, NULL); 
    599599                        return trace_get_wireless_antenna(l, arphrd_type_to_libtrace(type), antenna); 
    600600                default: 
  • trunk/lib/linktypes.c

    r1646 r1691  
    4141#include <string.h> 
    4242 
    43 #ifndef WIN32 
    44 #include <net/if_arp.h> 
    45 #endif 
    46  
    47 #ifndef ARPHRD_ETHER 
    48 #define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */ 
    49 #endif 
    50  
    51 #ifndef ARPHRD_EETHER 
    52 #define ARPHRD_EETHER    2               /* Experimental Ethernet 10/100Mbps.  */ 
    53 #endif 
    54  
    55 #ifndef ARPHRD_PPP 
    56 #define ARPHRD_PPP      512 
    57 #endif 
    58  
    59 #ifndef ARPHRD_IEEE80211 
    60 #define ARPHRD_IEEE80211        801 
    61 #endif 
    62  
    63 #ifndef ARPHRD_NONE 
    64 #define ARPHRD_NONE     0xFFFE 
    65 #endif 
     43#include "arphrd.h" 
    6644 
    6745 
     
    209187                case ARPHRD_80211_RADIOTAP: return TRACE_TYPE_80211_RADIO; 
    210188                case ARPHRD_PPP: return TRACE_TYPE_NONE; 
     189                case ARPHRD_LOOPBACK: return TRACE_TYPE_NONE; 
    211190                case ARPHRD_NONE: return TRACE_TYPE_NONE; 
    212191        } 
     
    351330 
    352331                        /* Invalidate caches */ 
    353                         packet->l3_header = NULL; 
    354                         packet->capture_length = -1; 
    355  
     332                        trace_clear_cache(packet); 
    356333                        return true; 
    357334 
     
    377354 
    378355                        /* Invalidate caches */ 
    379                         packet->l3_header = NULL; 
    380                         packet->capture_length = -1; 
     356                        trace_clear_cache(packet); 
    381357                        break; 
    382358                default: 
     
    385361 
    386362        /* Invalidate caches */ 
    387         packet->l3_header = NULL; 
    388         packet->capture_length = -1; 
     363        trace_clear_cache(packet); 
    389364        return true; 
    390365} 
  • trunk/lib/protocols_l2.c

    r1646 r1691  
    3737#include <assert.h> 
    3838#include <stdlib.h> 
     39 
    3940 
    4041/* This file contains all the protocol decoding functions for layer 2  
     
    398399{ 
    399400        void *l; 
     401 
    400402        if (linktype == ~0U) { 
    401403                fprintf(stderr, "Unable to determine linktype for packet\n"); 
  • trunk/lib/protocols_pktmeta.c

    r1646 r1691  
    6161/* NB: type is returned as an ARPHRD_ type for SLL*/ 
    6262void *trace_get_payload_from_linux_sll(const void *link, 
    63                 uint16_t *type, uint32_t *remaining)  
     63                uint16_t *arphrd_type, uint16_t *next,  
     64                uint32_t *remaining)  
    6465{ 
    6566        libtrace_sll_header_t *sll; 
     
    7576        } 
    7677 
    77         if (type) *type = ntohs(sll->hatype); 
     78        /* The SLL header is actually in place of a link layer header, so 
     79         * we want to use the protocol field to tell our caller what the 
     80         * next header is going to be */ 
     81        if (next) *next = (libtrace_linktype_t)(ntohs(sll->protocol)); 
     82        if (arphrd_type) *arphrd_type = ntohs(sll->hatype); 
    7883 
    7984        return (void*)((char*)sll+sizeof(*sll)); 
     
    189194                case TRACE_TYPE_LINUX_SLL: 
    190195                        nexthdr = trace_get_payload_from_linux_sll(meta, 
    191                                         &arphrd, remaining); 
    192                         *linktype = arphrd_type_to_libtrace(arphrd); 
     196                                        &arphrd, NULL, remaining); 
     197 
     198                        /* Ethernet header is usually absent in SLL captures, 
     199                         * so we don't want to skip it just yet */ 
     200                        if (arphrd_type_to_libtrace(arphrd) == TRACE_TYPE_ETH)  
     201                                *linktype = TRACE_TYPE_NONE;  
     202                        else  
     203                                *linktype = arphrd_type_to_libtrace(arphrd); 
    193204                        return nexthdr; 
    194205                case TRACE_TYPE_80211_RADIO: 
  • trunk/lib/protocols_transport.c

    r1663 r1691  
    6868        size_t len = 0; 
    6969 
    70          
    71  
     70        /* Just use the cached length if we can */ 
     71        if (packet->payload_length != -1) 
     72                return packet->payload_length;   
     73 
     74        /* Set to zero so that we can return early without having to  
     75         * worry about forgetting to update the cached value */ 
     76        ((libtrace_packet_t *)packet)->payload_length = 0; 
    7277        layer = trace_get_layer3(packet, &ethertype, &rem); 
    73  
    7478        if (!layer) 
    7579                return 0; 
     
    122126        } 
    123127 
     128 
     129        ((libtrace_packet_t *)packet)->payload_length = len; 
    124130        return len; 
    125131 
     
    139145 
    140146        if (!remaining) remaining=&dummy_remaining; 
     147 
     148        if (packet->l4_header) { 
     149                void *link; 
     150                libtrace_linktype_t linktype; 
     151                link = trace_get_packet_buffer(packet, &linktype, remaining); 
     152                if (!link) 
     153                        return NULL; 
     154                *proto = packet->transport_proto; 
     155                *remaining -= (packet->l4_header - link); 
     156                return packet->l4_header; 
     157        } 
    141158 
    142159        transport = trace_get_layer3(packet,&ethertype,remaining); 
     
    154171                                 (libtrace_ip6_t*)transport, proto,remaining); 
    155172                        } 
    156                         return transport; 
     173                        break; 
    157174                case TRACE_ETHERTYPE_IPV6: /* IPv6 */ 
    158                         return trace_get_payload_from_ip6( 
     175                        transport = trace_get_payload_from_ip6( 
    159176                                (libtrace_ip6_t*)transport, proto, remaining); 
     177                        break; 
     178                default: 
     179                        *proto = 0; 
     180                        transport = NULL; 
     181                        break; 
    160182                         
    161183        } 
    162184 
    163         *proto=0; 
    164         return NULL; 
     185        ((libtrace_packet_t *)packet)->transport_proto = *proto; 
     186        ((libtrace_packet_t *)packet)->l4_header = transport; 
     187 
     188 
     189        return transport; 
    165190} 
    166191 
  • trunk/lib/trace.c

    r1687 r1691  
    243243        libtrace->event.psize = 0; 
    244244        libtrace->event.trace_last_ts = 0.0; 
     245        libtrace->event.waiting = false; 
    245246        libtrace->filter = NULL; 
    246247        libtrace->snaplen = 0; 
     
    590591        if (libtrace->uridata) 
    591592                free(libtrace->uridata); 
     593        if (libtrace->event.packet) 
     594                trace_destroy_packet(libtrace->event.packet); 
    592595        free(libtrace); 
    593596} 
     
    624627 
    625628        packet->buf_control=TRACE_CTRL_PACKET; 
    626         packet->capture_length=-1; 
     629        trace_clear_cache(packet); 
    627630        return packet; 
    628631} 
     
    648651        /* Reset the cache - better to recalculate than try to convert 
    649652         * the values over to the new packet */ 
    650         dest->capture_length = -1; 
    651         dest->l3_header = NULL; 
    652         dest->l3_ethertype = 0; 
    653          
     653        trace_clear_cache(dest);         
    654654        /* Ooooh nasty memcpys! This is why we want to avoid copying packets 
    655655         * as much as possible */ 
     
    712712                        size_t ret; 
    713713                        /* Clear the packet cache */ 
    714                         packet->capture_length = -1; 
    715                         packet->l3_header = NULL; 
    716                         packet->l3_ethertype = 0; 
    717  
     714                        trace_clear_cache(packet); 
    718715                        ret=libtrace->format->read_packet(libtrace,packet); 
    719716                        if (ret==(size_t)-1 || ret==0) { 
     
    777774         
    778775        /* Clear packet cache */ 
    779         packet->capture_length = -1; 
    780         packet->l3_header = NULL; 
    781         packet->l3_ethertype = 0; 
     776        trace_clear_cache(packet); 
    782777 
    783778        if (trace->format->prepare_packet) { 
     
    10991094 
    11001095        /* Clear the packet cache */ 
    1101         packet->capture_length = -1; 
    1102         packet->l3_header = NULL; 
    1103         packet->l3_ethertype = 0; 
     1096        trace_clear_cache(packet); 
    11041097         
    11051098        /* Store the trace we are reading from into the packet opaque 
     
    18181811        assert(trace); 
    18191812        return trace->accepted_packets; 
     1813} 
     1814 
     1815void trace_clear_cache(libtrace_packet_t *packet) { 
     1816 
     1817        packet->l3_header = NULL; 
     1818        packet->l4_header = NULL; 
     1819        packet->l3_ethertype = 0; 
     1820        packet->transport_proto = 0; 
     1821        packet->capture_length = -1; 
     1822        packet->payload_length = -1; 
     1823 
    18201824} 
    18211825 
Note: See TracChangeset for help on using the changeset viewer.