diff options
-rw-r--r-- | conditions.c | 2 | ||||
-rw-r--r-- | dumpcap.c | 18 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-lte.c | 27 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-lte.h | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-rlc-lte.c | 290 | ||||
-rw-r--r-- | epan/filesystem.c | 46 | ||||
-rw-r--r-- | epan/filesystem.h | 2 | ||||
-rw-r--r-- | gtk/file_dlg.c | 2 | ||||
-rw-r--r-- | gtk/file_dlg.h | 2 | ||||
-rw-r--r-- | gtk/rlc_lte_stat_dlg.c | 5 | ||||
-rw-r--r-- | tap-megaco-common.c | 2 | ||||
-rwxr-xr-x | test/test.sh | 2 |
12 files changed, 235 insertions, 165 deletions
diff --git a/conditions.c b/conditions.c index 7a1e9ee63a..67c408b423 100644 --- a/conditions.c +++ b/conditions.c @@ -206,7 +206,7 @@ void _cnd_find_hash_key_for_class_id(gpointer key, gpointer user_data){ char* class_id = (char*)user_data; char* key_value = (char*)key; - if(strcmp(class_id, key_value) == 0) pkey = key; + if(strcmp(class_id, key_value) == 0) pkey = key_value; } /* END _cnd_find_hash_key_for_class_id() */ /* @@ -273,7 +273,7 @@ static int need_timeout_workaround; */ #define THREAD_READ_TIMEOUT 100 #define THREAD_OPEN_TIMEOUT (5 * 1000000) -static char *cap_pipe_err_str; +static const char *cap_pipe_err_str; static void console_log_handler(const char *log_domain, GLogLevelFlags log_level, @@ -457,7 +457,7 @@ print_statistics_loop(gboolean machine_readable) } for (if_entry = g_list_first(if_list); if_entry != NULL; if_entry = g_list_next(if_entry)) { - if_info = if_entry->data; + if_info = (if_info_t *)if_entry->data; #ifdef HAVE_PCAP_OPEN pch = pcap_open(if_info->name, MIN_PACKET_SIZE, 0, 0, NULL, errbuf); #else @@ -465,7 +465,7 @@ print_statistics_loop(gboolean machine_readable) #endif if (pch) { - if_stat = g_malloc(sizeof(if_stat_t)); + if_stat = (if_stat_t *)g_malloc(sizeof(if_stat_t)); if_stat->name = g_strdup(if_info->name); if_stat->pch = pch; stat_list = g_list_append(stat_list, if_stat); @@ -485,7 +485,7 @@ print_statistics_loop(gboolean machine_readable) global_ld.go = TRUE; while (global_ld.go) { for (stat_entry = g_list_first(stat_list); stat_entry != NULL; stat_entry = g_list_next(stat_entry)) { - if_stat = stat_entry->data; + if_stat = (if_stat_t *)stat_entry->data; pcap_stats(if_stat->pch, &ps); if (!machine_readable) { @@ -507,7 +507,7 @@ print_statistics_loop(gboolean machine_readable) /* XXX - Not reached. Should we look for 'q' in stdin? */ for (stat_entry = g_list_first(stat_list); stat_entry != NULL; stat_entry = g_list_next(stat_entry)) { - if_stat = stat_entry->data; + if_stat = (if_stat_t *)stat_entry->data; pcap_close(if_stat->pch); g_free(if_stat->name); g_free(if_stat); @@ -598,14 +598,14 @@ static void /* '=' means 'all= ' ie: no capabilities */ /* '=ip' means 'all=ip' ie: all capabilities are permissible and inheritable */ /* .... */ -print_caps(char *pfx) { +print_caps(const char *pfx) { cap_t caps = cap_get_proc(); g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "%s: EUID: %d Capabilities: %s", pfx, geteuid(), cap_to_text(caps, NULL)); cap_free(caps); #else -print_caps(char *pfx _U_) { +print_caps(const char *pfx _U_) { #endif } @@ -656,7 +656,7 @@ relinquish_privs_except_capture(void) static void -relinquish_all_capabilities() +relinquish_all_capabilities(void) { /* Drop any and all capabilities this process may have. */ /* Allowed whether or not process has any privileges. */ @@ -2559,7 +2559,7 @@ static void capture_loop_packet_cb(u_char *user, const struct pcap_pkthdr *phdr, const u_char *pd) { - loop_data *ld = (void *) user; + loop_data *ld = (loop_data *) (void *) user; int err; /* We may be called multiple times from pcap_dispatch(); if we've set diff --git a/epan/dissectors/packet-mac-lte.c b/epan/dissectors/packet-mac-lte.c index 6dec643e9e..8d973680b7 100644 --- a/epan/dissectors/packet-mac-lte.c +++ b/epan/dissectors/packet-mac-lte.c @@ -1304,6 +1304,11 @@ static int DetectIfDLHARQResend(packet_info *pinfo, tvbuff_t *tvb, volatile int DLHARQResult *result = NULL; proto_item *result_ti; + /* FDD only for now! */ + if (p_mac_lte_info->radioType != FDD_RADIO) { + return FALSE; + } + if (!pinfo->fd->flags.visited) { /* First time, so set result and update DL harq table */ LastFrameData *lastData = NULL; @@ -1328,6 +1333,7 @@ static int DetectIfDLHARQResend(packet_info *pinfo, tvbuff_t *tvb, volatile int gint nseconds_between_packets = pinfo->fd->abs_ts.nsecs - lastData->received_time.nsecs; + /* TODO: want to round to nearest millisecond */ gint total_gap = (seconds_between_packets*1000) + (nseconds_between_packets / 1000000); @@ -1382,6 +1388,22 @@ static int DetectIfDLHARQResend(packet_info *pinfo, tvbuff_t *tvb, volatile int return (result != NULL); } + +/* Return TRUE if the given packet is thought to be a retx */ +int is_mac_lte_frame_retx(packet_info *pinfo, guint8 direction) +{ + if (direction == DIRECTION_UPLINK) { + /* For UL, retx count is stored in per-packet struct */ + struct mac_lte_info *p_mac_lte_info = p_get_proto_data(pinfo->fd, proto_mac_lte); + return ((p_mac_lte_info != NULL) && (p_mac_lte_info->reTxCount > 0)); + } + else { + /* For DL, must consult result table */ + return (g_hash_table_lookup(mac_lte_dl_harq_result_hash, GUINT_TO_POINTER(pinfo->fd->num)) != NULL); + } +} + + /* Track UL frames, so that when a retx is indicated, we can search for the original tx. We will either find it, and provide a link back to it, or flag that we couldn't find as an expert error */ @@ -1391,6 +1413,11 @@ static void TrackReportedULHARQResend(packet_info *pinfo, tvbuff_t *tvb, volatil { ULHARQResult *result = NULL; + /* FDD only for now! */ + if (p_mac_lte_info->radioType != FDD_RADIO) { + return; + } + if (!pinfo->fd->flags.visited) { /* First time, so set result and update UL harq table */ LastFrameData *lastData = NULL; diff --git a/epan/dissectors/packet-mac-lte.h b/epan/dissectors/packet-mac-lte.h index b2859c83ef..b50178c83f 100644 --- a/epan/dissectors/packet-mac-lte.h +++ b/epan/dissectors/packet-mac-lte.h @@ -121,6 +121,8 @@ typedef struct mac_lte_tap_info { } mac_lte_tap_info; +/* Accessor function to check if a frame was considered to be ReTx */ +int is_mac_lte_frame_retx(packet_info *pinfo, guint8 direction); /*****************************************************************/ /* UDP framing format */ diff --git a/epan/dissectors/packet-rlc-lte.c b/epan/dissectors/packet-rlc-lte.c index 82e2360f90..d2b992e423 100644 --- a/epan/dissectors/packet-rlc-lte.c +++ b/epan/dissectors/packet-rlc-lte.c @@ -35,6 +35,7 @@ #include <epan/prefs.h> #include <epan/tap.h> +#include "packet-mac-lte.h" #include "packet-rlc-lte.h" #include "packet-pdcp-lte.h" @@ -48,6 +49,9 @@ - AM re-assembly? */ +/********************************/ +/* Preference settings */ + #define SEQUENCE_ANALYSIS_MAC_ONLY 1 #define SEQUENCE_ANALYSIS_RLC_ONLY 2 @@ -62,11 +66,16 @@ static gboolean global_rlc_lte_call_rrc = FALSE; /* Preference to expect RLC headers without payloads */ static gboolean global_rlc_lte_headers_expected = FALSE; +/* Heuristic dissection */ +static gboolean global_rlc_lte_heur = FALSE; + +/**************************************************/ /* Initialize the protocol and registered fields. */ int proto_rlc_lte = -1; extern int proto_mac_lte; +extern int proto_pdcp_lte; static int rlc_lte_tap = -1; @@ -128,6 +137,8 @@ static int hf_rlc_lte_sequence_analysis_ok = -1; static int hf_rlc_lte_sequence_analysis_previous_frame = -1; static int hf_rlc_lte_sequence_analysis_expected_sn = -1; static int hf_rlc_lte_sequence_analysis_framing_info_correct = -1; + +static int hf_rlc_lte_sequence_analysis_mac_retx = -1; static int hf_rlc_lte_sequence_analysis_retx = -1; static int hf_rlc_lte_sequence_analysis_repeated = -1; static int hf_rlc_lte_sequence_analysis_skipped = -1; @@ -140,7 +151,7 @@ static int ett_rlc_lte_am_header = -1; static int ett_rlc_lte_extension_part = -1; static int ett_rlc_lte_sequence_analysis = -1; - +/* Value-strings */ static const value_string direction_vals[] = { { DIRECTION_UPLINK, "Uplink"}, @@ -165,7 +176,6 @@ static const value_string rlc_mode_vals[] = { 0, NULL } }; - static const value_string rlc_channel_type_vals[] = { { CHANNEL_TYPE_CCCH, "CCCH"}, @@ -176,7 +186,6 @@ static const value_string rlc_channel_type_vals[] = { 0, NULL } }; - static const value_string framing_info_vals[] = { { 0, "First byte begins a RLC SDU and last byte ends a RLC SDU"}, @@ -221,7 +230,6 @@ static const value_string polling_bit_vals[] = { 0, NULL } }; - static const value_string lsf_vals[] = { { 0, "Last byte of the AMD PDU segment does not correspond to the last byte of an AMD PDU"}, @@ -229,7 +237,6 @@ static const value_string lsf_vals[] = { 0, NULL } }; - static const value_string control_pdu_type_vals[] = { { 0, "STATUS PDU"}, @@ -257,7 +264,6 @@ static const value_string header_only_vals[] = { 0, NULL } }; -extern int proto_pdcp_lte; /**********************************************************************************/ @@ -268,6 +274,75 @@ guint8 s_number_of_extensions = 0; guint16 s_lengths[MAX_RLC_SDUS]; +/*********************************************************************/ +/* UM/AM sequence analysis */ + +/* Types for RLC channel hash table */ +/* This table is maintained during initial dissection of RLC */ +/* frames, mapping from rlc_channel_hash_key -> rlc_channel_status */ + +/* Channel key */ +typedef struct +{ + guint16 ueId; + guint16 channelType; + guint16 channelId; + guint8 direction; +} rlc_channel_hash_key; + +/* Conversation-type status for sequence analysis on channel */ +typedef struct +{ + guint8 rlcMode; + + /* For UM, we always expect the SN to keep advancing, and these fields + keep track of this. + For AM, these correspond to new data */ + guint16 previousSequenceNumber; + guint32 previousFrameNum; + gboolean previousSegmentIncomplete; +} rlc_channel_status; + +/* The sequence analysis channel hash table instance itself */ +static GHashTable *rlc_lte_sequence_analysis_channel_hash = NULL; + + +/* Types for sequence analysis frame report hash table */ +/* This is a table from framenum -> state_report_in_frame */ +/* This is necessary because the per-packet info is already being used */ +/* for conext information before the dissector is called */ + +/* Info to attach to frame when first read, recording what to show about sequence */ +typedef struct +{ + gboolean sequenceExpectedCorrect; + guint16 sequenceExpected; + guint32 previousFrameNum; + gboolean previousSegmentIncomplete; + + guint16 firstSN; + guint16 lastSN; + + /* AM Only */ + enum { SN_OK, SN_Repeated, SN_MAC_Retx, SN_Retx, SN_Missing} amState; +} state_sequence_analysis_report_in_frame; + + +/* The sequence analysis frame report hash table instance itself */ +static GHashTable *rlc_lte_frame_sequence_analysis_report_hash = NULL; + +/* TODO: add types for repeated NACKs table */ + + + +/* Forwad declarations */ +void proto_reg_handoff_rlc_lte(void); +void dissect_rlc_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + + + + + /* Dissect extension headers (common to both UM and AM) */ static int dissect_rlc_lte_extension_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, @@ -315,7 +390,7 @@ static int dissect_rlc_lte_extension_header(tvbuff_t *tvb, packet_info *pinfo, } else { offset++; } - + s_lengths[s_number_of_extensions++] = (guint16)length; } @@ -362,6 +437,7 @@ static void show_PDU_in_info(packet_info *pinfo, } +/* Show an AM PDU. If configured, pass to PDCP dissector */ static void show_AM_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, rlc_lte_info *rlc_info, gboolean whole_pdu) { @@ -407,40 +483,6 @@ static void show_AM_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t * } } - -/*********************************************************************/ -/* UM/AM sequence analysis */ - -/* Types for RLC channel hash table */ -/* This table is maintained during initial dissection of RLC */ -/* frames, mapping from rlc_channel_hash_key -> rlc_channel_status */ - -/* Channel key */ -typedef struct -{ - guint16 ueId; - guint16 channelType; - guint16 channelId; - guint8 direction; -} rlc_channel_hash_key; - -/* Conversation-type status for channel */ -typedef struct -{ - guint8 rlcMode; - - /* For UM, we always expect the SN to keep advancing, and these fields - keep track of this. - For AM, these correspond to new data */ - guint16 previousSequenceNumber; - guint32 previousFrameNum; - gboolean previousSegmentIncomplete; - - /* For AM, if we have NACKs we need to clear these before we send new data. - TODO: Keep a list of these SNs ?? */ -} rlc_channel_status; - - /* Hash table functions for RLC channels */ /* Equal keys */ @@ -465,31 +507,6 @@ static guint rlc_channel_hash_func(gconstpointer v) return ((val1->ueId * 1024) + (val1->channelType*64) + (val1->channelId*2) + val1->direction); } -/* The channel hash table instance itself */ -static GHashTable *rlc_lte_channel_hash = NULL; - - - - -/* Types for frame report hash table */ -/* This is a table from framenum -> state_report_in_frame */ -/* This is necessary because the per-packet info is already being used */ -/* for conext information before the dissector is called */ - -/* Info to attach to frame when first read, recording what to show about sequence */ -typedef struct -{ - gboolean sequenceExpectedCorrect; - guint16 sequenceExpected; - guint32 previousFrameNum; - gboolean previousSegmentIncomplete; - - guint16 firstSN; - guint16 lastSN; - - /* AM Only */ - enum { SN_OK, SN_Repeated, SN_Retx, SN_Missing} amState; -} state_report_in_frame; /* Hash table functions for frame reports */ @@ -506,15 +523,11 @@ static guint rlc_frame_hash_func(gconstpointer v) return GPOINTER_TO_UINT(v); } -/* The frame report hash table instance itself */ -static GHashTable *rlc_lte_frame_report_hash = NULL; - /* Add to the tree values associated with sequence analysis for this frame */ -static void addChannelSequenceInfo(state_report_in_frame *p, - guint16 UEId, - guint8 rlcMode, +static void addChannelSequenceInfo(state_sequence_analysis_report_in_frame *p, + rlc_lte_info *p_rlc_lte_info, guint16 sequenceNumber, gboolean newSegmentStarted, rlc_lte_tap_info *tap_info, @@ -534,7 +547,7 @@ static void addChannelSequenceInfo(state_report_in_frame *p, ett_rlc_lte_sequence_analysis); PROTO_ITEM_SET_GENERATED(seqnum_ti); - switch (rlcMode) { + switch (p_rlc_lte_info->rlcMode) { case RLC_AM_MODE: /********************************************/ @@ -547,7 +560,20 @@ static void addChannelSequenceInfo(state_report_in_frame *p, PROTO_ITEM_SET_GENERATED(ti); proto_item_append_text(seqnum_ti, " - OK"); break; - + + case SN_MAC_Retx: + ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok, + tvb, 0, 0, FALSE); + PROTO_ITEM_SET_GENERATED(ti); + ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_mac_retx, + tvb, 0, 0, TRUE); + PROTO_ITEM_SET_GENERATED(ti); + expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN, + "AM Frame retransmitted for %s on UE %u - due to MAC retx!", + val_to_str(p_rlc_lte_info->direction, direction_vals, "Unknown"), + p_rlc_lte_info->ueid); + break; + case SN_Retx: ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_ok, tvb, 0, 0, FALSE); @@ -556,8 +582,9 @@ static void addChannelSequenceInfo(state_report_in_frame *p, tvb, 0, 0, TRUE); PROTO_ITEM_SET_GENERATED(ti); expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN, - "AM Frame retransmitted for UE %u - most likely in response to NACK", - UEId); + "AM Frame retransmitted for %s on UE %u - most likely in response to NACK", + val_to_str(p_rlc_lte_info->direction, direction_vals, "Unknown"), + p_rlc_lte_info->ueid); proto_item_append_text(seqnum_ti, " - SN %u retransmitted", p->firstSN); break; @@ -569,8 +596,9 @@ static void addChannelSequenceInfo(state_report_in_frame *p, tvb, 0, 0, TRUE); PROTO_ITEM_SET_GENERATED(ti); expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN, - "AM SN Repeated for UE %u - probably because didn't receive Status PDU, or maybe MAC Retx?", - UEId); + "AM SN Repeated for %s for UE %u - probably because didn't receive Status PDU?", + val_to_str(p_rlc_lte_info->direction, direction_vals, "Unknown"), + p_rlc_lte_info->ueid); proto_item_append_text(seqnum_ti, "- SN %u Repeated", p->sequenceExpected); break; @@ -584,16 +612,18 @@ static void addChannelSequenceInfo(state_report_in_frame *p, PROTO_ITEM_SET_GENERATED(ti); if (p->lastSN != p->firstSN) { expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN, - "AM SNs missing for UE %u (%u to %u)", - UEId, p->firstSN, p->lastSN); + "AM SNs missing for %s on UE %u (%u to %u)", + val_to_str(p_rlc_lte_info->direction, direction_vals, "Unknown"), + p_rlc_lte_info->ueid, p->firstSN, p->lastSN); proto_item_append_text(seqnum_ti, " - SNs missing (%u to %u)", p->firstSN, p->lastSN); tap_info->missingSNs = ((p->lastSN - p->firstSN) % 1024) + 1; } else { expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN, - "AM SN missing for UE %u (%u)", - UEId, p->firstSN); + "AM SN missing for %s on UE %u (%u)", + val_to_str(p_rlc_lte_info->direction, direction_vals, "Unknown"), + p_rlc_lte_info->ueid, p->firstSN); proto_item_append_text(seqnum_ti, " - SN missing (%u)", p->firstSN); tap_info->missingSNs = 1; @@ -613,18 +643,18 @@ static void addChannelSequenceInfo(state_report_in_frame *p, proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_previous_frame, tvb, 0, 0, p->previousFrameNum); } - + /* Expected sequence number */ ti = proto_tree_add_uint(seqnum_tree, hf_rlc_lte_sequence_analysis_expected_sn, tvb, 0, 0, p->sequenceExpected); PROTO_ITEM_SET_GENERATED(ti); - - + if (!p->sequenceExpectedCorrect) { /* Incorrect sequence number */ expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN, - "Wrong Sequence Number for UE %u - got %u, expected %u", - UEId, sequenceNumber, p->sequenceExpected); + "Wrong Sequence Number for %s on UE %u - got %u, expected %u", + val_to_str(p_rlc_lte_info->direction, direction_vals, "Unknown"), + p_rlc_lte_info->ueid, sequenceNumber, p->sequenceExpected); } else { /* Correct sequence number, so check frame indication bits consistent */ @@ -636,7 +666,7 @@ static void addChannelSequenceInfo(state_report_in_frame *p, if (!p->sequenceExpectedCorrect) { expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN, "Last segment of previous PDU was not continued for UE %u", - UEId); + p_rlc_lte_info->ueid); } } else { @@ -658,7 +688,7 @@ static void addChannelSequenceInfo(state_report_in_frame *p, ti = proto_tree_add_boolean(seqnum_tree, hf_rlc_lte_sequence_analysis_framing_info_correct, tvb, 0, 0, TRUE); } - + } PROTO_ITEM_SET_GENERATED(ti); } @@ -677,17 +707,16 @@ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, rlc_channel_hash_key channel_key; rlc_channel_hash_key *p_channel_key; rlc_channel_status *p_channel_status; - state_report_in_frame *p_report_in_frame = NULL; + state_sequence_analysis_report_in_frame *p_report_in_frame = NULL; guint8 createdChannel = FALSE; guint16 expectedSequenceNumber = 0; /* If find stat_report_in_frame already, use that and get out */ if (pinfo->fd->flags.visited) { - p_report_in_frame = (state_report_in_frame*)g_hash_table_lookup(rlc_lte_frame_report_hash, - &pinfo->fd->num); + p_report_in_frame = (state_sequence_analysis_report_in_frame*)g_hash_table_lookup(rlc_lte_frame_sequence_analysis_report_hash, + &pinfo->fd->num); if (p_report_in_frame != NULL) { - addChannelSequenceInfo(p_report_in_frame, p_rlc_lte_info->ueid, - p_rlc_lte_info->rlcMode, + addChannelSequenceInfo(p_report_in_frame, p_rlc_lte_info, sequenceNumber, first_includes_start, tap_info, pinfo, tree, tvb); return; @@ -707,7 +736,7 @@ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, channel_key.direction = p_rlc_lte_info->direction; /* Do the table lookup */ - p_channel_status = (rlc_channel_status*)g_hash_table_lookup(rlc_lte_channel_hash, &channel_key); + p_channel_status = (rlc_channel_status*)g_hash_table_lookup(rlc_lte_sequence_analysis_channel_hash, &channel_key); /* Create table entry if necessary */ if (p_channel_status == NULL) { @@ -724,11 +753,11 @@ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, p_channel_status->rlcMode = p_rlc_lte_info->rlcMode; /* Add entry */ - g_hash_table_insert(rlc_lte_channel_hash, p_channel_key, p_channel_status); + g_hash_table_insert(rlc_lte_sequence_analysis_channel_hash, p_channel_key, p_channel_status); } /* Create space for frame state_report */ - p_report_in_frame = se_alloc(sizeof(state_report_in_frame)); + p_report_in_frame = se_alloc(sizeof(state_sequence_analysis_report_in_frame)); switch (p_channel_status->rlcMode) { case RLC_UM_MODE: @@ -773,8 +802,17 @@ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, - new SN, but with frames missed out Assume window whose front is at expectedSequenceNumber */ + /* First of all, check to see whether frame is judged to be MAC Retx */ + if (is_mac_lte_frame_retx(pinfo, p_rlc_lte_info->direction)) { + /* Just report that this is a MAC Retx */ + p_report_in_frame->amState = SN_MAC_Retx; + + /* No channel state to update */ + } + + /* Expected? */ - if (sequenceNumber == expectedSequenceNumber) { + else if (sequenceNumber == expectedSequenceNumber) { /* Set report for this frame */ p_report_in_frame->sequenceExpectedCorrect = TRUE; @@ -841,18 +879,17 @@ static void checkChannelSequenceInfo(packet_info *pinfo, tvbuff_t *tvb, } /* Associate with this frame number */ - g_hash_table_insert(rlc_lte_frame_report_hash, &pinfo->fd->num, p_report_in_frame); + g_hash_table_insert(rlc_lte_frame_sequence_analysis_report_hash, &pinfo->fd->num, p_report_in_frame); /* Add state report for this frame into tree */ - addChannelSequenceInfo(p_report_in_frame, p_rlc_lte_info->ueid, - p_rlc_lte_info->rlcMode, sequenceNumber, + addChannelSequenceInfo(p_report_in_frame, p_rlc_lte_info, sequenceNumber, first_includes_start, tap_info, pinfo, tree, tvb); } /***************************************************/ -/* Unacknowledged mode PDU */ +/* Transparent mode PDU. Call RRC if configured to */ static void dissect_rlc_lte_tm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, @@ -1075,7 +1112,6 @@ static void dissect_rlc_lte_um(tvbuff_t *tvb, packet_info *pinfo, - /* Dissect an AM STATUS PDU */ static void dissect_rlc_lte_am_status_pdu(tvbuff_t *tvb, packet_info *pinfo, @@ -1083,6 +1119,7 @@ static void dissect_rlc_lte_am_status_pdu(tvbuff_t *tvb, proto_item *status_ti, int offset, proto_item *top_ti, + rlc_lte_info *p_rlc_lte_info, rlc_lte_tap_info *tap_info) { guint8 cpt; @@ -1106,11 +1143,7 @@ static void dissect_rlc_lte_am_status_pdu(tvbuff_t *tvb, return; } - - /*****************************************************************/ - /* STATUS PDU */ - - /* The PDU itself starts 4 bits into the byte */ + /* The Status PDU itself starts 4 bits into the byte */ bit_offset += 4; /* ACK SN */ @@ -1158,11 +1191,15 @@ static void dissect_rlc_lte_am_status_pdu(tvbuff_t *tvb, /* Report as expert info */ if (e2) { expert_add_info_format(pinfo, nack_ti, PI_SEQUENCE, PI_WARN, - "Status PDU reports NACK for SN=%u (partial)", (guint16)nack_sn); + "Status PDU reports NACK (partial) on %s for UE %u", + val_to_str(p_rlc_lte_info->direction, direction_vals, "Unknown"), + p_rlc_lte_info->ueid); } else { expert_add_info_format(pinfo, nack_ti, PI_SEQUENCE, PI_WARN, - "Status PDU reports NACK for SN=%u", (guint16)nack_sn); + "Status PDU reports NACK on %s for UE %u", + val_to_str(p_rlc_lte_info->direction, direction_vals, "Unknown"), + p_rlc_lte_info->ueid); } bit_offset++; @@ -1243,21 +1280,21 @@ static void dissect_rlc_lte_am(tvbuff_t *tvb, packet_info *pinfo, am_header_tree = proto_item_add_subtree(am_header_ti, ett_rlc_lte_am_header); - - /*******************************************/ /* First bit is Data/Control flag */ is_data = (tvb_get_guint8(tvb, offset) & 0x80) >> 7; proto_tree_add_item(am_header_tree, hf_rlc_lte_am_data_control, tvb, offset, 1, FALSE); tap_info->isControlPDU = !is_data; - /**************************************************/ if (!is_data) { + /**********************/ + /* Status PDU */ col_append_str(pinfo->cinfo, COL_INFO, " [CONTROL]"); proto_item_append_text(top_ti, " [CONTROL]"); /* Control PDUs are a completely separate format */ dissect_rlc_lte_am_status_pdu(tvb, pinfo, am_header_tree, am_header_ti, - offset, top_ti, tap_info); + offset, top_ti, + p_rlc_lte_info, tap_info); return; } @@ -1401,13 +1438,6 @@ static void dissect_rlc_lte_am(tvbuff_t *tvb, packet_info *pinfo, } -/* Forwad declarations */ -void proto_reg_handoff_rlc_lte(void); -void dissect_rlc_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); - -/* Heuristic dissection */ -static gboolean global_rlc_lte_heur = FALSE; - /* Heuristic dissector looks for supported framing protocol (see wiki page) */ static gboolean dissect_rlc_lte_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) @@ -1694,17 +1724,17 @@ static void rlc_lte_init_protocol(void) { /* Destroy any existing hashes. */ - if (rlc_lte_channel_hash) { - g_hash_table_destroy(rlc_lte_channel_hash); + if (rlc_lte_sequence_analysis_channel_hash) { + g_hash_table_destroy(rlc_lte_sequence_analysis_channel_hash); } - if (rlc_lte_frame_report_hash) { - g_hash_table_destroy(rlc_lte_frame_report_hash); + if (rlc_lte_frame_sequence_analysis_report_hash) { + g_hash_table_destroy(rlc_lte_frame_sequence_analysis_report_hash); } /* Now create them over */ - rlc_lte_channel_hash = g_hash_table_new(rlc_channel_hash_func, rlc_channel_equal); - rlc_lte_frame_report_hash = g_hash_table_new(rlc_frame_hash_func, rlc_frame_equal); + rlc_lte_sequence_analysis_channel_hash = g_hash_table_new(rlc_channel_hash_func, rlc_channel_equal); + rlc_lte_frame_sequence_analysis_report_hash = g_hash_table_new(rlc_frame_hash_func, rlc_frame_equal); } @@ -1981,6 +2011,12 @@ void proto_register_rlc_lte(void) NULL, HFILL } }, + { &hf_rlc_lte_sequence_analysis_mac_retx, + { "Frame retransmitted by MAC", + "rlc-lte.sequence-analysis.mac-retx", FT_BOOLEAN, BASE_NONE, 0, 0x0, + NULL, HFILL + } + }, { &hf_rlc_lte_sequence_analysis_retx, { "Retransmitted frame", "rlc-lte.sequence-analysis.retx", FT_BOOLEAN, BASE_NONE, 0, 0x0, diff --git a/epan/filesystem.c b/epan/filesystem.c index a9aa16f4c8..98468b1619 100644 --- a/epan/filesystem.c +++ b/epan/filesystem.c @@ -420,7 +420,7 @@ init_progfile_dir(const char *arg0 return g_strdup_printf("pathconf failed: %s\n", strerror(errno)); } - curdir = g_malloc(path_max); + curdir = (char *)g_malloc(path_max); if (getcwd(curdir, path_max) == NULL) { /* * It failed - give up, and just stick @@ -448,7 +448,7 @@ init_progfile_dir(const char *arg0 if (path_end == NULL) path_end = path_start + strlen(path_start); path_component_len = path_end - path_start; - path = g_malloc(path_component_len + 1 + path = (char *)g_malloc(path_component_len + 1 + strlen(arg0) + 1); memcpy(path, path_start, path_component_len); path[path_component_len] = '\0'; @@ -603,7 +603,7 @@ get_datafile_dir(void) #ifdef _WIN32 char *u3deviceexecpath; #endif - static char *datafile_dir = NULL; + static const char *datafile_dir = NULL; if (datafile_dir != NULL) return datafile_dir; @@ -1321,12 +1321,13 @@ copy_persconffile_profile(const char *toname, const char *fromname, char **pf_fi /* * Get the (default) directory in which personal data is stored. * - * On Win32, this is the "My Documents" folder in the personal profile. + * On Win32, this is the "My Documents" folder in the personal profile, + * except that, if we're running from a U3 device, this is the + * "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder. * On UNIX this is simply the current directory. - * On a U3 device this is "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder. */ /* XXX - should this and the get_home_dir() be merged? */ -extern char * +extern const char * get_persdatafile_dir(void) { #ifdef _WIN32 @@ -1335,7 +1336,6 @@ get_persdatafile_dir(void) char *szPath; BOOL bRet; - /* Return the cached value, if available */ if (persdatafile_dir != NULL) return persdatafile_dir; @@ -1346,28 +1346,30 @@ get_persdatafile_dir(void) u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH"); if (u3devicedocumentpath != NULL) { + /* the "My Captures" sub-directory is created (if it doesn't + exist) by u3util.exe when the U3 Wireshark is first run */ - /* the "My Captures" sub-directory is created (if it doesn't exist) - by u3util.exe when the U3 Wireshark is first run */ - - szPath = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES); - - persdatafile_dir = szPath; - return szPath; + szPath = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES); - } else { - /* Hint: SHGetFolderPath is not available on MSVC 6 - without Platform SDK */ - bRet = SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE); - if(bRet == TRUE) { - szPath = utf_16to8(tszPath); persdatafile_dir = szPath; return szPath; } else { - return ""; + /* + * Hint: SHGetFolderPath is not available on MSVC 6 - without + * Platform SDK + */ + bRet = SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, + FALSE); + if(bRet == TRUE) { + szPath = utf_16to8(tszPath); + persdatafile_dir = szPath; + return szPath; + } else { + return ""; + } } -} #else - return ""; + return ""; #endif } diff --git a/epan/filesystem.h b/epan/filesystem.h index 6998147d5b..6e459393f3 100644 --- a/epan/filesystem.h +++ b/epan/filesystem.h @@ -186,7 +186,7 @@ extern char *get_persconffile_path(const char *filename, gboolean from_profile, * On Win32, this is the "My Documents" folder in the personal profile. * On UNIX this is simply the current directory. */ -extern char *get_persdatafile_dir(void); +extern const char *get_persdatafile_dir(void); /* * Construct the path name of a file in $TMP/%TEMP% directory. diff --git a/gtk/file_dlg.c b/gtk/file_dlg.c index 8c8a94e634..7b9e67ef7a 100644 --- a/gtk/file_dlg.c +++ b/gtk/file_dlg.c @@ -222,7 +222,7 @@ file_selection_browse_destroy_cb(GtkWidget *win, GtkWidget* parent_te) void -set_last_open_dir(char *dirname) +set_last_open_dir(const char *dirname) { size_t len; gchar *new_last_open_dir; diff --git a/gtk/file_dlg.h b/gtk/file_dlg.h index fc9c039174..87dd8d4d8d 100644 --- a/gtk/file_dlg.h +++ b/gtk/file_dlg.h @@ -110,6 +110,6 @@ extern char *get_last_open_dir(void); * * @param dirname the dirname */ -extern void set_last_open_dir(char *dirname); +extern void set_last_open_dir(const char *dirname); #endif diff --git a/gtk/rlc_lte_stat_dlg.c b/gtk/rlc_lte_stat_dlg.c index ce69feb17f..4325d01783 100644 --- a/gtk/rlc_lte_stat_dlg.c +++ b/gtk/rlc_lte_stat_dlg.c @@ -1109,7 +1109,10 @@ static void gtk_rlc_lte_stat_init(const char *optarg, void *userdata _U_) pdu_source_lb = gtk_frame_new("PDUs to use"); show_mac_cb = gtk_check_button_new_with_mnemonic("Show RLC PDUs found inside logged MAC frames"); gtk_container_add(GTK_CONTAINER(pdu_source_lb), show_mac_cb); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_mac_cb), FALSE); + + /* MAC on by default */ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_mac_cb), TRUE); + hs->show_mac = TRUE; gtk_box_pack_start(GTK_BOX(top_level_vbox), pdu_source_lb, FALSE, FALSE, 0); /* TODO: add tooltips... */ g_signal_connect(show_mac_cb, "toggled", G_CALLBACK(toggle_show_mac), hs); diff --git a/tap-megaco-common.c b/tap-megaco-common.c index a6aa587436..882ecba0d7 100644 --- a/tap-megaco-common.c +++ b/tap-megaco-common.c @@ -112,7 +112,7 @@ int megacostat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pmi) { megacostat_t *ms=(megacostat_t *)pms; - const gcp_cmd_t *mi=(gcp_cmd_t*)pmi; + const gcp_cmd_t *mi=(const gcp_cmd_t*)pmi; nstime_t delta; int ret = 0; diff --git a/test/test.sh b/test/test.sh index f13377f4da..6517873171 100755 --- a/test/test.sh +++ b/test/test.sh @@ -92,7 +92,7 @@ test_suite() { test_suite_add "Command line options" clopt_suite test_suite_add "File I/O" io_suite test_suite_add "Capture" capture_suite - test_suite_add "Unittests" unittests_suite + test_suite_add "Unit tests" unittests_suite } |