tcpdump mailing list archives

Re: Some Win32 code for timed captures


From: "Vincent Fatica" <vefatica () syr edu>
Date: Wed, 18 Feb 2004 20:07:44 -0500

On 18 Feb 2004 at 11:27, Rob Quinn wrote:

To suit my purposes, I added some Win32 code to tcpdump.c which allows 
the user to specify a capture duration as
    -g hhmmss

 I suggested a similar change last Nov, and I posted some patches (that
apparently didn't work under Win32) that prompted a code change from Guy
Harris.  But then nothing seemed to happen.  Did anyone respond to your email?

You're the first, Rob.  I don't have a clue how this would be done under
UNIX.  I suppose the "wait" functions would have to be os-specific.
My windump.exe has been running for over a week, wrapped in a batch
file which restarts it each hour (using the "-g yyyymmddhhmmss" (run until)
option) and which produces an hourly report.  As I said before, it simply works
for my purposes.  I'm running it on XP; it should run on earlier NT's (and not on
Windows9x) but it has not been tested elsewhere.  Here's the code I used,
with a bit of explanation.  I apologize for the crude format ... I don't have and
I'm not up on the use of the diff utils.  

/* This must appear before #include <tcpdump-stdinc.h> */

#ifdef WIN32
#define _WIN32_WINNT 0x0400
#endif /* WIN32 */

****************************

/* globals */
#ifdef WIN32
int gflag = 0;          /* gflag: duration or ending date/time specified */
void timer_thread( void* );
__int64 DecipherTimeArg (char*);
#endif /* WIN32 */

****************************

/*In main: */

/* decls */
#ifdef WIN32
        __int64 i64EndSpec;
        HANDLE hTimer;
#endif /* WIN32 */

/* later ... inside the WIN32 ifdef ... add the "g:" option */

        (op = getopt(argc, argv, "aAB:c:C:dDeE:fF:g:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1)

/* later ... */

#ifdef WIN32
                case 'g' :
                        if ( gflag ) error("-g may be specified only once");
                        gflag = 1;
                        i64EndSpec = DecipherTimeArg(optarg);
                        break;
#endif /* WIN32 */

/* later ... after the arg-parsing loop ... */

#ifdef WIN32
        if ( gflag ) {
                if ( !i64EndSpec )
                        error("duration incorrectly specified or not greater than 0");
                if ( !(hTimer = CreateWaitableTimer(NULL, TRUE, NULL)) )
                        error("failed to create waitable timer");
                if ( !SetWaitableTimer(hTimer, (LARGE_INTEGER*) &i64EndSpec, 0, NULL, NULL, FALSE) )
                        error("failed to set waitable timer");
                if ( _beginthread(timer_thread, 65536, &hTimer) == -1L )
                        error("failed to create timer thread");
        }
#endif /* WIN32 */

******************************

/* In usage(), add the "-g" option .... */

#ifdef WIN32
"Usage: %s [-aAdDeflnNOpqRStuvxX] [-B size] [-c count] [-C file_size]\
\n\t\t[ -g hhmmss | yyyymmddhhmmss ]\n", program_name);
/* et c. */

******************************

/* And the two necessary functions: */

/* Change project settings to use multi-threaded libs (/MT) */

#ifdef WIN32
void timer_thread( void *pArg )
{
        WaitForSingleObject ( *((HANDLE*) pArg) ), INFINITE );
        CloseHandle ( *((HANDLE*) pArg) );
        raise ( SIGINT );
}

/* Below, the members of SYSTEMTIME are WORDs (unsigned 16-bit).  So the
checks for <100 and <60 rule out strings with negative signs (like "00-500").
System times are UTC; thus all the messing around in the "else" clause. The
user can specify a duration as HHSSMM, or an end-time as YYYYMMDDHHMMSS.
In the "else" clause, SystemTimeToFileTime() serves as a check, failing (FALSE)
without a *valid* date/time specification. Positive return values specify an
absolute end time; negative values, a relative time (a duration). This return
value is passed, as is, to SetWaitableTimer(). */

__int64 DecipherTimeArg( char* szTimeString )
{
        SYSTEMTIME st = {0};
        __int64 i64TimeSpec100ns = 0, ftNowUtc, ftNowLocal, ftEndLocal;
        int len = strlen(szTimeString);

        /* dureation specified as hhmmss */
        if ( len == 6 && sscanf( szTimeString, "%2d%2d%2d", &st.wHour, &st.wMinute, &st.wSecond ) == 3 
                        && st.wHour < 100 && st.wMinute < 60 && st.wSecond < 60 )
                i64TimeSpec100ns = (__int64) -10000000 * ( 3600 * st.wHour + 60 * st.wMinute + st.wSecond );

        /* end-time specified as yyyymmddhhmmss */
        else if ( len == 14 && sscanf( szTimeString, "%4d%2d%2d%2d%2d%2d",
                        &st.wYear, &st.wMonth, &st.wDay, &st.wHour, &st.wMinute, &st.wSecond ) == 6
                                && SystemTimeToFileTime( &st, (FILETIME*) &ftEndLocal ) ) {
                GetSystemTimeAsFileTime( (FILETIME*) &ftNowUtc );
                FileTimeToLocalFileTime( (FILETIME*) &ftNowUtc, (FILETIME*) &ftNowLocal );
                if ( ftEndLocal > ftNowLocal ) i64TimeSpec100ns = ftNowUtc + (ftEndLocal - ftNowLocal);
        }

        return i64TimeSpec100ns;
}
#endif /* WIN32 */



-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:tcpdump-workers-request () tcpdump org?body=unsubscribe


Current thread: