Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Inconsistent g_snprintf behaviour (Wireshark 3.2.5)

Hello,

I'm continuing working on my dissector and am stumped on this behaviour.

We have a timestamp field in a message that I've written a custom callback function for.

This is the structure of the timestamp, starting at octet 43 within this particular internal message (little endian):

  43  .cal_time                calendar_time_t    STRUCT              8
  43  ..hundredths_of_seconds  bcd_t              byte                 1
  44  ..seconds                bcd_t              byte                 1
  45  ..minutes                bcd_t              byte                 1
  46  ..hours                  bcd_t              byte                 1
  47  ..day                    bcd_t              byte                 1
  48  ..month                  bcd_t              byte                 1
  49  ..year                   long_bcd_t         word                 2

And this is the CF I wrote to output the timestamp correctly:

static void
print_cal_time(gchar *result, guint64 cal_time)
{
    guint16 cal_time_year = (cal_time >> 48);
    gint8 cal_time_month = (cal_time >> 40) & 0xFF;
    gint8 cal_time_day = (cal_time >> 32) & 0xFF;
    gint8 cal_time_hour = (cal_time >> 24) & 0xFF;
    gint8 cal_time_min = (cal_time >> 16) & 0xFF;
    gint8 cal_time_sec = (cal_time >> 8) & 0xFF;
    gint8 cal_time_100ths = cal_time & 0xFF;

    g_snprintf(result, ITEM_LABEL_LENGTH, "%4X-%02X-%02X %02X:%02X:%02X.%02X",
               cal_time_year,
               cal_time_month,
               cal_time_day,
               cal_time_hour,
               cal_time_min,
               cal_time_sec,
               cal_time_100ths);
}

The other relevant bits in my dissector:

proto_tree_add_item(dmx_tree, hf_emb_dx_FCC8_cal_time, payload_tvb, 43, 8, ENC_LITTLE_ENDIAN);

... and ...

{ &hf_emb_dx_FCC8_cal_time,
    {"FCC8 calendar time", "emb.dmx.fcc8.cal_time",
        FT_UINT64, BASE_CUSTOM, CF_FUNC(print_cal_time), 0x0,
        "Calender time of log", HFILL}},

This works most of the time, but sometimes it is giving a weird output for the 1/100s field.

Working okay:

FCC8 calendar time: 2020-06-18 11:47:58.64

0000   64 58 47 11 18 06 20 20

Not working:

FCC8 calendar time: 2020-06-18 11:47:59.FFFFFF96

0000   96 59 47 11 18 06 20 20

The 1/100s field is being output as a dword even though the variable is a single byte and the format string specifies %02X:

gint8 cal_time_100ths = cal_time & 0xFF;

What am I missing?

Inconsistent g_snprintf behaviour (Wireshark 3.2.5)

Hello,

I'm continuing working on my dissector and am stumped on this behaviour.

We have a timestamp field in a message that I've written a custom callback function for.

This is the structure of the timestamp, starting at octet 43 within this particular internal message (little endian):

  43  .cal_time                calendar_time_t    STRUCT              8
  43  ..hundredths_of_seconds  bcd_t              byte                 1
  44  ..seconds                bcd_t              byte                 1
  45  ..minutes                bcd_t              byte                 1
  46  ..hours                  bcd_t              byte                 1
  47  ..day                    bcd_t              byte                 1
  48  ..month                  bcd_t              byte                 1
  49  ..year                   long_bcd_t         word                 2

And this is the CF I wrote to output the timestamp correctly:

static void
print_cal_time(gchar *result, guint64 cal_time)
{
    guint16 cal_time_year = (cal_time >> 48);
    gint8 cal_time_month = (cal_time >> 40) & 0xFF;
    gint8 cal_time_day = (cal_time >> 32) & 0xFF;
    gint8 cal_time_hour = (cal_time >> 24) & 0xFF;
    gint8 cal_time_min = (cal_time >> 16) & 0xFF;
    gint8 cal_time_sec = (cal_time >> 8) & 0xFF;
    gint8 cal_time_100ths = cal_time & 0xFF;

    g_snprintf(result, ITEM_LABEL_LENGTH, "%4X-%02X-%02X %02X:%02X:%02X.%02X",
               cal_time_year,
               cal_time_month,
               cal_time_day,
               cal_time_hour,
               cal_time_min,
               cal_time_sec,
               cal_time_100ths);
}

The other relevant bits in my dissector:

proto_tree_add_item(dmx_tree, hf_emb_dx_FCC8_cal_time, payload_tvb, 43, 8, ENC_LITTLE_ENDIAN);

... and ...

{ &hf_emb_dx_FCC8_cal_time,
    {"FCC8 calendar time", "emb.dmx.fcc8.cal_time",
        FT_UINT64, BASE_CUSTOM, CF_FUNC(print_cal_time), 0x0,
        "Calender time of log", HFILL}},

This works most of the time, but sometimes it is giving a weird output for the 1/100s field.

Working okay:

FCC8 calendar time: 2020-06-18 11:47:58.64

0000   64 58 47 11 18 06 20 20

Not working:

FCC8 calendar time: 2020-06-18 11:47:59.FFFFFF96

0000   96 59 47 11 18 06 20 20

The 1/100s field is being output as a dword even though the variable is a single byte and the format string specifies %02X:

gint8 cal_time_100ths = cal_time & 0xFF;

What am I missing?missing? I see the same behaviour in 64-bit 3.2.5 compiled on both Win10 and macOS.