Commit 4b96947e authored by Abhijith's avatar Abhijith

Added support for MAC PDU analysis using Wireshark in NR

parent 951fdfef
......@@ -36,6 +36,7 @@
#include <pthread.h>
#include "COMMON/platform_constants.h"
#include "PHY/defs_eNB.h"
#include "PHY/defs_gNB.h"
#include "PHY/types.h"
#include "PHY/impl_defs_top.h"
......
......@@ -967,6 +967,10 @@ void nr_generate_Msg2(module_id_t module_idP,
nr_mac->TX_req[CC_id].Slot = slotP;
memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length);
trace_nr_pdu(DIRECTION_DOWNLINK, &cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length,
find_nr_UE_id(module_idP, ra->rnti), 0, /* harq pid, meaningful? */
WS_NR_RA_RNTI , RA_rnti ,true ,frameP, slotP);
T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id),
T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */,
T_BUFFER(&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length));
......
......@@ -47,6 +47,7 @@
/*Softmodem params*/
#include "executables/softmodem-common.h"
#include "UTIL/OPT/opt.h"
////////////////////////////////////////////////////////
/////* DLSCH MAC PDU generation (6.1.2 TS 38.321) */////
......@@ -778,6 +779,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
UE_id);
}
trace_nr_pdu(DIRECTION_DOWNLINK, (uint8_t *)buf , TBS , 0 , current_harq_pid , WS_C_RNTI , rnti ,true , frame , slot );
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(buf, TBS));
......
......@@ -32,6 +32,7 @@
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "executables/softmodem-common.h"
#include "common/utils/nr/nr_common.h"
#include "UTIL/OPT/opt.h"
void nr_process_mac_pdu(
......@@ -325,6 +326,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
int target_snrx10 = gNB_mac->pusch_target_snrx10;
if (sduP != NULL) {
trace_nr_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, UE_id ,harq_pid ,WS_NR_C_RNTI ,current_rnti ,
true , frameP, slotP);
T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP),
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */,
T_BUFFER(sduP, sdu_lenP));
......
......@@ -60,7 +60,9 @@ typedef uint32_t guint32;
typedef guint8 gboolean;
#include "packet-mac-lte.h"
#include "packet-mac-nr.h"
#include "mac_pcap.h"
#include "stdbool.h"
/* OPT parameters definitions */
#define OPT_CONFIGPREFIX "opt"
......@@ -113,6 +115,12 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p
int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
int oob_event, int oob_event_value);
#define trace_nr_pdu(x...) if (opt_enabled) trace_nr_pdu_implementation(x)
void trace_nr_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int ueid, int harqid, int rntiType, int rnti,
bool sfnSlotInfoPresent, uint16_t sysframeNumber, uint16_t slotNumber);
int init_opt(void);
void terminate_opt(void);
......
/* packet-mac-nr.h
*
* Martin Mathieson
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/* radioType */
#define FDD_RADIO 1
#define TDD_RADIO 2
/* Direction */
#define DIRECTION_UPLINK 0
#define DIRECTION_DOWNLINK 1
/* rntiType */
#define WS_NR_NO_RNTI 0
#define WS_NR_P_RNTI 1
#define WS_NR_RA_RNTI 2
#define WS_NR_C_RNTI 3
#define WS_NR_SI_RNTI 4
#define WS_NR_CS_RNTI 5
/* Context info attached to each NR MAC frame */
typedef struct mac_nr_info
{
/* Needed for decode */
guint8 radioType;
guint8 direction;
guint8 rntiType;
/* Extra info to display */
guint16 rnti;
guint16 ueid;
guint8 harqid;
/* Will these be included in the ME PHR report? */
guint8 phr_type2_othercell;
/* Timing info */
gboolean sfnSlotInfoPresent;
guint16 sysframeNumber;
guint16 slotNumber;
/* Length of DL PDU or UL grant size in bytes */
guint16 length;
} mac_nr_info;
/* Functions to be called from outside this module (e.g. in a plugin, where mac_nr_info
isn't available) to get/set per-packet data */
// WS_DLL_PUBLIC
// mac_nr_info *get_mac_nr_proto_data(packet_info *pinfo);
// WS_DLL_PUBLIC
// void set_mac_nr_proto_data(packet_info *pinfo, mac_nr_info *p_mac_nr_info);
/*****************************************************************/
/* UDP framing format */
/* ----------------------- */
/* Several people have asked about dissecting MAC by framing */
/* PDUs over IP. A suggested format over UDP has been created */
/* and implemented by this dissector, using the definitions */
/* below. */
/* */
/* A heuristic dissector (enabled by a preference) will */
/* recognise a signature at the beginning of these frames. */
/*****************************************************************/
/* Signature. Rather than try to define a port for this, or make the
port number a preference, frames will start with this string (with no
terminating NULL */
#define MAC_NR_START_STRING "mac-nr"
/* Fixed fields. This is followed by the following 3 mandatory fields:
- radioType (1 byte)
- direction (1 byte)
- rntiType (1 byte)
(where the allowed values are defined above */
/* Optional fields. Attaching this info to frames will allow you
to show you display/filter/plot/add-custom-columns on these fields, so should
be added if available.
The format is to have the tag, followed by the value (there is no length field,
it's implicit from the tag) */
#define MAC_NR_RNTI_TAG 0x02
/* 2 bytes, network order */
#define MAC_NR_UEID_TAG 0x03
/* 2 bytes, network order */
#define MAC_NR_FRAME_SUBFRAME_TAG 0x04
/* 2 bytes, deprecated, do not use it */
#define MAC_NR_PHR_TYPE2_OTHERCELL_TAG 0x05
/* 1 byte, TRUE/FALSE */
#define MAC_NR_HARQID 0x06
/* 1 byte */
#define MAC_NR_FRAME_SLOT_TAG 0x07
/* 4 bytes, network order, SFN is stored in the 2 first bytes and slot number in the 2 last bytes */
/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
continues until the end of the frame) */
#define MAC_NR_PAYLOAD_TAG 0x01
/* Type to store parameters for configuring LCID->RLC channel settings for DRB */
/* Some are optional, and may not be seen (e.g. on reestablishment) */
typedef struct nr_drb_mapping_t
{
guint16 ueid; /* Mandatory */
guint8 drbid; /* Mandatory */
gboolean lcid_present;
guint8 lcid; /* Part of LogicalChannelConfig - optional */
gboolean rlcMode_present;
guint8 rlcMode; /* Part of RLC config - optional */
guint8 tempDirection; /* So know direction of next SN length... */
gboolean rlcUlSnLength_present;
guint8 rlcUlSnLength; /* Part of RLC config - optional */
gboolean rlcDlSnLength_present;
guint8 rlcDlSnLength; /* Part of RLC config - optional */
gboolean pdcpUlSnLength_present;
guint8 pdcpUlSnLength; /* Part of PDCP config - optional */
gboolean pdcpDlSnLength_present;
guint8 pdcpDlSnLength; /* Part of PDCP config - optional */
} nr_drb_mapping_t;
/* Set details of an LCID -> drb channel mapping. To be called from
configuration protocol (i.e. RRC) */
void set_mac_nr_bearer_mapping(nr_drb_mapping_t *drb_mapping);
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/
\ No newline at end of file
......@@ -134,6 +134,11 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
guint8 oob_event, guint8 oob_event_value,
uint8_t *pdu_buffer, unsigned int pdu_buffer_size);
static void SendNRFrame(guint8 radioType, guint8 direction, guint8 rntiType,
guint16 rnti, guint16 ueid, guint8 harqid,
gboolean sfnSlotInfoPresent, guint16 sysframeNumber, guint16 slotNumber,
uint8_t *pdu_buffer, unsigned int pdu_buffer_size);
unsigned short checksum(unsigned short *ptr, int length) {
int sum = 0;
u_short answer = 0;
......@@ -409,6 +414,79 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
}
}
static void SendNRFrame(guint8 radioType, guint8 direction, guint8 rntiType,
guint16 rnti, guint16 ueid, guint8 harqid, gboolean sfnSlotInfoPresent, guint16 sysframeNumber, guint16 slotNumber,
uint8_t *pdu_buffer, unsigned int pdu_buffer_size) {
unsigned char frameBuffer[9000];
unsigned int frameOffset;
ssize_t bytesSent;
frameOffset = 0;
uint16_t tmp16;
memcpy(frameBuffer+frameOffset, MAC_NR_START_STRING,
strlen(MAC_NR_START_STRING));
frameOffset += strlen(MAC_NR_START_STRING);
/******************************************************************************/
/* Now write out fixed fields (the mandatory elements of struct mac_nr_info) */
frameBuffer[frameOffset++] = radioType;
frameBuffer[frameOffset++] = direction;
frameBuffer[frameOffset++] = rntiType;
/*************************************/
/* Now optional fields */
/* RNTI */
frameBuffer[frameOffset++] = MAC_NR_RNTI_TAG;
tmp16 = htons(rnti);
memcpy(frameBuffer+frameOffset, &tmp16, 2);
frameOffset += 2;
/* UEId */
frameBuffer[frameOffset++] = MAC_NR_UEID_TAG;
tmp16 = htons(ueid);
memcpy(frameBuffer+frameOffset, &tmp16, 2);
frameOffset += 2;
/* HARQId */
frameBuffer[frameOffset++] = MAC_NR_HARQID;
frameBuffer[frameOffset++] = harqid;
if (sfnSlotInfoPresent)
{
frameBuffer[frameOffset++] = MAC_NR_FRAME_SLOT_TAG;
tmp16 = htons(sysframeNumber);
memcpy(frameBuffer+frameOffset, &tmp16, 2);
frameOffset += 2;
tmp16 = htons(slotNumber);
memcpy(frameBuffer+frameOffset, &tmp16, 2);
frameOffset += 2;
}
/***************************************/
/* Now write the MAC PDU */
frameBuffer[frameOffset++] = MAC_NR_PAYLOAD_TAG;
/* Append actual PDU */
//memcpy(frameBuffer+frameOffset, g_PDUBuffer, g_PDUOffset);
//frameOffset += g_PDUOffset;
if (pdu_buffer != NULL) {
memcpy(frameBuffer+frameOffset, (void *)pdu_buffer, pdu_buffer_size);
frameOffset += pdu_buffer_size;
}
if ( opt_type == OPT_WIRESHARK )
/* Send out the data over the UDP socket */
bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
(const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
else
bytesSent = MAC_LTE_PCAP_WritePDU(frameBuffer, frameOffset);
if (bytesSent != frameOffset) {
LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
frameOffset, bytesSent, errno);
//exit(1);
}
}
#include <common/ran_context.h>
extern RAN_CONTEXT_t RC;
#include <openair1/PHY/phy_extern_ue.h>
......@@ -456,6 +534,48 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p
pdu_buffer, pdu_buffer_size);
}
void trace_nr_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int ueid, int harqid, int rntiType, int rnti,
bool sfnSlotInfoPresent, uint16_t sysframeNumber, uint16_t slotNumber
) {
int radioType=FDD_RADIO;
LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/slot: %d.%d\n",
direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysframeNumber, slotNumber);
if (RC.gNB && RC.gNB[0] != NULL)
radioType=(RC.gNB[0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO);
else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL)
radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
else {
LOG_E(OPT,"not a gNB neither a UE!!! \n");
return;
}
switch (opt_type) {
case OPT_WIRESHARK :
if (g_socksd == -1)
return;
break;
case OPT_PCAP:
if (file_fd == NULL)
return;
break;
case OPT_TSHARK:
default:
return;
break;
}
SendNRFrame( radioType,
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
rntiType, rnti, ueid, harqid, sfnSlotInfoPresent, sysframeNumber, slotNumber,
pdu_buffer, pdu_buffer_size);
}
/*---------------------------------------------------*/
int init_opt(void) {
in_type=malloc(200);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment