Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-users: Re: [Wireshark-users] Help on MAC-LTE Decoder

From: Madhur Raj N <madhurrajn@xxxxxxxxx>
Date: Tue, 29 Jun 2010 19:14:14 +0530
Attach mac-lte-logger.c. Missed in last email.

On 29 June 2010 19:08, Madhur Raj N <madhurrajn@xxxxxxxxx> wrote:
Hi Martin,

        Thanks for the quick response. I have enabled heuristic MAC-LTE over UDP framing, as you have already mentioned in one of the previous list emails. under edit->preference->protocol->mac-lte.  I am hereby attaching the pcap file, which I am trying to decode. Please let me know, if anything is missing.

I am using wireshark version 1.3.5.

Regards,
Madhur


On 29 June 2010 18:46, Martin Mathieson <martin.r.mathieson@xxxxxxxxxxxxxx> wrote:


On Tue, Jun 29, 2010 at 1:57 PM, Madhur Raj N <madhurrajn@xxxxxxxxx> wrote:
Hi,

      I am trying to use  MAC-LTE packet dissector on the eNodeB side. Currently I am finding difficulty in using it. I have gone through many of your support site but things are not looking good at my side.

This is what I have tried.
1. I do not have any catapult DCT2000. Hence I can not capture files in .out format.
2. I am using UDP packets to carry MAC-LTE frames.

OK, did you check the MAC-LTE protocol preference 'Try Heuristic MAC-LTE over UDP framing"?
 
3. As I can not decode the packets, I have added handler to get the option for " Decode As" inside proto_reg_handoff_mac_lte() function. With this I am able to find the "Decode As" option for MAC-LTE. But whence i try to decode, I am thrownwith following error:
        "Can't dissect LTE MAC frame because no per-frame info was attached!"


The heuristic dissector parses the header, populates a struct with the given info and attaches it to the frame (for mac-lte).
If the heuristic dissector didn't match the frame, p_get_proto_data won't contain a filled-in struct.
 
Can you please help me, as why "p_get_proto_data" is throwing error.
4. Currently to bring up the setup, I am using the sample program "mac_lte_logger.c" file given at wireshark site to generate the packets.

Can you please also let me know any list where I can paste, it might be helpful for others too.

If you've tried the preference setting I mentioned above and its still not working, could you send me the captured file and I'll see what is going wrong with it?

Regards,
Martin
 

Regards,
Madhur

___________________________________________________________________________
Sent via:    Wireshark-users mailing list <wireshark-users@xxxxxxxxxxxxx>
Archives:    http://www.wireshark.org/lists/wireshark-users
Unsubscribe: https://wireshark.org/mailman/options/wireshark-users
            mailto:wireshark-users-request@xxxxxxxxxxxxx?subject=unsubscribe


___________________________________________________________________________
Sent via:    Wireshark-users mailing list <wireshark-users@xxxxxxxxxxxxx>
Archives:    http://www.wireshark.org/lists/wireshark-users
Unsubscribe: https://wireshark.org/mailman/options/wireshark-users
            mailto:wireshark-users-request@xxxxxxxxxxxxx?subject=unsubscribe


/* mac_lte_logger.c
 *
 * Example code for sending MAC LTE frames over UDP
 * Written by Martin Mathieson, with input from Kiran Kumar
 * This header file may also be distributed under
 * the terms of the BSD Licence as follows:
 * 
 * Copyright (C) 2009 Martin Mathieson. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE
 */



#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

typedef unsigned char  guint8;
typedef unsigned short guint16;
typedef unsigned int   guint32;
#include "packet-mac-lte.h"


/* Globals where each frame is composed before sending */
static unsigned char g_PDUBuffer[16000];
static unsigned int  g_PDUOffset;
static unsigned char g_frameBuffer[16000];
static unsigned int  g_frameOffset;

/* UDP socket used for sending frames */
static int                  g_sockfd;

/* Remote serveraddress (where Wireshark is running) */
static struct sockaddr_in   g_serv_addr;

