[Snort-devel] plugbase.c timezone BUG and timestamp functions with millisecs

Marcus Janoski mjanoski at ...2142...
Tue Feb 24 06:57:09 EST 2004


Hey all, thanks for all the great work on snort.

In trying to use the 2.x versions in my environment (Solaris 9 and 
Postgres) there were some issues with formatting the timestamp.

database: postgresql_error: ERROR:  Bad timestamp  external 
representation '2004-02-20 18:55:46-32115'

In src/plugbase.c the GetLocalTimezone function uses gettimeofday() to 
get the timezone.
The timezone part of the call is no longer supported in Solaris or Linux 
for that matter.

Solaris man page:
     The second argument to gettimeofday() and settimeofday()  is ignored.
Linux Man page:
       The use of the timezone struct is obsolete; the tz_dsttime field  
has  never  been used
       under Linux - it has not been and will not be supported by  libc  
or  glibc.   Each  and
       every occurrence of this field in the kernel source (other than 
the declaration) is a bug.
       Thus,  the  following  is purely of historic interest.

I changed it to

int GetLocalTimezone()
{
    time_t ut;
    struct tm * ltm;

    time(&ut);
    ltm = localtime(&ut);
    return  timezone/3600;
}

Also with what started as just checking all the timezone stuff  I added 
millseconds to the timestamp
routines (GetTimestamp and GetCurrentTimestamp) and made some changes in 
spo_database.c for Postgres.

Following is the diff of all changes to src/plugbase.h.

$diff  plugbase.h.orig plugbase.h
198c198
< char *GetTimestamp(time_t *, int);
---
 > char *GetTimestamp(register const struct timeval *, int);

Following is the diff of all changes to src/plugbase.c.

$diff  plugbase.c.orig plugbase.c
1059c1059
<  * Function: GetTimestamp(time_t * tv_sec, int tz)
---
 >  * Function: GetTimestamp(register const struct timeval *tvp, int tz)
1061c1061
<  * Purpose: Get an ISO-8601 formatted timestamp for tv_sec within the tz
---
 >  * Purpose: Get an ISO-8601 formatted timestamp for tvp within the tz
1064c1064
<  * Arguments: tv_sec is a time_t pointer. tz is a timezone.
---
 >  * Arguments: tvp is a timeval pointer. tz is a timezone.
1069c1069
< char *GetTimestamp(time_t * tv_sec, int tz)
---
 > char *GetTimestamp(register const struct timeval *tvp, int tz)
1071c1071
<     struct tm *time;
---
 >     struct tm *lt;
1072a1073
 >     int msec;
1075a1077
 >     msec = tvp->tv_usec/1000;
1077,1081d1078
<         time = gmtime(tv_sec);
<     else
<         time = localtime(tv_sec);
<
<     if(tz < 0)
1083,1085c1080,1083
<         snprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i%03i",
<                  1900 + time->tm_year, time->tm_mon + 1, time->tm_mday,
<                  time->tm_hour, time->tm_min, time->tm_sec, tz);
---
 >         lt = gmtime((time_t *)&tvp->tv_sec);
 >         snprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i",
 >                 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
 >                 lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
1089,1091c1087,1092
<         snprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i+%02i",
<                  1900 + time->tm_year, time->tm_mon + 1, time->tm_mday,
<                  time->tm_hour, time->tm_min, time->tm_sec, tz);
---
 >         lt = localtime((time_t *)&tvp->tv_sec);
 >
 >         snprintf(buf, SMALLBUFFER,
 >                 "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
 >                 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
 >                 lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz);
1110,1111c1111,1112
<     struct timezone tz;
<     struct timeval tv;
---
 >     time_t ut;
 >     struct tm * ltm;
1113,1116c1114,1116
<     gettimeofday(&tv,&tz);
<
<     if(tz.tz_minuteswest > 720) return(24 - tz.tz_minuteswest/60);
<     else          return(0 - tz.tz_minuteswest/60);
---
 >     time(&ut);
 >     ltm = localtime(&ut);
 >     return  timezone/3600;
1137a1138
 >     int msec;
1143a1145
 >     msec = tvp->tv_usec/1000;
1147,1149c1149,1151
<         snprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i",
<                 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
<                 lt->tm_hour, lt->tm_min, lt->tm_sec);
---
 >         snprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i",
 >                 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
 >                 lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
1157,1166c1159,1162
<         if(tzone < 0)
<             snprintf(buf, SMALLBUFFER,
<                     "%04i-%02i-%02i %02i:%02i:%02i%03i",
<                     1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
<                     lt->tm_hour, lt->tm_min, lt->tm_sec, tzone);
<         else
<             snprintf(buf, SMALLBUFFER,
<                     "%04i-%02i-%02i %02i:%02i:%02i+%02i",
<                     1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
<                     lt->tm_hour, lt->tm_min, lt->tm_sec, tzone);
---
 >         snprintf(buf, SMALLBUFFER,
 >                 "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
 >                 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
 >                 lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tzone);

Following is the diff of all changes to src/plugbase.c.

$diff spo_database.c.orig spo_database.c
953c953
<         timestamp_string = GetTimestamp((time_t *)&p->pkth->ts.tv_sec, 
data->t
z);
---
 >         timestamp_string = GetTimestamp((struct timeval *) & 
p->pkth->ts, data
->tz);
959c959,976
<
---
 > #ifdef ENABLE_POSTGRESQL
 >     if( data->shared->dbtype_id == DB_POSTGRESQL ){
 >         /* From Posgres Documentation
 >          * For timestamp with time zone, the internally stored
 >          * value is always in UTC (GMT). An input value that has
 >          * an explicit time zone specified is converted to UTC
 >          * using the appropriate offset for that time zone. If no
 >          * time zone is stated in the input string, then it is assumed
 >          * to be in the time zone indicated by the system's TimeZone
 >          * parameter, and is converted to UTC using the offset for
 >          * the TimeZone zone
 >          */
 >         if( timestamp_string!=NULL && strlen(timestamp_string)>24 )
 >         {
 >             timestamp_string[23] = '\0';
 >         }
 >     }
 > #endif

I hope this helps :). I have only tested Postgres on Solaris and  Linux 
with and without the -U flag

Thanks,

Marcus Janoski


Bug reports should be sent to roesch at ...835... and cc'd to
snort-devel at lists.sourceforge.net (Snort Developers mailing list) and
Jeremy Hewlett <jh at ...402...>.








More information about the Snort-devel mailing list