cfree-diameter

freeDiameter - Event-Timestamp


I just had one question about "Event-Timestamp" AVP.

I know that i should put the epoch time in there, but i mainly concerned about its format, it is what i found in RFC so far:

8.21.  Event-Timestamp AVP

 The Event-Timestamp (AVP Code 55) is of type Time, and MAY be
 included in an Accounting-Request and Accounting-Answer messages to
 record the time that the reported event occurred, in seconds since
 January 1, 1900 00:00 UTC.


Time
  The Time format is derived from the OctetString AVP Base Format.
  The string MUST contain four octets, in the same format as the
  first four bytes are in the NTP timestamp format.  The NTP
  Timestamp format is defined in chapter 3 of [SNTP].

  This represents the number of seconds since 0h on 1 January 1900
  with respect to the Coordinated Universal Time (UTC).

  On 6h 28m 16s UTC, 7 February 2036 the time value will overflow.
  SNTP [SNTP] describes a procedure to extend the time to 2104.
  This procedure MUST be supported by all DIAMETER nodes.

So, the question is should i first get the system current time (in epoch format) and then convert it to string and pass it to Event-Timestamp directly ?

But the standard says: "The string MUST contain four octets".

I dont know how to achieve this ... could you please elaborate on this ?


Solution

  • Well, the problem here is that you have a reference in the RFC you are reading that links you to the NTP rfc for a definition of the NTP timestamp.

    The 4 first bytes of the NTP timestamp show you the integer part (in seconds) from the epoch to the time the timestamp was acquired.

    The time(2) function gives you a time_t value (some architectures have a 64bit time_t, and some have 32, you have to be able to know which one you have) BUT WITH A DIFFERENT EPOCH. This is what you are doing bad. The epoch in NTP is 00:00h 1st/jan/1900 and in UNIX time is 00:00h 1st/jan/1970, so you have to correct for that difference in seconds to compensate for those 70 years difference.

    To convert a unix time() time to NTP seconds, you have to add the constant 2208988800U (be careful, as this constant has to be unsigned in 32bit architectures, as it has the msb on, to not being interpreted as a negative value) to the time_t value, or make your calculations in 64bit mode.

    So, finally, your code should be:

    time_t t = time(NULL);
    time_t t2 = t + 2208988800UL;
    
    bytes[0] = (t2 >> 24) & 0xFF;
    bytes[1] = (t2 >> 16) & 0xFF;
    bytes[2] = (t2 >> 8) & 0xFF;
    bytes[3] = t2 & 0xFF;
    

    (as both timestamps are referred to UTC, no local conversions are needed)