This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

RLC-LTE Heuristic Dissector Issue

0

Hello,

I am facing difficulty while calling heuristic dissector through lua script. I am using the sample code provided at wireshark wiki for sending RLC frames over udp thenafter I am using lua to call dissector, but getting error message "Can't dissect LTE RLC frame because no per-frame info was attached".

I need to show the header part of rlc frames e.g RLC Mode, Direction, Logical Channel ID etc, in segregated way. alt text

Here below the lua being used :

enter code here:

do print("hello Lua!!!")

local channel_dissectors = { [0] = { [0] = Dissector.get("rlc-lte") } }

local uelog_proto = Proto("uelog","UE Log Protocol")

– create a function to dissect it function uelog_proto.dissector(buffer,pinfo,tree)

local dissector = channel_dissectors[0][0] if dissector ~= nil then print("Buffer %x,%x,%x \n",buffer(0,1):uint(),buffer(1,1):uint(),buffer(2,1):uint()) –dissector:call(buffer(0):tvb(),pinfo,tree) –pinfo.proto_data=NULL print("Value %s",buffer(0,7):string()) pinfo.cols.info:set(buffer(0,7):string()) dissector:call(buffer(7):tvb(),pinfo,tree) else print(string.format("dissector not found, pkt number = %d", pinfo.number )) end

end

– load the udp.port table udp_table = DissectorTable.get("udp.port") – register our protocol to handle udp port 5001 udp_table:add(8001,uelog_proto)

end

/************************* rlc-lte Sample Code *******************************/

#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> #include <stdint.h> #include "lteRlc.h"

typedef unsigned char guint8; typedef unsigned short guint16; typedef unsigned int guint32;

/* 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;

extern int rrcSockFd; void sendLteRlcPdu();

/* Write a RLC TM PDU */ static void EncodeDummyRLCPDU1(void) { g_PDUOffset = 0;

g_PDUBuffer[g_PDUOffset++] = 0x60;
g_PDUBuffer[g_PDUOffset++] = 0x12;
g_PDUBuffer[g_PDUOffset++] = 0x9b;
g_PDUBuffer[g_PDUOffset++] = 0x3e;
g_PDUBuffer[g_PDUOffset++] = 0x9c;
g_PDUBuffer[g_PDUOffset++] = 0xc0;
g_PDUBuffer[g_PDUOffset++] = 0x7f;
g_PDUBuffer[g_PDUOffset++] = 0xf0;
g_PDUBuffer[g_PDUOffset++] = 0x96;
g_PDUBuffer[g_PDUOffset++] = 0x64;
g_PDUBuffer[g_PDUOffset++] = 0x30;
g_PDUBuffer[g_PDUOffset++] = 0x64;
g_PDUBuffer[g_PDUOffset++] = 0xcb;
g_PDUBuffer[g_PDUOffset++] = 0x05;
g_PDUBuffer[g_PDUOffset++] = 0x23;
g_PDUBuffer[g_PDUOffset++] = 0xc0;

}

/* Write a RLC AM control PDU */ static void EncodeDummyRLCPDU2(void) { g_PDUOffset = 0;

g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0x04;

}

/* Write a RLC AM data PDU */ static void EncodeDummyRLCPDU3(void) { g_PDUOffset = 0;

g_PDUBuffer[g_PDUOffset++] = 0x88;
g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0x80;
g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0x01;
g_PDUBuffer[g_PDUOffset++] = 0x08;
g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0x06;
g_PDUBuffer[g_PDUOffset++] = 0x04;
g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0x01;
g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0xFF;
g_PDUBuffer[g_PDUOffset++] = 0x1D;
g_PDUBuffer[g_PDUOffset++] = 0xA1;
g_PDUBuffer[g_PDUOffset++] = 0x3D;
g_PDUBuffer[g_PDUOffset++] = 0x28;
g_PDUBuffer[g_PDUOffset++] = 0xC0;
g_PDUBuffer[g_PDUOffset++] = 0xA8;
g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0x01;
g_PDUBuffer[g_PDUOffset++] = 0x00;
g_PDUBuffer[g_PDUOffset++] = 0x00;

}

/******************************************/ / Add framing header to RLC PDU and send. */ void SendFrame(guint8 rlcMode, guint8 direction, guint8 priority, guint16 ueid, guint16 channelType, guint16 channelId, guint8 UMSequenceNumberLength) { 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, RLC_LTE_START_STRING,
       strlen(RLC_LTE_START_STRING));
g_frameOffset += strlen(RLC_LTE_START_STRING);

/******************************************************************************/
/* Now write out fixed field (the mandatory element of struct rlc_lte_info)   */
g_frameBuffer[g_frameOffset++] = rlcMode;

/*************************************/
/* Now conditional fields            */

/* UM SN length */
if (rlcMode == RLC_UM_MODE) {
    g_frameBuffer[g_frameOffset++] = RLC_LTE_UM_SN_LENGTH_TAG;
    g_frameBuffer[g_frameOffset++] = UMSequenceNumberLength;
}

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

/* Direction */
g_frameBuffer[g_frameOffset++] = RLC_LTE_DIRECTION_TAG;
g_frameBuffer[g_frameOffset++] = direction;

