/*
 * tnmInt.h --
 *
 *	Declarations of things used internally by the Tnm extension.
 *
 * Copyright (c) 1993-1996 Technical University of Braunschweig.
 * Copyright (c) 1996-1997 University of Twente.
 * Copyright (c) 1997-1998 Technical University of Braunschweig.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TNMINT
#define _TNMINT

#include <stdio.h>

#ifndef _TNM
#include "tnm.h"
#endif

#ifndef _TNMPORT
#include "tnmPort.h"
#endif

/*
 *----------------------------------------------------------------
 * The following define should only be used when compiling a
 * demo/alpha/beta version to make sure that such a binary is
 * not used forever.
 *----------------------------------------------------------------
 */

#define TNM_EXPIRE_TIME	870390000
#undef TNM_EXPIRE_TIME

/*
 *----------------------------------------------------------------
 * The ckstrdup macro is useful for two reasons: It emulates
 * strdup which is missing on some systems and it allows to track
 * memory allocation problems using Tcl's memory debugger.
 *----------------------------------------------------------------
 */

#define ckstrdup(s)	strcpy(ckalloc(strlen(s)+1), s)

/*
 *----------------------------------------------------------------
 * The following functions are not officially exported by Tcl. 
 * They are used anyway because they make this code simpler and 
 * platform independent.
 *----------------------------------------------------------------
 */

#define TnmGetTime		TclpGetTime
#define TnmMakeDirs		TclFileMakeDirsCmd

EXTERN void
TclpGetTime		_ANSI_ARGS_((Tcl_Time *timePtr));

EXTERN int
TclFileMakeDirsCmd	_ANSI_ARGS_((Tcl_Interp *interp, 
				     int argc, char **argv));
EXTERN void
panic			_ANSI_ARGS_(TCL_VARARGS(char *,format));

/*
 *----------------------------------------------------------------
 * These functions provide the platform independent initialization
 * points. They are called from platform specific dynamic link
 * entry points.
 *----------------------------------------------------------------
 */

EXTERN int
TnmInit			_ANSI_ARGS_((Tcl_Interp *interp, int safe));

EXTERN void
TnmInitPath		_ANSI_ARGS_((Tcl_Interp *interp));

EXTERN void
TnmInitDns		_ANSI_ARGS_((Tcl_Interp *interp));

/*
 *----------------------------------------------------------------
 * The following structure describes simple tables that map 
 * integer keys to string values and vice versa. This is usually 
 * used to map error codes or similar tokens to strings.
 *----------------------------------------------------------------
 */

typedef struct TnmTable {
    unsigned key;
    char *value;
} TnmTable;

EXTERN char*
TnmGetTableValue	_ANSI_ARGS_((TnmTable *table, unsigned key));

EXTERN int
TnmGetTableKey		_ANSI_ARGS_((TnmTable *table, char *value));

EXTERN char*
TnmGetTableValues	_ANSI_ARGS_((TnmTable *table));

EXTERN void
TnmListFromTable	_ANSI_ARGS_((TnmTable *table, Tcl_Obj *listPtr,
				     char *pattern));
EXTERN int
TnmGetTableKeyFromObj	_ANSI_ARGS_((Tcl_Interp *interp, TnmTable *table,
				     Tcl_Obj *objPtr, char *what));
/*
 *----------------------------------------------------------------
 * A simple mechanism to handle object configuration options.
 * This is not as flexible as the Tk option handling mechanism
 * but it fits our needs.
 *----------------------------------------------------------------
 */

typedef Tcl_Obj* (TnmGetConfigProc) _ANSI_ARGS_((Tcl_Interp *interp,
        ClientData clientData, int option));
typedef int (TnmSetConfigProc) _ANSI_ARGS_((Tcl_Interp *interp,
        ClientData clientData, int option, Tcl_Obj *objPtr));

typedef struct TnmConfig {
    TnmTable *optionTable;
    TnmSetConfigProc *setOption;
    TnmGetConfigProc *getOption;
} TnmConfig;

EXTERN int
TnmSetConfig		_ANSI_ARGS_((Tcl_Interp *interp, TnmConfig *config,
				     ClientData obj, int objc, 
				     Tcl_Obj *CONST objv[]));
EXTERN int
TnmGetConfig		_ANSI_ARGS_((Tcl_Interp *interp, TnmConfig *config,
				     ClientData obj, int objc, 
				     Tcl_Obj *CONST objv[]));
/*
 *----------------------------------------------------------------
 * Functions used internally to make error handling simple and
 * consistent.
 *----------------------------------------------------------------
 */

