Changeset 7c72e4d for lib/protocols.c


Ignore:
Timestamp:
06/20/07 13:10:40 (15 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).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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;
Note: See TracChangeset for help on using the changeset viewer.