Add a script to convert GLib types to their C equivalents

Convert wsutil/802_11-utils.[ch] as a test.

Update some of our documentation.

Ping #19116
This commit is contained in:
Gerald Combs 2023-06-02 16:23:39 -07:00
parent 0f71aa256c
commit 591f89d785
6 changed files with 129 additions and 67 deletions

View File

@ -118,13 +118,12 @@ instead.
Don't use "uchar", "u_char", "ushort", "u_short", "uint", "u_int",
"ulong", "u_long" or "boolean"; they aren't defined on all platforms.
glib typedefs are used extensively throughout the codebase (gchar, guint8,
gint16, etc). We would like to move instead towards the fixed width integers
provided in C since C99. These are defined in <stdint.h>. However, lots of our
internal APIs are defined using these glib types, and it seems that even the
glib project is finding it difficult to move away from them. So when you
have a choice, choose stdint types, but realise that until we can change
our APIs, in many situations the glib types still make sense.
GLib typedefs have historically been used extensively throughout the
codebase (gchar, guint8, gint16, etc). We are moving towards the fixed
width integers provided in C since C99. These are defined in <stdint.h>,
which is included in <wireshark.h>. You should choose stdint types when
possible, but realise that until we can fully migrate our APIs, in many
situations the GLib types still make sense.
If you want an 8-bit unsigned quantity, use "uint8_t"; if you want an
8-bit character value with the 8th bit not interpreted as a sign bit,
@ -141,8 +140,8 @@ To print fixed width integers you must use the macros provided in <inttypes.h>.
Don't use "long" to mean "signed 32-bit integer", and don't use
"unsigned long" to mean "unsigned 32-bit integer"; "long"s are 64 bits
long on many platforms. Use "gint32" for signed 32-bit integers and use
"guint32" for unsigned 32-bit integers.
long on many platforms. Use "int32_t" for signed 32-bit integers and use
"uint32_t" for unsigned 32-bit integers.
Don't use "long" to mean "signed 64-bit integer" and don't use "unsigned
long" to mean "unsigned 64-bit integer"; "long"s are 32 bits long on
@ -163,7 +162,7 @@ functions won't accept a size_t on LLP64:
size_t i;
char greeting[] = "hello, sailor";
guint byte_after_greet;
unsigned byte_after_greet;
i = strlen(greeting);
byte_after_greet = tvb_get_guint8(tvb, i); /* Compiler warning */

View File

