1 /*
2  **      $Id: owamp.h 1089 2012-03-27 02:23:05Z boote $
3  */
4 /************************************************************************
5  *                                                                      *
6  *                             Copyright (C)  2002                      *
7  *                                Internet2                             *
8  *                             All Rights Reserved                      *
9  *                                                                      *
10  ************************************************************************/
11 /*
12  **        File:        owamp.h
13  **
14  **        Author:      Jeff W. Boote
15  **                     Anatoly Karp
16  **
17  **        Date:        Wed Mar 20 11:10:33  2002
18  **
19  **        Description:
20  **        This header file describes the owamp API. The owamp API is intended
21  **        to provide a portable layer for implementing the owamp protocol.
22  */
23 #ifndef        OWAMP_H
24 #define        OWAMP_H
25 
26 /*
27  * Portablility sanity checkes.
28  */
29 #if        HAVE_CONFIG_H
30 #undef PACKAGE_BUGREPORT
31 #undef PACKAGE_NAME
32 #undef PACKAGE_STRING
33 #undef PACKAGE_TARNAME
34 #undef PACKAGE_VERSION
35 
36 #include <owamp/config.h>
37 #endif        /* HAVE_CONFIG_H */
38 
39 #if        !HAVE_ERRNO_H || !HAVE_NETDB_H || !HAVE_STDLIB_H || !HAVE_SYS_PARAM_H
40 #error        Missing Header!
41 #endif
42 
43 #if        !HAVE_GETADDRINFO || !HAVE_SOCKET
44 #error        Missing needed networking capabilities! (getaddrinfo and socket)
45 #endif
46 
47 
48 #if        !HAVE_MALLOC || !HAVE_MEMSET
49 #error        Missing needed memory functions!
50 #endif
51 
52 #ifndef        HAVE___ATTRIBUTE__
53 #define __attribute__(x)
54 #endif
55 
56 #if        defined HAVE_DECL_FSEEKO && !HAVE_DECL_FSEEKO
57 #define fseeko(a,b,c) fseek(a,b,c)
58 #endif
59 
60 #include <limits.h>
61 #include <sys/types.h>
62 #ifdef  HAVE_INTTYPES_H
63 #include <inttypes.h>
64 #endif
65 #include <sys/stat.h>
66 #include <sys/time.h>
67 #include <sys/socket.h>
68 /* sys/param.h defines MIN/MAX on some systems... */
69 #ifdef MIN
70 #undef MIN
71 #endif
72 #ifdef MAX
73 #undef MAX
74 #endif
75 #include <sys/param.h>
76 #include <netdb.h>
77 #include <time.h>
78 
79 /* Deal with needed inttypes.h - hopefully these were already defined... */
80 #ifndef PRIuPTR
81 #if SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG
82 #define	PRIuPTR "lu"
83 #elif SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG_LONG
84 #define PRIuPTR "llu"
85 #else
86 #error "Need real PRIuPTR defined by inttypes.h on this system"
87 #endif
88 #endif  /* PRIuPTR */
89 
90 #ifndef PRIu64
91 #if SIZEOF_UINT64_T == SIZEOF_UNSIGNED_LONG
92 #define	PRIu64 "lu"
93 #elif SIZEOF_UINT64_T == SIZEOF_UNSIGNED_LONG_LONG
94 #define PRIu64 "llu"
95 #else
96 #error "Need real PRIu64 defined by inttypes.h on this system"
97 #endif
98 #endif  /* PRIu64 */
99 
100 #ifndef        False
101 #define        False        (0)
102 #endif
103 #ifndef        True
104 #define        True        (!False)
105 #endif
106 
107 #ifndef MIN
108 #define MIN(a,b) ((a<b)?a:b)
109 #endif
110 #ifndef MAX
111 #define MAX(a,b) ((a>b)?a:b)
112 #endif
113 
114 #include <I2util/util.h>
115 
116 /*
117  * Filename/path component macros used by various parts of owamp.
118  */
119 #ifndef OWP_PATH_SEPARATOR
120 #define OWP_PATH_SEPARATOR        "/"
121 #endif
122 #ifndef OWP_PATH_SEPARATOR_LEN
123 #define OWP_PATH_SEPARATOR_LEN        1
124 #endif
125 #ifndef OWP_FILE_EXT
126 #define OWP_FILE_EXT        ".owp"
127 #endif
128 
129 /*
130  * The ascii decimal encoding of the 64 bit timestamps takes this many
131  * chars. Log(2^64)
132  *
133  * fmt indicates 0 padding, 20 significant digits.
134  */
135 #ifndef OWP_TSTAMPFMT
136 #define OWP_TSTAMPFMT  "%020" PRIu64
137 #endif
138 
139 #ifndef OWP_TSTAMPCHARS
140 #define OWP_TSTAMPCHARS  20
141 #endif
142 
143 /*
144  * Char used between start_end.owp files.
145  */
146 #ifndef OWP_NAME_SEP
147 #define OWP_NAME_SEP    "_"
148 #endif
149 
150 
151 #include <owamp/rijndael-api-fst.h>
152 
153 /* Default mode offered by the server */
154 #define OWP_DEFAULT_OFFERED_MODE         (OWP_MODE_OPEN|OWP_MODE_AUTHENTICATED|OWP_MODE_ENCRYPTED)
155 
156 /*
157  * IANA 'blessed' port number for OWAMP
158  */
159 #define OWP_CONTROL_SERVICE_NAME        "861"
160 
161 /*
162  * Default value to use for the listen backlog. We pick something large
163  * and let the OS truncate it if it isn't willing to do that much.
164  */
165 #define OWP_LISTEN_BACKLOG        (64)
166 
167 /*
168  * OWPNum64 is interpreted as 32bits of "seconds" and 32bits of
169  * "fractional seconds".
170  * The byte ordering is defined by the hardware for this value. 4 MSBytes are
171  * seconds, 4 LSBytes are fractional. Each set of 4 Bytes is pulled out
172  * via shifts/masks as a 32bit unsigned int when needed independently.
173  *
174  * sync/multiplier/scale are defined as in Section 5.1 of
175  * draft-ietf-ippm-owdp-05.txt:
176  * If sync is non-zero, then the party generating the timestamp claims to
177  * have an external source of synchronization to UTC.
178  * multiplier and scale are used to indicate the estimated error of
179  * owptime.
180  * They are interpreted as follows:
181  * multiplier*(2^(-32))*(2^Scale)
182  *
183  * (implementor note)
184  * Effectively, this breaks down such that if Scale is 0, then the multiplier
185  * is the error in the same scale as the fractional seconds of owptime.
186  * Therefore, for "real" errors greater than an 8 bit number at that scale
187  * the value can just be right shifted until it fits into an 8 bit integer,
188  * and the number of shifts would indicate the "Scale" value.
189  */
190 typedef uint64_t OWPNum64;
191 
192 /*
193  * Arithmetic/Conversion functions on OWPNum64 numbers.
194  */
195 
196 /*
197  * These macros should be used instead of directly using
198  * arithmetic on these types in the event that the underlying
199  * type is changed from an uint64_t to some kind of structure.
200  *
201  */
202 #define OWPNum64Add(x,y)    (x+y)
203 #define OWPNum64Sub(x,y)    (x-y)
204 #define OWPNum64Cmp(x,y)    ((x<y)?\
205         (-1):\
206         ((x>y)?1:0))
207 #define OWPNum64Diff(x,y)   ((x>y)?\
208         (x-y):\
209         (y-x))
210 #define OWPNum64Min(x,y)    MIN(x,y)
211 #define OWPNum64Max(x,y)    MAX(x,y)
212 
213 extern OWPNum64
214 OWPNum64Mult(
215         OWPNum64    x,
216         OWPNum64    y
217         );
218 
219 extern OWPNum64
220 OWPULongToNum64(
221         uint32_t   from
222         );
223 
224 
225 extern void
226 OWPNum64ToTimeval(
227         struct timeval  *to,
228         OWPNum64        from
229         );
230 
231 extern void
232 OWPTimevalToNum64(
233         OWPNum64        *to,
234         struct timeval  *from
235         );
236 
237 extern void
238 OWPNum64ToTimespec(
239         struct timespec *to,
240         OWPNum64        from
241         );
242 
243 extern void
244 OWPTimespecToNum64(
245         OWPNum64        *to,
246         struct timespec *from
247         );
248 
249 extern double
250 OWPNum64ToDouble(
251         OWPNum64    from
252         );
253 
254 extern OWPNum64
255 OWPDoubleToNum64(
256         double      from
257         );
258 
259 extern OWPNum64
260 OWPUsecToNum64(
261         uint32_t   usec
262         );
263 
264 /*
265  * These structures are opaque to the API user.
266  * They are used to maintain state internal to the library.
267  */
268 typedef struct OWPContextRec    *OWPContext;
269 typedef struct OWPControlRec    *OWPControl;
270 
271 /*
272  * Timestamp related types and structures needed throughout.
273  */
274 
275 typedef struct OWPTimeStampRec{
276     OWPNum64    owptime;
277     uint8_t    sync;
278     uint8_t    multiplier;
279     uint8_t    scale;
280 } OWPTimeStamp;
281 
282 
283 /* Codes for returning error severity and type. */
284 /* values are mapped to syslog "priorities" we want to use. */
285 typedef enum {
286     OWPErrFATAL=3,
287     OWPErrWARNING=4,
288     OWPErrINFO=6,
289     OWPErrDEBUG=7,
290     OWPErrOK=8
291 } OWPErrSeverity;
292 
293 typedef enum {
294     OWPErrUNKNOWN=0,
295     OWPErrPOLICY,
296     OWPErrINVALID,
297     OWPErrUNSUPPORTED
298 } OWPErrType;
299 
300 
301 /*
302  * Valid values for "accept" - this will be added to for the purpose of
303  * enumerating the reasons for rejecting a session, or early termination
304  * of a test session.
305  */
306 typedef enum{
307     OWP_CNTRL_INVALID=-1,           /* No value yet                     */
308     OWP_CNTRL_ACCEPT=0,             /* ok                               */
309     OWP_CNTRL_REJECT=1,             /* reject for any reason            */
310     OWP_CNTRL_FAILURE=2,            /* internal failure                 */
311     OWP_CNTRL_UNSUPPORTED=3,        /* request functionality unsupported */
312     OWP_CNTRL_UNAVAILABLE_PERM=4,   /* Permanent resource limitation    */
313     OWP_CNTRL_UNAVAILABLE_TEMP=5    /* Temporary resource limitation    */
314 } OWPAcceptType;
315 
316 typedef intptr_t    OWPBoolean;
317 typedef uint8_t     OWPSID[16];
318 typedef uint8_t     OWPSequence[4];
319 
320 /*
321  * technically the username in the client greeting message can have uint8_t
322  * but this implementation limits it to a valid "char" type.
323  */
324 #define OWP_USERID_LEN        80
325 typedef char        OWPUserID[OWP_USERID_LEN+1];        /* add 1 for '\0' */
326 
327 
328 #define OWP_MODE_UNDEFINED      (0)
329 #define OWP_MODE_OPEN           (01)
330 #define OWP_MODE_AUTHENTICATED  (02)
331 #define OWP_MODE_ENCRYPTED      (04)
332 #define OWP_MODE_DOCIPHER       (OWP_MODE_AUTHENTICATED|OWP_MODE_ENCRYPTED)
333 
334 typedef uint32_t        OWPSessionMode;
335 
336 typedef enum {
337     OWPSlotUnspecifiedType = -1,        /* invalid value        */
338     OWPSlotRandExpType = 0,
339     OWPSlotLiteralType = 1
340 } OWPSlotType;
341 
342 typedef struct{
343     OWPSlotType slot_type;
344     OWPNum64    mean;
345 } OWPSlotRandExp;
346 
347 typedef struct{
348     OWPSlotType slot_type;
349     OWPNum64    offset;
350 } OWPSlotLiteral;
351 
352 /*
353  * For now - all current slot types are of the exact same format, and
354  * the "time" element can be interpreted as the mean_delay between packets
355  * for the purposes of bandwidth calculations. If that is ever not true,
356  * this type should be removed, and any code that uses it will need to
357  * have a switch statement to do whatever is appropriate for each individual
358  * slot type.
359  */
360 typedef struct{
361     OWPSlotType slot_type;
362     OWPNum64    mean_delay;
363 } OWPSlotAny;
364 
365 typedef union OWPSlotUnion{
366     OWPSlotType     slot_type;
367     OWPSlotRandExp  rand_exp;
368     OWPSlotLiteral  literal;
369     OWPSlotAny      any;
370 } OWPSlot;
371 
372 typedef struct{
373     OWPNum64    start_time;
374     OWPNum64    loss_timeout;
375     uint32_t    typeP;
376     uint32_t    packet_size_padding;
377     uint32_t    npackets;
378     uint32_t    nslots;
379     OWPSlot     *slots;
380 } OWPTestSpec;
381 
382 typedef uint32_t OWPPacketSizeT;
383 
384 /*
385  * an OWPScheduleContextRec is used to maintain state for the schedule
386  * generator. Multiple contexts can be allocated to maintain multiple
387  * "streams" of schedules.
388  */
389 typedef struct OWPScheduleContextRec        *OWPScheduleContext;
390 
391 OWPScheduleContext
392 OWPScheduleContextCreate(
393         OWPContext      ctx,
394         OWPSID          sid,
395         OWPTestSpec     *tspec
396         );
397 
398 void
399 OWPScheduleContextFree(
400         OWPScheduleContext  sctx
401         );
402 
403 OWPErrSeverity
404 OWPScheduleContextReset(
405         OWPScheduleContext  sctx,
406         OWPSID              sid,
407         OWPTestSpec         *tspec
408         );
409 
410 OWPNum64
411 OWPScheduleContextGenerateNextDelta(
412         OWPScheduleContext  sctx
413         );
414 void
415 OWPScheduleContextFree(
416         OWPScheduleContext  sctx
417         );
418 
419 /*
420  * These functions expose the exponential deviates for the exponential
421  * distribution used to generate send schedules.
422  */
423 typedef struct OWPExpContextRec *OWPExpContext;
424 
425 OWPExpContext
426 OWPExpContextCreate(
427         OWPContext      ctx,
428         uint8_t        seed[16]
429         );
430 OWPNum64
431 OWPExpContextNext(
432         OWPExpContext   exp
433         );
434 
435 void
436 OWPExpContextFree(
437         OWPExpContext   exp
438         );
439 
440 
441 /*
442  * Error Reporting:
443  *
444  * Notice that this macro expands to multiple statements so it is
445  * imperative that you enclose it's use in {} in single statement
446  * context's such as:
447  *         if(test)
448  *                 OWPError(...);        NO,NO,NO,NO!
449  * Instead:
450  *         if(test){
451  *                 OWPError(...);
452  *         }
453  *
454  *
455  * (Sure would be nice if it were possible to to vararg macros...)
456  */
457 #define OWPError        I2ErrLocation_(__FILE__,__DATE__,__LINE__);        \
458     OWPError_
459 
460 /*
461  * Don't call this directly - use the OWPError macro.
462  *         Let me repeat.
463  * Don't call this directly - use the OWPError macro.
464  */
465 extern void
466 OWPError_(
467         OWPContext      ctx,
468         OWPErrSeverity  severity,
469         OWPErrType      etype,
470         const char      *fmt,
471         ...
472         );
473 
474 /*
475  * The "context"  is used to basically initialize the library. There is no
476  * "global" state - so you can create more than one "context" if you like.
477  * (Well... SIGPIPE is disabled... I suppose that is global.)
478  *
479  * There are specific defaults that can be modified within the context by
480  * calling the OWPContextConfigSet{F,V} function with the following keys and
481  * types. (The key is a string - the type indicates what type of data
482  * will be stored/retrieved using that key.
483  * The 'F' version is for setting/getting functions and the 'V' version
484  * is for values. (The C standard does not allow us to treat them
485  * generically - I suppose I could have exposed a union, but this
486  * seems easier.)
487  */
488 
489 /*
490  * This typedef is used for the "generic" type of all function pointer
491  * types. (void *) is used for the 'value' equivalent.
492  */
493 
494 typedef void (*OWPFunc)(void);
495 
496 /*
497  * This type is used to hold a pointer to an integer pointer. That pointer
498  * points at a value that determines if the low/level i/o functions should
499  * return on interrupt. If it is non-zero an interrupt will cause the i/o
500  * routine to fail and return. If it is zero, the low level i/o routine will
501  * ignore the interrupt and restart the i/o.
502  * (this can be used to ignore some signals and return on others.)
503  */
504 #define OWPInterruptIO                "OWPInterruptIO"
505 
506 /*
507  * This type is used to hold a pointer to a port-range record. This
508  * record is used to indicate what port ranges should be used for
509  * opening test connections.
510  */
511 #define        OWPTestPortRange        "OWPTestPortRange"
512 typedef        struct OWPPortRangeRec{
513     uint16_t       low;
514     uint16_t       high;
515 } OWPPortRangeRec, *OWPPortRange;
516 
517 /*
518  * This type is used to define the function that retrieves the shared
519  * secret from whatever key-store is in use.
520  * It should return True if it is able to returnfill in the key_ret variable that
521  * is passed in from the caller. False if not. If the function returns false,
522  * the caller should check the err_ret value. If OK, then the userid simply
523  * didn't exist - otherwise it indicates an error in the key store mechanism.
524  *
525  * If an application doesn't set this, Encrypted and Authenticated
526  * mode will be disabled.
527  *
528  * The 'pf_free' pointer will be set to the memory block allocated for pf
529  * if the caller needs to free the memory after calling this function.
530  * (Different pass-phrase stores use different memory models. The returned
531  * pf value should NOT be freed directly!)
532  */
533 #define        OWPGetPF                "OWPGetPF"
534 typedef OWPBoolean      (*OWPGetPFFunc)(
535         OWPContext      ctx,
536         const OWPUserID userid,
537         uint8_t         **pf,
538         size_t          *pf_len,
539         void            **pf_free,  /* If implementation uses dynamic memory */
540         OWPErrSeverity  *err_ret
541         );
542 
543 /*
544  * This function will be called from OWPControlOpen and OWPServerAccept
545  * to determine if the control connection should be accepted.
546  * It is called after connecting, and after determining the userid.
547  * On failure, value of *err_ret can be inspected: if > OWPErrWARNING,
548  * this means rejection based on policy, otherwise there was an error
549  * in the function itself.
550  *
551  * If an application doesn't set this, all connections will be allowed.
552  */
553 #define OWPCheckControlPolicy        "OWPCheckControlPolicy"
554 typedef OWPBoolean (*OWPCheckControlPolicyFunc)(
555         OWPControl      cntrl,
556         OWPSessionMode  mode_req,
557         const OWPUserID userid,
558         struct sockaddr *local_sa_addr,
559         struct sockaddr *remote_sa_addr,
560         OWPErrSeverity  *err_ret
561         );
562 
563 /*
564  * This function will be called by OWPRequestTestSession if
565  * one of the endpoints of the test is on the localhost.
566  * If err_ret returns OWPErrFATAL, OWPRequestTestSession/OWPProcessTestSession
567  * will not continue, and return OWPErrFATAL as well.
568  *
569  * Only the IP address values will be set in the sockaddr structures -
570  * i.e. port numbers will not be valid.
571  *
572  * If an application doesn't set this, all tests will be allowed.
573  *
574  * The application can use the "closure" pointer to store data that will
575  * be passed onto the Open/Close and TestComplete functions. The intended
576  * purpose of this pointer is to keep track of resources that are "reserved"
577  * from this function - allowing the other functions to "free" or modify
578  * those resource reservations.
579  */
580 #define OWPCheckTestPolicy        "OWPCheckTestPolicy"
581 typedef OWPBoolean (*OWPCheckTestPolicyFunc)(
582         OWPControl      cntrl,
583         OWPBoolean      local_sender,
584         struct sockaddr *local_sa_addr,
585         struct sockaddr *remote_sa_addr,
586         socklen_t       sa_len,
587         OWPTestSpec     *test_spec,
588         void            **closure,
589         OWPErrSeverity  *err_ret
590         );
591 
592 /*
593  * This function will be called by OWPProcessFetchSession to implement
594  * the 'policy' decision if the fetch request should be allowed.
595  * If err_ret returns OWPErrFATAL, OWPProcessFetchSession
596  * will not continue, and return OWPErrFATAL as well.
597  *
598  * Only the IP address values will be set in the sockaddr structures -
599  * i.e. port numbers will not be valid.
600  *
601  * If an application doesn't set this, all data that is buffered
602  * that can be found, will be returned.
603  *
604  * The application can use the "closure" pointer to store data that will
605  * be passed onto the Open/Close and TestComplete functions. The intended
606  * purpose of this pointer is to keep track of resources that are "reserved"
607  * from this function - allowing the other functions to "free" or modify
608  * those resource reservations.
609  *
610  */
611 #define OWPCheckFetchPolicy        "OWPCheckFetchPolicy"
612 typedef OWPBoolean (*OWPCheckFetchPolicyFunc)(
613         OWPControl      cntrl,
614         struct sockaddr *local_sa_addr,
615         struct sockaddr *remote_sa_addr,
616         socklen_t       sa_len,
617         uint32_t        begin,
618         uint32_t        end,
619         OWPSID          sid,
620         void            **closure,
621         OWPErrSeverity  *err_ret
622         );
623 
624 /*
625  * This function will be called when a test is "complete". It is used
626  * to free resources that were allocated on behalf of the test including
627  * memory associated with the "closure" pointer itself if necessary.
628  */
629 #define OWPTestComplete                "OWPTestComplete"
630 typedef void (*OWPTestCompleteFunc)(
631         OWPControl      cntrl,
632         void            *closure,
633         OWPAcceptType   aval
634         );
635 
636 /*
637  * This function will be called by the test endpoint initialization
638  * code to open a file for writing. It will also be called by the
639  * fetch-session code to open an existing file to return the data
640  * to an application. (fname_ret is PATH_MAX+1 to include a nul byte.)
641  * (if
642  */
643 #define OWPOpenFile                "OWPOpenFile"
644 typedef FILE* (*OWPOpenFileFunc)(
645         OWPControl  cntrl,
646         void        *closure,
647         OWPSID      sid,
648         char        fname_ret[PATH_MAX+1]
649         );
650 
651 /*
652  * This function will be called by the test endpoint "cleanup" code
653  * to indicate that the given fp (from OWPOpenFile) is no longer needed.
654  * This allows the implementation to do it's own cleanup based on policy.
655  * For example, a delete-on-fetch functionality could be implemented here
656  * to delete the given file now that is it no longer needed.
657  */
658 #define OWPCloseFile                "OWPCloseFile"
659 typedef void (*OWPCloseFileFunc)(
660         OWPControl      cntrl,
661         void            *closure,
662         FILE            *fp,
663         OWPAcceptType   aval
664         );
665 
666 #ifndef NDEBUG
667 /*
668  * This integer type is used to aid in child-debugging. If OWPChildWait is
669  * set and non-zero forked off endpoints will go into a busy-wait loop to
670  * allow a debugger to attach to the process. (i.e. they will be hung until
671  * attached and the loop variable modified with the debugger. This should
672  * not strictly be needed, but the gdb on many of the test plateforms I
673  * used did not implement the follow-fork-mode option.) This was a quick
674  * fix. (This will not be used if owamp is compiled with -DNDEBUG.)
675  */
676 #define OWPChildWait        "OWPChildWait"
677 #endif
678 
679 /*
680  * If this variable is set in the context, send/recv children processes
681  * are directed to detach from the process group. (This is useful to
682  * catch ^C from a shell in the parent process without having the
683  * SIGINT being sent to the children processes. By doing this, it is
684  * possible to gracefully shutdown an owamp test session in response
685  * to SIGINT.)
686  */
687 #define OWPDetachProcesses  "OWPDetachProcesses"
688 
689 /*
690  * Set the 'count' value for the pbkdf2 function.
691  */
692 #define OWPKeyDerivationCount "OWPKeyDerivationCount"
693 
694 /*
695  * Set the 'enddelay' (time for a sender to wait after session completion
696  * to actually send the stop session message).
697  * (double ptr)
698  */
699 #define OWPEndDelay "OWPEndDelay"
700 
701 /*
702  * Use IPv4 addresses only.
703  */
704 #define OWPIPv4Only "OWPIPv4Only"
705 
706 /*
707  * Use IPv6 addresses only.
708  */
709 #define OWPIPv6Only "OWPIPv6Only"
710 
711 extern OWPContext
712 OWPContextCreate(
713         I2ErrHandle eh
714         );
715 
716 extern void
717 OWPContextFree(
718         OWPContext  ctx
719         );
720 
721 extern I2ErrHandle
722 OWPContextErrHandle(
723         OWPContext  ctx
724         );
725 
726 extern OWPBoolean
727 OWPContextConfigSetF(
728         OWPContext  ctx,
729         const char  *key,
730         OWPFunc     func
731         );
732 
733 extern OWPBoolean
734 OWPContextConfigSetV(
735         OWPContext  ctx,
736         const char  *key,
737         void        *value
738         );
739 
740 extern OWPBoolean
741 OWPContextConfigSetU32(
742         OWPContext  ctx,
743         const char  *key,
744         uint32_t    value
745         );
746 
747 extern OWPFunc
748 OWPContextConfigGetF(
749         OWPContext  ctx,
750         const char  *key
751         );
752 
753 extern void*
754 OWPContextConfigGetV(
755         OWPContext  ctx,
756         const char  *key
757         );
758 
759 extern OWPBoolean
760 OWPContextConfigGetU32(
761         OWPContext  ctx,
762         const char  *key,
763         uint32_t    *val
764         );
765 
766 extern OWPBoolean
767 OWPContextConfigDelete(
768         OWPContext  ctx,
769         const char  *key
770         );
771 
772 /*
773  * The following functions are completely analogous to the Context versions
774  * but are used to maintain state information about a particular control
775  * connection.
776  */
777 extern OWPBoolean
778 OWPControlConfigSetF(
779         OWPControl  cntrl,
780         const char  *key,
781         OWPFunc     func
782         );
783 
784 extern OWPBoolean
785 OWPControlConfigSetV(
786         OWPControl  cntrl,
787         const char  *key,
788         void        *value
789         );
790 
791 extern OWPFunc
792 OWPControlConfigGetF(
793         OWPControl  cntrl,
794         const char  *key
795         );
796 
797 extern void*
798 OWPControlConfigGetV(
799         OWPControl  cntrl,
800         const char  *key
801         );
802 
803 extern OWPBoolean
804 OWPControlConfigDelete(
805         OWPControl  cntrl,
806         const char  *key
807         );
808 
809 /*
810  * OWPControlOpen allocates an OWPclient structure, opens a connection to
811  * the OWP server and goes through the initialization phase of the
812  * connection. This includes AES/CBC negotiation. It returns after receiving
813  * the ServerStart message.
814  *
815  * This is typically only used by an OWP client application (or a server
816  * when acting as a client of another OWP server).
817  *
818  * err_ret values:
819  *         OWPErrOK        completely successful - highest level mode ok'd
820  *         OWPErrINFO        session connected with less than highest level mode
821  *         OWPErrWARNING        session connected but future problems possible
822  *         OWPErrFATAL        function will return NULL - connection is closed.
823  *                 (Errors will have been reported through the OWPErrFunc
824  *                 in all cases.)
825  * function return values:
826  *         If successful - even marginally - a valid OWPclient handle
827  *         is returned. If unsuccessful, NULL is returned.
828  *
829  * Once an I2Addr record is passed into this function - it is
830  * automatically free'd and should not be referenced again in any way.
831  *
832  * Client
833  */
834 extern OWPControl
835 OWPControlOpen(
836         OWPContext      ctx,
837         I2Addr          local_addr,     /* src addr or NULL             */
838         I2Addr          server_addr,    /* server addr or NULL          */
839         uint32_t       mode_mask,      /* OR of OWPSessionMode vals    */
840         OWPUserID       userid,         /* null if unwanted             */
841         OWPNum64        *uptime_ret,    /* server uptime - ret or NULL  */
842         OWPErrSeverity  *err_ret
843         );
844 
845 /*
846  * Client and Server
847  */
848 extern OWPErrSeverity
849 OWPControlClose(
850         OWPControl  cntrl
851         );
852 
853 /*
854  * Request a test session - if the function returns True, then the function
855  * returns a valid SID for the session.
856  *
857  * If the function returns False - check err_ret. If err_ret is ErrOK, the
858  * session was denied by the server, and the control connection is still
859  * valid.
860  *
861  * TODO:Add OWPControlStatus(cntrl) function to determine cntrl status...
862  *
863  * Reasons this function will return False:
864  * 1. Server denied test: err_ret==ErrOK
865  * 2. Control connection failure: err_ret == ErrFATAL
866  * 3. Local resource problem (malloc/fork/fdopen): err_ret == ErrFATAL
867  * 4. Bad addresses: err_ret == ErrWARNING
868  *
869  * Once an I2Addr record has been passed into this function, it
870  * is automatically free'd. It should not be referenced again in any way.
871  *
872  * Conversely, the test_spec is completely copied, and the caller continues
873  * to "own" all memory associated with it after this call. (Including
874  * the "slots" array that is part of the test_spec.)
875  *
876  * Client
877  */
878 extern OWPBoolean
879 OWPSessionRequest(
880         OWPControl      control_handle,
881         I2Addr          sender,
882         OWPBoolean      server_conf_sender,
883         I2Addr          receiver,
884         OWPBoolean      server_conf_receiver,
885         OWPTestSpec     *test_spec,
886         FILE            *fp,
887         OWPSID          sid_ret,
888         OWPErrSeverity  *err_ret
889         );
890 
891 /*
892  * Start all test sessions - if successful, returns OWPErrOK.
893  *
894  * Client and Server
895  */
896 extern OWPErrSeverity
897 OWPStartSessions(
898         OWPControl  control_handle
899         );
900 
901 /*
902  * Wait for test sessions to complete. This function will return the
903  * following integer values:
904  *         <0        ErrorCondition
905  *         0        StopSessions received, acted upon, and sent back.
906  *         1        wake_time reached
907  *
908  *        2        system event (signal)
909  *
910  * To effect a poll - specify a waketime in the past. 1 will be returned
911  * if there is nothing to read.
912  *
913  * To use a signal interaction instead of the waketime interface, set the
914  * retn_on_intr pointer. Install a signal handler that sets the value
915  * to non-zero, and this function will return 2. (If wake_time is non-null,
916  * retn_on_intr is not used.) This interface can be used without signal
917  * handlers as well be simply passing in a pointer to a non-zero value.
918  * This function will return for any interrupt. (The signal interface
919  * allows you to set the value to non-zero only for signals you are
920  * actually interested in.)
921  *
922  * To block indefinately, specify NULL for wake_time and NULL for
923  * retn_on_intr. (StopSessionsWait will poll the status of current tests
924  * automatically whenever a system event takes place in this case, so
925  * StopSessionsWait will never return 1 or 2 in this case.)
926  *
927  * If wake_time or retn_on_intr is set, and this function returns 1 or 2, then
928  * it is required to poll the status of each local endpoint using
929  * OWPTestSessionStatus until all sessions complete.  (OWPSessionsActive is
930  * a simple way to poll all of them - you know you are done when it returns 0.)
931  * You can of course recall StopSessionsWait in this case.
932  *
933  * If acceptval returns anything other than OWP_CNTRL_ACCEPT, the
934  * data files associated with the recieve sessions SHOULD be deleted.
935  *
936  * Client and Server
937  */
938 extern int
939 OWPStopSessionsWait(
940         OWPControl      control_handle,
941         OWPNum64        *wake_time,                /* abs time */
942         int             *retn_on_intr,
943         OWPAcceptType   *acceptval,                /* out */
944         OWPErrSeverity  *err_ret
945         );
946 
947 /*
948  * Used to poll the status of a test endpoint.
949  *
950  * returns:
951  *                 True if it could get the status,
952  *                 False if it could not. (session with given sid wasn't found,
953  *                 or "send" indicated a remote endpoint.)
954  *
955  *                 aval returns the following for status:
956  *         <0        Test is not yet complete.
957  *         >=0        Accept value of completed test. 0 indicates success
958  *                 other values indicate type of error test encountered.
959  */
960 extern OWPBoolean
961 OWPSessionStatus(
962         OWPControl      cntrl,
963         OWPSID          sid,        /* SID of test to poll        */
964         OWPAcceptType   *aval        /* out - return accept value        */
965         );
966 
967 /*
968  * Used to determine how many local endpoints are still active.
969  * (effectively calls the OWPTestSessionStatus function on all endpoints
970  * and determines if they are complete yet.)
971  *
972  * If acceptval is non-null it is set to the MAX acceptval of any
973  * complete session.
974  *
975  * returns:
976  *         number of active endpoints.
977  */
978 extern int
979 OWPSessionsActive(
980         OWPControl      cntrl,
981         OWPAcceptType   *acceptval        /* rtn */
982         );
983 
984 /*
985  * Send the StopSession message, and wait for the response.
986  *
987  * Client and Server.
988  */
989 extern OWPErrSeverity
990 OWPStopSessions(
991         OWPControl      control_handle,
992         int             *retn_on_intr,
993         OWPAcceptType   *acceptval        /* in/out */
994         );
995 
996 
997 /*
998  * Return the file descriptor being used for the control connection. An
999  * application can use this to call select or otherwise poll to determine
1000  * if anything is ready to be read but they should not read or write to
1001  * the descriptor.
1002  * This can be used in conjunction with the OWPStopSessionsWait
1003  * function so that the application can recieve user input, and only call
1004  * the OWPStopSessionsWait function when there is something to read
1005  * from the connection. (A nul timestamp would be used in this case
1006  * so that OWPStopSessionsWait does not block.)
1007  *
1008  * This is also useful in a policy context - getpeername can be called
1009  * on this descriptor.
1010  *
1011  * If the control_handle is no longer connected - the function will return
1012  * a negative value.
1013  *
1014  * Client and Server.
1015  */
1016 extern int
1017 OWPControlFD(
1018         OWPControl  control_handle
1019         );
1020 
1021 extern int
1022 OWPErrorFD(
1023         OWPContext  ctx
1024         );
1025 
1026 extern
1027 I2Addr
1028 OWPServerSockCreate(
1029         OWPContext      ctx,
1030         I2Addr          addr,
1031         OWPErrSeverity  *err_ret
1032         );
1033 
1034 
1035 /*!
1036  * Function:        OWPControlAccept
1037  *
1038  * Description:
1039  *                 This function is used to initialiize the communication
1040  *                 to the peer.
1041  *
1042  * In Args:
1043  *                 connfd,connsaddr, and connsaddrlen are all returned
1044  *                 from "accept".
1045  *
1046  * Returns:        Valid OWPControl handle on success, NULL if
1047  *              the request has been rejected, or error has occurred.
1048  *
1049  *              If *rtn_on_intr and an inturrupt happens during write/read
1050  *              err_ret will be set to OWPErrWARNING.
1051  *
1052  *              Return value does not distinguish between illegal
1053  *              requests, those rejected on policy reasons, or
1054  *              errors encountered by the server during execution.
1055  *
1056  * Side Effect:
1057  */
1058 extern OWPControl
1059 OWPControlAccept(
1060         OWPContext      ctx,            /* library context              */
1061         int             connfd,         /* conencted socket             */
1062         struct sockaddr *connsaddr,     /* connected socket addr        */
1063         socklen_t       connsaddrlen,   /* connected socket addr len    */
1064         uint32_t       mode_offered,   /* advertised server mode       */
1065         OWPNum64        uptime,         /* uptime report                */
1066         int             *retn_on_intr,  /* return on i/o interrupt      */
1067         OWPErrSeverity  *err_ret        /* err - return                 */
1068         );
1069 
1070 typedef enum OWPRequestType{
1071     OWPReqInvalid=-1,
1072     OWPReqSockClose=10,
1073     OWPReqSockIntr=11,
1074     OWPReqTest=1,
1075     OWPReqStartSessions=2,
1076     OWPReqStopSessions=3,
1077     OWPReqFetchSession=4
1078 } OWPRequestType;
1079 
1080 extern OWPRequestType
1081 OWPReadRequestType(
1082         OWPControl  cntrl,
1083         int         *retn_on_intr
1084         );
1085 
1086 extern OWPErrSeverity
1087 OWPProcessTestRequest(
1088         OWPControl  cntrl,
1089         int         *retn_on_intr
1090         );
1091 
1092 extern OWPErrSeverity
1093 OWPProcessStartSessions(
1094         OWPControl  cntrl,
1095         int         *retn_on_intr
1096         );
1097 
1098 extern OWPErrSeverity
1099 OWPProcessStopSessions(
1100         OWPControl  cntrl
1101         );
1102 
1103 extern OWPErrSeverity
1104 OWPProcessFetchSession(
1105         OWPControl  cntrl,
1106         int         *retn_on_intr
1107         );
1108 
1109 extern OWPContext
1110 OWPGetContext(
1111         OWPControl  cntrl
1112         );
1113 
1114 extern OWPSessionMode
1115 OWPGetMode(
1116         OWPControl  cntrl
1117         );
1118 
1119 
1120 /*
1121  ** Given the protocol family, OWAMP mode and packet padding,
1122  ** compute the size of resulting full IP test packet.
1123  */
1124 
1125 /*
1126  * Payload size is used to determine how large the buffers need to be
1127  * to read a packet.
1128  */
1129 extern OWPPacketSizeT
1130 OWPTestPayloadSize(
1131         OWPSessionMode  mode,
1132         uint32_t       padding
1133         );
1134 /*
1135  * PacketSize is used to compute the full packet size - this is used to
1136  * determine bandwidth requirements for policy purposes.
1137  */
1138 extern OWPPacketSizeT
1139 OWPTestPacketSize(
1140         int             af,
1141         OWPSessionMode  mode,
1142         uint32_t       padding
1143         );
1144 
1145 /*
1146  * Returns # packets/second: 0.0 on error.
1147  */
1148 extern double
1149 OWPTestPacketRate(
1150         OWPContext      ctx,
1151         OWPTestSpec     *tspec
1152         );
1153 
1154 /*
1155  * Returns bits/second: 0.0 on error.
1156  */
1157 extern double
1158 OWPTestPacketBandwidth(
1159         OWPContext      ctx,
1160         int             af,
1161         OWPSessionMode  mode,
1162         OWPTestSpec     *tspec
1163         );
1164 
1165 extern uint32_t
1166 OWPFetchSession(
1167         OWPControl      cntrl,
1168         FILE            *fp,
1169         uint32_t       begin,
1170         uint32_t       end,
1171         OWPSID          sid,
1172         OWPErrSeverity  *err_ret
1173         );
1174 
1175 /*
1176  ** Processing Session data to/from local disk.
1177  */
1178 typedef enum{
1179     OWP_SESSION_FINISHED_ERROR=0,       /* Invalid session datafile     */
1180     OWP_SESSION_FINISHED_NORMAL=1,      /* Complete datafile            */
1181     OWP_SESSION_FINISHED_INCOMPLETE=2   /* StopSessions did not happen  */
1182 } OWPSessionFinishedType;
1183 
1184 /*
1185  * This data structure is used to read/write a session header. When
1186  * reading a header, if the "header" element returns false, the file
1187  * did not contain any header information, and the remaining fields
1188  * are not valid.
1189  */
1190 typedef struct OWPSessionHeaderRec{
1191     OWPBoolean              header;         /* RO: TestSession header?  */
1192     uint32_t                version;        /* RO: File version         */
1193     uint32_t                rec_size;       /* RO: data record size     */
1194     OWPSessionFinishedType  finished;       /* RW: is session finished?
1195                                                0:no,1:yes,2:unknown     */
1196 
1197     uint32_t                next_seqno;     /* RW: next seq for sender  */
1198     uint32_t                num_skiprecs;   /* RW: nskips               */
1199     uint32_t                num_datarecs;   /* RW: nrecs                */
1200 
1201     off_t                   oset_skiprecs;  /* RO: file offset to skips */
1202     off_t                   oset_datarecs;  /* RO: file offset to data  */
1203     struct stat             sbuf;           /* RO: sbuf of file         */
1204 
1205     uint8_t                 ipvn;           /* RO: ipvn of addrs        */
1206     socklen_t               addr_len;       /* RO: saddr_len of saddrs  */
1207     struct sockaddr_storage addr_sender;    /* RW                       */
1208     struct sockaddr_storage addr_receiver;  /* RW                       */
1209     OWPBoolean              conf_sender;    /* RW                       */
1210     OWPBoolean              conf_receiver;  /* RW                       */
1211     OWPSID                  sid;            /* RW                       */
1212     OWPTestSpec             test_spec;      /* RW                       */
1213 } OWPSessionHeaderRec, *OWPSessionHeader;
1214 
1215 /*
1216  * Write data header to the file.
1217  * Returns:
1218  */
1219 extern OWPBoolean
1220 OWPWriteDataHeader(
1221         OWPContext          ctx,
1222         FILE                *fp,
1223         OWPSessionHeader    hdr
1224         );
1225 
1226 /*
1227  *  OWPWriteDataHeaderNumSkipRecs
1228  * Sets num_skips filed and the oset_skips field. oset_datarecs and
1229  * num_datarecs MUST be set in the file before this call. (Either by
1230  * calling OWPWriteDataHeader with num_datarecs or by calling
1231  * OWPWriteDataHeaderNumDataRecs.)
1232  *
1233  * This funciton should only be called if skip records are being placed
1234  * in the file after datarecs, and then only after the number of datarecs
1235  * has been fixed.
1236  */
1237 extern OWPBoolean
1238 OWPWriteDataHeaderNumSkipRecs(
1239         OWPContext  ctx,
1240         FILE        *fp,
1241         uint32_t   num_skiprecs
1242         );
1243 
1244 /*
1245  *  OWPWriteDataHeaderNumDataRecs
1246  * Sets the num_datarecs field in the file. If oset_skiprecs is nil, this
1247  * function sets that to just beyond the data records.
1248  */
1249 extern OWPBoolean
1250 OWPWriteDataHeaderNumDataRecs(
1251         OWPContext  ctx,
1252         FILE        *fp,
1253         uint32_t   num_datarecs
1254         );
1255 
1256 /*
1257  * Returns:
1258  * number of records in the file. 0 on error. (errno will be set.)
1259  * fp is moved to beginning of data records.
1260  */
1261 extern uint32_t
1262 OWPReadDataHeader(
1263         OWPContext          ctx,
1264         FILE                *fp,
1265         OWPSessionHeader    hdr_ret
1266         );
1267 
1268 /*
1269  * OWPReadDataHeaderSlots
1270  *  This function is used to read the "slots" out of the file. It is only
1271  *  valid for data files of version 2 or above so it is important to check
1272  *  the file version using OWPReadDataHeader before calling this function.
1273  *  OWPReadDataHeader only reads the fixed portion of the TestReq out
1274  *  of the file. OWPReadDataHeader can be used to determine how many slots
1275  *  are in the file, and the caller of this function is required to pass
1276  *  in the memory for "slots".
1277  *
1278  * Returns:
1279  * OWPBoolean - T if successful, F if not.
1280  */
1281 extern OWPBoolean
1282 OWPReadDataHeaderSlots(
1283         OWPContext  ctx,
1284         FILE        *fp,
1285         uint32_t   nslots,
1286         OWPSlot     *slots
1287         );
1288 
1289 /*
1290  * Applications use this type to manipulate individual timestamp data records.
1291  */
1292 typedef struct OWPDataRec {
1293     uint32_t       seq_no;
1294     OWPTimeStamp    send;
1295     OWPTimeStamp    recv;
1296     uint8_t        ttl;
1297 } OWPDataRec;
1298 
1299 /*
1300  * Write data record to a file.
1301  * Returns:
1302  * 0        Success
1303  */
1304 extern OWPBoolean
1305 OWPWriteDataRecord(
1306         OWPContext  ctx,
1307         FILE        *fp,
1308         OWPDataRec  *rec
1309         );
1310 
1311 /*
1312  * This (type of) function is used by Fetch-Client to process
1313  * data records.
1314  *
1315  * The function should return < 0 to indicate an error condition in which
1316  * case OWPParseRecords will return OWPErrFATAL.
1317  * It should return 0 to continue parsing.
1318  * It should return 1 to terminate parsing in which case OWPParseRecords will
1319  * return OWPErrOK.
1320  *
1321  * num_rec can be any number less than or equal to the number of valid
1322  * records in the file reported by OWPReadDataHeader. This function assumes
1323  * the fp is currently pointing at the beginning of a data record.
1324  * (This can be done simply by calling OWPReadDataHeader or fseek'ing to
1325  * the offset reported by OWPReadDataHeader.) Or advancing by some multiple
1326  * of hdr.rec_size.
1327  *
1328  * If OWPParseRecords completes parsing "num_rec" records with out error,
1329  * it will return OWPErrOK.
1330  * If OWPParseRecords is unable to complete parsing because of file i/o problems
1331  * it will return OWPErrFATAL.
1332  */
1333 typedef int (*OWPDoDataRecord)(
1334         OWPDataRec  *rec,
1335         void        *udata
1336         );
1337 
1338 extern OWPErrSeverity
1339 OWPParseRecords(
1340         OWPContext      ctx,
1341         FILE            *fp,
1342         uint32_t       num_rec,
1343         uint32_t       file_version,   /* from OWPReadDataHeader   */
1344         OWPDoDataRecord proc_rec,
1345         void            *udata          /* passed into proc_rec     */
1346         );
1347 
1348 /*
1349  * OWPReadDataSkipRecs
1350  *  This function is used to read the "skips" out of the file. It is only
1351  *  valid for data files of version 2 or above so it is important to check
1352  *  the file version.
1353  *  OWPReadDataHeader can be used to determine how many skips
1354  *  are in the file, and the caller of this function is required to pass
1355  *  in the memory for "skips".
1356  *
1357  *  (For very large session files it may become necessary to create a
1358  *  Parse interface so the entire array does not have to be in memory
1359  *  at one time - but for now I will be wasteful.)
1360  *
1361  * Returns:
1362  * OWPBoolean - T if successful, F if not.
1363  */
1364 typedef struct OWPSkipRec OWPSkipRec, *OWPSkip;
1365 struct OWPSkipRec{
1366     uint32_t   begin;
1367     uint32_t   end;
1368 };
1369 
1370 extern OWPBoolean
1371 OWPReadDataSkips(
1372         OWPContext          ctx,
1373         FILE                *fp,
1374         uint32_t           nskips,
1375         OWPSkip             skips
1376         );
1377 
1378 
1379 extern double
1380 OWPDelay(
1381         OWPTimeStamp    *send_time,
1382         OWPTimeStamp    *recv_time
1383         );
1384 
1385 extern OWPBoolean
1386 OWPIsLostRecord(
1387         OWPDataRec      *rec
1388         );
1389 
1390 extern I2Boolean
1391 OWPParsePortRange (
1392         char    *pspec,
1393         OWPPortRangeRec   *portspec
1394         );
1395 /*
1396  * TODO: This needs lots of clean-up to be a good public interface.
1397  * Most of these fields do not really need to be exposed.
1398  *
1399  * This structure is used to pass into a OWPDoDataRecord function
1400  * that will parse an owd file and generate some statistics.
1401  */
1402 typedef struct OWPPacketRec OWPPacketRec, *OWPPacket;
1403 struct OWPPacketRec{
1404     OWPPacket   next;
1405     uint32_t    seq;        /* packet seq no */
1406     OWPNum64    schedtime;  /* scheduled send time */
1407     uint32_t    seen;       /* how many times seen? */
1408     OWPBoolean  lost;
1409 };
1410 
1411 typedef struct OWPBucketRec OWPBucketRec, *OWPBucket;
1412 struct OWPBucketRec{
1413     OWPBucket   next;
1414     int         b;      /* bucket index */
1415     uint32_t    n;      /* samples in this bucket */
1416 };
1417 
1418 typedef struct OWPStatsRec{
1419 
1420     /*
1421      * Error reporting context
1422      */
1423     OWPContext          ctx;
1424 
1425     /*
1426      * Output values
1427      */
1428     FILE                *output;    /* If set, verbose description of rec's */
1429 
1430     char                fromhost[NI_MAXHOST];
1431     char                fromaddr[NI_MAXHOST];
1432     char                fromserv[NI_MAXSERV];
1433 
1434     char                tohost[NI_MAXHOST];
1435     char                toaddr[NI_MAXHOST];
1436     char                toserv[NI_MAXSERV];
1437 
1438     float               scale_factor;
1439     char                scale_abrv[3];
1440 
1441     /*
1442      * data file information
1443      */
1444     FILE                *fp;
1445     OWPSessionHeaderRec hdr_rec;
1446     OWPSessionHeader    hdr;    /* file header                          */
1447     OWPSkip             skips;
1448     long int            iskip;
1449 
1450     /*
1451      * TestSession information
1452      */
1453     OWPScheduleContext  sctx;
1454     uint32_t            isctx;      /* index for next seq_no */
1455     OWPNum64            endnum;     /* current sched time for (isctx-1) */
1456 
1457     OWPNum64            start_time; /* send time for first scheduled packet */
1458     OWPNum64            end_time;   /* send time for last scheduled packet */
1459 
1460     /*
1461      * Parsing information
1462      */
1463     uint32_t            i;      /* keeps track of current record index  */
1464 
1465     uint32_t            first;  /* first seqno of interest (inclusive)  */
1466     uint32_t            last;   /* last seqno of interest (non-inclusive)   */
1467 
1468     off_t               begin_oset; /* starting file offset                 */
1469     off_t               next_oset;  /* upon completing, this will have either
1470                                      * null, or the offset of the first seqno
1471                                      * greater than or equal to "last".
1472                                      */
1473     uint32_t            sent;   /* actual number sent */
1474 
1475     /*
1476      * Packet records (used to count dups/lost)
1477      */
1478     I2Table         ptable;
1479     long int        plistlen;
1480     OWPPacket       pallocated;
1481     OWPPacket       pfreelist;
1482     OWPPacket       pbegin;
1483     OWPPacket       pend;
1484 
1485     /*
1486      * Delay histogram
1487      */
1488     double          bucketwidth;
1489     I2Table         btable;
1490     long int        blistlen;
1491     OWPBucket       ballocated;
1492     OWPBucket       bfreelist;
1493     OWPBucket       *bsort;
1494     uint32_t        bsorti;         /* current index */
1495     uint32_t        bsortsize;      /* number used in sort array */
1496     uint32_t        bsortlen;       /* number allocated */
1497 
1498     /*
1499      * TTL info - histogram of received TTL values.
1500      */
1501     uint8_t        ttl_count[256];
1502 
1503     /*
1504      * Reordering buffers
1505      */
1506     long int        rlistlen;
1507     long int        rindex;
1508     long int        rnumseqno;
1509     uint32_t       *rseqno;    /* buffer of seqno's seen */
1510     uint32_t       *rn;        /* number of j-reordered packets */
1511 
1512     /*
1513      * Summary Stats
1514      */
1515     double          inf_delay;
1516     double          min_delay;
1517     double          max_delay;
1518     OWPBoolean      sync;
1519     double          maxerr;
1520 
1521     uint32_t       dups;
1522     uint32_t       lost;
1523 
1524 } OWPStatsRec, *OWPStats;
1525 
1526 /*
1527  * Stats utility functions:
1528  *
1529  * The Stats functions are used to create/free context for statistics
1530  * functions as well as providing those functions.
1531  */
1532 
1533 extern void
1534 OWPStatsFree(
1535         OWPStats    stats
1536         );
1537 
1538 extern OWPStats
1539 OWPStatsCreate(
1540         OWPContext          ctx,
1541         FILE                *fp,
1542         OWPSessionHeader    hdr,
1543         char                *fromhost,  /* from hostname */
1544         char                *tohost,    /* to hostname */
1545         char                scale,
1546         double              bucketWidth
1547         );
1548 
1549 extern OWPBoolean
1550 OWPStatsParse(
1551         OWPStats    stats,          /* Stats record */
1552         FILE        *output,        /* Print packet records here */
1553         off_t       begin_oset,     /* Hint:start offset - multistage parsing */
1554         uint32_t   first,           /* first seq num inclusive */
1555         uint32_t   last             /* last seq num non-inclusive */
1556         );
1557 
1558 extern OWPBoolean
1559 OWPStatsPrintSummary(
1560         OWPStats    stats,
1561         FILE        *output,
1562         float       *percentiles,
1563         uint32_t   npercentiles
1564         );
1565 
1566 extern OWPBoolean
1567 OWPStatsPrintMachine(
1568         OWPStats    stats,
1569         FILE        *output
1570         );
1571 
1572 extern float
1573 OWPStatsScaleFactor(
1574         char        scale,
1575         char        *abrv,
1576         size_t      *abrv_len
1577         );
1578 
1579 /*
1580  * How much disk space will a given test require?
1581  * (This is only an estimate - duplicates/loss will change this.)
1582  */
1583 extern uint64_t
1584 OWPTestDiskspace(
1585         OWPTestSpec     *tspec
1586         );
1587 
1588 /*
1589  * time.c conversion functions.
1590  */
1591 
1592 #define OWPJAN_1970 (unsigned long)0x83aa7e80        /* diffs in epoch*/
1593 
1594 #ifndef tvalclear
1595 #define tvalclear(a)        (a)->tv_sec = (a)->tv_usec = 0
1596 #endif
1597 
1598 #ifndef tvaladd
1599 #define tvaladd(a,b)                        \
1600     do{                                     \
1601         (a)->tv_sec += (b)->tv_sec;         \
1602         (a)->tv_usec += (b)->tv_usec;       \
1603         if((a)->tv_usec >= 1000000){        \
1604             (a)->tv_sec++;                  \
1605             (a)->tv_usec -= 1000000;        \
1606         }                                   \
1607     } while (0)
1608 #endif
1609 
1610 #ifndef tvalsub
1611 #define tvalsub(a,b)                        \
1612     do{                                     \
1613         (a)->tv_sec -= (b)->tv_sec;         \
1614         (a)->tv_usec -= (b)->tv_usec;       \
1615         if((a)->tv_usec < 0){               \
1616             (a)->tv_sec--;                  \
1617             (a)->tv_usec += 1000000;        \
1618         }                                   \
1619     } while (0)
1620 #endif
1621 
1622 #ifndef tvalcmp
1623 #define tvalcmp(tvp,uvp,cmp)                \
1624     (((tvp)->tv_sec == (uvp)->tv_sec) ?     \
1625      ((tvp)->tv_usec cmp (uvp)->tv_usec) :  \
1626      ((tvp)->tv_sec cmp (uvp)->tv_sec))
1627 #endif
1628 
1629 /* Operations on timespecs */
1630 #ifndef timespecclear
1631 #define timespecclear(tvp)      ((tvp)->tv_sec = (tvp)->tv_nsec = 0)
1632 #endif
1633 
1634 #ifndef timespecisset
1635 #define timespecisset(tvp)      ((tvp)->tv_sec || (tvp)->tv_nsec)
1636 #endif
1637 
1638 #undef	timespeccmp
1639 #define timespeccmp(tvp, uvp, cmp)          \
1640     (((tvp)->tv_sec == (uvp)->tv_sec) ?     \
1641      ((tvp)->tv_nsec cmp (uvp)->tv_nsec) :  \
1642      ((tvp)->tv_sec cmp (uvp)->tv_sec))
1643 
1644 #undef	timespecadd
1645 #define timespecadd(vvp, uvp)               \
1646     do {                                    \
1647         (vvp)->tv_sec += (uvp)->tv_sec;     \
1648         (vvp)->tv_nsec += (uvp)->tv_nsec;   \
1649         if ((vvp)->tv_nsec >= 1000000000){  \
1650             (vvp)->tv_sec++;                \
1651             (vvp)->tv_nsec -= 1000000000;   \
1652         }                                   \
1653     } while (0)
1654 
1655 #undef	timespecsub
1656 #define timespecsub(vvp, uvp)               \
1657     do {                                    \
1658         (vvp)->tv_sec -= (uvp)->tv_sec;     \
1659         (vvp)->tv_nsec -= (uvp)->tv_nsec;   \
1660         if ((vvp)->tv_nsec < 0) {           \
1661             (vvp)->tv_sec--;                \
1662             (vvp)->tv_nsec += 1000000000;   \
1663         }                                   \
1664     } while (0)
1665 
1666 #undef		timespecdiff
1667 #define        timespecdiff(vvp,uvp)        \
1668     do {                                    \
1669         struct timespec        ts1_,ts2_;   \
1670         if(timespeccmp(vvp,uvp,>)){         \
1671             ts1_ = *vvp;                    \
1672             ts2_ = *uvp;                    \
1673         }else{                              \
1674             ts1_ = *uvp;                    \
1675             ts2_ = *vvp;                    \
1676         }                                   \
1677         timespecsub(&ts1_,&ts2_);           \
1678         *vvp = ts1_;                        \
1679     } while(0)
1680 
1681 extern OWPNum64
1682 OWPGetRTTBound(
1683         OWPControl  cntrl
1684         );
1685 
1686 extern double
1687 OWPGetTimeStampError(
1688         OWPTimeStamp    *tstamp
1689         );
1690 
1691 extern OWPTimeStamp *
1692 OWPGetTimeOfDay(
1693         OWPContext      ctx,
1694         OWPTimeStamp    *tstamp
1695         );
1696 
1697 extern OWPTimeStamp *
1698 OWPTimevalToTimestamp(
1699         OWPTimeStamp    *tstamp,
1700         struct timeval  *tval
1701         );
1702 
1703 extern struct timeval *
1704 OWPTimestampToTimeval(
1705         struct timeval  *tval,
1706         OWPTimeStamp    *tstamp
1707         );
1708 
1709 extern OWPTimeStamp *
1710 OWPTimespecToTimestamp(
1711         OWPTimeStamp    *tstamp,
1712         struct timespec *tval,
1713         uint32_t       *errest,        /* usec's */
1714         uint32_t       *last_errest    /* usec's */
1715         );
1716 
1717 extern struct timespec *
1718 OWPTimestampToTimespec(
1719         struct timespec *tval,
1720         OWPTimeStamp    *tstamp
1721         );
1722 
1723 #endif        /* OWAMP_H */
1724