/* Compilation MADHUR */
#define MAC_LTE_START_STRING ""
#define MAC_LTE_RNTI_TAG     1
#define MAC_LTE_UEID_TAG     1
#define MAC_LTE_SUBFRAME_TAG 1
#define MAC_LTE_CRC_STATUS_TAG     1
#define MAC_LTE_PREDFINED_DATA_TAG 1
#define MAC_LTE_RETX_TAG     1
#define MAC_LTE_PAYLOAD_TAG 1


/* Write an RAR PDU */
static void EncodeDummyMACPDU1(void)
{
    g_PDUOffset = 0;

    /* RAR */
    g_PDUBuffer[g_PDUOffset++] = 0x40;
    g_PDUBuffer[g_PDUOffset++] = 0x00;
    g_PDUBuffer[g_PDUOffset++] = 0x00;
    g_PDUBuffer[g_PDUOffset++] = 0xdc;
    g_PDUBuffer[g_PDUOffset++] = 0x0c;
    g_PDUBuffer[g_PDUOffset++] = 0x21;
    g_PDUBuffer[g_PDUOffset++] = 0x21;
}

/* Write an uplink PDU (with dummy CCCH payload)*/
static void EncodeDummyMACPDU2(void)
{
    g_PDUOffset = 0;

    /* RAR */
    g_PDUBuffer[g_PDUOffset++] = 0x3f;
    g_PDUBuffer[g_PDUOffset++] = 0x3f;
    g_PDUBuffer[g_PDUOffset++] = 0x00;
    g_PDUBuffer[g_PDUOffset++] = 0xa5;
    g_PDUBuffer[g_PDUOffset++] = 0xa5;
    g_PDUBuffer[g_PDUOffset++] = 0xa5;
    g_PDUBuffer[g_PDUOffset++] = 0x79;
    g_PDUBuffer[g_PDUOffset++] = 0x79;
    g_PDUBuffer[g_PDUOffset++] = 0x41;
    g_PDUBuffer[g_PDUOffset++] = 0x41;
    g_PDUBuffer[g_PDUOffset++] = 0x36;
    g_PDUBuffer[g_PDUOffset++] = 0x36;
    g_PDUBuffer[g_PDUOffset++] = 0x36;
}

/* Write a (dummy) BCH PDU */
static void EncodeDummyMACPDU3(void)
{
    g_PDUOffset = 0;

    /* BCH (nonsense data) */
    g_PDUBuffer[g_PDUOffset++] = 0x00;
    g_PDUBuffer[g_PDUOffset++] = 0x00;
    g_PDUBuffer[g_PDUOffset++] = 0x00;
}




