On Tue, Dec 6, 2011 at 9:52 AM, Guy Harris <[email protected]> wrote: > > On Dec 6, 2011, at 12:21 AM, Yegor Yefremov wrote: > >> In CANOpen protocol there is a packet type TIME_STAMP. It is >> constructed in the following way: >> >> 1. first 4 bytes are milliseconds since midnight, but in LSB first >> form (0x10 0x20 0x30 0x40 is actually 0x40 0x30 0x20 0x10) >> 2. next 2 bytes are days since 01.01.1984 > > OK, that's about 179 years, so it's not *too* badly non-future-proof. :-) > >> Is there some build-in method to get milliseconds without changing the >> byte order? > > tvb_get_ntohl() fetches a 4-byte big-endian value. "n" stands for "network > byte order", meaning "big-endian". > > I know of no term similar to "network byte order" for little-endian, so the > routine to fetch a 4-byte little-endian value is called tvb_get_letohl(). > That's the routine you want. > > If the days-since-1984-01-01 is also little-endian, you'd want > tvb_get_letohs() ("s" for "short", as in "16-bit integer in C on 32-bit and > 64-bit platforms", just as it's "l" for "long", as in "32-bit integer in C on > most if not all 32-bit platforms - 64-bit C platforms first showed up long > after the Berkeley folks, or whoever introduced ntohs(), ntohl(), etc. added > them to UN*X, so it's not really 'long' on a lot of machines these days". I > suppose you could argue that they should be tvb_get_betoh16(), > tvb_get_betoh24(), tvb_get_betoh32(), tvb_get_betoh48(), tvb_get_betoh64(), > tvb_get_letoh16(), tvb_get_letoh24(), etc..) > >> What is the OS independent way to get UTC date from milliseconds (I >> guess I'll also need to make correction related to 1970)? > > Yes - the "days since 01.01.1984" is actually far more significant (in both > the conversational and mathematical senses of "significant") than the > "milliseconds since midnight" if you're trying to convert it to a date! > > Is that 1984-01-01 at the Greenwich Meridian, or is that 1984-01-01 in local > time? > > If it's at the Greenwich Meridian, then you take the "days since 01.01.1984" > value, add to it the number of days between 1970-01-01 and 1984-01-01 (to > convert it to days since 1970-01-01 - for at least a little future-proofing, > do that in a 32-bit integer), multiply that by 86400 to convert it to seconds > (we don't worry about leap seconds here - the POSIX spec requires that they > be treated in a somewhat bizarre manner, whether any UN*X systems actually do > so or not), and put that into the "secs" field of an nstime_t structure as > defined in <epan/nstime.h> in the Wireshark source. > > Then take the milliseconds-since-midnight value, multiply it by 1000000 to > convert it to nanoseconds, and put that into the "nsecs" field of the > nstime_t. > > You can then use that nstime_t to add an FT_ABSOLUTE_TIME field into the > protocol tree for those 6 bytes. (It will be displayed as if it had > nanosecond resolution, with a whole bunch of bogus zeroes after the least > significant digit, which is not ideal; we need to come up with a better way > to handle that.) > > If it's 1984-01-01 in local time, let us know; it's getting late and my > brain's beginning to overheat from several hours spent beating libpcap and > Wireshark's capture dialog box over the head to handle an annoying issue with > monitor mode and libpcap on at least some Linux distributions (Debian and its > derivatives, possibly others if they have libpcap 1.0.x or have libpcap 1.1.x > and it's not linked with libnl), so I'll think about how best to handle local > time, if necessary, later.
Thanks for this explanation. I have implemented everything so far. The issue left is milliseconds conversion. AFAIK nsec is an int value, so it is not enough even for a second :-( Yegor ___________________________________________________________________________ Sent via: Wireshark-dev mailing list <[email protected]> Archives: http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:[email protected]?subject=unsubscribe