/* Priority */
g_frameBuffer[g_frameOffset++] = RLC_LTE_PRIORITY_TAG;
g_frameBuffer[g_frameOffset++] = priority;

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

/* Channel Type */
g_frameBuffer[g_frameOffset++] = RLC_LTE_CHANNEL_TYPE_TAG;
tmp16 = htons(ueid);
memcpy(g_frameBuffer+g_frameOffset, &amp;tmp16, 2);
g_frameOffset += 2;

/* Channel Id */
g_frameBuffer[g_frameOffset++] = RLC_LTE_CHANNEL_ID_TAG;
tmp16 = htons(ueid);
memcpy(g_frameBuffer+g_frameOffset, &amp;tmp16, 2);
g_frameOffset += 2;

/**************************************/ / Now write the RLC PDU */ g_frameBuffer[g_frameOffset++] = RLC_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 */

 printf(&quot;Sending RLC Frame over socket::::RLC Mode: %u&quot;,rlcMode);
bytesSent = sendto(g_sockfd, g_frameBuffer, g_frameOffset, 0,(const struct sockaddr*)&amp;g_serv_addr, sizeof(g_serv_addr));
//bytesSent = sendto(rrcSockFd, g_frameBuffer, g_frameOffset, 0,(const struct sockaddr*)&amp;g_serv_addr, sizeof(g_serv_addr));
if (bytesSent != g_frameOffset) {
    fprintf(stderr, &quot;sendto() failed - expected %d bytes, got %d (errno=%d)\n&quot;,
            g_frameOffset, bytesSent, errno);
    exit(1);
}

}

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

if (argc &lt; 3) {
    fprintf(stderr, &quot;Usage: coclient &lt;server-host&gt; &lt;server-port&gt;\n&quot;);
    exit(1);
}

/***********************************/
/* Create local socket             */
g_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (g_sockfd == -1) {
    fprintf(stderr, &quot;Error trying to create socket (errno=%d)\n&quot;, 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, &quot;Unknown host %s (h_errno=%d)\n&quot;, argv[1], h_errno);
    exit(1);
}
memcpy((void*)&amp;g_serv_addr.sin_addr, (void*)hp-&gt;h_addr, hp-&gt;h_length);

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

/****************************************************/

//void sendLteRlcPdu() //{

while(1){

/* Encode and send some frames                       */

#if 0 EncodeDummyRLCPDU1(); SendFrame(RLC_TM_MODE, DIRECTION_DOWNLINK, 0 /* Priority */, 101 /* UEId */, CHANNEL_TYPE_CCCH, 0 /* Channel Id */, 0 /* UMSequenceNumberLength */); #endif

EncodeDummyRLCPDU2();
SendFrame(RLC_AM_MODE,
          DIRECTION_UPLINK,
          1   /* Priority */,
          101 /* UEId */,
          CHANNEL_TYPE_DRB,
          3   /* Channel Id */,
          0   /* UMSequenceNumberLength */);

EncodeDummyRLCPDU3();
SendFrame(RLC_AM_MODE,
          DIRECTION_UPLINK,
          1   /* Priority */,
          101 /* UEId */,
          CHANNEL_TYPE_DRB,
          3   /* Channel Id */,
          0   /* UMSequenceNumberLength */);

}

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

return EXIT_SUCCESS;

}

Please help me out as I am stuck at this. Any help will be appreciated

Regards Amit Kumar

asked 22 Sep ‘15, 05:19

amittkumm's gravatar image

amittkumm
6223
accept rate: 0%

edited 22 Sep ‘15, 07:24

grahamb's gravatar image

grahamb ♦
19.8k330206


One Answer:

0

If I understand your Lua code properly, you are trying to call directly the rlc-lte dissector. This will not work with the UDP framing protocol.

Instead you should let UDP dissector call the RLC-LTE over UDP heuristic dissector (after activating the heuristic dissector in RLC-LTE preferences), that will take care of filling the per frame info as requested by the framing protocol defined in epan\dissectors\packet-rlc-lte.h.

What is the purpose of your Lua dissector exactly? It seems to insert itself between the UDP and RLC-LTE dissector, preventing the per fram info to be populated.

answered 22 Sep '15, 06:35

Pascal%20Quantin's gravatar image

Pascal Quantin
5.5k1060
accept rate: 30%

Thanks for your reply and help on the same. The above snap was for testing only.

We have multiple UE connected to the system. And each UE is send the RLC packet in the UDP format , so we have added our own header above the RLC packet header to differentiate among each UE RLC packet.

In our lua script, we wanted to call the RLC-LTE dissector so that we can differentiate between UE. Could you tell me , can we directly call this RLC-LTE dissector instead of heuristic

(22 Sep '15, 07:29) amittkumm
1

Yes you could, but in that case you would need to fill the rlc_lte_info structure (as found in epan\dissectors\packet-rlc-lte.h file) and attach it to pinfo, duplicating what is done in dissect_rlc_lte_heur() function. I do not know how easy this is doable in Lua (I only write C code). Be aware that the rlc_lte_info structure already contains a UE identifier, so see if it can fill your needs or not.

(22 Sep '15, 10:29) Pascal Quantin

Thanks a ton. It really helped me.

(26 Sep '15, 04:36) amittkumm