Changeset 7c72e4d for lib


Ignore:
Timestamp:
06/20/07 13:10:40 (14 years ago)
Author:
Perry Lorier <perry@…>
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:
8ee3dbd
Parents:
f93f0b3
Message:

Add caching of trace_get_capture_length() (since this is used a lot in protocol
decodes to figure out if we captured the full header we're about to decode).

Add caching of the l3 header (avoiding parsing the linktype/l2/l2.5 protocol
headers).

Location:
lib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • lib/libtrace.h.in

    r67b0d4d r7c72e4d  
    323323        libtrace_rt_types_t  type;      /**< rt protocol type for the packet */
    324324        buf_control_t buf_control;      /**< who owns the memory */
     325        int capture_length;             /**< Cached capture length */
     326        void *l3_header;                /**< Cached l3 header */
     327        uint16_t l3_ethertype;          /**< Cached l3 ethertype */
    325328} libtrace_packet_t;
    326329
     
    946949void *trace_get_link(const libtrace_packet_t *packet);
    947950
    948 /** get a pointer to the IP header (if any)
    949  * @param packet        the packet opaque pointer
    950  *
    951  * @return a pointer to the IP header, or NULL if there is no IP header
     951/** get a pointer to the IPv4 header (if any)
     952 * @param packet        the packet opaque pointer
     953 *
     954 * @return a pointer to the IPv4 header, or NULL if there is no IPv4 header
    952955 */
    953956DLLEXPORT SIMPLE_FUNCTION
     
    961964DLLEXPORT SIMPLE_FUNCTION
    962965libtrace_ip6_t *trace_get_ip6(libtrace_packet_t *packet);
     966
     967/** Get a pointer to the layer 3 header.
     968 * @param packet                The packet opaque pointer
     969 * @param[out] ethertype        The ethertype of the layer 3 header
     970 * @param[out] remaining        The amount of space available after this header
     971 *                              has been removed.
     972 *
     973 * @return a pointer to the layer 3 header.
     974 * remaining may be NULL, otherwise it will be filled in by the remaining size
     975 * of the captured packet.
     976 */
     977DLLEXPORT SIMPLE_FUNCTION
     978void *trace_get_layer3(libtrace_packet_t *packet,
     979                uint16_t *ethertype, uint32_t *remaining);
    963980
    964981/** Gets a pointer to the transport layer header (if any)
     
    13121329 */
    13131330DLLEXPORT SIMPLE_FUNCTION
    1314 size_t trace_get_capture_length(const libtrace_packet_t *packet);
     1331size_t trace_get_capture_length(libtrace_packet_t *packet);
    13151332
    13161333/** Get the size of the packet as it was seen on the wire.
  • lib/linktypes.c

    rf93f0b3 r7c72e4d  
    161161                case ARPHRD_PPP: return TRACE_TYPE_NONE;
    162162        }
     163        printf("Unknown ARPHRD %08x\n",arphrd);
    163164        return ~0U;
    164165}
     
    300301                        packet->trace=trace;
    301302
     303                        /* Invalidate caches */
     304                        packet->l3_header = NULL;
     305                        packet->capture_length = -1;
     306
    302307                        return true;
    303308
     
    321326                                trace_get_capture_length(packet)
    322327                                        -sizeof(libtrace_sll_header_t));
     328
     329                        /* Invalidate caches */
     330                        packet->l3_header = NULL;
     331                        packet->capture_length = -1;
    323332                        break;
    324333                default:
    325334                        return false;
    326335        }
     336
     337        /* Invalidate caches */
     338        packet->l3_header = NULL;
     339        packet->capture_length = -1;
    327340        return true;
    328341}
  • lib/protocols.c

    ra005846 r7c72e4d  
    343343libtrace_ip_t *trace_get_ip(libtrace_packet_t *packet)
    344344{
    345         uint16_t type;
    346         void *link = trace_get_link(packet);
     345        uint16_t ethertype;
    347346        void *ret;
    348347
    349         if (!link)
    350                 return NULL;
    351        
    352         ret=trace_get_payload_from_link(
    353                         link,
    354                         trace_get_link_type(packet),
    355                         &type, NULL);
    356 
    357         if (!ret)
    358                 return NULL;
    359 
    360         for(;;) {
    361                 switch(type) {
    362                         case 0x8100:
    363                                 ret=trace_get_vlan_payload_from_ethernet_payload(ret,&type,NULL);
    364                                 continue;
    365                         case 0x8847:
    366                                 ret=trace_get_mpls_payload_from_ethernet_payload(ret,&type,NULL);
    367 
    368                                 if (ret && type == 0x0) {
    369                                         ret=trace_get_payload_from_ethernet(ret,&type,NULL);
    370                                 }
    371                                 continue;
    372                         default:
    373                                 break;
    374                 }
    375 
    376                 break;
    377         }
    378 
    379         if (!ret || type!=0x0800)
     348        uint32_t remaining = trace_get_capture_length(packet);
     349
     350        ret = trace_get_layer3(packet,&ethertype,&remaining);
     351
     352        if (!ret || ethertype!=0x0800)
    380353                return NULL;
    381354
     
    389362libtrace_ip6_t *trace_get_ip6(libtrace_packet_t *packet)
    390363{
    391         uint16_t type;
    392         void *link=trace_get_link(packet);
     364        uint16_t ethertype;
    393365        void *ret;
    394        
    395         if (!link)
    396                 return NULL;
    397 
    398         ret=trace_get_payload_from_link(
    399                         link,
    400                         trace_get_link_type(packet),
    401                         &type,NULL);
    402 
    403         if (!ret)
    404                 return NULL;
    405 
    406         for(;;) {
    407                 switch(type) {
    408                         case 0x8100:
    409                                 ret=trace_get_vlan_payload_from_ethernet_payload(ret,&type,NULL);
    410                                 continue;
    411                         case 0x8847:
    412                                 ret=trace_get_mpls_payload_from_ethernet_payload(ret,&type,NULL);
    413 
    414                                 if (ret && type == 0x0) {
    415                                         ret=trace_get_payload_from_ethernet(ret,&type,NULL);
    416                                 }
    417                                 continue;
    418                         default:
    419                                 break;
    420                 }
    421 
    422                 break;
    423         }
    424 
    425         if (!ret || type!=0x86DD)
     366
     367        uint32_t remaining = trace_get_capture_length(packet);
     368
     369        ret = trace_get_layer3(packet,&ethertype,&remaining);
     370
     371        if (!ret || ethertype!=0x86DD)
    426372                return NULL;
    427373
     
    497443}
    498444
     445DLLEXPORT void *trace_get_layer3(libtrace_packet_t *packet,
     446                uint16_t *ethertype,
     447                uint32_t *remaining)
     448{
     449        void *iphdr;
     450        uint16_t dummy_ethertype;
     451        void *link;
     452        uint32_t dummy_remaining;
     453
     454        /* use l3 cache */
     455        if (packet->l3_header)
     456        {
     457                *ethertype = packet->l3_ethertype;
     458                *remaining -= (packet->l3_header - trace_get_link(packet));
     459                return packet->l3_header;
     460        }
     461
     462        if (!ethertype) ethertype=&dummy_ethertype;
     463
     464        if (!remaining) remaining=&dummy_remaining;
     465
     466        *remaining = trace_get_capture_length(packet);
     467
     468        link=trace_get_link(packet);
     469
     470        if (!link)
     471                return NULL;
     472
     473        iphdr = trace_get_payload_from_link(
     474                        link,
     475                        trace_get_link_type(packet),
     476                        ethertype,
     477                        remaining);
     478
     479        if (!iphdr)
     480                return NULL;
     481
     482        for(;;) {
     483                switch(*ethertype) {
     484                case 0x8100: /* VLAN */
     485                        iphdr=trace_get_vlan_payload_from_ethernet_payload(
     486                                          iphdr,ethertype,NULL);
     487                        continue;
     488                case 0x8847: /* MPLS */
     489                        iphdr=trace_get_mpls_payload_from_ethernet_payload(
     490                                          iphdr,ethertype,NULL);
     491
     492                        if (iphdr && ethertype == 0x0) {
     493                                iphdr=trace_get_payload_from_ethernet(
     494                                                iphdr,ethertype,NULL);
     495                        }
     496                        continue;
     497                default:
     498                        break;
     499                }
     500
     501                break;
     502        }
     503
     504        /* Store values in the cache for later */
     505        packet->l3_ethertype = *ethertype;
     506        packet->l3_header = iphdr;
     507
     508        return iphdr;
     509}
     510
    499511DLLEXPORT void *trace_get_transport(libtrace_packet_t *packet,
    500512                uint8_t *proto,
     
    502514                )
    503515{
    504         void *transport;
    505516        uint8_t dummy_proto;
    506517        uint16_t ethertype;
    507         void *link;
    508518        uint32_t dummy_remaining;
     519        void *transport;
    509520
    510521        if (!proto) proto=&dummy_proto;
     
    514525        *remaining = trace_get_capture_length(packet);
    515526
    516         link=trace_get_link(packet);
    517 
    518         if (!link)
    519                 return NULL;
    520 
    521         transport = trace_get_payload_from_link(
    522                         link,
    523                         trace_get_link_type(packet),
    524                         &ethertype,
    525                         remaining);
    526 
    527         if (!transport)
    528                 return NULL;
    529 
    530         for(;;) {
    531                 switch(ethertype) {
    532                 case 0x8100:
    533                         transport=trace_get_vlan_payload_from_ethernet_payload(
    534                                           transport,&ethertype,NULL);
    535                         continue;
    536                 case 0x8847:
    537                         transport=trace_get_mpls_payload_from_ethernet_payload(
    538                                           transport,&ethertype,NULL);
    539 
    540                         if (transport && ethertype == 0x0) {
    541                                 transport=trace_get_payload_from_ethernet(
    542                                                 transport,&ethertype,NULL);
    543                         }
    544                         continue;
    545                 default:
    546                         break;
    547                 }
    548 
    549                 break;
    550         }
     527        transport = trace_get_layer3(packet,&ethertype,remaining);
    551528
    552529        if (!transport)
     
    792769}
    793770
    794 DLLEXPORT struct sockaddr *trace_get_source_address(const libtrace_packet_t *packet,
    795                 struct sockaddr *addr)
    796 {
    797         uint16_t proto;
     771DLLEXPORT struct sockaddr *trace_get_source_address(
     772                const libtrace_packet_t *packet, struct sockaddr *addr)
     773{
     774        uint16_t ethertype;
    798775        uint32_t remaining;
    799776        void *l3;
     
    806783        remaining = trace_get_capture_length(packet);
    807784
    808         l3 = trace_get_payload_from_link(
    809                         trace_get_link(packet),
    810                         trace_get_link_type(packet),
    811                         &proto,
    812                         &remaining);
     785        l3 = trace_get_layer3(packet,&ethertype,&remaining);
    813786
    814787        if (!l3)
    815                 return false;
    816 
    817         for(;;) {
    818                 switch(proto) {
    819                         case 0x8100:
    820                                 l3=trace_get_vlan_payload_from_ethernet_payload(
    821                                                 l3,&proto,NULL);
    822                                 continue;
    823                         case 0x8847:
    824                                 l3=trace_get_mpls_payload_from_ethernet_payload(
    825                                                 l3,&proto,NULL);
    826 
    827                                 if (l3 && proto == 0x0) {
    828                                         l3=trace_get_payload_from_ethernet(
    829                                                 l3,&proto,NULL);
    830                                 }
    831                                 continue;
    832                         default:
    833                                 break;
    834                 }
    835 
    836                 break;
    837         }
    838 
    839         if (!l3)
    840                 return NULL;
    841 
    842         switch (proto) {
     788                return NULL;
     789
     790        switch (ethertype) {
    843791                case 0x0800: /* IPv4 */
    844792                {
     
    863811                        addr6->sin6_family=AF_INET6;
    864812                        if (ports && remaining>=sizeof(*ports))
    865                                 addr6->sin6_port=ports->dst;
     813                                addr6->sin6_port=ports->src;
    866814                        else
    867815                                addr6->sin6_port=0;
     
    875823}
    876824
    877 DLLEXPORT struct sockaddr *trace_get_destination_address(const libtrace_packet_t *packet,
    878                 struct sockaddr *addr)
    879 {
    880         uint16_t proto;
     825DLLEXPORT struct sockaddr *trace_get_destination_address(
     826                const libtrace_packet_t *packet, struct sockaddr *addr)
     827{
     828        uint16_t ethertype;
    881829        uint32_t remaining;
    882         void *transport;
     830        void *l3;
     831        struct ports_t *ports;
    883832        static struct sockaddr_storage dummy;
    884833
     
    888837        remaining = trace_get_capture_length(packet);
    889838
    890         transport = trace_get_payload_from_link(
    891                         trace_get_link(packet),
    892                         trace_get_link_type(packet),
    893                         &proto,
    894                         &remaining);
    895 
    896         if (!transport)
    897                 return false;
    898         for(;;) {
    899                 switch(proto) {
    900                         case 0x8100:
    901                                 transport=trace_get_vlan_payload_from_ethernet_payload(transport,&proto,NULL);
    902                                 continue;
    903                         case 0x8847:
    904                                 transport=trace_get_mpls_payload_from_ethernet_payload(transport,&proto,NULL);
    905 
    906                                 if (transport && proto == 0x0) {
    907                                         transport=trace_get_payload_from_ethernet(
    908                                                         transport,&proto,NULL);
    909                                 }
    910                                 continue;
    911                         default:
    912                                 break;
    913                 }
    914 
    915                 break;
    916         }
    917 
    918         if (!transport)
    919                 return false;
    920 
    921         switch (proto) {
     839        l3 = trace_get_layer3(packet,&ethertype,&remaining);
     840
     841        if (!l3)
     842                return NULL;
     843
     844        switch (ethertype) {
    922845                case 0x0800: /* IPv4 */
    923846                {
    924847                        struct sockaddr_in *addr4=(struct sockaddr_in*)addr;
    925                         libtrace_ip_t *ip = (libtrace_ip_t*)transport;
     848                        libtrace_ip_t *ip = (libtrace_ip_t*)l3;
     849                        ports = (struct ports_t*)
     850                                trace_get_payload_from_ip(ip,NULL,&remaining);
    926851                        addr4->sin_family=AF_INET;
    927                         addr4->sin_port=0;
     852                        if (ports && remaining>=sizeof(*ports))
     853                                addr4->sin_port=ports->dst;
     854                        else
     855                                addr4->sin_port=0;
    928856                        addr4->sin_addr=ip->ip_dst;
    929857                        return addr;
     
    932860                {
    933861                        struct sockaddr_in6 *addr6=(struct sockaddr_in6*)addr;
    934                         libtrace_ip6_t *ip6 = (libtrace_ip6_t*)transport;
     862                        libtrace_ip6_t *ip6 = (libtrace_ip6_t*)l3;
     863                        ports = (struct ports_t*)
     864                                trace_get_payload_from_ip6(ip6,NULL,&remaining);
    935865                        addr6->sin6_family=AF_INET6;
    936                         addr6->sin6_port=0;
     866                        if (ports && remaining>=sizeof(*ports))
     867                                addr6->sin6_port=ports->dst;
     868                        else
     869                                addr6->sin6_port=0;
    937870                        addr6->sin6_flowinfo=0;
    938871                        addr6->sin6_addr=ip6->ip_dst;
  • lib/trace.c

    r984f7da r7c72e4d  
    632632        libtrace_packet_t *packet =
    633633                (libtrace_packet_t*)calloc((size_t)1,sizeof(libtrace_packet_t));
     634
    634635        packet->buf_control=TRACE_CTRL_PACKET;
     636        packet->capture_length=-1;
    635637        return packet;
    636638}
     
    687689         * structure */
    688690        packet->trace = libtrace;
     691
     692        /* Finalise the packet, freeing any resources the format module
     693         * may have allocated it
     694         */
     695        if (libtrace->format->fin_packet) {
     696                libtrace->format->fin_packet(packet);
     697        }
     698
     699        /* Clear the packet cache */
     700        packet->capture_length = -1;
     701        packet->l3_header = NULL;
     702        packet->l3_ethertype = 0;
    689703
    690704        if (libtrace->format->read_packet) {
     
    838852}
    839853
    840 DLLEXPORT size_t trace_get_capture_length(const libtrace_packet_t *packet)
    841 {
    842         if (packet->trace->format->get_capture_length) {
    843                 return packet->trace->format->get_capture_length(packet);
    844         }
    845         return ~0U;
     854DLLEXPORT size_t trace_get_capture_length(libtrace_packet_t *packet)
     855{
     856        /* Cache the capture length */
     857        if (packet->capture_length == -1) {
     858                if (!packet->trace->format->get_capture_length)
     859                        return ~0U;
     860                packet->capture_length =
     861                        packet->trace->format->get_capture_length(packet);
     862        }
     863
     864        return packet->capture_length;
    846865}
    847866       
Note: See TracChangeset for help on using the changeset viewer.