Commit ffd4c20e authored by laurent's avatar laurent

fix L2 tracing in wireshark, start security mode comman

parent 3024f578
...@@ -2640,7 +2640,7 @@ target_link_libraries (measurement_display minimal_lib) ...@@ -2640,7 +2640,7 @@ target_link_libraries (measurement_display minimal_lib)
add_executable(test5Gnas add_executable(test5Gnas
${OPENAIR_DIR}/openair3/TEST/test5Gnas.c ${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 # lte-softmodem is both eNB and UE implementation
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#define MAC_LTE_DLT 147 #define MAC_LTE_DLT 147
#define DLT_IPV4 228
/********************************************************/ /********************************************************/
/* Definitions and descriptions come from: /* Definitions and descriptions come from:
http://wiki.wireshark.org/Development/LibpcapFileFormat */ http://wiki.wireshark.org/Development/LibpcapFileFormat */
...@@ -29,20 +30,4 @@ typedef struct pcaprec_hdr_s { ...@@ -29,20 +30,4 @@ typedef struct pcaprec_hdr_s {
unsigned int orig_len; /* actual length of packet */ unsigned int orig_len; /* actual length of packet */
} pcaprec_hdr_t; } 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 #endif
...@@ -73,7 +73,7 @@ typedef guint8 gboolean; ...@@ -73,7 +73,7 @@ typedef guint8 gboolean;
/* optname helpstr paramflags XXXptr defXXXval type numelt */ /* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------------------------------------*/
#define OPT_PARAMS_DESC { \ #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}, \ {"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}, \ {"path" , CONFIG_HLP_L2MONPATH, 0, strptr:(char**)&in_path,defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, 0}, \
} }
......
...@@ -90,6 +90,7 @@ what about the implementation ...@@ -90,6 +90,7 @@ what about the implementation
#include <pthread.h> #include <pthread.h>
#include <stdint.h> #include <stdint.h>
#include <sys/time.h>
#include "common/config/config_userapi.h" #include "common/config/config_userapi.h"
#include "opt.h" #include "opt.h"
#include "common/utils/system.h" #include "common/utils/system.h"
...@@ -99,8 +100,6 @@ int opt_enabled=0; ...@@ -99,8 +100,6 @@ int opt_enabled=0;
//static unsigned char g_PDUBuffer[1600]; //static unsigned char g_PDUBuffer[1600];
//static unsigned int g_PDUOffset; //static unsigned int g_PDUOffset;
static char in_ip[128]={0};
static char in_path[128]={0};
FILE *file_fd = NULL; FILE *file_fd = NULL;
pcap_hdr_t file_header = { pcap_hdr_t file_header = {
0xa1b2c3d4, /* magic number */ 0xa1b2c3d4, /* magic number */
...@@ -108,10 +107,14 @@ pcap_hdr_t file_header = { ...@@ -108,10 +107,14 @@ pcap_hdr_t file_header = {
0, /* timezone */ 0, /* timezone */
0, /* sigfigs - apparently all tools do this */ 0, /* sigfigs - apparently all tools do this */
65535, /* snaplen - this should be long enough */ 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; 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 unsigned int subframesSinceCaptureStart;
static int g_socksd = -1;/* UDP socket used for sending frames */ static int g_socksd = -1;/* UDP socket used for sending frames */
...@@ -131,8 +134,80 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, ...@@ -131,8 +134,80 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
guint8 oob_event, guint8 oob_event_value, guint8 oob_event, guint8 oob_event_value,
uint8_t *pdu_buffer, unsigned int pdu_buffer_size); uint8_t *pdu_buffer, unsigned int pdu_buffer_size);
static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, unsigned short checksum(unsigned short *ptr, int length) {
const unsigned char *PDU, unsigned 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) { static void *opt_listener_thread(void *arg) {
ssize_t ret; ssize_t ret;
...@@ -198,7 +273,6 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) { ...@@ -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); threadCreate(&opt_listener.thread, opt_listener_thread, NULL, "flexran", -1, OAI_PRIORITY_RT_LOW);
return 0; return 0;
} }
...@@ -321,67 +395,20 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, ...@@ -321,67 +395,20 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
frameOffset += pdu_buffer_size; frameOffset += pdu_buffer_size;
} }
/* Send out the data over the UDP socket */ if ( opt_type == OPT_WIRESHARK )
bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0, /* Send out the data over the UDP socket */
(const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr)); 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) { 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); frameOffset, bytesSent, errno);
//exit(1); //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> #include <common/ran_context.h>
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
#include <openair1/PHY/phy_extern_ue.h> #include <openair1/PHY/phy_extern_ue.h>
...@@ -389,7 +416,6 @@ extern RAN_CONTEXT_t RC; ...@@ -389,7 +416,6 @@ extern RAN_CONTEXT_t RC;
void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, 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 ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
int oob_event_value) { int oob_event_value) {
MAC_Context_Info_t pdu_context;
int radioType=FDD_RADIO; int radioType=FDD_RADIO;
LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n", 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); 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 ...@@ -405,53 +431,41 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p
switch (opt_type) { switch (opt_type) {
case OPT_WIRESHARK : case OPT_WIRESHARK :
if (g_socksd == -1) { if (g_socksd == -1)
return; 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; break;
case OPT_PCAP: case OPT_PCAP:
if (file_fd == NULL) { if (file_fd == NULL)
return; 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; break;
case OPT_TSHARK: case OPT_TSHARK:
default: default:
return;
break; 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) int init_opt(void) {
{ in_type=malloc(200);
char *in_type=NULL; in_ip=malloc(200);
in_path=malloc(200);
paramdef_t opt_params[] = OPT_PARAMS_DESC ; paramdef_t opt_params[] = OPT_PARAMS_DESC ;
checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC; checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC;
uint16_t in_port=0;
config_set_checkfunctions(opt_params, opt_checkParams, config_set_checkfunctions(opt_params, opt_checkParams,
sizeof(opt_params)/sizeof(paramdef_t)); sizeof(opt_params)/sizeof(paramdef_t));
config_get( opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX); config_get( opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
subframesSinceCaptureStart = 0; subframesSinceCaptureStart = 0;
int tmptype = config_get_processedint( &(opt_params[OPTTYPE_IDX])); int tmptype = config_get_processedint( &(opt_params[OPTTYPE_IDX]));
...@@ -472,15 +486,13 @@ int init_opt(void) ...@@ -472,15 +486,13 @@ int init_opt(void)
config_printhelp(opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX); config_printhelp(opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
} }
in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT;
// trace_mode // trace_mode
switch (opt_type) { switch (opt_type) {
case OPT_WIRESHARK: case OPT_WIRESHARK:
/* Create local server socket only if using localhost address */ /* Create local server socket only if using localhost address */
if (strcmp(in_ip, "127.0.0.1") == 0) { 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); g_socksd = socket(AF_INET, SOCK_DGRAM, 0);
...@@ -493,7 +505,7 @@ int init_opt(void) ...@@ -493,7 +505,7 @@ int init_opt(void)
/* Get remote IP address from the function argument */ /* Get remote IP address from the function argument */
g_serv_addr.sin_family = AF_INET; 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); g_serv_addr.sin_addr.s_addr = inet_addr(in_ip);
break; break;
...@@ -521,7 +533,7 @@ int init_opt(void) ...@@ -521,7 +533,7 @@ int init_opt(void)
} }
if ( opt_type == OPT_WIRESHARK ) 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) else if (opt_type == OPT_PCAP)
LOG_E(OPT,"mode PCAB : path is %s \n",in_path); LOG_E(OPT,"mode PCAB : path is %s \n",in_path);
else else
......
...@@ -310,7 +310,7 @@ typedef struct __attribute__((packed)) { ...@@ -310,7 +310,7 @@ typedef struct __attribute__((packed)) {
} }
authenticationrequestHeader_t; authenticationrequestHeader_t;
typedef struct { typedef struct __attribute__((packed){
Extendedprotocoldiscriminator_t epd:8; Extendedprotocoldiscriminator_t epd:8;
Security_header_t sh:8; Security_header_t sh:8;
SGSmobilitymanagementmessages_t mt:8; SGSmobilitymanagementmessages_t mt:8;
...@@ -321,6 +321,26 @@ typedef struct { ...@@ -321,6 +321,26 @@ typedef struct {
//AUTHENTICATION RESULT //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 { typedef struct {
uicc_t *uicc; uicc_t *uicc;
......
...@@ -59,6 +59,7 @@ void SGSauthenticationResp(void *msg, NRUEcontext_t *UE) { ...@@ -59,6 +59,7 @@ void SGSauthenticationResp(void *msg, NRUEcontext_t *UE) {
} }
void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE) { void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE) {
} }
void SGSregistrationComplete(void *msg, NRUEcontext_t *UE) { void SGSregistrationComplete(void *msg, NRUEcontext_t *UE) {
...@@ -171,5 +172,20 @@ int authenticationRequest(void **msg, NRUEcontext_t *UE) { ...@@ -171,5 +172,20 @@ int authenticationRequest(void **msg, NRUEcontext_t *UE) {
int securityModeCommand(void **msg, NRUEcontext_t *UE) { int securityModeCommand(void **msg, NRUEcontext_t *UE) {
*msg=NULL; *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; return 0;
} }
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