Changeset f6730d8 for lib/protocols_l2.c


Ignore:
Timestamp:
02/09/10 13:43:51 (12 years ago)
Author:
Shane Alcock <salcock@…>
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:
ebf8071
Parents:
22a9ccc
Message:
  • Updated licensing and documentation for the protocol decoders
  • Moved trace_get_source_mac and trace_get_destination_mac into protocols_l2.c which is much more appropriate
  • Re-wrote trace_get_destination_mac to match the behaviour of trace_get_source_mac, especially with regard to ignoring link types that match meta-data headers
  • Added TRACE_TYPE_NONDATA handlers to several switch statements
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/protocols_l2.c

    r2d69532 rf6730d8  
    1 /* Protocol decodes for layer 2 */
     1/*
     2 * This file is part of libtrace
     3 *
     4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
     5 * New Zealand.
     6 *
     7 * Authors: Daniel Lawson
     8 *          Perry Lorier
     9 *          Shane Alcock
     10 *         
     11 * All rights reserved.
     12 *
     13 * This code has been developed by the University of Waikato WAND
     14 * research group. For further information please see http://www.wand.net.nz/
     15 *
     16 * libtrace is free software; you can redistribute it and/or modify
     17 * it under the terms of the GNU General Public License as published by
     18 * the Free Software Foundation; either version 2 of the License, or
     19 * (at your option) any later version.
     20 *
     21 * libtrace is distributed in the hope that it will be useful,
     22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     24 * GNU General Public License for more details.
     25 *
     26 * You should have received a copy of the GNU General Public License
     27 * along with libtrace; if not, write to the Free Software
     28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     29 *
     30 * $Id$
     31 *
     32 */
     33
    234#include "libtrace.h"
    335#include "protocols.h"
     
    537#include <assert.h>
    638#include <stdlib.h>
     39
     40/* This file contains all the protocol decoding functions for layer 2
     41 * (and 2.5) protocols. This includes functions for accessing MAC addresses.
     42 *
     43 * Supported protocols include (but are not limited to):
     44 *      Ethernet
     45 *      802.11
     46 *      802.1q (vlan)
     47 *      MPLS
     48 *      PPPoE
     49 *      LLCSnap
     50 *      ATM
     51 */
     52
    753
    854/* Returns the payload from 802.3 ethernet.  Type optionally returned in
     
    2975}
    3076
    31 /* skip any 802.1q headers if necessary
     77/* Skip any 802.1q headers if necessary
    3278 * type is now output only (why check it if we don't need to?)
    3379 */
     
    5399}
    54100
    55 /* skip any MPLS headers if necessary, guessing what the next type is
     101/* Skip any MPLS headers if necessary, guessing what the next type is
    56102 * type is input/output.  If the next type is "ethernet" this will
    57103 * return a type of 0x0000.
     
    338384                   */
    339385                case TRACE_TYPE_METADATA:
     386                case TRACE_TYPE_NONDATA:
    340387                        return NULL;
    341388
     
    346393                case TRACE_TYPE_NONE:
    347394                        if ((*(char*)link&0xF0) == 0x40)
    348                                 *ethertype=TRACE_ETHERTYPE_IP;  /* IPv4 */
     395                                *ethertype=TRACE_ETHERTYPE_IP;   /* IPv4 */
    349396                        else if ((*(char*)link&0xF0) == 0x60)
    350                                 *ethertype=TRACE_ETHERTYPE_IPV6;        /* IPv6 */
     397                                *ethertype=TRACE_ETHERTYPE_IPV6; /* IPv6 */
    351398                        return link; /* I love the simplicity */
    352399                case TRACE_TYPE_PPP:
     
    354401                case TRACE_TYPE_ATM:
    355402                        l=trace_get_payload_from_atm(link,NULL,remaining);
    356                         /* FIXME: We shouldn't skip llcsnap here, we should return
    357                          * an ethertype for it (somehow)
     403                        /* FIXME: We shouldn't skip llcsnap here, we should
     404                         * return an ethertype for it (somehow)
    358405                         */
    359406                        return (l ? trace_get_payload_from_llcsnap(l,
     
    376423}
    377424
    378 
    379 
     425/* Take a pointer to the start of an IEEE 802.11 MAC frame and return a pointer
     426 * to the source MAC address. 
     427 * If the frame does not contain a sender address, e.g. ACK frame, return NULL.
     428 * If the frame is a 4-address WDS frame, return TA, i.e. addr2.
     429 * NB: This function decodes the 802.11 header, so it assumes that there are no
     430 * bit-errors. If there are, all bets are off.
     431 */
     432static
     433uint8_t *get_source_mac_from_wifi(void *wifi) {
     434        struct libtrace_80211_t *w;
     435        if (wifi == NULL) return NULL;
     436        w = (struct libtrace_80211_t *) wifi;
     437
     438        /* If the frame is of type CTRL */
     439        if (w->type == 0x1)
     440                /* If bit 2 of the subtype field is zero, this indicates that
     441                 * there is no transmitter address, i.e. the frame is either an
     442                 * ACK or a CTS frame */
     443                if ((w->subtype & 0x2) == 0)
     444                        return NULL;
     445
     446        /* Always return the address of the transmitter, i.e. address 2 */
     447        return (uint8_t *) &w->mac2;
     448}
     449
     450DLLEXPORT uint8_t *trace_get_source_mac(libtrace_packet_t *packet) {
     451        void *link;
     452        uint32_t remaining;
     453        libtrace_linktype_t linktype;
     454        assert(packet);
     455        link = trace_get_layer2(packet,&linktype,&remaining);
     456
     457        if (!link)
     458                return NULL;
     459
     460        switch (linktype) {
     461                case TRACE_TYPE_ETH:
     462                        return (uint8_t *)&(((libtrace_ether_t*)link)->ether_shost);
     463                case TRACE_TYPE_80211:
     464                        return get_source_mac_from_wifi(link);
     465                /* These packets don't have MAC addresses */
     466                case TRACE_TYPE_POS:
     467                case TRACE_TYPE_NONE:
     468                case TRACE_TYPE_HDLC_POS:
     469                case TRACE_TYPE_PFLOG:
     470                case TRACE_TYPE_ATM:
     471                case TRACE_TYPE_DUCK:
     472                case TRACE_TYPE_METADATA:
     473                case TRACE_TYPE_AAL5:
     474                case TRACE_TYPE_LLCSNAP:
     475                case TRACE_TYPE_PPP:
     476                case TRACE_TYPE_NONDATA:
     477                        return NULL;
     478
     479                /* Metadata headers should already be skipped */
     480                case TRACE_TYPE_LINUX_SLL:
     481                case TRACE_TYPE_80211_PRISM:
     482                case TRACE_TYPE_80211_RADIO:
     483                        assert(!"Metadata headers should already be skipped");
     484                        break;
     485        }
     486        fprintf(stderr,"%s not implemented for linktype %i\n", __func__, linktype);
     487        assert(0);
     488        return NULL;
     489}
     490
     491DLLEXPORT uint8_t *trace_get_destination_mac(libtrace_packet_t *packet)
     492{
     493        void *link;
     494        libtrace_linktype_t linktype;
     495        uint32_t remaining;
     496        libtrace_80211_t *wifi;
     497        libtrace_ether_t *ethptr;
     498
     499        link = trace_get_layer2(packet,&linktype,&remaining);
     500
     501        ethptr = (libtrace_ether_t*)link;
     502
     503
     504        if (!link)
     505                return NULL;
     506
     507        switch (linktype) {
     508                case TRACE_TYPE_80211:
     509                        wifi=(libtrace_80211_t*)link;
     510                        return (uint8_t*)&wifi->mac1;
     511                case TRACE_TYPE_ETH:
     512                        return (uint8_t*)&ethptr->ether_dhost;
     513                case TRACE_TYPE_POS:
     514                case TRACE_TYPE_NONE:
     515                case TRACE_TYPE_ATM:
     516                case TRACE_TYPE_HDLC_POS:
     517                case TRACE_TYPE_PFLOG:
     518                case TRACE_TYPE_DUCK:
     519                case TRACE_TYPE_METADATA:
     520                case TRACE_TYPE_AAL5:
     521                case TRACE_TYPE_LLCSNAP:
     522                case TRACE_TYPE_PPP:   
     523                case TRACE_TYPE_NONDATA:
     524                        /* No MAC address */
     525                        return NULL;
     526                /* Metadata headers should already be skipped */
     527                case TRACE_TYPE_LINUX_SLL:
     528                case TRACE_TYPE_80211_PRISM:
     529                case TRACE_TYPE_80211_RADIO:
     530                        assert(!"Metadata headers should already be skipped");
     531                        break;
     532        }
     533        fprintf(stderr,"Not implemented\n");
     534        assert(0);
     535        return NULL;
     536}
     537
Note: See TracChangeset for help on using the changeset viewer.