/*******************************************/
/* Add framing header to MAC PDU and send. */
void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
               guint16 rnti, guint16 ueid, guint16 subframeNumber,
               guint8 isPredefinedData, guint8 retx, guint8 crcStatus)
{
    ssize_t bytesSent;
    g_frameOffset = 0;
    unsigned short tmp16;

    /********************************************************************/
    /* Fixed start to each frame (allowing heuristic dissector to work) */
    /* Not NULL terminated */
    memcpy(g_frameBuffer+g_frameOffset, MAC_LTE_START_STRING,
           strlen(MAC_LTE_START_STRING));
    g_frameOffset += strlen(MAC_LTE_START_STRING);

    /******************************************************************************/
    /* Now write out fixed fields (the mandatory elements of struct mac_lte_info) */
    g_frameBuffer[g_frameOffset++] = radioType;
    g_frameBuffer[g_frameOffset++] = direction;
    g_frameBuffer[g_frameOffset++] = rntiType;

    /*************************************/
    /* Now optional fields               */

    /* RNTI */
    g_frameBuffer[g_frameOffset++] = MAC_LTE_RNTI_TAG;
    tmp16 = htons(rnti);
    memcpy(g_frameBuffer+g_frameOffset, &tmp16, 2);
    g_frameOffset += 2;

    /* UEId */
    g_frameBuffer[g_frameOffset++] = MAC_LTE_UEID_TAG;
    tmp16 = htons(ueid);
    memcpy(g_frameBuffer+g_frameOffset, &tmp16, 2);
    g_frameOffset += 2;

    /* Subframe number */
    g_frameBuffer[g_frameOffset++] = MAC_LTE_SUBFRAME_TAG;
    tmp16 = htons(ueid);
    memcpy(g_frameBuffer+g_frameOffset, &tmp16, 2);
    g_frameOffset += 2;

    g_frameBuffer[g_frameOffset++] = MAC_LTE_CRC_STATUS_TAG;
    g_frameBuffer[g_frameOffset++] = crcStatus;


    /***********************************************************/
    /* For these optional fields, no need to encode if value is default */
    if (!isPredefinedData) {
        g_frameBuffer[g_frameOffset++] = MAC_LTE_PREDFINED_DATA_TAG;
        g_frameBuffer[g_frameOffset++] = isPredefinedData;
    }

    if (retx != 0) {
        g_frameBuffer[g_frameOffset++] = MAC_LTE_RETX_TAG;
        g_frameBuffer[g_frameOffset++] = retx;
    }


    /***************************************/
    /* Now write the MAC PDU               */
    g_frameBuffer[g_frameOffset++] = MAC_LTE_PAYLOAD_TAG;

    /* Append actual PDU  */
    memcpy(g_frameBuffer+g_frameOffset, g_PDUBuffer, g_PDUOffset);
    g_frameOffset += g_PDUOffset;

    /* Send out the data over the UDP socket */
    bytesSent = sendto(g_sockfd, g_frameBuffer, g_frameOffset, 0,
                      (const struct sockaddr*)&g_serv_addr, sizeof(g_serv_addr));
    if (bytesSent != g_frameOffset) {
        fprintf(stderr, "sendto() failed - expected %d bytes, got %d (errno=%d)\n",
                g_frameOffset, bytesSent, errno);
        exit(1);
    }
}


/*************************************************************************/
/* Main function                                                         */
/*  - set up socket + aserver address                                    */
/*  - encode and send some example LTE MAC frames using framing protocol */
int main(int argc, char *argv[])
{
    struct hostent *hp;

    if (argc < 3) {
        fprintf(stderr, "Usage: coclient <server-host> <server-port>\n");
        exit(1);
    }

    /***********************************/
    /* Create local socket             */
    g_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (g_sockfd == -1) {
        fprintf(stderr, "Error trying to create socket (errno=%d)\n", errno);
        exit(1);
    }

    /***************************************************/
    /* Get remote IP address from 1st command-line arg */
    g_serv_addr.sin_family = AF_INET;
    hp = gethostbyname(argv[1]);
    if (hp == (struct hostent *)0) {
        fprintf(stderr, "Unknown host %s (h_errno=%d)\n", argv[1], h_errno);
        exit(1);
    }
    memcpy((void*)&g_serv_addr.sin_addr, (void*)hp->h_addr, hp->h_length);

    /****************************************************/
    /* Get remote port number from 2nd command-line arg */
    g_serv_addr.sin_port = htons(atoi(argv[2]));

    /****************************************************/
    /* Encode and send some frames                       */
    EncodeDummyMACPDU1();
    SendFrame(FDD_RADIO, DIRECTION_DOWNLINK, RA_RNTI,
              1   /* RNTI */,
              101 /* UEId */,
              1   /* Subframe number */,
              0   /* isPredefined */,
              0   /* retx */,
              1   /* CRCStatus (i.e. OK) */);

    EncodeDummyMACPDU2();
    SendFrame(FDD_RADIO, DIRECTION_UPLINK, C_RNTI,
              50   /* RNTI */,
              101  /* UEId */,
              2    /* Subframe number */,
              0    /* isPredefined */,
              1    /* retx */,
              1    /* CRCStatus (i.e. OK) */);

    EncodeDummyMACPDU3();
    SendFrame(FDD_RADIO, DIRECTION_DOWNLINK, NO_RNTI,
              0    /* RNTI */,
              0    /* UEId */,
              3    /* Subframe number */,
              0    /* isPredefined */,
              0    /* retx */,
              0    /* CRCStatu (i.e. CRC error) */);


    /* Close local socket */
    close(g_sockfd);

    return EXIT_SUCCESS;

}