diff options
Diffstat (limited to 'usr.sbin/i4b/isdnmonitor/main.c')
-rw-r--r-- | usr.sbin/i4b/isdnmonitor/main.c | 897 |
1 files changed, 695 insertions, 202 deletions
diff --git a/usr.sbin/i4b/isdnmonitor/main.c b/usr.sbin/i4b/isdnmonitor/main.c index 873c241..1c0b199 100644 --- a/usr.sbin/i4b/isdnmonitor/main.c +++ b/usr.sbin/i4b/isdnmonitor/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998 Martin Husemann. All rights reserved. + * Copyright (c) 1998,1999 Martin Husemann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,36 +33,51 @@ * i4b daemon - network monitor client * ----------------------------------- * - * $FreeBSD$ + * $Id: main.c,v 1.34 1999/12/13 21:25:26 hm Exp $ * - * last edit-date: [Sun May 30 15:19:47 1999] + * $FreeBSD$ * - * -mh created - * -hm checking in - * -hm porting to HPUX - * -mh all events the fullscreen mode displays now as monitor event + * last edit-date: [Mon Dec 13 21:52:11 1999] * *---------------------------------------------------------------------------*/ - #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #include <string.h> #include <signal.h> #include <time.h> #include <errno.h> +#ifndef WIN32 #include <unistd.h> #include <netdb.h> +#endif #include <sys/types.h> +#ifndef WIN32 #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> +#else +#include <stdarg.h> +#include <windows.h> +extern char *optarg; +int getopt(int nargc, char * const nargv[], const char *ostr); +#define close(f) closesocket(f) +#define sleep(s) Sleep(s*1000) +#define vsnprintf _vsnprintf +#define ssize_t long +#endif +#ifdef ERROR +#undef ERROR +#endif -#include <machine/i4b_ioctl.h> +#define MAIN +#include "monprivate.h" +#undef MAIN -#ifdef __hpux +#ifndef AF_LOCAL #define AF_LOCAL AF_UNIX #endif @@ -75,61 +90,121 @@ /* * Local function prototypes */ -static int connect_local(const char *sockpath); -static int connect_remote(const char *host, int portno); +static int connect_local(char *sockpath); +static int connect_remote(char *host, int portno); static void usage(); static void mloop(); static void handle_input(); static void print_menu(); -static void print_logevent(time_t tstamp, int prio, const char * what, const char * msg); -static void print_charge(time_t tstamp, int channel, int units, int estimated); -static void print_connect(time_t tstamp, int dir, int channel, const char * cfgname, const char * devname, const char * remphone, const char * locphone); -static void print_disconnect(time_t tstamp, int channel); -static void print_updown(time_t tstamp, int channel, int isup); -static void handle_event(BYTE *msg, int len); +static void print_logevent(time_t tstamp, int prio, char * what, char * msg); +static void print_charge(time_t tstamp, int controller, int channel, int units, int estimated); +static void print_connect(time_t tstamp, int dir, int controller, int channel, char * cfgname, char * devname, char * remphone, char * locphone); +static void print_disconnect(time_t tstamp, int controller, int channel); +static void print_updown(time_t tstamp, int contoller, int channel, int isup); +static void handle_event(u_int8_t *msg, int len); #ifdef DEBUG -static void dump_event(BYTE *msg, int len, int readflag); +static void dump_event(u_int8_t *msg, int len, int readflag); #endif +static ssize_t sock_read(int fd, void *buf, size_t nbytes); +static ssize_t sock_write(int fd, void *buf, size_t nbytes); + +static void mprintf(char *fmt, ...); + /* * Global variables */ -static int dumpall = 0; +static int debug = 0; +#define DBG_DUMPALL 0x01 +#define DBG_PSEND 0x02 + static int monsock = -1; -static int state = 0; +static int state = ST_INIT; static int sub_state = 0; static int sub_state_count = 0; static int isdn_major = 0; static int isdn_minor = 0; -static int nctrl = 0; static u_int32_t rights = 0; -/* - * Parse command line, startup monitor client - */ +static char *logfilename = NULL; +static FILE *lfp = NULL; + +/*--------------------------------------------------------------------------- + * Display usage and exit + *---------------------------------------------------------------------------*/ +static void +usage() +{ + fprintf(stderr, "\n"); + fprintf(stderr, "isdnmonitor - version %02d.%02d.%d, %s %s (protocol %02d.%02d)\n", VERSION, REL, STEP, __DATE__, __TIME__, MPROT_VERSION, MPROT_REL); +#ifdef FOREIGN + fprintf(stderr, " usage: isdnmonitor [-c] [-d val] [-f name] [-h host] [-p port]\n"); +#else + fprintf(stderr, " usage: isdnmonitor [-c] [-d val] [-f name] [-h host] [-l path] [-p port]\n"); +#endif + fprintf(stderr, " -c switch to curses fullscreen output\n"); + fprintf(stderr, " -d <val> debug flags (see source ...)\n"); + fprintf(stderr, " -dn no debug output on fullscreen display\n"); + fprintf(stderr, " -f <name> filename to log output to\n"); + fprintf(stderr, " -h <host> hostname/address to connect to\n"); +#ifndef FOREIGN + fprintf(stderr, " -l <path> pathname to local domain socket to connect to\n"); +#endif + fprintf(stderr, " -p <port> portnumber to use to connect to remote host\n"); + exit(1); +} + +/*--------------------------------------------------------------------------- + * Parse command line, startup monitor client + *---------------------------------------------------------------------------*/ int main(int argc, char **argv) { - char * sockpath = NULL; - char * hostname = NULL; - int portno = DEF_MONPORT; int i; - while ((i = getopt(argc, argv, "dh:p:l:")) != -1) +#ifdef WIN32 + WSADATA wsCaps; + WSAStartup(MAKEWORD(2, 0), &wsCaps); +#endif + + portno = DEF_MONPORT; + devbuf[0] = '\0'; + +#ifndef FOREIGN + while((i = getopt(argc, argv, "cd:f:h:p:l:")) != -1) +#else + while((i = getopt(argc, argv, "cd:f:h:p:")) != -1) +#endif { - switch (i) + switch(i) { + case 'c': + fullscreen = 1; + break; case 'd': - dumpall = 1; + if(*optarg == 'n') + { + debug_noscreen = 1; + } + else + { + if((sscanf(optarg, "%i", &debug)) != 1) + usage(); + } + break; + case 'f': + logfilename = optarg; break; case 'h': hostname = optarg; break; +#ifndef FOREIGN case 'l': sockpath = optarg; break; +#endif case 'p': - if ((sscanf(optarg, "%i", &portno)) != 1) + if((sscanf(optarg, "%i", &portno)) != 1) usage(); break; default: @@ -138,18 +213,23 @@ int main(int argc, char **argv) } } - if (hostname && sockpath) +#ifndef FOREIGN + if(hostname && sockpath) { fprintf(stderr, "Error: can not use local socket path on remote machine\n" "conflicting options -h and -l!\n"); return 1; } - if (sockpath) + if(sockpath) { monsock = connect_local(sockpath); } - else if (hostname) + else if(hostname) +#else + if(hostname) +#endif + { monsock = connect_remote(hostname, portno); } @@ -158,13 +238,25 @@ int main(int argc, char **argv) usage(); } - if (monsock == -1) + if(monsock == -1) { fprintf(stderr, "Could not connect to i4b isdn daemon.\n"); return 1; } + if(logfilename != NULL) + { + if((lfp = fopen(logfilename, "w")) == NULL) + { + fprintf(stderr, "could not open logfile [%s], %s\n", logfilename, strerror(errno)); + exit(1); + } + } + +#ifndef WIN32 signal(SIGPIPE, SIG_IGN); +#endif + mloop(); close(monsock); @@ -172,30 +264,12 @@ int main(int argc, char **argv) return 0; } -/* - * Display usage and exit - */ -static void usage() -{ - fprintf(stderr, "usage:\n" - " isdnmonitor [-d] -h (host) -p (port)\n" - "or\n" - " isdnmonitor [-d] -l (path)\n" - "where (host) is the hostname and (port) the port number of\n" - "the isdnd to be monitored and (path) is the pathname of the\n" - "local domain socket used to communicate with a daemon on the\n" - "local machine.\n" - "Options are:\n" - " -d dump all incoming packets as hexdump\n" - ); - exit(0); -} - -/* - * Connect via tcp/ip. - * Return socket if successfull, -1 on error. - */ -static int connect_remote(const char *host, int portno) +/*--------------------------------------------------------------------------- + * Connect via tcp/ip. + * Return socket if successfull, -1 on error. + ---------------------------------------------------------------------------*/ +static int +connect_remote(char *host, int portno) { struct sockaddr_in sa; struct hostent *h; @@ -203,7 +277,7 @@ static int connect_remote(const char *host, int portno) h = gethostbyname(host); - if (!h) + if(!h) { fprintf(stderr, "could not resolve hostname '%s'\n", host); exit(1); @@ -211,23 +285,23 @@ static int connect_remote(const char *host, int portno) remotesockfd = socket(AF_INET, SOCK_STREAM, 0); - if (remotesockfd == -1) + if(remotesockfd == -1) { fprintf(stderr, "could not create remote monitor socket: %s\n", strerror(errno)); exit(1); } - memset(&sa, 0, sizeof sa); + memset(&sa, 0, sizeof(sa)); #ifdef BSD4_4 - sa.sin_len = sizeof sa; + sa.sin_len = sizeof(sa); #endif sa.sin_family = AF_INET; sa.sin_port = htons(portno); - memcpy(&sa.sin_addr.s_addr, h->h_addr_list[0], sizeof sa.sin_addr.s_addr); + memcpy(&sa.sin_addr.s_addr, h->h_addr_list[0], sizeof(sa.sin_addr.s_addr)); - if (connect(remotesockfd, (struct sockaddr *)&sa, sizeof sa) == -1) + if(connect(remotesockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { fprintf(stderr, "could not connect remote monitor: %s\n", strerror(errno)); exit(1); @@ -236,17 +310,19 @@ static int connect_remote(const char *host, int portno) return remotesockfd; } -/* - * Connect local. - * Return socket on success, -1 on failure. - */ -static int connect_local(const char *sockpath) +#ifndef FOREIGN +/*--------------------------------------------------------------------------- + * Connect local. + * Return socket on success, -1 on failure. + *---------------------------------------------------------------------------*/ +static int +connect_local(char *sockpath) { int s; struct sockaddr_un sa; /* check path length */ - if (strlen(sockpath) >= sizeof sa.sun_path) + if(strlen(sockpath) >= sizeof(sa.sun_path)) { fprintf(stderr, "pathname to long for local socket: %s\n", sockpath); @@ -256,35 +332,57 @@ static int connect_local(const char *sockpath) /* create and setup socket */ s = socket(AF_LOCAL, SOCK_STREAM, 0); - if (s == -1) + if(s == -1) { fprintf(stderr, "could not create local monitor socket:%s\n", strerror(errno)); exit(1); } - memset(&sa, 0, sizeof sa); - -#ifndef __hpux - sa.sun_len = sizeof sa; -#endif + memset(&sa, 0, sizeof(sa)); + sa.sun_len = sizeof(sa); sa.sun_family = AF_LOCAL; strcpy(sa.sun_path, sockpath); - if (connect(s, (struct sockaddr *)&sa, sizeof sa)) + if(connect(s, (struct sockaddr *)&sa, sizeof(sa))) { fprintf(stderr, "could not connect local monitor socket [%s]: %s\n", sockpath, strerror(errno)); } return s; } +#endif -/* - * main event loop - */ -static void mloop() +/*---------------------------------------------------------------------------* + * data from keyboard available, read and process it + *---------------------------------------------------------------------------*/ +#ifndef WIN32 +static void +kbdrdhdl(void) +{ + int ch = getch(); + + switch(ch) + { + case 0x0c: /* control L */ + wrefresh(curscr); + break; + + case '\n': + case '\r': + do_menu(); + break; + } +} +#endif + +/*--------------------------------------------------------------------------- + * main event loop + *---------------------------------------------------------------------------*/ +static void +mloop() { - for (;;) + for(;;) { fd_set rd, wr, ex; @@ -296,51 +394,83 @@ static void mloop() select(monsock+1, &rd, &wr, &ex, NULL); - if (FD_ISSET(fileno(stdin), &rd)) + if(FD_ISSET(fileno(stdin), &rd)) { - handle_input(); +#ifndef WIN32 + if(fullscreen && curses_ready) + kbdrdhdl(); + else +#endif + if(!fullscreen) + handle_input(); + else + getchar(); } - if (FD_ISSET(monsock, &rd)) + if(FD_ISSET(monsock, &rd)) { - BYTE buf[4096]; - u_long u; + u_int8_t buf[8192]; int bytes, ret; /* Network transfer may deliver two or more packets concatenated. * Peek at the header and read only one event at a time... */ - ioctl(monsock, FIONREAD, &u); - - if (u < I4B_MON_EVNT_HDR) - continue; /* not enough data there yet */ - bytes = recv(monsock, buf, I4B_MON_EVNT_HDR, MSG_PEEK); + if(bytes == 0) + { + close(monsock); + +#ifndef WIN32 + if(curses_ready) + { + endwin(); + curses_ready = 0; + } +#endif + + mprintf("remote isdnd has closed our connection\n"); + exit(0); + } + else if(bytes < 0) + { + fprintf(stderr, "recv error: %s\n", strerror(errno)); + close(monsock); + exit(1); + } + if (bytes < I4B_MON_EVNT_HDR) continue; /* errh? something must be wrong... */ bytes = I4B_GET_2B(buf, I4B_MON_EVNT_LEN); - if (bytes >= sizeof buf) + if(bytes >= sizeof(buf)) + { + fprintf(stderr, "mloop: socket recv buffer overflow %d!\n", bytes); break; + } /* now we know the size, it fits, so lets read it! */ - ret = read(monsock, buf, bytes); + ret = sock_read(monsock, buf, bytes); - if (ret == 0) + if(ret == 0) { - printf("remote isdnd has closed our connection\n"); - break; + close(monsock); +#ifndef WIN32 + if(curses_ready) + endwin(); +#endif + mprintf("remote isdnd has closed our connection\n"); + exit(0); } - else if (ret < 0) + else if(ret < 0) { - printf("error reading from isdnd: %s", strerror(errno)); + mprintf("error reading from isdnd: %s", strerror(errno)); break; } #ifdef DEBUG - if (dumpall) + if(debug & DBG_DUMPALL) dump_event(buf, ret, 1); #endif handle_event(buf, ret); @@ -352,39 +482,75 @@ static void mloop() /* * Dump a complete event packet. */ -static void dump_event(BYTE *msg, int len, int read) +static void dump_event(u_int8_t *msg, int len, int read) { int i; if(read) - printf("read from socket:"); + mprintf("read from socket:"); else - printf("write to socket:"); + mprintf("write to socket:"); - for (i = 0; i < len; i++) + for(i = 0; i < len; i++) { - if (i % 8 == 0) - printf("\n%02d: ", i); - printf("0x%02x %c ", msg[i], isprint(msg[i]) ? msg[i] : '.'); + if(i % 8 == 0) + mprintf("\n%02d: ", i); + mprintf("0x%02x %c ", msg[i], isprint(msg[i]) ? msg[i] : '.'); } - printf("\n"); + mprintf("\n"); } #endif -static void print_logevent(time_t tstamp, int prio, const char * what, const char * msg) +static void +print_logevent(time_t tstamp, int prio, char * what, char * msg) { char buf[256]; - strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp)); - printf("log: %s prio %d what=%s msg=%s\n", - buf, prio, what, msg); + strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp)); + mprintf("log: %s prio %d what=%s msg=%s\n", buf, prio, what, msg); + +#ifndef WIN32 + if(fullscreen) + { + if((!debug_noscreen) || (debug_noscreen && (((strcmp(what, "DBG"))) != 0))) + { +/* + * FreeBSD-current integrated ncurses. Since then it is no longer possible + * to write to the last column in the logfilewindow without causing an + * automatic newline to occur resulting in a blank line in that window. + */ +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif +#if defined(__FreeBSD_version) && __FreeBSD_version >= 400009 +#warning "FreeBSD ncurses is buggy: write to last column = auto newline!" + wprintw(lower_w, "%s %s %-.*s\n", buf, what, + COLS-((strlen(buf))+(strlen(what))+3), msg); +#else + wprintw(lower_w, "%s %s %-.*s\n", buf, what, + COLS-((strlen(buf))+(strlen(what))+2), msg); +#endif + wrefresh(lower_w); + } + } +#endif } -static void print_charge(time_t tstamp, int channel, int units, int estimated) +static void +print_charge(time_t tstamp, int controller, int channel, int units, int estimated) { char buf[256]; - strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp)); - printf("%s: channel %d, charge = %d%s\n", - buf, channel, units, estimated ? " (estimated)" : ""); + strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp)); + mprintf("%s: controller %d, channel %d, charge = %d%s\n", + buf, controller, channel, units, estimated ? " (estimated)" : ""); +#ifndef WIN32 + if(fullscreen) + { + if(estimated) + display_ccharge(CHPOS(controller, channel), units); + else + display_charge(CHPOS(controller, channel), units); + } +#endif } /* @@ -395,23 +561,35 @@ static void print_charge(time_t tstamp, int channel, int units, int estimated) static void print_connect( time_t tstamp, /* server time of event */ int outgoing, /* 0 = incoming, 1 = outgoing */ + int controller, /* controller number */ int channel, /* channel no, used to identify this connection until disconnect */ - const char * cfgname, /* name of config entry/connection */ - const char * devname, /* device used (e.g. isp0) */ - const char * remphone, /* phone no of remote side */ - const char * locphone) /* local phone no */ + char * cfgname, /* name of config entry/connection */ + char * devname, /* device used (e.g. isp0) */ + char * remphone, /* phone no of remote side */ + char * locphone) /* local phone no */ { char buf[256]; - strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp)); - if (outgoing) - printf("%s: calling out to '%s' [from msn: '%s']", + if(channel == 0) + remstate[controller].ch1state = 1; + else + remstate[controller].ch2state = 1; + + strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp)); + + if(outgoing) + mprintf("%s: calling out to '%s' [from msn: '%s']", buf, remphone, locphone); else - printf("%s: incoming call from '%s' [to msn: '%s']", + mprintf("%s: incoming call from '%s' [to msn: '%s']", buf, remphone, locphone); - printf(", channel %d, config '%s' on device '%s'\n", - channel, cfgname, devname); + mprintf(", controller %d, channel %d, config '%s' on device '%s'\n", + controller, channel, cfgname, devname); + +#ifndef WIN32 + if(fullscreen) + display_connect(CHPOS(controller, channel), outgoing, cfgname, remphone, devname); +#endif } /* @@ -419,59 +597,159 @@ static void print_connect( * A real monitor could free the "per connection" state * for this channel now */ -static void print_disconnect(time_t tstamp, int channel) +static void +print_disconnect(time_t tstamp, int controller, int channel) { char buf[256]; - strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp)); - printf("%s: channel %d disconnected\n", - buf, channel); + + if(channel == 0) + remstate[controller].ch1state = 0; + else + remstate[controller].ch2state = 0; + + strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp)); + + mprintf("%s: controller %d, channel %d disconnected\n", + buf, controller, channel); + +#ifndef WIN32 + if(fullscreen) + display_disconnect(CHPOS(controller, channel)); +#endif } /* * Print an up- or down event */ -static void print_updown(time_t tstamp, int channel, int isup) +static void +print_updown(time_t tstamp, int controller, int channel, int isup) { char buf[256]; - strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp)); - printf("%s: channel %d is %s\n", + strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp)); + mprintf("%s: channel %d is %s\n", buf, channel, isup ? "up" : "down"); } /* + * Print l1 / l2 status + */ +static void +print_l12stat(time_t tstamp, int controller, int layer, int state) +{ + char buf[256]; + strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp)); + + mprintf("%s: layer %d change on controller %d: %s\n", + buf, layer, controller, state ? "up" : "down"); +#ifndef WIN32 + if(fullscreen) + display_l12stat(controller, layer, state); +#endif +} + +/* + * Print TEI + */ +static void +print_tei(time_t tstamp, int controller, int tei) +{ + char buf[256]; + strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp)); + + mprintf("%s: controller %d, TEI is %d\n", + buf, controller, tei); + +#ifndef WIN32 + if(fullscreen) + display_tei(controller, tei); +#endif +} + +/* + * Print accounting information + */ +static void +print_acct(time_t tstamp, int controller, int channel, int obytes, int obps, + int ibytes, int ibps) +{ + char buf[256]; + strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp)); + + mprintf("%s: controller %d, channel %d: %d obytes, %d obps, %d ibytes, %d ibps\n", + buf, controller, channel, obytes, obps, ibytes, ibps); +#ifndef WIN32 + if(fullscreen) + display_acct(CHPOS(controller, channel), obytes, obps, ibytes, ibps); +#endif +} + +static void +print_initialization(void) +{ +#ifndef WIN32 + if(fullscreen) + { + if(curses_ready == 0) + init_screen(); + } + else +#endif + { + print_menu(); + } +} + +/* * Dispatch one message received from the daemon. */ -static void handle_event(BYTE *msg, int len) +static void +handle_event(u_int8_t *msg, int len) { - BYTE cmd[I4B_MON_ICLIENT_SIZE]; + u_int8_t cmd[I4B_MON_ICLIENT_SIZE]; int local; u_int32_t net; u_int32_t mask; u_int32_t who; + static int first = 1; - switch (state) + switch(state) { - case 0: /* initial data */ + case ST_INIT: /* initial data */ isdn_major = I4B_GET_2B(msg, I4B_MON_IDATA_VERSMAJOR); isdn_minor = I4B_GET_2B(msg, I4B_MON_IDATA_VERSMINOR); nctrl = I4B_GET_2B(msg, I4B_MON_IDATA_NUMCTRL); + nentries = I4B_GET_2B(msg, I4B_MON_IDATA_NUMENTR); rights = I4B_GET_4B(msg, I4B_MON_IDATA_CLACCESS); - printf("remote protocol version is %02d.%02d, %d controller(s) found, our rights = %x\n", - isdn_major, isdn_minor, nctrl, rights); + mprintf("remote protocol version is %02d.%02d\n", isdn_major, isdn_minor); - if (nctrl > 0) + if(isdn_major != MPROT_VERSION || isdn_minor != MPROT_REL) { - state = 1; - sub_state = 0; + fprintf(stderr, "ERROR, remote protocol version mismatch:\n"); + fprintf(stderr, "\tremote major version is %02d, local major version is %02d\n", isdn_major, MPROT_VERSION); + fprintf(stderr, "\tremote minor version is %02d, local minor version is %02d\n", isdn_minor, MPROT_REL); + exit(1); + } + + mprintf("our rights = 0x%x\n", rights); + + sub_state = 0; + first = 1; + + if(nctrl > 0) + { + state = ST_ICTRL; + } + else if(nentries > 0) + { + state = ST_IDEV; } else { - state = 2; - - /* show menu for the first time */ - print_menu(); + state = ST_ANYEV; + sleep(2); + print_initialization(); } /* set maximum event mask */ @@ -481,43 +759,79 @@ static void handle_event(BYTE *msg, int len) I4B_PUT_4B(cmd, I4B_MON_ICLIENT_EVENTS, ~0U); #ifdef DEBUG - if (dumpall) - dump_event(cmd, sizeof cmd, 0); + if(debug & DBG_DUMPALL) + dump_event(cmd, sizeof(cmd), 0); #endif - write(monsock, cmd, sizeof cmd); - + if((sock_write(monsock, cmd, sizeof(cmd))) == -1) + { + fprintf(stderr, "sock_write failed: %s\n", strerror(errno)); + exit(1); + } break; - case 1: /* initial controller list */ - printf("controller %d: %s\n", sub_state++, msg+I4B_MON_ICTRL_NAME); + case ST_ICTRL: /* initial controller list */ + if(first) + { + first = 0; + mprintf("%d controller(s) found:\n", nctrl); + } + mprintf("\tcontroller %d: %s\n", sub_state++, msg+I4B_MON_ICTRL_NAME); - if (sub_state >= nctrl) + if(sub_state >= nctrl) { - state = 2; /* end of list reached */ sub_state = 0; - - /* show menu for the first time */ - print_menu(); + first = 1; + if(nentries > 0) + { + state = ST_IDEV; /* end of list reached */ + } + else + { + state = ST_ANYEV; + sleep(2); + print_initialization(); + } } break; - case 2: /* any event */ + case ST_IDEV: /* initial entry devicename list */ + if(first) + { + first = 0; + mprintf("%d entries found:\n", nentries); + } + + mprintf("\tentry %d: device %s\n", sub_state++, msg+I4B_MON_IDEV_NAME); - switch (I4B_GET_2B(msg, I4B_MON_EVNT)) + strcat(devbuf, msg+I4B_MON_IDEV_NAME); + /* strcat(devbuf, " "); */ + + if(sub_state >= nentries) + { + first = 1; + state = ST_ANYEV; /* end of list reached */ + sub_state = 0; + sleep(2); + print_initialization(); + } + break; + + case ST_ANYEV: /* any event */ + switch(I4B_GET_2B(msg, I4B_MON_EVNT)) { case I4B_MON_DRINI_CODE: - state = 3; /* list of rights entries will follow */ + state = ST_RIGHT; /* list of rights entries will follow */ sub_state = 0; sub_state_count = I4B_GET_2B(msg, I4B_MON_DRINI_COUNT); - printf("monitor rights:\n"); + mprintf("monitor rights:\n"); break; case I4B_MON_DCINI_CODE: - state = 4; + state = ST_CONNS; sub_state = 0; sub_state_count = I4B_GET_2B(msg, I4B_MON_DCINI_COUNT); - printf("monitor connections:\n"); + mprintf("monitor connections:\n"); break; case I4B_MON_LOGEVNT_CODE: @@ -526,9 +840,10 @@ static void handle_event(BYTE *msg, int len) msg+I4B_MON_LOGEVNT_WHAT, msg+I4B_MON_LOGEVNT_MSG); break; - + case I4B_MON_CHRG_CODE: print_charge(I4B_GET_4B(msg, I4B_MON_CHRG_TSTAMP), + I4B_GET_4B(msg, I4B_MON_CHRG_CTRL), I4B_GET_4B(msg, I4B_MON_CHRG_CHANNEL), I4B_GET_4B(msg, I4B_MON_CHRG_UNITS), I4B_GET_4B(msg, I4B_MON_CHRG_ESTIMATED)); @@ -538,6 +853,7 @@ static void handle_event(BYTE *msg, int len) print_connect( I4B_GET_4B(msg, I4B_MON_CONNECT_TSTAMP), I4B_GET_4B(msg, I4B_MON_CONNECT_DIR), + I4B_GET_4B(msg, I4B_MON_CONNECT_CTRL), I4B_GET_4B(msg, I4B_MON_CONNECT_CHANNEL), msg+I4B_MON_CONNECT_CFGNAME, msg+I4B_MON_CONNECT_DEVNAME, @@ -548,34 +864,58 @@ static void handle_event(BYTE *msg, int len) case I4B_MON_DISCONNECT_CODE: print_disconnect( I4B_GET_4B(msg, I4B_MON_DISCONNECT_TSTAMP), + I4B_GET_4B(msg, I4B_MON_DISCONNECT_CTRL), I4B_GET_4B(msg, I4B_MON_DISCONNECT_CHANNEL)); break; case I4B_MON_UPDOWN_CODE: print_updown( I4B_GET_4B(msg, I4B_MON_UPDOWN_TSTAMP), + I4B_GET_4B(msg, I4B_MON_UPDOWN_CTRL), I4B_GET_4B(msg, I4B_MON_UPDOWN_CHANNEL), I4B_GET_4B(msg, I4B_MON_UPDOWN_ISUP)); break; - + case I4B_MON_L12STAT_CODE: + print_l12stat( + I4B_GET_4B(msg, I4B_MON_L12STAT_TSTAMP), + I4B_GET_4B(msg, I4B_MON_L12STAT_CTRL), + I4B_GET_4B(msg, I4B_MON_L12STAT_LAYER), + I4B_GET_4B(msg, I4B_MON_L12STAT_STATE)); + break; + case I4B_MON_TEI_CODE: + print_tei( + I4B_GET_4B(msg, I4B_MON_TEI_TSTAMP), + I4B_GET_4B(msg, I4B_MON_TEI_CTRL), + I4B_GET_4B(msg, I4B_MON_TEI_TEI)); + break; + case I4B_MON_ACCT_CODE: + print_acct( + I4B_GET_4B(msg, I4B_MON_ACCT_TSTAMP), + I4B_GET_4B(msg, I4B_MON_ACCT_CTRL), + I4B_GET_4B(msg, I4B_MON_ACCT_CHAN), + I4B_GET_4B(msg, I4B_MON_ACCT_OBYTES), + I4B_GET_4B(msg, I4B_MON_ACCT_OBPS), + I4B_GET_4B(msg, I4B_MON_ACCT_IBYTES), + I4B_GET_4B(msg, I4B_MON_ACCT_IBPS)); + break; default: - printf("unknown event code: %d\n", I4B_GET_2B(msg, I4B_MON_EVNT)); + mprintf("unknown event code: %d\n", I4B_GET_2B(msg, I4B_MON_EVNT)); } break; - case 3: /* one record in a list of monitor rights */ + case ST_RIGHT: /* one record in a list of monitor rights */ rights = I4B_GET_4B(msg, I4B_MON_DR_RIGHTS); net = I4B_GET_4B(msg, I4B_MON_DR_NET); mask = I4B_GET_4B(msg, I4B_MON_DR_MASK); local = I4B_GET_1B(msg, I4B_MON_DR_LOCAL); - if (local) + if(local) { - printf("\tlocal: rights = %x\n", rights); + mprintf("\tlocal: rights = %x\n", rights); } else { - printf("\tfrom: %d.%d.%d.%d, mask %d.%d.%d.%d, rights = %x\n", + mprintf("\tfrom: %d.%d.%d.%d, mask %d.%d.%d.%d, rights = %x\n", (net >> 24) & 0x00ff, (net >> 16) & 0x00ff, (net >> 8) & 0x00ff, net & 0x00ff, (mask >> 24) & 0x00ff, (mask >> 16) & 0x00ff, (mask >> 8) & 0x00ff, mask & 0x00ff, rights); @@ -583,32 +923,32 @@ static void handle_event(BYTE *msg, int len) sub_state++; - if (sub_state >= sub_state_count) + if(sub_state >= sub_state_count) { - state = 2; - print_menu(); + state = ST_ANYEV; + print_initialization(); } break; - case 4: + case ST_CONNS: who = I4B_GET_4B(msg, I4B_MON_DC_WHO); rights = I4B_GET_4B(msg, I4B_MON_DC_RIGHTS); - printf("\tfrom: %d.%d.%d.%d, rights = %x\n", + mprintf("\tfrom: %d.%d.%d.%d, rights = %x\n", (who >> 24) & 0x00ff, (who >> 16) & 0x00ff, (who >> 8) & 0x00ff, who & 0x00ff, rights); sub_state++; - if (sub_state >= sub_state_count) + if(sub_state >= sub_state_count) { - state = 2; - print_menu(); + state = ST_ANYEV; + print_initialization(); } break; default: - printf("unknown event from remote: local state = %d, evnt = %x, len = %d\n", + mprintf("unknown event from remote: local state = %d, evnt = %x, len = %d\n", state, I4B_GET_2B(msg, I4B_MON_EVNT), len); } } @@ -616,68 +956,92 @@ static void handle_event(BYTE *msg, int len) /* * Process input from user */ -static void handle_input() +static void +handle_input() { char buf[1024]; - int channel; + int channel, controller; - fgets(buf, sizeof buf, stdin); + fgets(buf, sizeof(buf), stdin); - switch (atoi(buf)) + switch(atoi(buf)) { case 1: { - BYTE cmd[I4B_MON_DUMPRIGHTS_SIZE]; + u_int8_t cmd[I4B_MON_DUMPRIGHTS_SIZE]; I4B_PREP_CMD(cmd, I4B_MON_DUMPRIGHTS_CODE); #ifdef DEBUG - if (dumpall) + if(debug & DBG_DUMPALL) dump_event(cmd, I4B_MON_DUMPRIGHTS_SIZE, 0); #endif - write(monsock, cmd, I4B_MON_DUMPRIGHTS_SIZE); + if((sock_write(monsock, cmd, I4B_MON_DUMPRIGHTS_SIZE)) == -1) + { + fprintf(stderr, "sock_write failed: %s\n", strerror(errno)); + exit(1); + } } break; case 2: { - BYTE cmd[I4B_MON_DUMPMCONS_SIZE]; + u_int8_t cmd[I4B_MON_DUMPMCONS_SIZE]; I4B_PREP_CMD(cmd, I4B_MON_DUMPMCONS_CODE); #ifdef DEBUG - if (dumpall) + if(debug & DBG_DUMPALL) dump_event(cmd, I4B_MON_DUMPMCONS_CODE, 0); #endif - write(monsock, cmd, I4B_MON_DUMPMCONS_SIZE); + if((sock_write(monsock, cmd, I4B_MON_DUMPMCONS_SIZE)) == -1) + { + fprintf(stderr, "sock_write failed: %s\n", strerror(errno)); + exit(1); + } } break; case 3: { - BYTE cmd[I4B_MON_CFGREREAD_SIZE]; + u_int8_t cmd[I4B_MON_CFGREREAD_SIZE]; I4B_PREP_CMD(cmd, I4B_MON_CFGREREAD_CODE); #ifdef DEBUG - if (dumpall) + if(debug & DBG_DUMPALL) dump_event(cmd, I4B_MON_CFGREREAD_CODE, 0); #endif - write(monsock, cmd, I4B_MON_CFGREREAD_SIZE); + if((sock_write(monsock, cmd, I4B_MON_CFGREREAD_SIZE)) == -1) + { + fprintf(stderr, "sock_write failed: %s\n", strerror(errno)); + exit(1); + } } break; case 4: { - BYTE cmd[I4B_MON_HANGUP_SIZE]; + u_int8_t cmd[I4B_MON_HANGUP_SIZE]; I4B_PREP_CMD(cmd, I4B_MON_HANGUP_CODE); + + printf("Which controller you wish to hangup? "); + fgets(buf, sizeof(buf), stdin); + controller = atoi(buf); + I4B_PUT_4B(cmd, I4B_MON_HANGUP_CTRL, controller); + printf("Which channel do you wish to hangup? "); - fgets(buf, sizeof buf, stdin); + fgets(buf, sizeof(buf), stdin); channel = atoi(buf); I4B_PUT_4B(cmd, I4B_MON_HANGUP_CHANNEL, channel); + #ifdef DEBUG - if (dumpall) + if(debug & DBG_DUMPALL) dump_event(cmd, I4B_MON_HANGUP_CHANNEL, 0); #endif - write(monsock, cmd, I4B_MON_HANGUP_SIZE); + if((sock_write(monsock, cmd, I4B_MON_HANGUP_SIZE)) == -1) + { + fprintf(stderr, "sock_write failed: %s\n", strerror(errno)); + exit(1); + } } break; @@ -692,12 +1056,141 @@ static void handle_input() } } +void +reread(void) +{ + u_int8_t cmd[I4B_MON_CFGREREAD_SIZE]; + I4B_PREP_CMD(cmd, I4B_MON_CFGREREAD_CODE); +#ifdef DEBUG + if(debug & DBG_DUMPALL) + dump_event(cmd, I4B_MON_CFGREREAD_CODE, 0); +#endif + if((sock_write(monsock, cmd, I4B_MON_CFGREREAD_SIZE)) == -1) + { + fprintf(stderr, "sock_write failed: %s\n", strerror(errno)); + exit(1); + } +} + +void +hangup(int ctrl, int chan) +{ + u_int8_t cmd[I4B_MON_HANGUP_SIZE]; + + I4B_PREP_CMD(cmd, I4B_MON_HANGUP_CODE); + I4B_PUT_4B(cmd, I4B_MON_HANGUP_CTRL, ctrl); + I4B_PUT_4B(cmd, I4B_MON_HANGUP_CHANNEL, chan); + +#ifdef DEBUG + if(debug & DBG_DUMPALL) + dump_event(cmd, I4B_MON_HANGUP_CHANNEL, 0); +#endif + + if((sock_write(monsock, cmd, I4B_MON_HANGUP_SIZE)) == -1) + { + fprintf(stderr, "sock_write failed: %s\n", strerror(errno)); + exit(1); + } +} + /* * Display menu */ -static void print_menu() +static void +print_menu() { - printf("Menu: <1> display rights, <2> display monitor connections,\n"); - printf(" <3> reread config file, <4> hangup \n"); - printf(" <9> quit isdnmonitor\n"); + if(!fullscreen) + { + printf("Menu: <1> display rights, <2> display monitor connections,\n"); + printf(" <3> reread config file, <4> hangup \n"); + printf(" <9> quit isdnmonitor\n"); + fflush(stdout); + } } + +static ssize_t +sock_read(int fd, void *buf, size_t nbytes) +{ + size_t nleft; + ssize_t nread; + unsigned char *ptr; + + ptr = buf; + nleft = nbytes; + + while(nleft > 0) + { + if((nread = read(fd, ptr, nleft)) < 0) + { + if(errno == EINTR) + { + nread = 0; + } + else + { + return(-1); + } + } + else if(nread == 0) + { + break; /* EOF */ + } + + nleft -= nread; + ptr += nread; + } + return(nbytes - nleft); +} + +static ssize_t +sock_write(int fd, void *buf, size_t nbytes) +{ + size_t nleft; + ssize_t nwritten; + unsigned char *ptr; + + ptr = buf; + nleft = nbytes; + + while(nleft > 0) + { + if((nwritten = write(fd, ptr, nleft)) <= 0) + { + if(errno == EINTR) + { + nwritten = 0; + } + else + { + return(-1); + } + } + + nleft -= nwritten; + ptr += nwritten; + } + return(nbytes); +} + +static void +mprintf(char *fmt, ...) +{ +#define PRBUFLEN 1024 + char buffer[PRBUFLEN]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buffer, PRBUFLEN-1, fmt, ap); + va_end(ap); + + if(!fullscreen || (fullscreen && (!curses_ready))) + printf("%s", buffer); + + if(logfilename != NULL) + { + fprintf(lfp, "%s", buffer); + fflush(lfp); + } +} + +/* EOF */ |