Changeset 450d198


Ignore:
Timestamp:
02/19/19 10:04:37 (20 months ago)
Author:
Shane Alcock <salcock@…>
Branches:
develop
Children:
243bfd1
Parents:
67fdca0 (diff), d3376d5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'jacobvw-vlan/mpls' into develop

Files:
5 added
7 edited

Legend:

Unmodified
Added
Removed
  • lib/dagformat.h

    r4e5a51f rd3376d5  
    104104} PACKED dag_record_t;
    105105
    106 typedef struct dag_section_header {
    107         uint16_t type;
    108         uint16_t len;
    109 } PACKED dag_sec_t;
    110 
    111 struct dag_opthdr {
    112         uint16_t optcode;
    113         uint16_t optlen;
    114 } PACKED;
    115 
    116106#ifdef WIN32
    117107#pragma pack(pop)
  • lib/format_dpdk.c

    r5cdb37d r3621e1c  
    748748                /* TODO filtering */
    749749        case TRACE_OPTION_META_FREQ:
     750        case TRACE_OPTION_DISCARD_META:
    750751        case TRACE_OPTION_EVENT_REALTIME:
    751752        case TRACE_OPTION_REPLAY_SPEEDUP:
  • lib/format_erf.h

    r0af3a4e rd3376d5  
    112112 */
    113113
     114typedef struct dag_section_header {
     115        uint16_t type;
     116        uint16_t len;
     117} PACKED dag_sec_t;
     118
     119struct dag_opthdr {
     120        uint16_t optcode;
     121        uint16_t optlen;
     122} PACKED;
     123
    114124int erf_get_framing_length(const libtrace_packet_t *packet);
    115125libtrace_linktype_t erf_get_link_type(const libtrace_packet_t *packet);
  • lib/libtrace.h.in

    r58c226e rb9af56e  
    576576        TRACE_ETHERTYPE_RARP    = 0x8035,       /**< Reverse ARP */
    577577        TRACE_ETHERTYPE_8021Q   = 0x8100,       /**< 802.1q VLAN Extended Header */
     578        TRACE_ETHERTYPE_8021QS  = 0x88A8,       /**< 802.1q Service VLAN tag */
    578579        TRACE_ETHERTYPE_IPV6    = 0x86DD,       /**< IPv6 */
    579580        TRACE_ETHERTYPE_MPLS    = 0x8847,       /**< MPLS Unicast traffic */
     
    582583        TRACE_ETHERTYPE_PPP_SES = 0x8864        /**< PPPoE Session Messages */
    583584} libtrace_ethertype_t;
     585
     586/** constant to check if a vlan was found */
     587#define VLAN_NOT_FOUND 0xFF
     588
     589/** constant to check if a mpls label was found */
     590#define MPLS_NOT_FOUND 0xFFFF
     591
     592typedef struct libtrace_layer2_header {
     593        uint16_t ethertype;                     /**< Ethertype of the header */
     594        void *data;                             /**< Pointer to the header */
     595} libtrace_layer2_header_t;
     596typedef struct libtrace_layer2_headers {
     597        uint64_t bitmask;                       /**< Bitmask of found headers */
     598        int num;                                /**< The number of header */
     599        libtrace_layer2_header_t *header;       /**< Array of all found layer2 headers */
     600} libtrace_layer2_headers_t;
     601/** Enumeration of bitmask layer2 headers within libtrace_layer2_headers_t */
     602enum {
     603        TRACE_BITMASK_LOOPBACK  = 1,
     604        TRACE_BITMASK_IP        = 2,
     605        TRACE_BITMASK_ARP       = 4,
     606        TRACE_BITMASK_RARP      = 8,
     607        TRACE_BITMASK_8021Q     = 16,
     608        TRACE_BITMASK_IPV6      = 32,
     609        TRACE_BITMASK_8021QS    = 64,
     610        TRACE_BITMASK_MPLS      = 128,
     611        TRACE_BITMASK_MPLS_MC   = 256,
     612        TRACE_BITMASK_PPP_DISC  = 512,
     613        TRACE_BITMASK_PPP_SES   = 1024,
     614};
    584615
    585616/** Enumeration of datatype returned inside libtrace_meta_item_t structure */
     
    24452476                void *vlan, uint16_t *type, uint32_t *remaining);
    24462477
     2478/** Get the outermost VLAN ID from a packet.
     2479 * @param packet                A pointer to the packet
     2480 * @param[out] vlanptr          A pointer to the VLAN header
     2481 * @param[out] remaining        Updated with the number of captured bytes remaining
     2482 *
     2483 * @return The outermost VLAN id if found or VLAN_NOT_FOUND
     2484 *
     2485 * vlanptr will be set to the start of the VLAN header found (or NULL if no
     2486 * VLAN tags are present).
     2487 *
     2488 * remaining will be set to the number of captured bytes in the packet,
     2489 * starting from the returned VLAN header.
     2490 */
     2491DLLEXPORT uint16_t trace_get_outermost_vlan(
     2492        libtrace_packet_t *packet, uint8_t **vlanptr, uint32_t *remaining);
     2493
     2494/** Get all layer2 headers from a packet.
     2495 * @param packet        A pointer to the packet
     2496 *
     2497 * @return A libtrace_layer2_headers_t structure containing all found layer2
     2498 * headers (or NULL if no layer2 headers are found). This structure must be
     2499 * destroyed with trace_destroy_layer2_headers().
     2500 */
     2501DLLEXPORT libtrace_layer2_headers_t *trace_get_layer2_headers(libtrace_packet_t *packet);
     2502
     2503/** Destroys a libtrace_layer2_headers_t structure.
     2504 * @param headers       A pointer to the libtrace_layer2_headers_t structure
     2505 *
     2506 * @returns 1 on successful deletion.
     2507 */
     2508DLLEXPORT int trace_destroy_layer2_headers(libtrace_layer2_headers_t *headers);
     2509
     2510/** Get the outermost MPLS label from a packet.
     2511 * @param packet                A pointer to the packet
     2512 * @param[out] mplsptr          A pointer to the mpls header
     2513 * @param[out] remaining        Updated with the number of captured bytes remaining
     2514 *
     2515 * @return The outmost MPLS label if found or MPLS_NOT_FOUND
     2516 *
     2517 * mplsptr will be set to the start of the MPLS header (or NULL if no
     2518 * MPLS header is found)
     2519 *
     2520 * remaining will be set to the number of captured bytes in the packet,
     2521 * starting from the MPLS header.
     2522 */
     2523DLLEXPORT uint32_t trace_get_outermost_mpls(
     2524        libtrace_packet_t *packet, uint8_t **mplsptr, uint32_t *remaining);
     2525
    24472526/** Gets a pointer to the payload following an MPLS header.
    24482527 * @param mpls      A pointer to the MPLS header
  • lib/protocols_l2.c

    r385678b r5325ff0  
    9090        return (void*)((char *)ethernet + sizeof(*vlanhdr));
    9191
     92}
     93
     94int trace_destroy_layer2_headers(libtrace_layer2_headers_t *headers) {
     95        if (headers == NULL) {
     96                fprintf(stderr, "NULL libtrace_layer2_headers_t passed into "
     97                        "trace_destroy_layer2_headers()\n");
     98                return -1;
     99        }
     100
     101        if (headers->header != NULL) {
     102                free(headers->header);
     103        }
     104        free(headers);
     105        return 1;
     106}
     107libtrace_layer2_headers_t *trace_get_layer2_headers(libtrace_packet_t *packet) {
     108
     109        char *ptr;
     110        libtrace_linktype_t linktype;
     111        uint32_t remaining;
     112        uint16_t ethertype;
     113        libtrace_layer2_headers_t *r;
     114        int allocated_headers = 0;
     115
     116        if (packet == NULL) {
     117                fprintf(stderr, "NULL packet passed into trace_get_layer2_headers()\n");
     118                return NULL;
     119        }
     120        if (packet->trace == NULL) {
     121                fprintf(stderr, "Packet contains a NULL trace in trace_get_layer2_headers()\n");
     122                return NULL;
     123        }
     124
     125        /* jump to layer 2 */
     126        ptr = trace_get_layer2(packet, &linktype, &remaining);
     127        /* packet does not contain layer2 */
     128        if (ptr == NULL) {
     129                return NULL;
     130        }
     131
     132        /* allocate memory for the result */
     133        r = calloc(1, sizeof(libtrace_layer2_headers_t));
     134        if (r == NULL) {
     135                trace_set_err(packet->trace, TRACE_ERR_OUT_OF_MEMORY,
     136                        "Unable to allocate memory in trace_get_layer2_headers()\n");
     137                return NULL;
     138        }
     139        /* Alloc enough space for 10 headers */
     140        r->header = calloc(1, sizeof(libtrace_layer2_header_t)*10);
     141        if (r->header == NULL) {
     142                trace_set_err(packet->trace, TRACE_ERR_OUT_OF_MEMORY,
     143                        "Unable to allocate memory in trace_get_layer2_headers()\n");
     144                free(r);
     145                return NULL;
     146        }
     147        allocated_headers = 10;
     148
     149        /* get the first layer2 header */
     150        ptr = trace_get_payload_from_layer2(ptr, linktype, &ethertype, &remaining);
     151
     152        while (remaining != 0 && ptr != NULL) {
     153
     154                /* if the last ethertype was IP stop */
     155                if (ethertype == TRACE_ETHERTYPE_IP || ethertype == TRACE_ETHERTYPE_IPV6) {
     156                        break;
     157                }
     158
     159                if (ethertype == TRACE_ETHERTYPE_LOOPBACK ||
     160                        ethertype == TRACE_ETHERTYPE_IP ||
     161                        ethertype == TRACE_ETHERTYPE_ARP ||
     162                        ethertype == TRACE_ETHERTYPE_RARP ||
     163                        ethertype == TRACE_ETHERTYPE_8021Q ||
     164                        ethertype == TRACE_ETHERTYPE_IPV6 ||
     165                        ethertype == TRACE_ETHERTYPE_8021QS ||
     166                        ethertype == TRACE_ETHERTYPE_MPLS ||
     167                        ethertype == TRACE_ETHERTYPE_MPLS_MC ||
     168                        ethertype == TRACE_ETHERTYPE_PPP_DISC ||
     169                        ethertype == TRACE_ETHERTYPE_PPP_SES) {
     170
     171                        /* Set the bitmask */
     172                        switch (ethertype) {
     173                                case (TRACE_ETHERTYPE_LOOPBACK):
     174                                        r->bitmask |= TRACE_BITMASK_LOOPBACK;
     175                                        break;
     176                                case (TRACE_ETHERTYPE_IP):
     177                                        r->bitmask |= TRACE_BITMASK_IP;
     178                                        break;
     179                                case (TRACE_ETHERTYPE_ARP):
     180                                        r->bitmask |= TRACE_BITMASK_ARP;
     181                                        break;
     182                                case (TRACE_ETHERTYPE_RARP):
     183                                        r->bitmask |= TRACE_BITMASK_RARP;
     184                                        break;
     185                                case (TRACE_ETHERTYPE_8021Q):
     186                                        r->bitmask |= TRACE_BITMASK_8021Q;
     187                                        break;
     188                                case (TRACE_ETHERTYPE_IPV6):
     189                                        r->bitmask |= TRACE_BITMASK_IPV6;
     190                                        break;
     191                                case (TRACE_ETHERTYPE_8021QS):
     192                                        r->bitmask |= TRACE_BITMASK_8021QS;
     193                                        break;
     194                                case (TRACE_ETHERTYPE_MPLS):
     195                                        r->bitmask |= TRACE_BITMASK_MPLS;
     196                                        break;
     197                                case (TRACE_ETHERTYPE_MPLS_MC):
     198                                        r->bitmask |= TRACE_BITMASK_MPLS_MC;
     199                                        break;
     200                                case (TRACE_ETHERTYPE_PPP_DISC):
     201                                        r->bitmask |= TRACE_BITMASK_PPP_DISC;
     202                                        break;
     203                                case (TRACE_ETHERTYPE_PPP_SES):
     204                                        r->bitmask |= TRACE_BITMASK_PPP_SES;
     205                                        break;
     206                        }
     207
     208                        if ((r->num+1) >= allocated_headers) {
     209                                allocated_headers += 10;
     210                                r->header = realloc(r->header,
     211                                        sizeof(libtrace_layer2_header_t)*allocated_headers);
     212
     213                                if (r->header == NULL) {
     214                                        trace_set_err(packet->trace, TRACE_ERR_OUT_OF_MEMORY,
     215                                                "Unable to allocate memory in trace_get_layer2_headers()");
     216                                        free(r);
     217                                        return NULL;
     218                                }
     219                        }
     220
     221                        r->header[r->num].ethertype = ethertype;
     222                        r->header[r->num++].data = ptr;
     223                }
     224
     225                /* get the next header */
     226                ptr = trace_get_payload_from_layer2(ptr, linktype, &ethertype, &remaining);
     227        }
     228
     229        /* If no results were found free memory now and just return NULL */
     230        if (r->num == 0) {
     231                free(r->header);
     232                free(r);
     233                return NULL;
     234        }
     235
     236        return r;
     237}
     238
     239uint16_t trace_get_outermost_vlan(libtrace_packet_t *packet, uint8_t **vlanptr,
     240        uint32_t *remaining) {
     241
     242        uint8_t *ptr;
     243        libtrace_linktype_t linktype;
     244        uint32_t rem;
     245        uint16_t vlanid = VLAN_NOT_FOUND;
     246        uint16_t ethertype = 0;
     247
     248        if (!packet) {
     249                fprintf(stderr, "NULL packet passed into trace_get_outermost_vlan()\n");
     250                *vlanptr = NULL;
     251                *remaining = 0;
     252                return vlanid;
     253        }
     254
     255        ptr = trace_get_layer2(packet, &linktype, &rem);
     256        /* No layer 2 */
     257        if (ptr == NULL) {
     258                *vlanptr = NULL;
     259                *remaining = 0;
     260                return vlanid;
     261        }
     262
     263        while (ethertype != TRACE_ETHERTYPE_8021Q && ethertype != TRACE_ETHERTYPE_8021QS) {
     264
     265                if (rem == 0 || ptr == NULL || ethertype == TRACE_ETHERTYPE_IP ||
     266                        ethertype == TRACE_ETHERTYPE_IPV6) {
     267
     268                        *vlanptr = NULL;
     269                        *remaining = 0;
     270                        return vlanid;
     271                }
     272
     273                /* get the next layer 2 header */
     274                ptr = trace_get_payload_from_layer2(ptr, linktype, &ethertype, &rem);
     275        }
     276
     277        /* found a vlan header */
     278        uint32_t val = ntohl(*(uint32_t *)ptr);
     279        /* the id portion is only 12 bits */
     280        vlanid = (((val >> 16) << 4) >> 4);
     281
     282        *remaining = rem;
     283        *vlanptr = ptr;
     284        return vlanid;
     285}
     286
     287uint32_t trace_get_outermost_mpls(libtrace_packet_t *packet, uint8_t **mplsptr,
     288        uint32_t *remaining) {
     289
     290        uint8_t *ptr;
     291        uint32_t mplslabel = MPLS_NOT_FOUND;
     292        libtrace_linktype_t linktype;
     293        uint32_t rem;
     294        uint16_t ethertype = 0;
     295
     296        if (!packet) {
     297                fprintf(stderr, "NULL packet passed into trace_get_outermost_mpls()\n");
     298                *remaining = 0;
     299                *mplsptr = NULL;
     300                return mplslabel;
     301        }
     302
     303        ptr = trace_get_layer2(packet, &linktype, &rem);
     304        /* No layer2 */
     305        if (ptr == NULL) {
     306                *remaining = 0;
     307                *mplsptr = NULL;
     308                return mplslabel;
     309        }
     310
     311        /* loop over the packet until we find a mpls label */
     312        while (ethertype != TRACE_ETHERTYPE_MPLS) {
     313                if (rem == 0 || ptr == NULL) {
     314
     315                        *remaining = 0;
     316                        *mplsptr = NULL;
     317                        return mplslabel;
     318                }
     319
     320                /* get next layer2 header */
     321                ptr = trace_get_payload_from_layer2(ptr, linktype, &ethertype, &rem);
     322        }
     323
     324        uint32_t val = ntohl(*(uint32_t *)ptr);
     325        mplslabel = val >> 12;
     326
     327        *remaining = rem;
     328        *mplsptr = ptr;
     329        return mplslabel;
    92330}
    93331
  • test/Makefile

    rec19a99 re78e408  
    1919BINS = test-pcap-bpf test-event test-time test-dir test-wireless test-errors \
    2020        test-plen test-autodetect test-ports test-fragment test-live \
    21         test-live-snaplen test-vxlan test-setcaplen test-wlen \
     21        test-live-snaplen test-vxlan test-setcaplen test-wlen test-vlan \
     22        test-mpls test-layer2-headers \
    2223        $(BINS_DATASTRUCT) $(BINS_PARALLEL)
    2324
  • test/do-tests.sh

    rec19a99 r71f218a  
    331331do_test ./test-vxlan
    332332
     333echo " * Outermost VLAN ID"
     334do_test ./test-vlan
     335
     336echo " * Outermost MPLS label"
     337do_test ./test-mpls
     338
     339echo " * Layer2 Headers"
     340do_test ./test-layer2-headers
     341
    333342echo
    334343echo "Tests passed: $OK"
Note: See TracChangeset for help on using the changeset viewer.