/* This is the standard '#include' file for the cnet simulator. This file may change at any time to correct any problems which are detected. DO NOT COPY this file, simply #include it into your cnet protocol files. Last modified: Tue Aug 31 15:00:03 WST 1999 */ #if !defined(_CNET_H) #define _CNET_H #define CNET_VERSION "cnet v1.5-2" #include #define MAX_NODENAME_LEN 32 /* len including terminating NULL */ #define K 1024 #define MAX_MESSAGE_SIZE (8 * K) /* largest msg (in bytes) that will be generated by the Application Layer */ #define LOOPBACK 0 #define ALLNODES (0xFFFFFFFF) typedef unsigned long CnetAddr; typedef long CnetData; typedef enum { NT_HOST, NT_ROUTER } CnetNodetype; typedef long CnetTimer; #define NULLTIMER (CnetTimer)0L /* -------- these global variables should be considered READ-ONLY -------- */ typedef struct { CnetNodetype nodetype; /* Either a NT_HOST or a NT_ROUTER */ int nodenumber; /* Ranging from 0.._NNODES-1 */ CnetAddr address; /* Possibly different to the nodenumber */ char *nodename; int nlinks; /* Ranging from 0(=LOOPBACK) .. nlinks */ int minmessagesize; /* min size (in bytes) of msgs generated */ int maxmessagesize; /* max size (in bytes) of msgs generated */ int messagerate; /* rate of msg generation (in ms) */ long time_in_ms; /* a monotonically increasing clock */ struct { long sec; long msec; } time_of_day; /* a reflection of the wall-clock time */ } CnetNodeinfo; extern CnetNodeinfo nodeinfo; extern int NNODES; /* only divulged with cnet -N */ typedef struct { int linkup; /* Boolean: true if link not severed */ int bandwidth; /* in bits per second */ int propagationdelay; /* in ms */ int transmitbufsize; /* in bytes */ int costperbyte; /* in cents(?) */ int costperframe; /* in cents(?) */ } CnetLinkinfo; extern CnetLinkinfo *linkinfo; /* linkinfo[0]..linkinfo[nodeinfo.nlinks] */ /* ------ these enumerated values should be used (and not changed!) ----- */ typedef enum { EV_NULL = 0, /* this event is never raised. */ EV_REBOOT, /* raised as reboot_node(EV_REBOOT, ... , ...) */ EV_SHUTDOWN, /* raised before cnet is (cleanly) terminated */ EV_APPLICATIONREADY,/* raised when there is a msg ready for delivery */ EV_PHYSICALREADY, /* raised when a frame arrives at one of the links */ EV_KEYBOARDREADY, /* raised when a line entered from the keyboard */ EV_LINKSTATE, /* raised when a link changes state (up or down) */ EV_DEBUG1, EV_DEBUG2, EV_DEBUG3, EV_DEBUG4, EV_DEBUG5, EV_TIMER1, EV_TIMER2, EV_TIMER3, EV_TIMER4, EV_TIMER5, EV_TIMER6, EV_TIMER7, EV_TIMER8, EV_TIMER9, EV_TIMER10 } CnetEvent; typedef enum { ER_OK = 0, /* No error */ ER_BADARG, /* Invalid argument passed to a function */ ER_BADEVENT, /* Invalid event passed to a function */ ER_BADLINK, /* Invalid link number passed to a function */ ER_BADNODE, /* Invalid node passed to a function */ ER_BADSENDER, /* Application Layer given msg from an unknown node */ ER_BADSESSION, /* Application Layer given msg from incorrect session */ ER_BADSIZE, /* Indicated length is of incorrect size */ ER_BADTIMER, /* Invalid CnetTimer passed to a function */ ER_CORRUPTDATA, /* Attempt to transfer corrupt data */ ER_LINKDOWN, /* Attempt to transmit on a link that is down */ ER_NOTFORME, /* Application Layer given a msg for another node */ ER_NOTREADY, /* Function called when service not available */ ER_NOTSUPPORTED, /* Invalid operation for this node type */ ER_OUTOFSEQ, /* Application Layer given msg out of sequence */ ER_TOOBUSY /* Function is too busy/congested to handle request */ } CnetError; #define N_CNET_DEBUGS 5 #define N_CNET_ERRORS 16 #define N_CNET_EVENTS 22 #define N_CNET_TIMERS 10 extern CnetError cnet_errno; extern char *cnet_evname[], *cnet_errname[], *cnet_errstr[]; /* -------- Functions for communicating with the network and timers ----- */ extern int CNET_set_handler(CnetEvent ev, void (*handler)(), CnetData data); /* Register handler as the void ``returning'' function to be invoked when the event ev occurs. When the handler is invoked, it will be passed the event, a timestamp and the user-specified data. */ extern int CNET_get_handler(CnetEvent ev, void (**handler)(), CnetData *data); /* Obtains the address of the void ``returning'' function which will be invoked when the indicated event occurs, together with the user-specified data value that will be passed to the handler. */ extern int CNET_read_application(CnetAddr *destaddr, char *msg, int *len); /* On invocation, len will point to an integer indicating the maximum number of bytes that may be copied into msg. On return, len will point to an integer now indicating the number of bytes copied into msg. The address of the required destination node is copied into destaddr. */ extern int CNET_write_physical(int link, char *frame, int *len); /* Passes a number of bytes, pointed to by frame ``down to'' the physical layer which will attempt to deliver them on the indicated link (wire). Each node has a fixed number of links, the first available link is number 1, the second is number 2, and so on. As a special case, a node may reliably transmit a frame to itself by requesting the loopback link, number 0. On invocation, len will point to an integer indicating the number of bytes to be taken from frame. On return, len will point to an integer now indicating the number of bytes accepted by the physical layer. */ extern int CNET_write_physical_reliable(int link, char *frame, int *len); /* CNET_write_physical_reliable() performs an identical function to CNET_write_physical() but will never introduce any corruption or loss (thus providing a reliable datalink layer). */ extern int CNET_write_direct(CnetAddr destaddr, char *frame, int *len); /* CNET_write_direct() performs identically to CNET_write_physical_reliable() although the address of the required destination node must be specified (providing a reliable network layer). All directly written frames arrive on link 1 in the destination. */ extern int CNET_read_physical(int *link, char *frame, int *len); /* Accepts the specified maximum number of bytes from the physical layer, placing them in the address pointed to by frame. On invocation, len will point to an integer indicating the maximum number of bytes that may be copied into frame. On return, len will point to an integer now indicating the number of bytes taken from the physical layer and link will point to an integer indicating on which link they were received. */ extern int CNET_write_application(char *msg, int *len); /* Passes a number of bytes, pointed to by msg, ``up to'' the application layer. On invocation, len must point to an integer indicating the number of bytes to be taken from msg. On return, len will point to an integer now indicating the number of bytes accepted by the application layer. */ extern int CNET_enable_application(CnetAddr destaddr); /* Permits the application layer to generate messages for the node with the indicated address. Initially, msg generation for all nodes is disabled and must be enabled to begin the generation of msgs. If destaddr == ALLNODES, message generation will be enabled for all nodes. */ extern int CNET_disable_application(CnetAddr destaddr); /* Prevents the application layer from generating new messages for the node with the indicated address. This function should be called when a harried node runs out of buffer space, or perhaps while routing information is being gathered. If destaddr == ALLNODES, message generation will be disabled for all nodes. */ extern CnetTimer CNET_start_timer(CnetEvent ev, long ms, CnetData data); /* Requests that a new timer be created which will expire in the indicated number of milliseconds. When the timer expires, the handler for the indicated event, EV_TIMER1..EV_TIMER10, will be called together with the user-specified data value. A unique timestamp is returned to distinguish this newly created timer from all others. This timestamp should later be used in subsequent calls to CNET_stop_timer(). */ extern int CNET_stop_timer(CnetTimer ts); /* Requests that the indicated timer be cancelled. */ extern int CNET_read_keyboard(char *line, int *len); /* Requests the specified maximum number of bytes from the keyboard buffer and places them in the address pointed to by line. On invocation, len will point to an integer indicating the maximum number of bytes that may be copied into line. On return, line will be NULL-byte terminated (and not include a newline) and the integer pointed to by len will contain strlen(line)+1. */ extern int CNET_set_time_of_day(long newsec, long newmsec); /* Changes the node's notion of the wall-clock time of day. time_of_day.sec is the number of seconds since Jan. 1, 1970, and may be used in a call to ctime(3c). As nodeinfo should be considered a read-only structure, this is the only method to set time_of_day.sec and time_of_day.msec . */ extern int CNET_set_debug_string(CnetEvent ev, char *str); /* Changes the string on the required debug button, indicated by the event EV_DEBUG1..EV_DEBUG5, to the indicated string. Passing the NULL or empty string will remove the button. */ extern void CNET_exit(char *file,char *fn,int line); /* Calling this function will exit (all of) cnet, and display the invoking node's name, source file, function, and line where it was called, together with the latest cnet_errno value. */ extern void CNET_perror(char *msg); extern unsigned short checksum_ccitt(unsigned char *addr, int nbytes); extern unsigned short checksum_crc16(unsigned char *addr, int nbytes); extern unsigned long checksum_crc32(unsigned char *addr, int nbytes); extern int checksum_internet(unsigned short *addr, int nbytes); /* --- Next, constants and declarations for debugging and event tracing --- */ #define TE_NOEVENTS (0) #define TE_ALLEVENTS (1) #define TE_REBOOT (1<<(int)EV_REBOOT) #define TE_SHUTDOWN (1<<(int)EV_SHUTDOWN) #define TE_APPLICATIONREADY (1<<(int)EV_APPLICATIONREADY) #define TE_PHYSICALREADY (1<<(int)EV_PHYSICALREADY) #define TE_KEYBOARDREADY (1<<(int)EV_KEYBOARDREADY) #define TE_LINKSTATE (1<<(int)EV_LINKSTATE) #define TE_DEBUG1 (1<<(int)EV_DEBUG1) #define TE_DEBUG2 (1<<(int)EV_DEBUG2) #define TE_DEBUG3 (1<<(int)EV_DEBUG3) #define TE_DEBUG4 (1<<(int)EV_DEBUG4) #define TE_DEBUG5 (1<<(int)EV_DEBUG5) #define TE_TIMER1 (1<<(int)EV_TIMER1) #define TE_TIMER2 (1<<(int)EV_TIMER2) #define TE_TIMER3 (1<<(int)EV_TIMER3) #define TE_TIMER4 (1<<(int)EV_TIMER4) #define TE_TIMER5 (1<<(int)EV_TIMER5) #define TE_TIMER6 (1<<(int)EV_TIMER6) #define TE_TIMER7 (1<<(int)EV_TIMER7) #define TE_TIMER8 (1<<(int)EV_TIMER8) #define TE_TIMER9 (1<<(int)EV_TIMER9) #define TE_TIMER10 (1<<(int)EV_TIMER10) extern int CNET_trace(const char *, ...); extern int CNET_set_trace(int); extern int CNET_get_trace(void); /* ---------------------- Some helpful macros ------------------------- */ #if defined(__GNUC__) #define CHECK(call) if((call) != 0) { \ CNET_exit(__FILE__, __FUNCTION__, __LINE__);} #else #define CHECK(call) if((call) != 0) { \ CNET_exit(__FILE__, (char *)NULL, __LINE__);} #endif #define IS_DEBUG(ev) ((int)EV_DEBUG1<=(int)ev && (int)ev<=(int)EV_DEBUG5) #define IS_TIMER(ev) ((int)EV_TIMER1<=(int)ev && (int)ev<=(int)EV_TIMER10) /* ----------------- Finally, the STDIO window definitions ------------ */ #if defined(putchar) #undef putchar #endif /* These functions are supported: */ extern int putchar(int ch); extern int puts(const char *str); extern int printf(const char *, ...); extern int fprintf(FILE *, const char *, ...); extern void CNET_clear(void); /* The following functions are no longer supported: */ extern int CNET_set_cursor(int row, int col); extern int CNET_get_cursor(int *row, int *col); extern void CNET_clear_to_eoln(void); extern void CNET_clear_to_eos(void); #endif