Wireshark mailing list archives

string manipulation


From: Brian Oleksa <oleksab () darkcornersoftware com>
Date: Mon, 25 Jan 2010 16:11:16 -0500

Guy

This past e-mail was very helpful. I have made some big leaps fixing 
some of my code to adhere to the coding standards.

But I do have some more questions:    I am on too strings now.

This is what I am currently doing:

PS. I am still working on fixing the ptr stuff....but wanted to start 
small and work one problem at a time.

                    char flowname[9];
                    strncpy(flowname, ptr, 8);
                    flowname[8] = '\0';
                    ptr += 8;
                    proto_tree_add_uint_format(helen_sub_tree, 
hf_helen_length, tvb, offset, 8, 0,
                            "Flowname: %s", flowname);
                    offset += 8;

In the developers README file... it tells you NOT to use strcpy...but 
instead use g_snprintf().

I am having a hard time interpreting this into what I already have. Any 
help (or examples using g_snprintf) is greatly appreciated.

Thanks,
Brian





Guy Harris wrote:
On Jan 21, 2010, at 11:59 AM, Brian Oleksa wrote:

  
But how I start the initial counting process is I do the following:

guint8 * ptr = (guint8*) tvb->real_data;
    

Don't do that.

First of all, that isn't guaranteed to work for all tvbuffs; we currently aren't using composite tvbuffs (and there 
are apparently some bugs in them), but, if we do, there is no guarantee that the "real_data" field of a tvbuff will 
always be valid.

Second of all, you should not just extract fields from the packet data yourself:

      doing so means that no bounds checking is done, so you might run past the end of the packet data (do *NOT* 
assume either that all packets for your protocol will be valid or that the capture wasn't cut short by setting the 
snapshot length when capturing);

      doing so means that if a field isn't aligned on an appropriate boundary in memory, attempting to fetch the data 
could fail (SPARC processors, for example, do not support unaligned accesses, and we *do* support Wireshark on SPARC);

      doing so means means that you have to do the byte swapping yourself.

Instead, use the tvb_get_ routines to fetch fields individually, using the offset variable.

Speaking of byte swapping, this:

      https://www.darkcornersoftware.com/confluence/display/open/Packet+Structure

says "All values are in network byte order", so if you're running on a machine with the most popular family of 
desktop and notebook processors - i.e., an x86 or x86-64 processor - you *would* have to byte-swap values if you 
fetch them yourself.  That also means that the tvb_get_ntoh routines should be used to fetch numerical field values.

  
Actually..... maybe you can see your answer better in the code. I have attached the packet-helen.c file.
    

Please don't use hf_helen_length for anything other than an actual length field.  Each field in the packet should 
have its *own* hf_ value.

Once you've started using the tvb_get_ routines, and the offset variable, to process the fields, and have given each 
field its own hf_ value, then:

The hf_ item for the time stamp should be something like

      { &hf_helen_time,
          { "Time", "helen.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0, "Time", HFILL}},

If you want to display the times as UTC, then the way you'd do this depends on the version of Wireshark you're using.

Wireshark 1.0.x or 1.2.x:

You would add that field to the packet by doing something such as

      nstime_t t;
      guint64 msecs_since_the_epoch;
      struct tm *tmp;
      static const char *mon_names[12] = {
              "Jan",
              "Feb",
              "Mar",
              "Apr",
              "May",
              "Jun",
              "Jul",
              "Aug",
              "Sep",
              "Oct",
              "Nov",
              "Dec"
      };

      msecs_since_the_epoch = tvb_get_ntoh64(tvb, offset);
      t.secs = msecs_since_the_epoch/1000;
      t.nsecs = (msecs_since_the_epoch%1000)*1000000; /* milliseconds to nanoseconds */
      tmp = gmtime(&t.secs);
      proto_tree_add_time_format_value(helen_sub_tree, hf_helen_time, tvb, offset, 8, &t,
          "%s %2d, %d %02d:%02d:%02d.%09ld UTC",
          mon_names[tmp->tm_mon],
          tmp->tm_mday,
          tmp->tm_year + 1900,
          tmp->tm_hour,
          tmp->tm_min,
          tmp->tm_sec,
          (long)t.nsecs);

Current top-of-tree Wireshark:

You would have the hf_ item be something like

      { &hf_helen_time,
          { "Time", "helen.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, "Time", HFILL}},

and do something like

      nstime_t t;
      guint64 msecs_since_the_epoch;

      msecs_since_the_epoch = tvb_get_ntoh64(tvb, offset);
      t.secs = msecs_since_the_epoch/1000;
      t.nsecs = (msecs_since_the_epoch%1000)*1000000; /* milliseconds to nanoseconds */
      proto_tree_add_time(helen_sub_tree, hf_helen_time, tvb, offset, 8, &t);

If you want to display the time as local time (in the time zone of the machine running Wireshark), that's a bit 
easier.
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev () wireshark org>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-request () wireshark org?subject=unsubscribe
  
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev () wireshark org>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-request () wireshark org?subject=unsubscribe


Current thread: