Wireshark-dev: Re: [Wireshark-dev] question on validation of a dissected string from a BASE_CUS

From: John Thacker <johnthacker@xxxxxxxxx>
Date: Tue, 12 Sep 2023 10:24:19 -0400
You may have noticed "proto_tree_add_item_ret_display_string()" and perhaps found that it doesn't do what you want; it produces the display string for a default display representation and doesn't use your custom function. (Perhaps it should?)

On Tue, Sep 12, 2023, 10:05 AM John Thacker <johnthacker@xxxxxxxxx> wrote:
In general you don't want to do that, if your goal is to create an expert info. The string would not exist and thus the Expert Info would not show in the "Analyze -> Expert Information" dialog, or in other situations where the tree was not visible and the item was faked; you might have to specifically filter for the item. (See https://gitlab.com/wireshark/wireshark/-/issues/18955 for a similar situation. Also somewhat relatedly https://gitlab.com/wireshark/wireshark/-/issues/19216 ) For optimization purposes, strings and display labels are not filled in unless necessary.

What you could do is allocate your own string buffer, and pass it and the uint64_t to your Receive_Frequency function. You can simplify that by replacing your proto_tree_add_item() call with:

uint64_t value;
char[ITEM_LABEL_LENGTH] label;
ti = proto_tree_add_item_ret_uint64(tree, hf_, tvb, start, length, encoding, &value);
Receive_Frequency(label, value);
if (....) {
  expert_add_info(pinfo, ti, &ei_);
}

However, since it's processor intensive and error prone to convert to a string only to parse the string back to floating point, you'd probably be better off retrieving the uint64_t value and passing it to a function that converts it directly to the floating point you need, separate from your custom display function.

Cheers,
John Thacker


On Thu, Sep 7, 2023 at 12:15 PM John Dill <John.Dill@xxxxxxxxxxxxxxxxx> wrote:

I have a question whether I can get the dissected string of the BASE_CUSTOM header field so that I can do analysis on it and convert it to floating point to do range analysis so I can issue an expert info if the value is valid but out of range.


    {
      &hf_Receive_Frequency,
      {
        "Receive Frequency",
        "Receive_Frequency",
        FT_UINT48,
        BASE_CUSTOM,
        CF_FUNC(Receive_Frequency),
        0x0,
        NULL,
        HFILL
      }
    },

...

    ti = proto_tree_add_item(word_tree, hf_XTS_5000_APX_8000_Receive_Frequency, tvb, offset, 6, ENC_BIG_ENDIAN);

...

static void Receive_Frequency(gchar *result, guint64 value)
{
  guint16 w_Base_Frequency;
  guint16 w_1_MHz_BCD;
  guint16 w_100_KHz_BCD;
  guint16 w_10_KHz_BCD;
  guint16 w_Rx_KHz_Frequency_Field;

  guint32 MHz_Frequency;
  guint32 KHz_Frequency;

... processing ...

  switch (lut_Base_Frequency[w_Base_Frequency])
  {
    case -1:
      g_snprintf(result, ITEM_LABEL_LENGTH, "Illegal");
      break;

    case 0:
      g_snprintf(result, ITEM_LABEL_LENGTH, "Invalid");
      break;

    default:
      /* Frequency is typically displayed in MHz with 4 significant digits */
      g_snprintf(result, ITEM_LABEL_LENGTH, "%" G_GUINT32_FORMAT ".%" G_GUINT32_FORMAT " MHz", MHz_Frequency, KHz_Frequency / 100);
      break;
  }
}

Is there a way for me to peel the dissected result string from "ti" after the proto_tree_add_item call so that I can do validation and range checking for expert info?

Can I try to hijack proto_item_fill_display_label to somehow push "tmp" out of the interface into a proto_tree_add_*_ret_processed_string?

\code
if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
gchar tmp[ITEM_LABEL_LENGTH];
custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;

DISSECTOR_ASSERT(fmtfunc);
fmtfunc(tmp, number);

label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
\endcode

This 'tmp' from fmtfunc is the string I want to grab for post-analysis, but it seems non-obvious how to get at it.

I might be completely overlooking an easy way to do this.

Any suggestions?  I already maintain a fork, so having a custom mod to pull this out is on the table for me.

Thanks,
John D.

___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev@xxxxxxxxxxxxx>
Archives:    https://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-request@xxxxxxxxxxxxx?subject=unsubscribe