Commit d5f28018 authored by Thomas Laurent's avatar Thomas Laurent

fix 344

parent 4bf6f26d
Pipeline #10340 failed with stage
in 0 seconds
......@@ -2617,7 +2617,7 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
dummy[0] = ue->pbch_vars[eNB_id]->decoded_output[2];
dummy[1] = ue->pbch_vars[eNB_id]->decoded_output[1];
dummy[2] = ue->pbch_vars[eNB_id]->decoded_output[0];
trace_pdu(1, dummy, 3, ue->Mod_id, 0, 0,
trace_pdu( DIRECTION_DOWNLINK, dummy, WS_C_RNTI, ue->Mod_id, 0, 0,
frame_rx, subframe_rx, 0, 0);
LOG_D(OPT,"[UE %d][PBCH] Frame %d trace pdu for PBCH\n",
ue->Mod_id, subframe_rx);
......
......@@ -988,9 +988,10 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
payload[0], ra->msg4_TBsize));
if (opt_enabled == 1) {
trace_pdu(1,
trace_pdu(DIRECTION_DOWNLINK,
(uint8_t *) mac->
UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3,
UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
rrc_sdu_length, UE_id, WS_C_RNTI,
UE_RNTI(module_idP, UE_id), mac->frame,
mac->subframe, 0, 0);
LOG_D(OPT,
......@@ -1193,9 +1194,10 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
payload[0], ra->msg4_TBsize));
if (opt_enabled == 1) {
trace_pdu(1,
trace_pdu(DIRECTION_DOWNLINK,
(uint8_t *) mac->
UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3,
UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
rrc_sdu_length, UE_id, WS_C_RNTI,
UE_RNTI(module_idP, UE_id), mac->frame,
mac->subframe, 0, 0);
LOG_D(OPT,
......
......@@ -281,10 +281,10 @@ schedule_SIB1_BR(module_id_t module_idP,
eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
if (opt_enabled == 1) {
trace_pdu(1,
trace_pdu(DIRECTION_DOWNLINK,
&cc->BCCH_BR_pdu[0].payload[0],
bcch_sdu_length,
0xffff, 4, 0xffff, eNB->frame, eNB->subframe, 0, 0);
0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0);
LOG_D(OPT,
"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
module_idP, frameP, CC_id, 0xffff, bcch_sdu_length);
......@@ -472,11 +472,11 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP,
eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
if (opt_enabled == 1) {
trace_pdu(1,
trace_pdu(DIRECTION_DOWNLINK,
&cc->BCCH_BR_pdu[i + 1].payload[0],
bcch_sdu_length,
0xffff,
4,
WS_SI_RNTI,
0xffff, eNB->frame, eNB->subframe, 0,
0);
LOG_D(OPT,
......@@ -759,11 +759,11 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
}
if (opt_enabled == 1) {
trace_pdu(1,
trace_pdu(DIRECTION_DOWNLINK,
&cc->BCCH_pdu.payload[0],
bcch_sdu_length,
0xffff,
4, 0xffff, eNB->frame, eNB->subframe, 0, 0);
WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0);
LOG_D(OPT,
"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
module_idP, frameP, CC_id, 0xffff,
......
......@@ -1359,9 +1359,9 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
}
if (opt_enabled == 1) {
trace_pdu(1, (uint8_t *)
UE_list->DLSCH_pdu[CC_id][0][UE_id].
payload[0], TBS, module_idP, 3,
trace_pdu(DIRECTION_DOWNLINK,
(uint8_t *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
TBS, module_idP, WS_C_RNTI,
UE_RNTI(module_idP, UE_id), eNB->frame,
eNB->subframe, 0, 0);
LOG_D(OPT,
......@@ -2085,7 +2085,7 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
}
if (opt_enabled == 1) {
trace_pdu(1,
trace_pdu(DIRECTION_DOWNLINK,
&eNB->common_channels[CC_id].PCCH_pdu.payload[0],
pcch_sdu_length,
0xffff,
......
......@@ -1655,8 +1655,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
}
if (opt_enabled == 1) {
trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
TBS, module_idP, 3, UE_RNTI(module_idP,UE_id),
trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP,UE_id),
eNB->frame, eNB->subframe,0,0);
LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n",
module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS);
......
......@@ -767,7 +767,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
/* Tracing of PDU is done on UE side */
if (opt_enabled == 1) {
trace_pdu(1, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, 6, 0xffff, // M_RNTI = 6 in wirehsark
trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xffff, // M_RNTI = 6 in wirehsark
RC.mac[module_idP]->frame,
RC.mac[module_idP]->subframe, 0, 0);
LOG_D(OPT,
......
......@@ -150,7 +150,7 @@ rx_sdu(const module_id_t enb_mod_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1);
if (opt_enabled == 1) {
trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP,
trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP,
0, 0);
LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n",
enb_mod_idP, frameP, current_rnti, sdu_lenP);
......
......@@ -248,7 +248,7 @@ Msg1_transmitted(module_id_t module_idP, uint8_t CC_id,
UE_mac_inst[module_idP].RA_attempt_number++;
if (opt_enabled) {
trace_pdu(0, NULL, 0, module_idP, 0,
trace_pdu(DIRECTION_UPLINK, NULL, 0, module_idP, WS_NO_RNTI,
UE_mac_inst[module_idP].RA_prach_resources.
ra_PreambleIndex, UE_mac_inst[module_idP].txFrame,
UE_mac_inst[module_idP].txSubframe, 0,
......@@ -277,8 +277,8 @@ Msg3_transmitted(module_id_t module_idP, uint8_t CC_id,
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1;
if (opt_enabled) { // msg3
trace_pdu(0, &UE_mac_inst[module_idP].CCCH_pdu.payload[0],
UE_mac_inst[module_idP].RA_Msg3_size, module_idP, 3,
trace_pdu(DIRECTION_UPLINK , &UE_mac_inst[module_idP].CCCH_pdu.payload[0],
UE_mac_inst[module_idP].RA_Msg3_size, module_idP, WS_C_RNTI,
UE_mac_inst[module_idP].crnti,
UE_mac_inst[module_idP].txFrame,
UE_mac_inst[module_idP].txSubframe, 0, 0);
......
......@@ -96,7 +96,7 @@ fill_rar(const module_id_t module_idP,
((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1);
if (opt_enabled) {
trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
trace_pdu(DIRECTION_DOWNLINK , dlsch_buffer, input_buffer_length, module_idP, WS_RA_RNTI , 1,
RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe,
0, 0);
LOG_D(OPT,
......@@ -181,7 +181,7 @@ fill_rar_br(eNB_MAC_INST * eNB,
ra->preamble_index, ra->timing_offset);
if (opt_enabled) {
trace_pdu(1, dlsch_buffer, input_buffer_length, eNB->Mod_id, 2, 1,
trace_pdu(DIRECTION_DOWNLINK , dlsch_buffer, input_buffer_length, eNB->Mod_id, WS_RA_RNTI , 1,
eNB->frame, eNB->subframe, 0, 0);
LOG_D(OPT,
"[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
......
......@@ -119,8 +119,8 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
LOG_D(OPT,
"[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n",
module_idP, CC_id, frameP, ra_rnti);
trace_pdu(1, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6,
module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame,
trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6,
module_idP, WS_RA_RNTI, ra_rnti, UE_mac_inst[module_idP].rxFrame,
UE_mac_inst[module_idP].rxSubframe, 0, 0);
}
......
......@@ -420,7 +420,7 @@ ue_send_sdu(module_id_t module_idP,
//LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]);
if (opt_enabled) {
trace_pdu(1, sdu, sdu_len, module_idP, 3,
trace_pdu(DIRECTION_DOWNLINK, sdu, sdu_len, module_idP, WS_C_RNTI,
UE_mac_inst[module_idP].crnti, frameP, subframeP, 0, 0);
LOG_D(OPT,
"[UE %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n",
......@@ -637,11 +637,11 @@ ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP,
stop_meas(&UE_mac_inst[module_idP].rx_si);
#endif
if (opt_enabled == 1) {
trace_pdu(0,
trace_pdu(DIRECTION_UPLINK,
(uint8_t *) pdu,
len,
module_idP,
4,
WS_SI_RNTI,
0xffff,
UE_mac_inst[module_idP].rxFrame,
UE_mac_inst[module_idP].rxSubframe, 0, 0);
......@@ -675,11 +675,11 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP,
stop_meas(&UE_mac_inst[module_idP].rx_p);
#endif
if (opt_enabled == 1) {
trace_pdu(0,
trace_pdu(DIRECTION_UPLINK ,
(uint8_t *) pdu,
len,
module_idP,
4,
WS_SI_RNTI,
P_RNTI,
UE_mac_inst[module_idP].rxFrame,
UE_mac_inst[module_idP].rxSubframe, 0, 0);
......@@ -2255,7 +2255,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
#endif
if (opt_enabled) {
trace_pdu(0, ulsch_buffer, buflen, module_idP, 3,
trace_pdu(DIRECTION_UPLINK, ulsch_buffer, buflen, module_idP, WS_C_RNTI,
UE_mac_inst[module_idP].crnti,
UE_mac_inst[module_idP].txFrame,
UE_mac_inst[module_idP].txSubframe, 0, 0);
......
2012 07 10 - Working version
How to configure wireshark for dissecting LTE protocols:
- start the wireshark as a sudoers
- goto analyze->enabled prototols
=> enable mac_lte_udp and rlc_lte_udp
- goto edit/preferences and expand Protocols
- select UDP and check "try heuristic sub-dissectors first"
- select MAC-LTE, and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info"
- select RLC-LTE, and check all the options except the "May see RLC headers only", and set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM.
How to use
- start eNB or UE with option -W (or -P if you want to make a pcap file)
- capture on local interface "lo"
- filter out the ICMP/DNS/TCP messages (e.g. "!icmp && !dns && !tcp")
......@@ -42,11 +42,4 @@ typedef struct MAC_Context_Info_t {
unsigned int subframesSinceCaptureStart;
} MAC_Context_Info_t;
pcap_hdr_t file_header = {
0xa1b2c3d4, /* magic number */
2, 4, /* version number is 2.4 */
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 */
};
......@@ -55,6 +55,16 @@ This header file must be included */
#include "PHY/impl_defs_lte.h"
#endif
#define PACKET_MAC_LTE_DEFAULT_UDP_PORT (9999)
typedef uint8_t guint8;
typedef uint16_t guint16;
typedef uint32_t guint32;
typedef guint8 gboolean;
#include "packet-mac-lte.h"
#include "mac_pcap.h"
#ifdef OCP_FRAMEWORK
#include <enums.h>
#else
......@@ -74,7 +84,7 @@ typedef enum radio_type_e {
extern trace_mode_t opt_type;
extern char in_ip[40];
extern char in_path[100];
extern char in_path[FILENAME_MAX];
/**
* function def
......@@ -84,7 +94,7 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
int oob_event, int oob_event_value);
int init_opt(char *path, char *ip, char *port, radio_type_t radio_type_p);
int init_opt(char *path, char *ip);
void terminate_opt(void);
......
This diff is collapsed.
......@@ -95,26 +95,22 @@ what about the implementation
int opt_enabled=0;
#define PACKET_MAC_LTE_DEFAULT_UDP_PORT (9999)
typedef uint8_t guint8;
typedef uint16_t guint16;
typedef uint32_t guint32;
typedef guint8 gboolean;
#include "packet-mac-lte.h"
#include "mac_pcap.h"
//static unsigned char g_PDUBuffer[1600];
//static unsigned int g_PDUOffset;
char in_ip[40];
char in_path[100];
char in_path[FILENAME_MAX];
FILE *file_fd = NULL;
pcap_hdr_t file_header = {
0xa1b2c3d4, /* magic number */
2, 4, /* version number is 2.4 */
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 */
};
trace_mode_t opt_type = OPT_NONE;
static radio_type_t radio_type;
static unsigned int subframesSinceCaptureStart;
static int g_socksd = -1;/* UDP socket used for sending frames */
......@@ -237,22 +233,13 @@ 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)
{
#ifdef JUMBO_FRAME
static unsigned char frameBuffer[9000];
#else
static unsigned char frameBuffer[1600];
#endif
static unsigned int frameOffset;
unsigned char frameBuffer[9000];
unsigned int frameOffset;
ssize_t bytesSent;
frameOffset = 0;
uint16_t tmp16;
/********************************************************************/
/* Fixed start to each frame (allowing heuristic dissector to work) */
/* Not NULL terminated */
memset(frameBuffer+frameOffset, 0, sizeof(mac_lte_info)+pdu_buffer_size + 8);
memcpy(frameBuffer+frameOffset, MAC_LTE_START_STRING,
strlen(MAC_LTE_START_STRING));
frameOffset += strlen(MAC_LTE_START_STRING);
......@@ -279,7 +266,7 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
frameOffset += 2;
/* Subframe number */
frameBuffer[frameOffset++] = MAC_LTE_SUBFRAME_TAG;
frameBuffer[frameOffset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
tmp16 = htons(sfnSf); // frame counter : this will give an expert info as wireshark expects SF and not F
memcpy(frameBuffer+frameOffset, &tmp16, 2);
frameOffset += 2;
......@@ -313,26 +300,29 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
if (pdu_buffer_size==0) {
switch (oob_event) {
case ltemac_send_preamble :
LOG_D(OPT,"oob ltemac_send_preamble event %02x."
LOG_D(OPT,"ltemac_send_preamble event %02x."
//"%02x."
"%02x.%02x\n",
MAC_LTE_OOB_EVENT_TAG,
MAC_LTE_SEND_PREAMBLE_TAG,
//ltemac_send_preamble,
rnti,
oob_event_value);
//frameBuffer[frameOffset++]=0;
//frameBuffer[frameOffset++]=0;
//frameBuffer[frameOffset++]=0;
frameBuffer[frameOffset++] = MAC_LTE_OOB_EVENT_TAG;
frameBuffer[frameOffset++] = MAC_LTE_SEND_PREAMBLE_TAG;
//frameBuffer[frameOffset++]=ltemac_send_preamble;
frameBuffer[frameOffset++]=rnti; // is the preamble
frameBuffer[frameOffset++]=oob_event_value;
break;
case ltemac_send_sr:
frameBuffer[frameOffset++]=ltemac_send_sr;
frameBuffer[frameOffset++]=MAC_LTE_SR_TAG ;
frameOffset+=2;
frameBuffer[frameOffset++]=rnti;
frameOffset++;
frameBuffer[frameOffset++]=oob_event_value;
frameOffset++;
break;
case ltemac_sr_failure:
......@@ -394,7 +384,7 @@ static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
offset += 2;
/* Subframe number */
context_header[offset++] = MAC_LTE_SUBFRAME_TAG;
context_header[offset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
tmp16 = htons(context->subFrameNumber);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
......@@ -423,21 +413,27 @@ static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
return 1;
}
#include <common/ran_context.h>
extern RAN_CONTEXT_t RC;
#include <openair1/PHY/phy_extern_ue.h>
/* Remote serveraddress (where Wireshark is running) */
void trace_pdu(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;
if (RC.eNB[0][0]!=NULL)
radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
if (PHY_vars_UE_g[0][0] != NULL)
radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
switch (opt_type) {
case OPT_WIRESHARK :
if (g_socksd == -1) {
return;
}
SendFrame(radio_type,
SendFrame( radioType,
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
......@@ -450,7 +446,7 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
return;
}
pdu_context.radioType = radio_type;
pdu_context.radioType = radioType;
pdu_context.direction = (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK
: DIRECTION_UPLINK;
pdu_context.rntiType = rntiType;
......@@ -470,7 +466,7 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
}
}
/*---------------------------------------------------*/
int init_opt(char *path, char *ip, char *port, radio_type_t radio_type_p)
int init_opt(char *path, char *ip)
{
uint16_t in_port;
subframesSinceCaptureStart = 0;
......@@ -489,13 +485,7 @@ int init_opt(char *path, char *ip, char *port, radio_type_t radio_type_p)
strcpy( in_ip, "127.0.0.1" );
}
if (port != NULL) {
in_port = atoi(port);
} else {
in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT;
}
radio_type = radio_type_p;
in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT;
// trace_mode
switch (opt_type) {
......
/* ws_compiler_tests.h
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __WS_COMPILER_TESTS_H__
#define __WS_COMPILER_TESTS_H__
/*
* This was introduced by Clang:
*
* http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
*
* in some version (which version?); it has been picked up by GCC 5.0.
*/
#ifndef __has_attribute
/*
* It's a macro, so you can check whether it's defined to check
* whether it's supported.
*
* If it's not, define it to always return 0, so that we move on to
* the fallback checks.
*/
#define __has_attribute(x) 0
#endif
/*
* Note that the C90 spec's "6.8.1 Conditional inclusion" and the
* C99 spec's and C11 spec's "6.10.1 Conditional inclusion" say:
*
* Prior to evaluation, macro invocations in the list of preprocessing
* tokens that will become the controlling constant expression are
* replaced (except for those macro names modified by the defined unary
* operator), just as in normal text. If the token "defined" is
* generated as a result of this replacement process or use of the
* "defined" unary operator does not match one of the two specified
* forms prior to macro replacement, the behavior is undefined.
*
* so you shouldn't use defined() in a #define that's used in #if or
* #elif. Some versions of Clang, for example, will warn about this.
*
* Instead, we check whether the pre-defined macros for particular
* compilers are defined and, if not, define the "is this version XXX
* or a later version of this compiler" macros as 0.
*/
/*
* Check whether this is GCC major.minor or a later release, or some
* compiler that claims to be "just like GCC" of that version or a
* later release.
*/
#if !defined(__GNUC__)
#define WS_IS_AT_LEAST_GNUC_VERSION(major, minor) 0
#else
#define WS_IS_AT_LEAST_GNUC_VERSION(major, minor) \
(__GNUC__ > (major) || \
(__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#endif
/*
* Check whether this is Clang major.minor or a later release.
*/
#if !defined(__clang__)
#define WS_IS_AT_LEAST_CLANG_VERSION(major, minor) 0
#else
#define WS_IS_AT_LEAST_CLANG_VERSION(major, minor) \
(__clang_major__ > (major) || \
(__clang_major__ == (major) && __clang_minor__ >= (minor)))
#endif
/*
* Check whether this is Sun C/SunPro C/Oracle Studio major.minor
* or a later release.
*
* The version number in __SUNPRO_C is encoded in hex BCD, with the
* uppermost hex digit being the major version number, the next
* one or two hex digits being the minor version number, and
* the last digit being the patch version.
*
* It represents the *compiler* version, not the product version;
* see
*
* https://sourceforge.net/p/predef/wiki/Compilers/
*
* for a partial mapping, which we assume continues for later
* 12.x product releases.
*/
#if !defined(__SUNPRO_C)
#define WS_IS_AT_LEAST_SUNC_VERSION(major, minor) 0
#else
#define WS_SUNPRO_VERSION_TO_BCD(major, minor) \
(((minor) >= 10) ? \
(((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \
(((major) << 8) | ((minor) << 4)))
#define WS_IS_AT_LEAST_SUNC_VERSION(major, minor) \
(__SUNPRO_C >= WS_SUNPRO_VERSION_TO_BCD((major), (minor)))
#endif
/*
* Check whether this is IBM XL C major.minor or a later release.
*
* The version number in __xlC__ has the major version in the
* upper 8 bits and the minor version in the lower 8 bits.
*/
#if !defined(__xlC__)
#define WS_IS_AT_LEAST_XL_C_VERSION(major, minor) 0
#else
#define WS_IS_AT_LEAST_XL_C_VERSION(major, minor) \
(__xlC__ >= (((major) << 8) | (minor)))
#endif
/*
* Check whether this is HP aC++/HP C major.minor or a later release.
*
* The version number in __HP_aCC is encoded in zero-padded decimal BCD,
* with the "A." stripped off, the uppermost two decimal digits being
* the major version number, the next two decimal digits being the minor
* version number, and the last two decimal digits being the patch version.
* (Strip off the A., remove the . between the major and minor version
* number, and add two digits of patch.)
*/
#if !defined(__HP_aCC)
#define WS_IS_AT_LEAST_HP_C_VERSION(major, minor) 0
#else
#define WS_IS_AT_LEAST_HP_C_VERSION(major, minor) \
(__HP_aCC >= ((major)*10000 + (minor)*100))
#endif
#endif /* __WS_COMPILER_TESTS_H__ */
/*
* Cross platform defines for exporting symbols from shared libraries
*
* Wireshark - Network traffic analyzer
* By Balint Reczey <balint@balintreczey.hu>
* Copyright 2013 Balint Reczey
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "ws_compiler_tests.h"
/** Reset symbol export behavior.
* If you {un}define WS_BUILD_DLL on the fly you'll have to define this
* as well.
*/
#ifdef RESET_SYMBOL_EXPORT
#ifdef SYMBOL_EXPORT_H
#undef SYMBOL_EXPORT_H
#endif
#ifdef WS_DLL_PUBLIC
#undef WS_DLL_PUBLIC
#endif
#ifdef WS_DLL_PUBLIC_DEF
#undef WS_DLL_PUBLIC_DEF
#endif
#ifdef WS_DLL_LOCAL
#undef WS_DLL_LOCAL
#endif
#endif /* RESET_SYMBOL_EXPORT */
#ifndef SYMBOL_EXPORT_H
#define SYMBOL_EXPORT_H
/*
* NOTE: G_HAVE_GNUC_VISIBILITY is defined only if all of
*
* __attribute__ ((visibility ("hidden")))
*
* __attribute__ ((visibility ("internal")))
*
* __attribute__ ((visibility ("protected")))
*
* __attribute__ ((visibility ("default")))
*
* are supported, and at least some versions of GCC from Apple support
* "default" and "hidden" but not "internal" or "protected", so it
* shouldn't be used to determine whether "hidden" or "default" is
* supported.
*
* This also means that we shouldn't use G_GNUC_INTERNAL instead of
* WS_DLL_LOCAL, as GLib uses G_HAVE_GNUC_VISIBILITY to determine
* whether to use __attribute__ ((visibility ("hidden"))) for
* G_GNUC_INTERNAL, and that will not use it even with compilers
* that support it.
*/
/* Originally copied from GCC Wiki at http://gcc.gnu.org/wiki/Visibility */
#if defined _WIN32 || defined __CYGWIN__
/* Compiling for Windows, so we use the Windows DLL declarations. */
#ifdef WS_BUILD_DLL
/*
* Building a DLL; for all definitions, we want dllexport, and
* (presumably so source from DLL and source from a program using the
* DLL can both include a header that declares APIs and exported data
* for the DLL), for declarations, either dllexport or dllimport will
* work (they mean the same thing for a declaration when building a DLL).
*/
#ifdef __GNUC__
/* GCC */
#define WS_DLL_PUBLIC_DEF __attribute__ ((dllexport))
#else /* ! __GNUC__ */
/*
* Presumably MSVC.
* Note: actually gcc seems to also support this syntax.
*/
#define WS_DLL_PUBLIC_DEF __declspec(dllexport)
#endif /* __GNUC__ */
#else /* WS_BUILD_DLL */
/*
* Building a program; we should only see declarations, not definitions,
* with WS_DLL_PUBLIC, and they all represent APIs or data imported
* from a DLL, so use dllimport.
*
* For functions, export shouldn't be necessary; for data, it might
* be necessary, e.g. if what's declared is an array whose size is
* not given in the declaration.
*/
#ifdef __GNUC__
/* GCC */
#define WS_DLL_PUBLIC_DEF __attribute__ ((dllimport))
#elif ! (defined ENABLE_STATIC) /* ! __GNUC__ */
/*
* Presumably MSVC, and we're not building all-static.
* Note: actually gcc seems to also support this syntax.
*/
#define WS_DLL_PUBLIC_DEF __declspec(dllimport)
#else /* ! __GNUC__ && ENABLE_STATIC */
/*
* Presumably MSVC, and we're building all-static, so we're
* not building any DLLs.
*/
#define WS_DLL_PUBLIC_DEF
#endif /* __GNUC__ */
#endif /* WS_BUILD_DLL */
/*
* Symbols in a DLL are *not* exported unless they're specifically
* flagged as exported, so, for a non-static but non-exported
* symbol, we don't have to do anything.
*/
#define WS_DLL_LOCAL
#else /* defined _WIN32 || defined __CYGWIN__ */