EXTERN void
TnmWrongNumArgs		_ANSI_ARGS_((Tcl_Interp *interp, int argc, 
				     char **argv, char *message));
EXTERN void
TnmBadOption		_ANSI_ARGS_((Tcl_Interp *interp, char *option,
				     char *message));

/*
 *----------------------------------------------------------------
 * The following structure describes simple vector to hold 
 * ClientData arguments. This is usually used to keep references
 * to other objects.
 *----------------------------------------------------------------
 */

#define TNM_VECTOR_STATIC_SIZE 8
typedef struct TnmVector {
    ClientData *elements;
    int size;
    int spaceAvl;
    ClientData staticSpace[TNM_VECTOR_STATIC_SIZE + 1];
} TnmVector;

EXTERN void
TnmVectorInit		_ANSI_ARGS_((TnmVector *vPtr));

EXTERN void
TnmVectorFree		_ANSI_ARGS_((TnmVector *vPtr));

EXTERN void
TnmVectorAdd		_ANSI_ARGS_((TnmVector *vPtr, ClientData clientData));

EXTERN void
TnmVectorDelete		_ANSI_ARGS_((TnmVector *vPtr, ClientData clientData));

#define TnmVectorGet(vPtr,index)	((vPtr)->elements[index])
#define TnmVectorSet(vPtr,index,value)	((vPtr)->elements[index] = value)
#define TnmVectorSize(vPtr)		((vPtr)->size)
#define TnmVectorElements(vPtr)		((vPtr)->elements)

/*
 *----------------------------------------------------------------
 * Functions to convert common string arguments into an
 * internal format with additional error checks.
 *----------------------------------------------------------------
 */

EXTERN int 
TnmGetUnsigned		_ANSI_ARGS_((Tcl_Interp *interp, char *string,
				     int *intPtr));
EXTERN int 
TnmGetUnsignedFromObj	_ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr,
				     int *intPtr));
EXTERN int 
TnmGetPositive		_ANSI_ARGS_((Tcl_Interp *interp, char *string,
				     int *intPtr));
EXTERN int 
TnmGetPositiveFromObj	_ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr,
				     int *intPtr));
EXTERN int
TnmGetIntRangeFromObj	_ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr,
				     int min, int max, int *intPtr));
EXTERN int
TnmGetCounter64		_ANSI_ARGS_((Tcl_Interp *interp, 
				     u_int *high, u_int *low));
EXTERN char*
TnmPrintCounter64	_ANSI_ARGS_((u_int high, u_int low));

EXTERN int
TnmSetIPAddress		_ANSI_ARGS_((Tcl_Interp *interp, char *name,
				     struct sockaddr_in *addr));
EXTERN char*
TnmGetIPName		_ANSI_ARGS_((Tcl_Interp *interp,
				     struct sockaddr_in *addr));
EXTERN int
TnmSetIPPort		_ANSI_ARGS_((Tcl_Interp *interp, char *protocol,
				     char *port, struct sockaddr_in *addr));
EXTERN char*
TnmGetIPPort		_ANSI_ARGS_((Tcl_Interp *interp, char *protocol,
				     struct sockaddr_in *addr));
EXTERN int
TnmValidateIpHostName	_ANSI_ARGS_((Tcl_Interp *interp, char *name));

EXTERN int
TnmValidateIpAddress	_ANSI_ARGS_((Tcl_Interp *interp, char *address));

/*
 *----------------------------------------------------------------
 * The following defines are taken from the UNIX syslog facility.
 * Not all of them may be supported on all platforms.
 *----------------------------------------------------------------
 */

#define	TNM_LOG_EMERG	0	/* system is unusable */
#define	TNM_LOG_ALERT	1	/* action must be taken immediately */
#define	TNM_LOG_CRIT	2	/* critical conditions */
#define	TNM_LOG_ERR	3	/* error conditions */
#define	TNM_LOG_WARNING	4	/* warning conditions */
#define	TNM_LOG_NOTICE	5	/* normal but significant condition */
#define	TNM_LOG_INFO	6	/* informational */
#define	TNM_LOG_DEBUG	7	/* debug-level messages */

EXTERN TnmTable tnmLogTable[];

EXTERN int 
TnmWriteLogMessage	_ANSI_ARGS_((int level, char *message));

EXTERN void
TnmWriteMessage		_ANSI_ARGS_((char *msg));

/*
 *----------------------------------------------------------------
 * The following defines are used to distinguish the ICMP packet
 * types supported by the icmp command.
 *----------------------------------------------------------------
 */