@ -61,18 +61,18 @@ static dissector_handle_t PROTOABBREV_handle;
static dissector_handle_t PROTOABBREV_tls_handle;
/* Global sample preference ("controls" display of numbers) */
static gboolean pref_hex = FALSE;
static bool pref_hex = false;
/* Global sample port preference - real port preferences should generally
* default to "" (for a range) or 0 (for a single uint) unless there is an
* IANA-registered (or equivalent) port for your protocol. */
#define PROTOABBREV_TLS_PORT 5678
static guint tls_port_pref = PROTOABBREV_TLS_PORT;
static unsigned tls_port_pref = PROTOABBREV_TLS_PORT;
#define PROTOABBREV_TCP_PORTS "1234"
static range_t *tcp_port_range = PROTOABBREV_TCP_PORTS;
/* Initialize the subtree pointers */
static gint ett_PROTOABBREV = -1;
static int ett_PROTOABBREV = -1;
/* A sample #define of the minimum length (in bytes) of the protocol data.
* If data is received with fewer than this many bytes it is rejected by
@ -88,8 +88,8 @@ dissect_PROTOABBREV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_item *ti, *expert_ti;
proto_tree *PROTOABBREV_tree;
/* Other misc. local variables. */
guint offset = 0;
int len = 0;
unsigned offset = 0;
int len = 0;
/*** HEURISTICS ***/
@ -231,7 +231,7 @@ proto_register_PROTOABBREV(void)
};
/* Setup protocol subtree array */
static gint *ett[] = {
static int *ett[] = {
&ett_PROTOABBREV
};
@ -321,7 +321,7 @@ proto_register_PROTOABBREV(void)
void
proto_reg_handoff_PROTOABBREV(void)
{
static gboolean initialized = FALSE;
static bool initialized = false;
static int current_tls_port_pref;
if (!initialized) {

View File

@ -297,7 +297,7 @@ and `proto_register_subtree_array()`:
[source,c]
----
static int hf_foo_pdu_type = -1;
static gint ett_foo = -1;
static int ett_foo = -1;
/* ... */
@ -314,7 +314,7 @@ proto_register_foo(void)
};
/* Setup protocol subtree array */
static gint *ett[] = {
static int *ett[] = {
&ett_foo
};
@ -410,7 +410,7 @@ static int hf_foo_initialip = -1;
static int
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
gint offset = 0;
int offset = 0;
...
proto_item *ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, ENC_NA);
@ -581,8 +581,8 @@ window.
static int
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
gint offset = 0;
guint8 packet_type = tvb_get_guint8(tvb, 0);
int offset = 0;
uint8_t packet_type = tvb_get_guint8(tvb, 0);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO");
/* Clear out stuff in the info column */
@ -702,7 +702,7 @@ to actually add the expert item to the dissection.
static int
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
guint32 sequenceno = 0xFFFF;
uint32_t sequenceno = 0xFFFF;
/* ... */
@ -749,10 +749,10 @@ effect.
.Decompressing data packets for dissection.
[source,c]
----
guint8 flags = tvb_get_guint8(tvb, offset);
uint8_t flags = tvb_get_guint8(tvb, offset);
offset ++;
if (flags & FLAG_COMPRESSED) { /* the remainder of the packet is compressed */
guint16 orig_size = tvb_get_ntohs(tvb, offset);
uint16_t orig_size = tvb_get_ntohs(tvb, offset);
guchar *decompressed_buffer = (guchar*)wmem_alloc(pinfo->pool, orig_size);
offset += 2;
decompress_packet(tvb_get_ptr(tvb, offset, -1),
@ -855,10 +855,10 @@ flags = tvb_get_guint8(tvb, offset); offset++;
if (flags & FL_FRAGMENT) { /* fragmented */
tvbuff_t* new_tvb = NULL;
fragment_data *frag_msg = NULL;
guint16 msg_seqid = tvb_get_ntohs(tvb, offset); offset += 2;
guint16 msg_num = tvb_get_ntohs(tvb, offset); offset += 2;
uint16_t msg_seqid = tvb_get_ntohs(tvb, offset); offset += 2;
uint16_t msg_num = tvb_get_ntohs(tvb, offset); offset += 2;
pinfo->fragmented = TRUE;
pinfo->fragmented = true;
frag_msg = fragment_add_seq_check(msg_reassembly_table,
tvb, offset, pinfo,
msg_seqid, NULL, /* ID for fragments belonging together */
@ -978,8 +978,8 @@ static int hf_msg_fragment_count = -1;
static int hf_msg_reassembled_in = -1;
static int hf_msg_reassembled_length = -1;
...
static gint ett_msg_fragment = -1;
static gint ett_msg_fragments = -1;
static int ett_msg_fragment = -1;
static int ett_msg_fragments = -1;
...
static const fragment_items msg_frag_items = {
/* Fragment subtrees */
@ -1038,7 +1038,7 @@ static hf_register_info hf[] =
{"Reassembled length", "msg.reassembled.length",
FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
...
static gint *ett[] =
static int *ett[] =
{
...
&ett_msg_fragment,
@ -1095,18 +1095,18 @@ dissect_foo_message(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_,
}
/* determine PDU length of protocol foo */
static guint
static unsigned
get_foo_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
/* TODO: change this to your needs */
return (guint)tvb_get_ntohl(tvb, offset+4); /* e.g. length is at offset 4 */
return (unsigned)tvb_get_ntohl(tvb, offset+4); /* e.g. length is at offset 4 */
}
/* The main dissecting routine */
static int
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN,
tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LEN,
get_foo_message_len, dissect_foo_message, data);
return tvb_captured_length(tvb);
}
@ -1157,8 +1157,8 @@ string name with which to find it again.
static int foo_tap = -1;
struct FooTap {
gint packet_type;
gint priority;
int packet_type;
int priority;
...
};
@ -1259,14 +1259,14 @@ In this case we only need the first two functions, as there is nothing specific
.Initialising a stats session
[source,c]
----
static const guint8* st_str_packets = "Total Packets";
static const guint8* st_str_packet_types = "FOO Packet Types";
static const uint8_t* st_str_packets = "Total Packets";
static const uint8_t* st_str_packet_types = "FOO Packet Types";
static int st_node_packets = -1;
static int st_node_packet_types = -1;
static void foo_stats_tree_init(stats_tree* st)
{
st_node_packets = stats_tree_create_node(st, st_str_packets, 0, STAT_DT_INT, TRUE);
st_node_packets = stats_tree_create_node(st, st_str_packets, 0, STAT_DT_INT, true);
st_node_packet_types = stats_tree_create_pivot(st, st_str_packet_types, st_node_packets);
}
----
@ -1282,7 +1282,7 @@ different packet types.
static tap_packet_status foo_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt, const void* p, tap_flags_t flags)
{
struct FooTap *pi = (struct FooTap *)p;
tick_stat_node(st, st_str_packets, 0, FALSE);
tick_stat_node(st, st_str_packets, 0, false);
stats_tree_tick_pivot(st, st_node_packet_types,
val_to_str(pi->packet_type, packettypenames, "Unknown packet type (%d)"));
return TAP_PACKET_REDRAW;

63
tools/convert-glib-types.py Executable file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env python3
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# SPDX-License-Identifier: GPL-2.0-or-later
'''\
convert-glib-types.py - Convert glib types to their C and C99 eqivalents.
'''
# Imports
import argparse
import re
import sys
type_map = {
'gboolean': 'bool',
'gchar': 'char',
'gint': 'int',
'guint': 'unsigned', # Matches README.developer
'gint8': 'int8_t',
'gint16': 'int16_t',
'gint32': 'int32_t',
'gint64': 'int64_t',
'guint8': 'uint8_t',
'guint16': 'uint16_t',
'guint32': 'uint32_t',
'guint64': 'uint64_t',
'gfloat': 'float',
'gdouble': 'double',
'gpointer': 'void *',
# Is gsize the same as size_t on the platforms we support?
# https://gitlab.gnome.org/GNOME/glib/-/issues/2493
'gsize': 'size_t',
'gssize': 'ssize_t',
'TRUE': 'true',
'FALSE': 'false',
}
def convert_file(file):
lines = ''
with open(file, 'r') as f:
lines = f.read()
for glib_type, c99_type in type_map.items():
lines = re.sub(rf'([^"])\b{glib_type}\b([^"])', rf'\1{c99_type}\2', lines, flags=re.MULTILINE)
with open(file, 'w') as f:
f.write(lines)
print(f'Converted {file}')
def main():
parser = argparse.ArgumentParser(description='Convert glib types to their C and C99 eqivalents.')
parser.add_argument('files', metavar='FILE', nargs='*')
args = parser.parse_args()
for file in args.files:
convert_file(file)
# On with the show
if __name__ == "__main__":
sys.exit(main())

View File

@ -12,10 +12,10 @@
#include "802_11-utils.h"
typedef struct freq_cvt_s {
guint fmin; /* Minimum frequency in MHz */
guint fmax; /* Maximum frequency in MHz */
gint cmin; /* Minimum/base channel */
gboolean is_bg; /* B/G channel? */
unsigned fmin; /* Minimum frequency in MHz */
unsigned fmax; /* Maximum frequency in MHz */
int cmin; /* Minimum/base channel */
bool is_bg; /* B/G channel? */
} freq_cvt_t;
#define FREQ_STEP 5 /* MHz. This seems to be consistent, thankfully */
@ -34,22 +34,22 @@ typedef struct freq_cvt_s {
* XXX - what about 802.11ad?
*/
static freq_cvt_t freq_cvt[] = {
{ 2412, 2472, 1, TRUE }, /* IEEE Std 802.11-2020: Section 15.4.4.3 and Annex E */
{ 2484, 2484, 14, TRUE }, /* IEEE Std 802.11-2020: Section 15.4.4.3 and Annex E */
{ 5000, 5925, 0, FALSE }, /* IEEE Std 802.11-2020: Annex E */
{ 5950, 7125, 0, FALSE }, /* IEEE Std 802.11ax-2021: Annex E */
{ 4910, 4980, 182, FALSE },
{ 2412, 2472, 1, true }, /* IEEE Std 802.11-2020: Section 15.4.4.3 and Annex E */
{ 2484, 2484, 14, true }, /* IEEE Std 802.11-2020: Section 15.4.4.3 and Annex E */
{ 5000, 5925, 0, false }, /* IEEE Std 802.11-2020: Annex E */
{ 5950, 7125, 0, false }, /* IEEE Std 802.11ax-2021: Annex E */
{ 4910, 4980, 182, false },
};
#define NUM_FREQ_CVT (sizeof(freq_cvt) / sizeof(freq_cvt_t))
#define MAX_CHANNEL(fc) ( (gint) ((fc.fmax - fc.fmin) / FREQ_STEP) + fc.cmin )
#define MAX_CHANNEL(fc) ( (int) ((fc.fmax - fc.fmin) / FREQ_STEP) + fc.cmin )
/*
* Get channel number given a Frequency
*/
gint
ieee80211_mhz_to_chan(guint freq) {
guint i;
int
ieee80211_mhz_to_chan(unsigned freq) {
unsigned i;
for (i = 0; i < NUM_FREQ_CVT; i++) {
if (freq >= freq_cvt[i].fmin && freq <= freq_cvt[i].fmax) {
@ -70,9 +70,9 @@ ieee80211_mhz_to_chan(guint freq) {
* Unfortunately, this is not possible in some cases, so for now, the order on
* which frequency ranges are defined will favor 2.4 and 5 GHz over 6 GHz.
*/
guint
ieee80211_chan_to_mhz(gint chan, gboolean is_bg) {
guint i;
unsigned
ieee80211_chan_to_mhz(int chan, bool is_bg) {
unsigned i;
for (i = 0; i < NUM_FREQ_CVT; i++) {
if (is_bg == freq_cvt[i].is_bg &&
@ -86,10 +86,10 @@ ieee80211_chan_to_mhz(gint chan, gboolean is_bg) {
/*
* Get channel representation string given a Frequency
*/
gchar*
ieee80211_mhz_to_str(guint freq){
gint chan = ieee80211_mhz_to_chan(freq);
gboolean is_bg = FREQ_IS_BG(freq);
char*
ieee80211_mhz_to_str(unsigned freq){
int chan = ieee80211_mhz_to_chan(freq);
bool is_bg = FREQ_IS_BG(freq);
if (chan < 0) {
return ws_strdup_printf("%u", freq);

View File

@ -27,18 +27,18 @@ extern "C" {
* @return The equivalent channel or -1 if no match is found.
*/
WS_DLL_PUBLIC
gint
ieee80211_mhz_to_chan(guint freq);
int
ieee80211_mhz_to_chan(unsigned freq);
/**
* Given an 802.11 channel number and a band type, return a center frequency.
* @param chan Channel number
* @param is_bg TRUE if the channel is a b/g channel, FALSE otherwise.
* @param is_bg true if the channel is a b/g channel, false otherwise.
* @return The equivalent frequency or 0 if no match is found.
*/
WS_DLL_PUBLIC
guint
ieee80211_chan_to_mhz(gint chan, gboolean is_bg);
unsigned
ieee80211_chan_to_mhz(int chan, bool is_bg);
/**
* Given an 802.11 channel center frequency in MHz, return a string
@ -48,8 +48,8 @@ ieee80211_chan_to_mhz(gint chan, gboolean is_bg);
* The string must be freed with g_free() after use.
*/
WS_DLL_PUBLIC
gchar*
ieee80211_mhz_to_str(guint freq);
char*
ieee80211_mhz_to_str(unsigned freq);
/* Should this be "(freq < 4920)", or something else? */
#define FREQ_IS_BG(freq) ((freq) <= 2484)