fix L2 tracing in wireshark, start security mode comman
This commit is contained in:
@@ -2640,7 +2640,7 @@ target_link_libraries (measurement_display minimal_lib)
|
||||
add_executable(test5Gnas
|
||||
${OPENAIR_DIR}/openair3/TEST/test5Gnas.c
|
||||
)
|
||||
target_link_libraries (test5Gnas LIB_5GNAS_GNB CONFIG_LIB minimal_lib ${NETTLE_LIBRARIES})
|
||||
target_link_libraries (test5Gnas ${NETTLE_LIBRARIES} LIB_5GNAS_GNB CONFIG_LIB minimal_lib )
|
||||
|
||||
|
||||
# lte-softmodem is both eNB and UE implementation
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define MAC_LTE_DLT 147
|
||||
#define DLT_IPV4 228
|
||||
/********************************************************/
|
||||
/* Definitions and descriptions come from:
|
||||
http://wiki.wireshark.org/Development/LibpcapFileFormat */
|
||||
@@ -29,20 +30,4 @@ typedef struct pcaprec_hdr_s {
|
||||
unsigned int orig_len; /* actual length of packet */
|
||||
} pcaprec_hdr_t;
|
||||
|
||||
/* Context information for every MAC PDU that will be logged */
|
||||
typedef struct MAC_Context_Info_t {
|
||||
unsigned short radioType;
|
||||
unsigned char direction;
|
||||
unsigned char rntiType;
|
||||
unsigned short rnti;
|
||||
unsigned short ueid;
|
||||
unsigned char isRetx;
|
||||
unsigned char crcStatusOK;
|
||||
|
||||
unsigned short sysFrameNumber;
|
||||
unsigned short subFrameNumber;
|
||||
|
||||
unsigned int subframesSinceCaptureStart;
|
||||
} MAC_Context_Info_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -73,7 +73,7 @@ typedef guint8 gboolean;
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define OPT_PARAMS_DESC { \
|
||||
{"type" , CONFIG_HLP_TYPEMON, 0, strptr:&in_type, defstrval:"none", TYPE_STRING, 0}, \
|
||||
{"type" , CONFIG_HLP_TYPEMON, 0, strptr:(char**)&in_type, defstrval:"none", TYPE_STRING, 0}, \
|
||||
{"ip" , CONFIG_HLP_L2MONIP, 0, strptr:(char**)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, 0}, \
|
||||
{"path" , CONFIG_HLP_L2MONPATH, 0, strptr:(char**)&in_path,defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, 0}, \
|
||||
}
|
||||
|
||||
+105
-93
@@ -90,6 +90,7 @@ what about the implementation
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "opt.h"
|
||||
#include "common/utils/system.h"
|
||||
@@ -99,8 +100,6 @@ int opt_enabled=0;
|
||||
//static unsigned char g_PDUBuffer[1600];
|
||||
//static unsigned int g_PDUOffset;
|
||||
|
||||
static char in_ip[128]={0};
|
||||
static char in_path[128]={0};
|
||||
FILE *file_fd = NULL;
|
||||
pcap_hdr_t file_header = {
|
||||
0xa1b2c3d4, /* magic number */
|
||||
@@ -108,10 +107,14 @@ pcap_hdr_t file_header = {
|
||||
0, /* timezone */
|
||||
0, /* sigfigs - apparently all tools do this */
|
||||
65535, /* snaplen - this should be long enough */
|
||||
MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */
|
||||
DLT_IPV4
|
||||
//MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */
|
||||
};
|
||||
|
||||
trace_mode_t opt_type = OPT_NONE;
|
||||
static char *in_type=NULL;
|
||||
static char *in_path=NULL;
|
||||
static char *in_ip=NULL;
|
||||
static unsigned int subframesSinceCaptureStart;
|
||||
|
||||
static int g_socksd = -1;/* UDP socket used for sending frames */
|
||||
@@ -131,8 +134,80 @@ 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 int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
|
||||
const unsigned char *PDU, unsigned int length);
|
||||
unsigned short checksum(unsigned short *ptr, int length) {
|
||||
int sum = 0;
|
||||
u_short answer = 0;
|
||||
unsigned short *w = ptr;
|
||||
int nleft = length;
|
||||
|
||||
while(nleft > 1) {
|
||||
sum += *w++;
|
||||
nleft -= 2;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xFFFF);
|
||||
sum += (sum >> 16);
|
||||
answer = ~sum;
|
||||
return(answer);
|
||||
}
|
||||
|
||||
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
|
||||
static int MAC_LTE_PCAP_WritePDU(const uint8_t *PDU,
|
||||
unsigned int length) {
|
||||
pcaprec_hdr_t packet_header;
|
||||
// IPv4 header
|
||||
typedef struct ip_hdr {
|
||||
unsigned char ip_verlen; // 4-bit IPv4 version 4-bit header length (in 32-bit words)
|
||||
unsigned char ip_tos; // IP type of service
|
||||
unsigned short ip_totallength; // Total length
|
||||
unsigned short ip_id; // Unique identifier
|
||||
unsigned short ip_offset; // Fragment offset field
|
||||
unsigned char ip_ttl; // Time to live
|
||||
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
|
||||
unsigned short ip_checksum; // IP checksum
|
||||
unsigned int ip_srcaddr; // Source address
|
||||
unsigned int ip_destaddr; // Source address
|
||||
} IPV4_HDR;
|
||||
// Define the UDP header
|
||||
typedef struct udp_hdr {
|
||||
unsigned short src_portno; // Source port no.
|
||||
unsigned short dst_portno; // Dest. port no.
|
||||
unsigned short udp_length; // Udp packet length
|
||||
unsigned short udp_checksum; // Udp checksum (optional)
|
||||
} UDP_HDR;
|
||||
IPV4_HDR IPheader= {0};
|
||||
IPheader.ip_verlen = (4 << 4) | (sizeof(IPV4_HDR) / sizeof(uint32_t));
|
||||
IPheader.ip_totallength = htons(sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length);
|
||||
IPheader.ip_ttl = 8; // Time-to-live is eight
|
||||
IPheader.ip_protocol = IPPROTO_UDP;
|
||||
IPheader.ip_srcaddr = inet_addr(in_ip);
|
||||
IPheader.ip_destaddr = inet_addr(in_ip);
|
||||
IPheader.ip_checksum = checksum((unsigned short *)&IPheader, sizeof(IPV4_HDR));
|
||||
// Initialize the UDP header
|
||||
UDP_HDR UDPheader;
|
||||
UDPheader.src_portno = htons( PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
UDPheader.dst_portno = htons( PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
UDPheader.udp_length = htons(sizeof(UDP_HDR) + length);
|
||||
UDPheader.udp_checksum = 0;
|
||||
/****************************************************************/
|
||||
/* PCAP Header */
|
||||
/* TODO: Timestamp might want to be relative to a more sensible
|
||||
base time... */
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
packet_header.ts_sec = tv.tv_sec;
|
||||
packet_header.ts_usec = tv.tv_usec;
|
||||
packet_header.incl_len =sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length;
|
||||
packet_header.orig_len =sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length;
|
||||
/***************************************************************/
|
||||
/* Now write everything to the file */
|
||||
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd);
|
||||
fwrite(&IPheader, sizeof(IPV4_HDR), 1, file_fd);
|
||||
fwrite(&UDPheader, sizeof(UDP_HDR), 1, file_fd);
|
||||
fwrite(PDU, 1, length, file_fd);
|
||||
fflush(file_fd);
|
||||
return length;
|
||||
}
|
||||
|
||||
static void *opt_listener_thread(void *arg) {
|
||||
ssize_t ret;
|
||||
@@ -198,7 +273,6 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) {
|
||||
}
|
||||
|
||||
threadCreate(&opt_listener.thread, opt_listener_thread, NULL, "flexran", -1, OAI_PRIORITY_RT_LOW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -321,67 +395,20 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
frameOffset += pdu_buffer_size;
|
||||
}
|
||||
|
||||
/* 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));
|
||||
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, "sendto() failed (not a thread-safe func)- expected %d bytes, got %ld (errno=%d)\n",
|
||||
LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
|
||||
frameOffset, bytesSent, errno);
|
||||
//exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
|
||||
static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
|
||||
const uint8_t *PDU,
|
||||
unsigned int length)
|
||||
{
|
||||
pcaprec_hdr_t packet_header;
|
||||
uint8_t context_header[256];
|
||||
int offset = 0;
|
||||
unsigned short tmp16;
|
||||
/*****************************************************************/
|
||||
/* Context information (same as written by UDP heuristic clients */
|
||||
context_header[offset++] = context->radioType;
|
||||
context_header[offset++] = context->direction;
|
||||
context_header[offset++] = context->rntiType;
|
||||
/* RNTI */
|
||||
context_header[offset++] = MAC_LTE_RNTI_TAG;
|
||||
tmp16 = htons(context->rnti);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
/* UEId */
|
||||
context_header[offset++] = MAC_LTE_UEID_TAG;
|
||||
tmp16 = htons(context->ueid);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
/* Subframe number */
|
||||
context_header[offset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
|
||||
tmp16 = htons(context->subFrameNumber);
|
||||
memcpy(context_header+offset, &tmp16, 2);
|
||||
offset += 2;
|
||||
/* CRC Status */
|
||||
context_header[offset++] = MAC_LTE_CRC_STATUS_TAG;
|
||||
context_header[offset++] = context->crcStatusOK;
|
||||
/* Data tag immediately preceding PDU */
|
||||
context_header[offset++] = MAC_LTE_PAYLOAD_TAG;
|
||||
/****************************************************************/
|
||||
/* PCAP Header */
|
||||
/* TODO: Timestamp might want to be relative to a more sensible
|
||||
base time... */
|
||||
packet_header.ts_sec = context->subframesSinceCaptureStart / 1000;
|
||||
packet_header.ts_usec = (context->subframesSinceCaptureStart % 1000) * 1000;
|
||||
packet_header.incl_len = offset + length;
|
||||
packet_header.orig_len = offset + length;
|
||||
/***************************************************************/
|
||||
/* Now write everything to the file */
|
||||
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd);
|
||||
fwrite(context_header, 1, offset, file_fd);
|
||||
fwrite(PDU, 1, length, file_fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include <common/ran_context.h>
|
||||
extern RAN_CONTEXT_t RC;
|
||||
#include <openair1/PHY/phy_extern_ue.h>
|
||||
@@ -389,7 +416,6 @@ extern RAN_CONTEXT_t RC;
|
||||
void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
|
||||
int oob_event_value) {
|
||||
MAC_Context_Info_t pdu_context;
|
||||
int radioType=FDD_RADIO;
|
||||
LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n",
|
||||
direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber);
|
||||
@@ -405,53 +431,41 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p
|
||||
|
||||
switch (opt_type) {
|
||||
case OPT_WIRESHARK :
|
||||
if (g_socksd == -1) {
|
||||
if (g_socksd == -1)
|
||||
return;
|
||||
}
|
||||
|
||||
SendFrame( radioType,
|
||||
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
|
||||
rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
|
||||
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
|
||||
oob_event,oob_event_value,
|
||||
pdu_buffer, pdu_buffer_size);
|
||||
break;
|
||||
|
||||
case OPT_PCAP:
|
||||
if (file_fd == NULL) {
|
||||
if (file_fd == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
pdu_context.radioType = radioType;
|
||||
pdu_context.direction = (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK
|
||||
: DIRECTION_UPLINK;
|
||||
pdu_context.rntiType = rntiType;
|
||||
pdu_context.rnti = rnti;
|
||||
pdu_context.ueid = ueid;
|
||||
pdu_context.isRetx = 0;
|
||||
pdu_context.crcStatusOK =1;
|
||||
pdu_context.sysFrameNumber = sysFrameNumber;
|
||||
pdu_context.subFrameNumber = subFrameNumber;
|
||||
pdu_context.subframesSinceCaptureStart = subframesSinceCaptureStart++;
|
||||
MAC_LTE_PCAP_WritePDU( &pdu_context, pdu_buffer, pdu_buffer_size);
|
||||
break;
|
||||
|
||||
case OPT_TSHARK:
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
SendFrame( radioType,
|
||||
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
|
||||
rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
|
||||
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
|
||||
oob_event,oob_event_value,
|
||||
pdu_buffer, pdu_buffer_size);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int init_opt(void)
|
||||
{
|
||||
char *in_type=NULL;
|
||||
int init_opt(void) {
|
||||
in_type=malloc(200);
|
||||
in_ip=malloc(200);
|
||||
in_path=malloc(200);
|
||||
paramdef_t opt_params[] = OPT_PARAMS_DESC ;
|
||||
checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC;
|
||||
uint16_t in_port=0;
|
||||
config_set_checkfunctions(opt_params, opt_checkParams,
|
||||
sizeof(opt_params)/sizeof(paramdef_t));
|
||||
config_get( opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
|
||||
|
||||
subframesSinceCaptureStart = 0;
|
||||
int tmptype = config_get_processedint( &(opt_params[OPTTYPE_IDX]));
|
||||
|
||||
@@ -472,15 +486,13 @@ int init_opt(void)
|
||||
config_printhelp(opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
|
||||
}
|
||||
|
||||
in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT;
|
||||
|
||||
// trace_mode
|
||||
switch (opt_type) {
|
||||
case OPT_WIRESHARK:
|
||||
|
||||
/* Create local server socket only if using localhost address */
|
||||
if (strcmp(in_ip, "127.0.0.1") == 0) {
|
||||
opt_create_listener_socket(in_ip, in_port);
|
||||
opt_create_listener_socket(in_ip, PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
}
|
||||
|
||||
g_socksd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
@@ -493,7 +505,7 @@ int init_opt(void)
|
||||
|
||||
/* Get remote IP address from the function argument */
|
||||
g_serv_addr.sin_family = AF_INET;
|
||||
g_serv_addr.sin_port = htons(in_port);
|
||||
g_serv_addr.sin_port = htons(PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
g_serv_addr.sin_addr.s_addr = inet_addr(in_ip);
|
||||
break;
|
||||
|
||||
@@ -521,7 +533,7 @@ int init_opt(void)
|
||||
}
|
||||
|
||||
if ( opt_type == OPT_WIRESHARK )
|
||||
LOG_E(OPT,"mode Wireshark: ip %s port %d\n", in_ip, in_port);
|
||||
LOG_E(OPT,"mode Wireshark: ip %s port %d\n", in_ip, PACKET_MAC_LTE_DEFAULT_UDP_PORT);
|
||||
else if (opt_type == OPT_PCAP)
|
||||
LOG_E(OPT,"mode PCAB : path is %s \n",in_path);
|
||||
else
|
||||
|
||||
@@ -310,7 +310,7 @@ typedef struct __attribute__((packed)) {
|
||||
}
|
||||
authenticationrequestHeader_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct __attribute__((packed){
|
||||
Extendedprotocoldiscriminator_t epd:8;
|
||||
Security_header_t sh:8;
|
||||
SGSmobilitymanagementmessages_t mt:8;
|
||||
@@ -321,6 +321,26 @@ typedef struct {
|
||||
|
||||
//AUTHENTICATION RESULT
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
Extendedprotocoldiscriminator_t epd:8;
|
||||
Security_header_t sh:8;
|
||||
SGSmobilitymanagementmessages_t mt:8;
|
||||
|
||||
unsigned int selectedNASsecurityalgorithms;
|
||||
unsigned int ngKSI:4; //ngKSI NAS key set identifier 9.11.3.32
|
||||
unsigned int spare:4;
|
||||
// LV 3-9 bytes Replayed UE security capabilities UE security capability 9.11.3.54
|
||||
|
||||
/* optional
|
||||
TV (E-, 1 byte) Oprional IMEISV request IMEISV request 9.11.3.28
|
||||
TV (57, 2 bytes ) Selected EPS NAS security algorithms EPS NAS security algorithms 9.11.3.25
|
||||
TLV (36, 3 bytes) Additional 5G security information Additional 5G security information 9.11.3.12
|
||||
TLV-E (78,, 7-1503 bytes) EAP message EAP message 9.11.2.2
|
||||
TLV (38, 4-n)ABBA ABBA 9.11.3.10
|
||||
TLV (19, 4-7) Replayed S1 UE security capabilities S1 UE security capability 9.11.3.48A
|
||||
*/
|
||||
|
||||
} securityModeCommand_t;
|
||||
|
||||
typedef struct {
|
||||
uicc_t *uicc;
|
||||
|
||||
@@ -59,6 +59,7 @@ void SGSauthenticationResp(void *msg, NRUEcontext_t *UE) {
|
||||
}
|
||||
|
||||
void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE) {
|
||||
|
||||
}
|
||||
|
||||
void SGSregistrationComplete(void *msg, NRUEcontext_t *UE) {
|
||||
@@ -171,5 +172,20 @@ int authenticationRequest(void **msg, NRUEcontext_t *UE) {
|
||||
|
||||
int securityModeCommand(void **msg, NRUEcontext_t *UE) {
|
||||
*msg=NULL;
|
||||
myCalloc(req, securityModeCommand_t);
|
||||
req->epd=SGSmobilitymanagementmessages;
|
||||
req->sh=0;
|
||||
req->mt=Securitymodecommand;
|
||||
|
||||
// integrity algo from 5G-IA0 (null algo) to 5G-IA7 in first 4 bits
|
||||
unsigned int ia=0;
|
||||
// cyphering algo from 5G-EA0 (null algo) to 5G-IA7 in MSB 4 bits
|
||||
unsigned int ea=0;
|
||||
// trace from commercial: 5G-IA0 (0) 128-5G-IA2 (2)
|
||||
req->selectedNASsecurityalgorithms= ea<<4 | ia;
|
||||
|
||||
// KSI: N-NAS-int-alg 0x02
|
||||
req->ngKSI=2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user