typedef struct TnmIcmpTarget {
    unsigned int tid;		/* The unique identifier for this target. */
    struct in_addr dst;		/* The address of the ICMP target. */
    struct in_addr res;		/* The address contained in the response. */
    union {
	unsigned rtt;		/* The round trip time in ms. */
	int tdiff;		/* The time stamp difference. */
	int mask;		/* The address mask. */
    } u;
    u_char status;		/* The status of this entry (see below). */
    u_char flags;		/* Some flags (see below). */
} TnmIcmpTarget;

#define TNM_ICMP_TYPE_ECHO		0x01
#define TNM_ICMP_TYPE_MASK		0x02
#define TNM_ICMP_TYPE_TIMESTAMP		0x03
#define TNM_ICMP_TYPE_TRACE		0x04

#define TNM_ICMP_STATUS_NOERROR		0x00
#define TNM_ICMP_STATUS_TIMEOUT		0x01
#define TNM_ICMP_STATUS_GENERROR	0x02

#define TNM_ICMP_FLAG_LASTHOP		0x01

typedef struct TnmIcmpRequest {
    int type;			/* The ICMP request type (see above). */
    int ttl;			/* The time-to-live value for this request. */
    int timeout;		/* The timeout value (ms) for this request. */
    int retries;		/* The retry value for this request. */
    int delay;			/* The delay value (ms) for this request. */
    int size;			/* The size of the ICMP packet. */
    int window;			/* The window size for this request. */
    int flags;			/* The flags for this particular request. */
    int numTargets;		/* The number of targets for this request. */
    TnmIcmpTarget *targets;	/* The vector of targets. */
    struct TnmIcmpRequest *nextPtr;	/* Next queued request. */
} TnmIcmpRequest;

EXTERN int
TnmIcmp			_ANSI_ARGS_((Tcl_Interp *interp, 
				     TnmIcmpRequest *icmpPtr));

/*
 *----------------------------------------------------------------
 * The following functions are used internally to implement
 * attributes for objects.
 *----------------------------------------------------------------
 */

EXTERN int
TnmAttrSet	_ANSI_ARGS_((Tcl_HashTable *tablePtr, Tcl_Interp *interp,
			     char *name, char *value));
EXTERN void
TnmAttrList	_ANSI_ARGS_((Tcl_HashTable *tablePtr, Tcl_Interp *interp));

EXTERN void
TnmAttrClear	_ANSI_ARGS_((Tcl_HashTable *tablePtr));

EXTERN void
TnmAttrDump	_ANSI_ARGS_((Tcl_HashTable *tablePtr, char *name, 
			     Tcl_DString *dsPtr));

/*
 *----------------------------------------------------------------
 * The following functions are used internally to encode/decode
 * internal data into/from various formats.
 *----------------------------------------------------------------
 */

EXTERN void
TnmHexEnc	_ANSI_ARGS_((char *s, int n, char *d));

EXTERN int
TnmHexDec	_ANSI_ARGS_((char *s, char *d, int *n));

/*
 *----------------------------------------------------------------
 * Functions to simplify the handling of object-based Tcl
 * commands.
 *----------------------------------------------------------------
 */

EXTERN char*
TnmGetHandle	_ANSI_ARGS_((Tcl_Interp *interp, char *prefix,
			     unsigned *id));
EXTERN int
TnmMatchTags	_ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *tagListObj, 
			     Tcl_Obj *patternListObj));
/*
 *----------------------------------------------------------------
 * The following functions are used internally to access sockets
 * in a platform independent way. These functions return the value
 * TNM_SOCKET_ERROR as an error result and set the errno variable
 * in a way that allows to use Tcl_PosixError().
 *----------------------------------------------------------------
 */

#define TNM_SOCKET_ERROR -1

EXTERN int
TnmSocket		_ANSI_ARGS_((int domain, int type, int protocol));

EXTERN int
TnmSocketBind		_ANSI_ARGS_((int s, struct sockaddr *name,
				     int namelen));
EXTERN int
TnmSocketSendTo		_ANSI_ARGS_((int s, char *buf, int len, int flags,
				     struct sockaddr *to, int tolen));
EXTERN int
TnmSocketRecvFrom	_ANSI_ARGS_((int s, char *buf, int len, int flags,
				     struct sockaddr *from, int *fromlen));
EXTERN int
TnmSocketClose		_ANSI_ARGS_((int s));

typedef void (TnmSocketProc) _ANSI_ARGS_((ClientData clientData, int mask));

EXTERN void
TnmCreateSocketHandler	_ANSI_ARGS_((int sock, int mask,
				     TnmSocketProc *proc,
				     ClientData clientData));
EXTERN void
TnmDeleteSocketHandler	_ANSI_ARGS_((int sock));

#endif /* _TNMINT */
