summaryrefslogtreecommitdiffstats
path: root/usr.sbin/i4b/isdnmonitor/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/i4b/isdnmonitor/main.c')
-rw-r--r--usr.sbin/i4b/isdnmonitor/main.c897
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 */
OpenPOWER on IntegriCloud