diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index cfd96f39c0..e68b3b0716 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -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 diff --git a/openair2/UTIL/OPT/mac_pcap.h b/openair2/UTIL/OPT/mac_pcap.h index 3141d17d59..c443ceb1fb 100644 --- a/openair2/UTIL/OPT/mac_pcap.h +++ b/openair2/UTIL/OPT/mac_pcap.h @@ -6,6 +6,7 @@ #include #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 diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h index 6861e09cb1..ab591d3a65 100644 --- a/openair2/UTIL/OPT/opt.h +++ b/openair2/UTIL/OPT/opt.h @@ -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}, \ } diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index 8c6a74e042..912782dd47 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -90,6 +90,7 @@ what about the implementation #include #include +#include #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 extern RAN_CONTEXT_t RC; #include @@ -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 diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h index a84d8db4f8..927b65c74c 100644 --- a/openair3/NAS/COMMON/NR_NAS_defs.h +++ b/openair3/NAS/COMMON/NR_NAS_defs.h @@ -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; diff --git a/openair3/NAS/gNB/network_process_nas.c b/openair3/NAS/gNB/network_process_nas.c index bdfa2183d6..a878d7c8a4 100644 --- a/openair3/NAS/gNB/network_process_nas.c +++ b/openair3/NAS/gNB/network_process_nas.c @@ -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; }