Changeset 9231fe5 for lib/protocols.c


Ignore:
Timestamp:
04/07/06 00:17:36 (16 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:
d320b63
Parents:
a842286
Message:

Minor cleanups in format_rt
Shuffled protocols.c around for better vlan support
Cleaned up IPv6 support to be more generic (less duplicated code)
added trace_get_{source,destination}_address

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/protocols.c

    ra842286 r9231fe5  
    66#include "libtrace_int.h"
    77#include "wag.h"
    8 
    9 
    10 static void *trace_get_ip_from_ethernet(void *ethernet, int *skipped)
     8#include <assert.h>
     9
     10
     11/* Returns the payload from 802.3 ethernet.  Type optionally returned in
     12 * "type" in host byte order.  This will return a vlan header.
     13 */
     14static void *trace_get_payload_from_ethernet(void *ethernet,
     15                uint16_t *type,
     16                uint32_t *remaining)
    1117{
    1218        libtrace_ether_t *eth = ethernet;
    13        
    14         if (ntohs(eth->ether_type)==0x0800) {
    15                 if (skipped)
    16                         *skipped=sizeof(libtrace_ether_t);
    17                 return (void*)((char *)eth + sizeof(*eth));
    18         } else if (ntohs(eth->ether_type) == 0x8100) {
    19                 libtrace_8021q_t *vlanhdr = (libtrace_8021q_t *)eth;
    20                 if (skipped)
    21                         *skipped=sizeof(libtrace_ether_t);
    22                 if (ntohs(vlanhdr->vlan_ether_type) == 0x0800) {
    23                         return (void*)((char *)eth + sizeof(*vlanhdr));
    24                 }
    25         }
    26        
     19
     20        if (remaining) {
     21                if (*remaining < sizeof(*eth))
     22                        return NULL;
     23                *remaining-=sizeof(*eth);
     24        }
     25
     26        if (type)
     27                *type = ntohs(eth->ether_type);
     28
     29        return (void*)((char *)eth + sizeof(*eth));
     30}
     31
     32/* skip any 802.1q headers if necessary
     33 * type is input/output
     34 */
     35static void *trace_get_vlan_payload_from_ethernet_payload(void *ethernet, uint16_t *type,
     36                uint32_t *remaining)
     37{
     38        assert(type && "You must pass a type in!");
     39
     40        if (*type == 0x8100) {
     41                libtrace_8021q_t *vlanhdr = (libtrace_8021q_t *)ethernet;
     42
     43                if (remaining) {
     44                        if (*remaining < sizeof(libtrace_8021q_t))
     45                                return NULL;
     46
     47                        *remaining=*remaining-sizeof(libtrace_8021q_t);
     48                }
     49
     50                *type = ntohs(vlanhdr->vlan_ether_type);
     51
     52                return (void*)((char *)ethernet + sizeof(*vlanhdr));
     53        }
     54
    2755        return NULL;
    2856}
    2957
    30 static void *trace_get_ip6_from_ethernet(void *ethernet, int *skipped)
    31 {
    32         libtrace_ether_t *eth = ethernet;
    33        
    34         if (ntohs(eth->ether_type)==0x86DD) {
    35                 if (skipped)
    36                         *skipped=sizeof(libtrace_ether_t);
    37                 return (void*)((char *)eth + sizeof(*eth));
    38         } else if (ntohs(eth->ether_type) == 0x8100) {
    39                 libtrace_8021q_t *vlanhdr = (libtrace_8021q_t *)eth;
    40                 if (skipped)
    41                         *skipped=sizeof(libtrace_ether_t);
    42                 if (ntohs(vlanhdr->vlan_ether_type) == 0x86DD) {
    43                         return (void*)((char *)eth + sizeof(*vlanhdr));
    44                 }
    45         }
    46        
    47         return NULL;
    48 }
    49 
    50 static void *trace_get_ip_from_80211(void *link, int *skipped)
     58static void *trace_get_payload_from_80211(void *link, uint16_t *type, uint32_t *remaining)
    5159{
    5260        libtrace_80211_t *wifi = link;
    5361        struct ieee_802_11_payload *eth;
    5462
    55         if (*skipped) skipped+=sizeof(libtrace_80211_t);
    56 
    57         if (!wifi) {
    58                 return NULL;
    59         }
     63        if (remaining && *remaining < sizeof(libtrace_80211_t))
     64                return NULL;
    6065
    6166        /* Data packet? */
     
    6469        }
    6570
    66         if (skipped) *skipped+=sizeof(*eth);
    67         eth=(void*)((char*)wifi+sizeof(libtrace_80211_t));
    68 
    69         if (ntohs(eth->type) == 0x0800) {
    70                 return (void*)((char*)eth + sizeof(*eth));
    71         } else if (ntohs(eth->type) == 0x8100) {
    72                 struct libtrace_8021q *vlanhdr = (struct libtrace_8021q *)eth;
    73                 if (ntohs(vlanhdr->vlan_ether_type) == 0x0800) {
    74                         if (skipped) *skipped+=sizeof(*vlanhdr);
    75                         return (void*)((char*)eth + sizeof(*vlanhdr));
    76                 }
    77         }
    78 
    79         return NULL;
    80 }
    81 
    82 static void *trace_get_ip6_from_80211(void *link, int *skipped)
    83 {
    84         libtrace_80211_t *wifi = link;
    85         struct ieee_802_11_payload *eth;
    86 
    87         if (*skipped) skipped+=sizeof(libtrace_80211_t);
    88 
    89         if (!wifi) {
    90                 return NULL;
    91         }
    92 
    93         /* Data packet? */
    94         if (wifi->type != 2) {
    95                 return NULL;
    96         }
    97 
    98         if (skipped) *skipped+=sizeof(*eth);
    99         eth=(void*)((char*)wifi+sizeof(libtrace_80211_t));
    100 
    101         if (ntohs(eth->type) == 0x86DD) {
    102                 return (void*)((char*)eth + sizeof(*eth));
    103         } else if (ntohs(eth->type) == 0x8100) {
    104                 struct libtrace_8021q *vlanhdr = (struct libtrace_8021q *)eth;
    105                 if (ntohs(vlanhdr->vlan_ether_type) == 0x86DD) {
    106                         if (skipped) *skipped+=sizeof(*vlanhdr);
    107                         return (void*)((char*)eth + sizeof(*vlanhdr));
    108                 }
    109         }
    110 
    111         return NULL;
    112 }
    113 
    114 /* TODO: split these cases into get_*_from_* functions */
    115 struct libtrace_ip *trace_get_ip(const struct libtrace_packet_t *packet) {
    116         struct libtrace_ip *ipptr = 0;
    117 
    118         switch(trace_get_link_type(packet)) {
     71        if (remaining && *remaining < sizeof(*eth))
     72                return NULL;
     73
     74        eth=(void*)((char*)wifi+sizeof(*eth));
     75
     76        if (*type) *type=eth->type;
     77
     78        return eth;
     79}
     80
     81static void *trace_get_payload_from_linux_sll(void *link,
     82                uint16_t *type, uint32_t *remaining)
     83{
     84        struct trace_sll_header_t *sll;
     85
     86        sll = link;
     87
     88        if (remaining) {
     89                if (*remaining < sizeof(*sll))
     90                        return NULL;
     91                *remaining-=sizeof(*sll);
     92        }
     93
     94        if (*type) *type = sll->protocol;
     95
     96        return (void*)((char*)sll+sizeof(*sll));
     97}
     98
     99static void *trace_get_payload_from_atm(void *link,
     100                uint16_t *type, uint32_t *remaining)
     101{
     102        /* 64 byte capture. */
     103        struct libtrace_llcsnap *llc = link;
     104
     105        if (remaining) {
     106                if (*remaining < sizeof(struct libtrace_llcsnap)+4)
     107                        return NULL;
     108                *remaining-=(sizeof(struct libtrace_llcsnap)+4);
     109        }
     110
     111        /* advance the llc ptr +4 into the link layer.
     112         * TODO: need to check what is in these 4 bytes.
     113         * don't have time!
     114         */
     115        llc = (void*)((char *)llc + 4);
     116
     117        if (*type) *type = ntohs(llc->type);
     118
     119        return (void*)((char*)llc+sizeof(*llc));
     120}
     121
     122static void *trace_get_payload_from_legacy_pos(void *link,
     123                uint16_t *type, uint32_t *remaining)
     124{
     125        /* 64 byte capture. */
     126        struct libtrace_pos *pos = link;
     127
     128        if (remaining) {
     129                if (*remaining < sizeof(struct libtrace_pos))
     130                        return NULL;
     131                *remaining-=sizeof(struct libtrace_pos);
     132        }
     133
     134        if (type) *type = ntohs(pos->ether_type);
     135
     136        return (void*)((char *)pos+sizeof(*pos));
     137}
     138
     139static void *trace_get_payload_from_pflog(void *link,
     140                uint16_t *type, uint32_t *remaining)
     141{
     142        struct trace_pflog_header_t *pflog = link;
     143        if (remaining) {
     144                if (*remaining<sizeof(*pflog))
     145                        return NULL;
     146                *remaining-=sizeof(*pflog);
     147        }
     148        if (type) {
     149                switch(pflog->af) {
     150                        case AF_INET6: *type=0x86DD; break;
     151                        case AF_INET: *type=0x0800; break;
     152                        default:
     153                                      /* Unknown */
     154                                      return NULL;
     155                }
     156        }
     157        return (void*)((char*)pflog+ sizeof(*pflog));
     158}
     159
     160void *trace_get_payload_from_link(void *link, libtrace_linktype_t linktype,
     161                uint16_t *type, uint32_t *remaining)
     162{
     163        switch(linktype) {
    119164                case TRACE_TYPE_80211_PRISM:
    120                         ipptr = trace_get_ip_from_80211(
    121                                         (char*)trace_get_link(packet)+144,
    122                                         NULL);
    123                         break;
     165                        return trace_get_payload_from_80211((char*)link+144,
     166                                        type,remaining);
    124167                case TRACE_TYPE_80211:
    125                         ipptr = trace_get_ip_from_80211(
    126                                         trace_get_link(packet),
    127                                         NULL);
    128                         break;
     168                        return trace_get_payload_from_80211(link,type,remaining);
    129169                case TRACE_TYPE_ETH:
    130170                case TRACE_TYPE_LEGACY_ETH:
    131                         ipptr = trace_get_ip_from_ethernet(
    132                                         trace_get_link(packet),
    133                                         NULL);
    134                         break;
     171                        return trace_get_payload_from_ethernet(link,type,remaining);
    135172                case TRACE_TYPE_NONE:
    136                         ipptr = trace_get_link(packet);
    137                         break;
     173                        return link; /* I love the simplicity */
    138174                case TRACE_TYPE_LINUX_SLL:
    139                         {
    140                                 struct trace_sll_header_t *sll;
    141 
    142                                 sll = trace_get_link(packet);
    143                                 if (!sll) {
    144                                         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;
     175                        return trace_get_payload_from_linux_sll(link,type,remaining);
    153176                case TRACE_TYPE_PFLOG:
    154                         {
    155                                 struct trace_pflog_header_t *pflog;
    156                                 pflog = trace_get_link(packet);
    157                                 if (!pflog) {
    158                                         ipptr = NULL;
    159                                         break;
    160                                 }
    161                                 if (pflog->af != AF_INET6) {
    162                                         ipptr = NULL;
    163                                 } else {
    164                                         ipptr = (void*)((char*)pflog+
    165                                                 sizeof(*pflog));
    166                                 }
    167                         }
    168                         break;
     177                        return trace_get_payload_from_pflog(link,type,remaining);
    169178                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                         }
     179                        return trace_get_payload_from_legacy_pos(link,type,remaining);
    182180                case TRACE_TYPE_LEGACY_ATM:
    183181                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                         }
     182                        return trace_get_payload_from_atm(link,type,remaining);
    201183                default:
    202184                        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                                 } else if (ntohs(sll->protocol)!=0x86DD) {
    246                                         ipptr = NULL;
    247                                 }
    248                                 else {
    249                                         ipptr = (void*)((char*)sll+
    250                                                         sizeof(*sll));
    251                                 }
    252                         }
    253                         break;
    254                 case TRACE_TYPE_PFLOG:
    255                         {
    256                                 struct trace_pflog_header_t *pflog;
    257                                 pflog = trace_get_link(packet);
    258                                 if (!pflog) {
    259                                         ipptr = NULL;
    260                                         break;
    261                                 }
    262                                 if (pflog->af != AF_INET) {
    263                                         ipptr = NULL;
    264                                 } else {
    265                                         ipptr = (void*)((char*)pflog+
    266                                                 sizeof(*pflog));
    267                                 }
    268                         }
    269                         break;
    270                 case TRACE_TYPE_LEGACY_POS:
    271                         {
    272                                 /* 64 byte capture. */
    273                                 struct libtrace_pos *pos =
    274                                         trace_get_link(packet);
    275                                 if (ntohs(pos->ether_type) == 0x86DD) {
    276                                         ipptr=(void*)((char *)pos+sizeof(*pos));
    277                                 } else {
    278                                         ipptr=NULL;
    279                                 }
    280                                 break;
    281                                
    282                         }
    283                 case TRACE_TYPE_LEGACY_ATM:
    284                 case TRACE_TYPE_ATM:
    285                         {
    286                                 /* 64 byte capture. */
    287                                 struct libtrace_llcsnap *llc =
    288                                         trace_get_link(packet);
    289 
    290                                 /* advance the llc ptr +4 into the link layer.
    291                                  * need to check what is in these 4 bytes.
    292                                  * don't have time!
    293                                  */
    294                                 llc = (void*)((char *)llc + 4);
    295                                 if (ntohs(llc->type) == 0x86DD) {
    296                                         ipptr=(void*)((char*)llc+sizeof(*llc));
    297                                 } else {
    298                                         ipptr = NULL;
    299                                 }
    300                                 break;
    301                         }
    302                 default:
    303                         fprintf(stderr,"Don't understand link layer type %i in trace_get_ip()\n",
    304                                 trace_get_link_type(packet));
    305                         ipptr=NULL;
    306                         break;
    307         }
    308 
    309         return ipptr;
     185                                linktype);
     186                        return NULL;
     187        }
     188}
     189
     190libtrace_ip_t *trace_get_ip(libtrace_packet_t *packet)
     191{
     192        uint16_t type;
     193        void *ret=trace_get_payload_from_link(
     194                        trace_get_link(packet),
     195                        trace_get_link_type(packet),
     196                        &type, NULL);
     197
     198        if (!ret)
     199                return NULL;
     200
     201        ret=trace_get_vlan_payload_from_ethernet_payload(ret,&type,NULL);
     202
     203        if (!ret || type!=0x0800)
     204                return NULL;
     205
     206        return ret;
     207}
     208
     209libtrace_ip6_t *trace_get_ip6(libtrace_packet_t *packet)
     210{
     211        uint16_t type;
     212        void *ret=trace_get_payload_from_link(
     213                        trace_get_link(packet),
     214                        trace_get_link_type(packet),
     215                        &type,NULL);
     216
     217        if (!ret)
     218                return NULL;
     219
     220        ret=trace_get_vlan_payload_from_ethernet_payload(ret,&type,NULL);
     221
     222        if (!ret || type!=0x86DD)
     223                return NULL;
     224
     225        return ret;
    310226}
    311227
     
    313229
    314230void *trace_get_payload_from_ip(libtrace_ip_t *ipptr, uint8_t *prot,
    315                 int *skipped)
     231                uint32_t *remaining)
    316232{
    317233        void *trans_ptr = 0;
    318234
    319         if ((ipptr->ip_off & SW_IP_OFFMASK) == 0) {
    320                 if (skipped) *skipped=(ipptr->ip_hl * 4);
    321                 trans_ptr = (void *)((char *)ipptr + (ipptr->ip_hl * 4));
    322                 if (prot) *prot = ipptr->ip_p;
    323         }
     235        if ((ipptr->ip_off & SW_IP_OFFMASK) != 0)
     236                return NULL;
     237
     238        if (remaining) {
     239                if (*remaining<(ipptr->ip_hl*4U)) {
     240                        return NULL;
     241                }
     242                *remaining-=(ipptr->ip_hl * 4);
     243        }
     244
     245        trans_ptr = (void *)((char *)ipptr + (ipptr->ip_hl * 4));
     246
     247        if (prot) *prot = ipptr->ip_p;
     248
    324249        return trans_ptr;
    325250}
    326251
    327252void *trace_get_payload_from_ip6(libtrace_ip6_t *ipptr, uint8_t *prot,
    328                 int *skipped)
     253                uint32_t *remaining)
    329254{
    330255        void *payload = (char*)ipptr+sizeof(libtrace_ip6_t);
    331256        uint8_t nxt = ipptr->nxt;
    332257
    333         if (skipped) skipped+=sizeof(libtrace_ip6_t);
     258        if (remaining) {
     259                if (*remaining<sizeof(libtrace_ip6_t))
     260                        return NULL;
     261                *remaining-=sizeof(libtrace_ip6_t);
     262        }
    334263
    335264        while(1) {
     
    345274                                        +sizeof(libtrace_ip6_ext_t);
    346275
    347                                         if (skipped)
    348                                                 *skipped+=len;
     276                                        if (remaining) {
     277                                                if (*remaining < len) {
     278                                                        /* Snap too short */
     279                                                        return NULL;
     280                                                }
     281                                                *remaining-=len;
     282                                        }
    349283
    350284                                        payload=(char*)payload+len;
     
    359293}
    360294
    361 static void *trace_get_ip4_transport(const libtrace_packet_t *packet,
    362                 uint8_t *proto)
    363 {
    364         libtrace_ip_t *ipptr = 0;
    365 
    366         if (!(ipptr = trace_get_ip(packet))) {
    367                 return 0;
    368         }
    369 
    370         return trace_get_payload_from_ip(ipptr,proto,NULL);
    371 }
    372 
    373 static 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))) {
    379                 return 0;
    380         }
    381 
    382         return trace_get_payload_from_ip6(ipptr,proto,NULL);
    383 }
    384 
    385 void *trace_get_transport(const struct libtrace_packet_t *packet,
    386                 uint8_t *proto)
     295void *trace_get_transport(libtrace_packet_t *packet,
     296                uint8_t *proto,
     297                uint32_t *remaining
     298                )
    387299{
    388300        void *transport;
    389301        uint8_t dummy;
     302        uint16_t ethertype;
    390303
    391304        if (!proto) proto=&dummy;
    392305
    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 
    404 libtrace_tcp_t *trace_get_tcp(const libtrace_packet_t *packet) {
     306        if (remaining)
     307                *remaining = trace_get_capture_length(packet);
     308
     309        transport = trace_get_payload_from_link(
     310                        trace_get_link(packet),
     311                        trace_get_link_type(packet),
     312                        &ethertype,
     313                        remaining);
     314
     315        if (!transport)
     316                return NULL;
     317
     318        transport = trace_get_vlan_payload_from_ethernet_payload(transport,
     319                        &ethertype,
     320                        remaining);
     321
     322        if (!transport)
     323                return NULL;
     324
     325        switch (*proto) {
     326                case 0x0800: /* IPv4 */
     327                        transport=trace_get_payload_from_ip(transport, proto, remaining);
     328                        /* IPv6 */
     329                        if (transport && *proto == 41) {
     330                                transport=trace_get_payload_from_ip6(transport,
     331                                                proto,remaining);
     332                        }
     333                        return transport;
     334                case 0x86DD: /* IPv6 */
     335                        return trace_get_payload_from_ip6(transport, proto, remaining);
     336                       
     337                default:
     338                        return NULL;
     339        }
     340
     341}
     342
     343libtrace_tcp_t *trace_get_tcp(libtrace_packet_t *packet) {
    405344        uint8_t proto;
    406345        libtrace_tcp_t *tcp;
    407346
    408         tcp=trace_get_transport(packet,&proto);
     347        tcp=trace_get_transport(packet,&proto,NULL);
    409348
    410349        if (proto != 6)
     
    414353}
    415354
    416 libtrace_tcp_t *trace_get_tcp_from_ip(libtrace_ip_t *ip, int *skipped)
     355libtrace_tcp_t *trace_get_tcp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
    417356{
    418357        struct libtrace_tcp *tcpptr = 0;
     
    420359        if (ip->ip_p == 6)  {
    421360                tcpptr = (struct libtrace_tcp *)
    422                         trace_get_payload_from_ip(ip, NULL, skipped);
     361                        trace_get_payload_from_ip(ip, NULL, remaining);
    423362        }
    424363
     
    430369        libtrace_udp_t *udp;
    431370
    432         udp=trace_get_transport(packet,&proto);
     371        udp=trace_get_transport(packet,&proto,NULL);
    433372
    434373        if (proto != 17)
     
    438377}
    439378
    440 libtrace_udp_t *trace_get_udp_from_ip(libtrace_ip_t *ip, int *skipped)
     379libtrace_udp_t *trace_get_udp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
    441380{
    442381        struct libtrace_udp *udpptr = 0;
     
    444383        if (ip->ip_p == 17) {
    445384                udpptr = (libtrace_udp_t *)
    446                         trace_get_payload_from_ip(ip, NULL, skipped);
     385                        trace_get_payload_from_ip(ip, NULL, remaining);
    447386        }
    448387
     
    450389}
    451390
    452 libtrace_icmp_t *trace_get_icmp(const libtrace_packet_t *packet) {
     391libtrace_icmp_t *trace_get_icmp(libtrace_packet_t *packet) {
    453392        uint8_t proto;
    454393        libtrace_icmp_t *icmp;
    455394
    456         icmp=trace_get_transport(packet,&proto);
     395        icmp=trace_get_transport(packet,&proto,NULL);
    457396
    458397        if (proto != 1)
     
    462401}
    463402
    464 libtrace_icmp_t *trace_get_icmp_from_ip(libtrace_ip_t *ip, int *skipped)
     403libtrace_icmp_t *trace_get_icmp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
    465404{
    466405        libtrace_icmp_t *icmpptr = 0;
    467406
    468407        if (ip->ip_p == 1)  {
    469                 icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, NULL, skipped);
     408                icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip,
     409                                NULL, remaining);
    470410        }
    471411
     
    473413}
    474414
    475 void *trace_get_payload_from_udp(libtrace_udp_t *udp, int *skipped)
    476 {
    477         if (skipped) *skipped+=sizeof(libtrace_udp_t);
     415void *trace_get_payload_from_udp(libtrace_udp_t *udp, uint32_t *remaining)
     416{
     417        if (remaining) {
     418                if (*remaining < sizeof(libtrace_udp_t))
     419                        return NULL;
     420                *remaining-=sizeof(libtrace_udp_t);
     421        }
    478422        return (void*)((char*)udp+sizeof(libtrace_udp_t));
    479423}
    480424
    481 void *trace_get_payload_from_tcp(libtrace_tcp_t *tcp, int *skipped)
    482 {
    483         int dlen = tcp->doff*4;
    484         if (skipped) *skipped=dlen;
     425void *trace_get_payload_from_tcp(libtrace_tcp_t *tcp, uint32_t *remaining)
     426{
     427        unsigned int dlen = tcp->doff*4;
     428        if (remaining) {
     429                if (*remaining < dlen)
     430                        return NULL;
     431                *remaining-=dlen;
     432        }
    485433        return tcp+dlen;
    486434}
    487435
    488 void *trace_get_payload_from_icmp(libtrace_icmp_t *icmp, int *skipped)
    489 {
    490         if (skipped) *skipped = sizeof(libtrace_icmp_t);
     436void *trace_get_payload_from_icmp(libtrace_icmp_t *icmp, uint32_t *remaining)
     437{
     438        if (remaining) {
     439                if (*remaining < sizeof(libtrace_icmp_t))
     440                        return NULL;
     441                *remaining-=sizeof(libtrace_icmp_t);
     442        }
    491443        return (char*)icmp+sizeof(libtrace_icmp_t);
    492444}
    493445
     446struct ports_t {
     447        uint16_t src;
     448        uint16_t dst;
     449};
     450
     451/* Return the client port
     452 */
     453uint16_t trace_get_source_port(const libtrace_packet_t *packet)
     454{
     455        struct ports_t *port = trace_get_transport((libtrace_packet_t*)packet,
     456                        NULL, NULL);
     457
     458        return ntohs(port->src);
     459}
     460
     461/* Same as get_source_port except use the destination port */
     462uint16_t trace_get_destination_port(const libtrace_packet_t *packet)
     463{
     464        struct ports_t *port = trace_get_transport((libtrace_packet_t*)packet,
     465                        NULL, NULL);
     466
     467        return ntohs(port->dst);
     468}
     469
     470
     471uint8_t *trace_get_source_mac(libtrace_packet_t *packet) {
     472        void *link = trace_get_link(packet);
     473        libtrace_80211_t *wifi = link;
     474        libtrace_ether_t *ethptr = link;
     475        if (!link)
     476                return NULL;
     477        switch (trace_get_link_type(packet)) {
     478                case TRACE_TYPE_80211:
     479                        return (uint8_t*)&wifi->mac2;
     480                case TRACE_TYPE_ETH:
     481                        return (uint8_t*)&ethptr->ether_shost;
     482                default:
     483                        fprintf(stderr,"Not implemented\n");
     484                        assert(0);
     485        }
     486}
     487
     488uint8_t *trace_get_destination_mac(libtrace_packet_t *packet) {
     489        void *link = trace_get_link(packet);
     490        libtrace_80211_t *wifi = link;
     491        libtrace_ether_t *ethptr = link;
     492        if (!link)
     493                return NULL;
     494        switch (trace_get_link_type(packet)) {
     495                case TRACE_TYPE_80211:
     496                        return (uint8_t*)&wifi->mac1;
     497                case TRACE_TYPE_ETH:
     498                        return (uint8_t*)&ethptr->ether_dhost;
     499                default:
     500                        fprintf(stderr,"Not implemented\n");
     501                        assert(0);
     502        }
     503}
     504
     505struct sockaddr *trace_get_source_address(const libtrace_packet_t *packet,
     506                struct sockaddr *addr)
     507{
     508        uint16_t proto;
     509        uint32_t remaining;
     510        void *transport;
     511        static struct sockaddr_storage dummy;
     512
     513        if (!addr)
     514                addr=(struct sockaddr*)&dummy;
     515
     516        remaining = trace_get_capture_length(packet);
     517
     518        transport = trace_get_payload_from_link(
     519                        trace_get_link(packet),
     520                        trace_get_link_type(packet),
     521                        &proto,
     522                        &remaining);
     523
     524        if (!transport)
     525                return false;
     526
     527        transport = trace_get_vlan_payload_from_ethernet_payload(transport,
     528                        &proto,
     529                        &remaining);
     530
     531        if (!transport)
     532                return false;
     533
     534        switch (proto) {
     535                case 0x0800: /* IPv4 */
     536                {
     537                        struct sockaddr_in *addr4=(struct sockaddr_in*)addr;
     538                        libtrace_ip_t *ip = transport;
     539                        addr4->sin_family=AF_INET;
     540                        addr4->sin_port=0;
     541                        addr4->sin_addr=ip->ip_src;
     542                        return addr;
     543                }
     544                case 0x86DD: /* IPv6 */
     545                {
     546                        struct sockaddr_in6 *addr6=(struct sockaddr_in6*)addr;
     547                        libtrace_ip6_t *ip6 = transport;
     548                        addr6->sin6_family=AF_INET6;
     549                        addr6->sin6_port=0;
     550                        addr6->sin6_flowinfo=0;
     551                        addr6->sin6_addr=ip6->ip_src;
     552                        return addr;
     553                }
     554                default:
     555                        return NULL;
     556        }
     557}
     558
     559struct sockaddr *trace_get_destination_address(const libtrace_packet_t *packet,
     560                struct sockaddr *addr)
     561{
     562        uint16_t proto;
     563        uint32_t remaining;
     564        void *transport;
     565        static struct sockaddr_storage dummy;
     566
     567        if (!addr)
     568                addr=(struct sockaddr*)&dummy;
     569
     570        remaining = trace_get_capture_length(packet);
     571
     572        transport = trace_get_payload_from_link(
     573                        trace_get_link(packet),
     574                        trace_get_link_type(packet),
     575                        &proto,
     576                        &remaining);
     577
     578        if (!transport)
     579                return false;
     580
     581        transport = trace_get_vlan_payload_from_ethernet_payload(transport,
     582                        &proto,
     583                        &remaining);
     584
     585        if (!transport)
     586                return false;
     587
     588        switch (proto) {
     589                case 0x0800: /* IPv4 */
     590                {
     591                        struct sockaddr_in *addr4=(struct sockaddr_in*)addr;
     592                        libtrace_ip_t *ip = transport;
     593                        addr4->sin_family=AF_INET;
     594                        addr4->sin_port=0;
     595                        addr4->sin_addr=ip->ip_dst;
     596                        return addr;
     597                }
     598                case 0x86DD: /* IPv6 */
     599                {
     600                        struct sockaddr_in6 *addr6=(struct sockaddr_in6*)addr;
     601                        libtrace_ip6_t *ip6 = transport;
     602                        addr6->sin6_family=AF_INET6;
     603                        addr6->sin6_port=0;
     604                        addr6->sin6_flowinfo=0;
     605                        addr6->sin6_addr=ip6->ip_dst;
     606                        return addr;
     607                }
     608                default:
     609                        return NULL;
     610        }
     611}
     612
Note: See TracChangeset for help on using the changeset viewer.