Changeset a842286 for lib/protocols.c


Ignore:
Timestamp:
04/06/06 20:50:57 (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:
9231fe5
Parents:
4029ce7
Message:

Finish migration to protocols.c, add more IPv6 support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/protocols.c

    r4af54d1 ra842286  
     1/* This file has the various helper functions used to decode various protocols
     2 *
     3 * $Id$
     4 */
    15#include "libtrace.h"
    26#include "libtrace_int.h"
    37#include "wag.h"
    48
    5 /* This file has the various helper functions used to decode various protocols */
    69
    710static void *trace_get_ip_from_ethernet(void *ethernet, int *skipped)
     
    140143                                if (!sll) {
    141144                                        ipptr = NULL;
     145                                } else if (ntohs(sll->protocol)!=0x0800) {
     146                                        ipptr = NULL;
     147                                }
     148                                else {
     149                                        ipptr=(void*)((char*)sll+sizeof(*sll));
     150                                }
     151                        }
     152                        break;
     153                case TRACE_TYPE_PFLOG:
     154                        {
     155                                struct trace_pflog_header_t *pflog;
     156                                pflog = trace_get_link(packet);
     157                                if (!pflog) {
     158                                        ipptr = NULL;
    142159                                        break;
    143160                                }
    144                                 if (ntohs(sll->protocol)!=0x86DD) {
     161                                if (pflog->af != AF_INET6) {
     162                                        ipptr = NULL;
     163                                } else {
     164                                        ipptr = (void*)((char*)pflog+
     165                                                sizeof(*pflog));
     166                                }
     167                        }
     168                        break;
     169                case TRACE_TYPE_LEGACY_POS:
     170                        {
     171                                /* 64 byte capture. */
     172                                struct libtrace_pos *pos =
     173                                        trace_get_link(packet);
     174                                if (ntohs(pos->ether_type) == 0x0800) {
     175                                        ipptr=(void*)((char *)pos+sizeof(*pos));
     176                                } else {
     177                                        ipptr=NULL;
     178                                }
     179                                break;
     180                               
     181                        }
     182                case TRACE_TYPE_LEGACY_ATM:
     183                case TRACE_TYPE_ATM:
     184                        {
     185                                /* 64 byte capture. */
     186                                struct libtrace_llcsnap *llc =
     187                                        trace_get_link(packet);
     188
     189                                /* advance the llc ptr +4 into the link layer.
     190                                 * need to check what is in these 4 bytes.
     191                                 * don't have time!
     192                                 */
     193                                llc = (void*)((char *)llc + 4);
     194                                if (ntohs(llc->type) == 0x0800) {
     195                                        ipptr=(void*)((char*)llc+sizeof(*llc));
     196                                } else {
     197                                        ipptr = NULL;
     198                                }
     199                                break;
     200                        }
     201                default:
     202                        fprintf(stderr,"Don't understand link layer type %i in trace_get_ip6()\n",
     203                                trace_get_link_type(packet));
     204                        ipptr=NULL;
     205                        break;
     206        }
     207
     208        return ipptr;
     209}
     210
     211/* TODO: split these cases into get_*_from_* functions */
     212struct libtrace_ip6 *trace_get_ip6(const struct libtrace_packet_t *packet) {
     213        libtrace_ip6_t *ipptr = 0;
     214
     215        switch(trace_get_link_type(packet)) {
     216                case TRACE_TYPE_80211_PRISM:
     217                        {
     218                                ipptr = trace_get_ip6_from_80211(
     219                                        (char*)trace_get_link(packet)+144, NULL);
     220                        }
     221                        break;
     222                case TRACE_TYPE_80211:
     223                        ipptr = trace_get_ip6_from_80211(
     224                                        trace_get_link(packet),
     225                                        NULL);
     226                        break;
     227                case TRACE_TYPE_ETH:
     228                case TRACE_TYPE_LEGACY_ETH:
     229                        {
     230                                ipptr = trace_get_ip6_from_ethernet(
     231                                                trace_get_link(packet),
     232                                                NULL);
     233                                break;
     234                        }
     235                case TRACE_TYPE_NONE:
     236                        ipptr = trace_get_link(packet);
     237                        break;
     238                case TRACE_TYPE_LINUX_SLL:
     239                        {
     240                                trace_sll_header_t *sll;
     241
     242                                sll = trace_get_link(packet);
     243                                if (!sll) {
     244                                        ipptr = NULL;
     245                                } else if (ntohs(sll->protocol)!=0x86DD) {
    145246                                        ipptr = NULL;
    146247                                }
     
    159260                                        break;
    160261                                }
    161                                 if (pflog->af != AF_INET6) {
     262                                if (pflog->af != AF_INET) {
    162263                                        ipptr = NULL;
    163264                                } else {
     
    200301                        }
    201302                default:
    202                         fprintf(stderr,"Don't understand link layer type %i in trace_get_ip6()\n",
    203                                 trace_get_link_type(packet));
    204                         ipptr=NULL;
    205                         break;
    206         }
    207 
    208         return ipptr;
    209 }
    210 
    211 /* TODO: split these cases into get_*_from_* functions */
    212 struct libtrace_ip6 *trace_get_ip6(const struct libtrace_packet_t *packet) {
    213         libtrace_ip6_t *ipptr = 0;
    214 
    215         switch(trace_get_link_type(packet)) {
    216                 case TRACE_TYPE_80211_PRISM:
    217                         {
    218                                 ipptr = trace_get_ip6_from_80211(
    219                                         (char*)trace_get_link(packet)+144, NULL);
    220                         }
    221                         break;
    222                 case TRACE_TYPE_80211:
    223                         ipptr = trace_get_ip6_from_80211(
    224                                         trace_get_link(packet),
    225                                         NULL);
    226                         break;
    227                 case TRACE_TYPE_ETH:
    228                 case TRACE_TYPE_LEGACY_ETH:
    229                         {
    230                                 ipptr = trace_get_ip6_from_ethernet(
    231                                                 trace_get_link(packet),
    232                                                 NULL);
    233                                 break;
    234                         }
    235                 case TRACE_TYPE_NONE:
    236                         ipptr = trace_get_link(packet);
    237                         break;
    238                 case TRACE_TYPE_LINUX_SLL:
    239                         {
    240                                 trace_sll_header_t *sll;
    241 
    242                                 sll = trace_get_link(packet);
    243                                 if (!sll) {
    244                                         ipptr = NULL;
    245                                         break;
    246                                 }
    247                                 if (ntohs(sll->protocol)!=0x0800) {
    248                                         ipptr = NULL;
    249                                 }
    250                                 else {
    251                                         ipptr = (void*)((char*)sll+
    252                                                         sizeof(*sll));
    253                                 }
    254                         }
    255                         break;
    256                 case TRACE_TYPE_PFLOG:
    257                         {
    258                                 struct trace_pflog_header_t *pflog;
    259                                 pflog = trace_get_link(packet);
    260                                 if (!pflog) {
    261                                         ipptr = NULL;
    262                                         break;
    263                                 }
    264                                 if (pflog->af != AF_INET) {
    265                                         ipptr = NULL;
    266                                 } else {
    267                                         ipptr = (void*)((char*)pflog+
    268                                                 sizeof(*pflog));
    269                                 }
    270                         }
    271                         break;
    272                 case TRACE_TYPE_LEGACY_POS:
    273                         {
    274                                 /* 64 byte capture. */
    275                                 struct libtrace_pos *pos =
    276                                         trace_get_link(packet);
    277                                 if (ntohs(pos->ether_type) == 0x0800) {
    278                                         ipptr=(void*)((char *)pos+sizeof(*pos));
    279                                 } else {
    280                                         ipptr=NULL;
    281                                 }
    282                                 break;
    283                                
    284                         }
    285                 case TRACE_TYPE_LEGACY_ATM:
    286                 case TRACE_TYPE_ATM:
    287                         {
    288                                 /* 64 byte capture. */
    289                                 struct libtrace_llcsnap *llc =
    290                                         trace_get_link(packet);
    291 
    292                                 /* advance the llc ptr +4 into the link layer.
    293                                  * need to check what is in these 4 bytes.
    294                                  * don't have time!
    295                                  */
    296                                 llc = (void*)((char *)llc + 4);
    297                                 if (ntohs(llc->type) == 0x0800) {
    298                                         ipptr=(void*)((char*)llc+sizeof(*llc));
    299                                 } else {
    300                                         ipptr = NULL;
    301                                 }
    302                                 break;
    303                         }
    304                 default:
    305303                        fprintf(stderr,"Don't understand link layer type %i in trace_get_ip()\n",
    306304                                trace_get_link_type(packet));
     
    314312#define SW_IP_OFFMASK 0xff1f
    315313
    316 void *trace_get_payload_from_ip(libtrace_ip_t *ipptr, int *skipped)
     314void *trace_get_payload_from_ip(libtrace_ip_t *ipptr, uint8_t *prot,
     315                int *skipped)
    317316{
    318317        void *trans_ptr = 0;
     
    321320                if (skipped) *skipped=(ipptr->ip_hl * 4);
    322321                trans_ptr = (void *)((char *)ipptr + (ipptr->ip_hl * 4));
     322                if (prot) *prot = ipptr->ip_p;
    323323        }
    324324        return trans_ptr;
    325325}
    326326
    327 void *trace_get_transport(const struct libtrace_packet_t *packet)
    328 {
    329         struct libtrace_ip *ipptr = 0;
     327void *trace_get_payload_from_ip6(libtrace_ip6_t *ipptr, uint8_t *prot,
     328                int *skipped)
     329{
     330        void *payload = (char*)ipptr+sizeof(libtrace_ip6_t);
     331        uint8_t nxt = ipptr->nxt;
     332
     333        if (skipped) skipped+=sizeof(libtrace_ip6_t);
     334
     335        while(1) {
     336                switch (nxt) {
     337                        case 0: /* hop by hop options */
     338                        case 43: /* routing */
     339                        case 44: /* fragment */
     340                        case 50: /* ESP */
     341                        case 51: /* AH */
     342                        case 60: /* Destination options */
     343                                {
     344                                        uint16_t len=((libtrace_ip6_ext_t*)payload)->len
     345                                        +sizeof(libtrace_ip6_ext_t);
     346
     347                                        if (skipped)
     348                                                *skipped+=len;
     349
     350                                        payload=(char*)payload+len;
     351                                        nxt=((libtrace_ip6_ext_t*)payload)->nxt;
     352                                        continue;
     353                                }
     354                        default:
     355                                if (prot) *prot=nxt;
     356                                return payload;
     357                }
     358        }
     359}
     360
     361static void *trace_get_ip4_transport(const libtrace_packet_t *packet,
     362                uint8_t *proto)
     363{
     364        libtrace_ip_t *ipptr = 0;
    330365
    331366        if (!(ipptr = trace_get_ip(packet))) {
     
    333368        }
    334369
    335         return trace_get_payload_from_ip(ipptr,NULL);
    336 }
    337 
    338 libtrace_tcp_t *trace_get_tcp(const libtrace_packet_t *packet) {
    339         struct libtrace_tcp *tcpptr = 0;
    340         struct libtrace_ip *ipptr = 0;
    341 
    342         if(!(ipptr = trace_get_ip(packet))) {
    343                 return 0;
    344         }
    345         if (ipptr->ip_p == 6) {
    346                 tcpptr = (struct libtrace_tcp *)trace_get_payload_from_ip(ipptr, 0);
    347         }
    348         return tcpptr;
    349 }
    350 
    351 libtrace_tcp_t *trace_get_tcp_from_ip(libtrace_ip_t *ip, int *skipped)
    352 {
    353         struct libtrace_tcp *tcpptr = 0;
    354 
    355         if (ip->ip_p == 6)  {
    356                 tcpptr = (struct libtrace_tcp *)trace_get_payload_from_ip(ip, skipped);
    357         }
    358 
    359         return tcpptr;
    360 }
    361 
    362 libtrace_udp_t *trace_get_udp(libtrace_packet_t *packet) {
    363         struct libtrace_udp *udpptr = 0;
    364         struct libtrace_ip *ipptr = 0;
    365        
    366         if(!(ipptr = trace_get_ip(packet))) {
     370        return trace_get_payload_from_ip(ipptr,proto,NULL);
     371}
     372
     373static void *trace_get_ip6_transport(const libtrace_packet_t *packet,
     374                uint8_t *proto)
     375{
     376        libtrace_ip6_t *ipptr = 0;
     377
     378        if (!(ipptr = trace_get_ip6(packet))) {
    367379                return 0;
    368380        }
    369         if (ipptr->ip_p == 17)  {
    370                 udpptr = (struct libtrace_udp *)trace_get_payload_from_ip(ipptr, 0);
    371         }
    372 
    373         return udpptr;
     381
     382        return trace_get_payload_from_ip6(ipptr,proto,NULL);
     383}
     384
     385void *trace_get_transport(const struct libtrace_packet_t *packet,
     386                uint8_t *proto)
     387{
     388        void *transport;
     389        uint8_t dummy;
     390
     391        if (!proto) proto=&dummy;
     392
     393        transport=trace_get_ip4_transport(packet,proto);
     394        if (transport) {
     395                if (*proto == 41) {
     396                        trace_get_payload_from_ip6(transport,proto,NULL);
     397                }
     398                return transport;
     399        }
     400
     401        return trace_get_ip6_transport(packet,proto);
     402}
     403
     404libtrace_tcp_t *trace_get_tcp(const libtrace_packet_t *packet) {
     405        uint8_t proto;
     406        libtrace_tcp_t *tcp;
     407
     408        tcp=trace_get_transport(packet,&proto);
     409
     410        if (proto != 6)
     411                return NULL;
     412
     413        return tcp;
     414}
     415
     416libtrace_tcp_t *trace_get_tcp_from_ip(libtrace_ip_t *ip, int *skipped)
     417{
     418        struct libtrace_tcp *tcpptr = 0;
     419
     420        if (ip->ip_p == 6)  {
     421                tcpptr = (struct libtrace_tcp *)
     422                        trace_get_payload_from_ip(ip, NULL, skipped);
     423        }
     424
     425        return tcpptr;
     426}
     427
     428libtrace_udp_t *trace_get_udp(libtrace_packet_t *packet) {
     429        uint8_t proto;
     430        libtrace_udp_t *udp;
     431
     432        udp=trace_get_transport(packet,&proto);
     433
     434        if (proto != 17)
     435                return NULL;
     436
     437        return udp;
    374438}
    375439
     
    379443
    380444        if (ip->ip_p == 17) {
    381                 udpptr = (libtrace_udp_t *)trace_get_payload_from_ip(ip, skipped);
     445                udpptr = (libtrace_udp_t *)
     446                        trace_get_payload_from_ip(ip, NULL, skipped);
    382447        }
    383448
     
    386451
    387452libtrace_icmp_t *trace_get_icmp(const libtrace_packet_t *packet) {
    388         struct libtrace_icmp *icmpptr = 0;
    389         struct libtrace_ip *ipptr = 0;
    390        
    391         if(!(ipptr = trace_get_ip(packet))) {
    392                 return 0;
    393         }
    394         if (ipptr->ip_p == 1){
    395                 icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ipptr, 0);
    396         }
    397         return icmpptr;
     453        uint8_t proto;
     454        libtrace_icmp_t *icmp;
     455
     456        icmp=trace_get_transport(packet,&proto);
     457
     458        if (proto != 1)
     459                return NULL;
     460
     461        return icmp;
    398462}
    399463
     
    403467
    404468        if (ip->ip_p == 1)  {
    405                 icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, skipped);
     469                icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, NULL, skipped);
    406470        }
    407471
Note: See TracChangeset for help on using the changeset viewer.