summaryrefslogtreecommitdiffstats
path: root/usr.sbin/i4b/isdnmonitor
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1998-12-27 21:47:14 +0000
committerphk <phk@FreeBSD.org>1998-12-27 21:47:14 +0000
commitc7ecc129d72ba32b5d83c9a6019e93fd181d719c (patch)
tree8d5099bc7ef24151b4f6deb00d1d34a7e7ac694a /usr.sbin/i4b/isdnmonitor
parent3f431df8ec46b86090ad59ee153872c45d4d429d (diff)
downloadFreeBSD-src-c7ecc129d72ba32b5d83c9a6019e93fd181d719c.zip
FreeBSD-src-c7ecc129d72ba32b5d83c9a6019e93fd181d719c.tar.gz
Initial entry of ISDN4BSD into the FreeBSD tree.
ISDN4BSD is the work of our brand-new comitter: Hellmuth Michaelis, who has done a tremendous amount of work to bring us this far. There are still some outstanding issues and files to bring into the tree, and for now it will be needed to pick up all the extra docs from the isdn4bsd release. It is probably also a very good idea to subscribe to the isdn@freebsd.org mailing list before you try this out. These files correspond to release "beta Version 0.70.00 / December 1998" from Hellmuth.
Diffstat (limited to 'usr.sbin/i4b/isdnmonitor')
-rw-r--r--usr.sbin/i4b/isdnmonitor/Makefile8
-rw-r--r--usr.sbin/i4b/isdnmonitor/isdnmonitor.840
-rw-r--r--usr.sbin/i4b/isdnmonitor/main.c675
-rw-r--r--usr.sbin/i4b/isdnmonitor/monitor.h263
4 files changed, 986 insertions, 0 deletions
diff --git a/usr.sbin/i4b/isdnmonitor/Makefile b/usr.sbin/i4b/isdnmonitor/Makefile
new file mode 100644
index 0000000..9d3811b
--- /dev/null
+++ b/usr.sbin/i4b/isdnmonitor/Makefile
@@ -0,0 +1,8 @@
+PROG = isdnmonitor
+SRCS = main.c
+MAN8 = isdnmonitor.8
+
+# compile debug support
+COPTS += -DDEBUG
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/i4b/isdnmonitor/isdnmonitor.8 b/usr.sbin/i4b/isdnmonitor/isdnmonitor.8
new file mode 100644
index 0000000..9bcb783
--- /dev/null
+++ b/usr.sbin/i4b/isdnmonitor/isdnmonitor.8
@@ -0,0 +1,40 @@
+.\" Copyright (c) 1998 Martin Husemann <martin@rumolt.teuto.de>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. The name of the author may not be used to endorse or promote products
+.\" derived from this software withough specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $Id: isdnmonitor.8,v 1.2 1998/08/10 13:55:29 hm Exp $
+.\"
+.\" last edit-date: [Fri Jan 30 22:49:48 1998]
+.\"
+.\" -mh writing manual pages
+.\"
+.\"
+.Dd April 18, 1998
+.Dt isdnmonitor 8
+.Sh NAME
+.Nm isdnmonitor
+.Nd raw sample and test client for isdnd network monitoring
+.Sh DESCRIPTION
+The
+.Nm
+is not intended for real world use. It will be replaced
+by something with a better user interface as soon as the monitoring
+subsystem is functional.
diff --git a/usr.sbin/i4b/isdnmonitor/main.c b/usr.sbin/i4b/isdnmonitor/main.c
new file mode 100644
index 0000000..73ae8fe
--- /dev/null
+++ b/usr.sbin/i4b/isdnmonitor/main.c
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 1998 Martin Husemann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 4. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software and/or documentation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * i4b daemon - network monitor client
+ * -----------------------------------
+ *
+ * $Id: main.c,v 1.9 1998/10/27 10:54:23 hm Exp $
+ *
+ * last edit-date: [Tue Oct 27 11:53:12 1998]
+ *
+ * -mh created
+ * -hm checking in
+ * -hm porting to HPUX
+ * -mh all events the fullscreen mode displays now as monitor event
+ *
+ *---------------------------------------------------------------------------*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <machine/i4b_ioctl.h>
+
+#ifdef __hpux
+#define AF_LOCAL AF_UNIX
+#endif
+
+#ifdef DEBUG
+#include <ctype.h>
+#endif
+
+#include "monitor.h"
+
+/*
+ * Local function prototypes
+ */
+static int connect_local(const char *sockpath);
+static int connect_remote(const 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);
+#ifdef DEBUG
+static void dump_event(BYTE *msg, int len);
+#endif
+
+/*
+ * Global variables
+ */
+static int dumpall = 0;
+static int monsock = -1;
+static int state = 0;
+static int sub_state = 0;
+static int sub_state_count = 0;
+
+static int major = 0;
+static int minor = 0;
+static int nctrl = 0;
+static u_int32_t rights = 0;
+
+/*
+ * 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:")) != EOF)
+ {
+ switch (i)
+ {
+ case 'd':
+ dumpall = 1;
+ break;
+ case 'h':
+ hostname = optarg;
+ break;
+ case 'l':
+ sockpath = optarg;
+ break;
+ case 'p':
+ if ((sscanf(optarg, "%i", &portno)) != 1)
+ usage();
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ 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)
+ {
+ monsock = connect_local(sockpath);
+ }
+ else if (hostname)
+ {
+ monsock = connect_remote(hostname, portno);
+ }
+ else
+ {
+ usage();
+ }
+
+ if (monsock == -1)
+ {
+ fprintf(stderr, "Could not connect to i4b isdn daemon.\n");
+ return 1;
+ }
+
+ signal(SIGPIPE, SIG_IGN);
+ mloop();
+
+ close(monsock);
+
+ 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)
+{
+ struct sockaddr_in sa;
+ struct hostent *h;
+ int remotesockfd;
+
+ h = gethostbyname(host);
+
+ if (!h)
+ {
+ fprintf(stderr, "could not resolve hostname '%s'\n", host);
+ exit(1);
+ }
+
+ remotesockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (remotesockfd == -1)
+ {
+ fprintf(stderr, "could not create remote monitor socket: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ memset(&sa, 0, sizeof sa);
+
+#ifdef BSD4_4
+ 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);
+
+ if (connect(remotesockfd, (struct sockaddr *)&sa, sizeof sa) == -1)
+ {
+ fprintf(stderr, "could not connect remote monitor: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ return remotesockfd;
+}
+
+/*
+ * Connect local.
+ * Return socket on success, -1 on failure.
+ */
+static int connect_local(const char *sockpath)
+{
+ int s;
+ struct sockaddr_un sa;
+
+ /* check path length */
+ if (strlen(sockpath) >= sizeof sa.sun_path)
+ {
+ fprintf(stderr, "pathname to long for local socket: %s\n",
+ sockpath);
+ exit(1);
+ }
+
+ /* create and setup socket */
+ s = socket(AF_LOCAL, SOCK_STREAM, 0);
+
+ 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
+
+ sa.sun_family = AF_LOCAL;
+ strcpy(sa.sun_path, sockpath);
+
+ if (connect(s, (struct sockaddr *)&sa, sizeof sa))
+ {
+ fprintf(stderr, "could not connect local monitor socket [%s]: %s\n", sockpath, strerror(errno));
+ }
+
+ return s;
+}
+
+/*
+ * main event loop
+ */
+static void mloop()
+{
+ for (;;)
+ {
+ fd_set rd, wr, ex;
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&ex);
+ FD_SET(fileno(stdin), &rd);
+ FD_SET(monsock, &rd);
+
+ select(monsock+1, &rd, &wr, &ex, NULL);
+
+ if (FD_ISSET(fileno(stdin), &rd))
+ {
+ handle_input();
+ }
+
+ if (FD_ISSET(monsock, &rd))
+ {
+ BYTE buf[1024];
+ u_long u;
+ 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 < I4B_MON_EVNT_HDR)
+ continue; /* errh? something must be wrong... */
+
+ bytes = I4B_GET_2B(buf, I4B_MON_EVNT_LEN);
+
+ if (bytes >= sizeof buf)
+ break;
+
+ /* now we know the size, it fits, so lets read it! */
+
+ ret = read(monsock, buf, bytes);
+
+ if (ret == 0)
+ {
+ printf("remote isdnd has closed our connection\n");
+ break;
+ }
+ else if (ret < 0)
+ {
+ printf("error reading from isdnd: %s", strerror(errno));
+ break;
+ }
+#ifdef DEBUG
+ if (dumpall)
+ dump_event(buf, ret);
+#endif
+ handle_event(buf, ret);
+ }
+ }
+}
+
+#ifdef DEBUG
+/*
+ * Dump a complete event packet.
+ */
+static void dump_event(BYTE *msg, int len)
+{
+ int i;
+
+ printf("event dump:");
+
+ for (i = 0; i < len; i++)
+ {
+ if (i % 8 == 0)
+ printf("\n%02x: ", i);
+ printf("%02x %c ", msg[i], isprint(msg[i]) ? msg[i] : '.');
+ }
+ printf("\n");
+}
+#endif
+
+static void print_logevent(time_t tstamp, int prio, const char * what, const 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);
+}
+
+static void print_charge(time_t tstamp, 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)" : "");
+}
+
+/*
+ * Print a connect event.
+ * A real monitor would allocate state info for "channel" on this
+ * event.
+ */
+static void print_connect(
+ time_t tstamp, /* server time of event */
+ int outgoing, /* 0 = incoming, 1 = outgoing */
+ 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 buf[256];
+ strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp));
+
+ if (outgoing)
+ printf("%s: calling out to '%s' [from msn: '%s']",
+ buf, remphone, locphone);
+ else
+ printf("%s: incoming call from '%s' [to msn: '%s']",
+ buf, remphone, locphone);
+ printf(", channel %d, config '%s' on device '%s'\n",
+ channel, cfgname, devname);
+}
+
+/*
+ * Print a disconnect event.
+ * A real monitor could free the "per connection" state
+ * for this channel now
+ */
+static void print_disconnect(time_t tstamp, int channel)
+{
+ char buf[256];
+ strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp));
+ printf("%s: channel %d disconnected\n",
+ buf, channel);
+}
+
+/*
+ * Print an up- or down event
+ */
+static void print_updown(time_t tstamp, int channel, int isup)
+{
+ char buf[256];
+ strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp));
+ printf("%s: channel %d is %s\n",
+ buf, channel, isup ? "up" : "down");
+}
+
+/*
+ * Dispatch one message received from the daemon.
+ */
+static void handle_event(BYTE *msg, int len)
+{
+ BYTE cmd[I4B_MON_ICLIENT_SIZE];
+ int local;
+ u_int32_t net;
+ u_int32_t mask;
+ u_int32_t who;
+
+ switch (state)
+ {
+ case 0: /* initial data */
+
+ major = I4B_GET_2B(msg, I4B_MON_IDATA_VERSMAJOR);
+ minor = I4B_GET_2B(msg, I4B_MON_IDATA_VERSMINOR);
+ nctrl = I4B_GET_2B(msg, I4B_MON_IDATA_NUMCTRL);
+ rights = I4B_GET_4B(msg, I4B_MON_IDATA_CLACCESS);
+
+ printf("remote protocol version is %02d.%02d, %d controller(s) found, our rights = %x\n",
+ major, minor, nctrl, rights);
+
+ if (nctrl > 0)
+ {
+ state = 1;
+ sub_state = 0;
+ }
+ else
+ {
+ state = 2;
+
+ /* show menu for the first time */
+ print_menu();
+ }
+
+ /* set maximum event mask */
+ I4B_PREP_CMD(cmd, I4B_MON_CCMD_SETMASK);
+ I4B_PUT_2B(cmd, I4B_MON_ICLIENT_VERMAJOR, MPROT_VERSION);
+ I4B_PUT_2B(cmd, I4B_MON_ICLIENT_VERMINOR, MPROT_REL);
+ I4B_PUT_4B(cmd, I4B_MON_ICLIENT_EVENTS, ~0U);
+
+ write(monsock, cmd, sizeof cmd);
+
+ break;
+
+ case 1: /* initial controller list */
+ printf("controller %d: %s\n", sub_state++, msg+I4B_MON_ICTRL_NAME);
+
+ if (sub_state >= nctrl)
+ {
+ state = 2; /* end of list reached */
+ sub_state = 0;
+
+ /* show menu for the first time */
+ print_menu();
+ }
+ break;
+
+ case 2: /* any event */
+
+ switch (I4B_GET_2B(msg, I4B_MON_EVNT))
+ {
+ case I4B_MON_DRINI_CODE:
+ state = 3; /* list of rights entries will follow */
+ sub_state = 0;
+ sub_state_count = I4B_GET_2B(msg, I4B_MON_DRINI_COUNT);
+ printf("monitor rights:\n");
+ break;
+
+ case I4B_MON_DCINI_CODE:
+ state = 4;
+ sub_state = 0;
+ sub_state_count = I4B_GET_2B(msg, I4B_MON_DCINI_COUNT);
+ printf("monitor connections:\n");
+ break;
+
+ case I4B_MON_LOGEVNT_CODE:
+ print_logevent(I4B_GET_4B(msg, I4B_MON_LOGEVNT_TSTAMP),
+ I4B_GET_4B(msg, I4B_MON_LOGEVNT_PRIO),
+ 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_CHANNEL),
+ I4B_GET_4B(msg, I4B_MON_CHRG_UNITS),
+ I4B_GET_4B(msg, I4B_MON_CHRG_ESTIMATED));
+ break;
+
+ case I4B_MON_CONNECT_CODE:
+ 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_CHANNEL),
+ msg+I4B_MON_CONNECT_CFGNAME,
+ msg+I4B_MON_CONNECT_DEVNAME,
+ msg+I4B_MON_CONNECT_REMPHONE,
+ msg+I4B_MON_CONNECT_LOCPHONE);
+ break;
+
+ case I4B_MON_DISCONNECT_CODE:
+ print_disconnect(
+ I4B_GET_4B(msg, I4B_MON_DISCONNECT_TSTAMP),
+ 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_CHANNEL),
+ I4B_GET_4B(msg, I4B_MON_UPDOWN_ISUP));
+ break;
+
+ default:
+ printf("unknown event code: %d\n", I4B_GET_2B(msg, I4B_MON_EVNT));
+ }
+ break;
+
+ case 3: /* 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)
+ {
+ printf("\tlocal: rights = %x\n", rights);
+ }
+ else
+ {
+ printf("\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);
+ }
+
+ sub_state++;
+
+ if (sub_state >= sub_state_count)
+ {
+ state = 2;
+ print_menu();
+ }
+ break;
+
+ case 4:
+ 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",
+ (who >> 24) & 0x00ff, (who >> 16) & 0x00ff, (who >> 8) & 0x00ff, who & 0x00ff,
+ rights);
+
+ sub_state++;
+
+ if (sub_state >= sub_state_count)
+ {
+ state = 2;
+ print_menu();
+ }
+ break;
+
+ default:
+ printf("unknown event from remote: local state = %d, evnt = %x, len = %d\n",
+ state, I4B_GET_2B(msg, I4B_MON_EVNT), len);
+ }
+}
+
+/*
+ * Process input from user
+ */
+static void handle_input()
+{
+ char buf[1024];
+ int channel;
+
+ fgets(buf, sizeof buf, stdin);
+
+ switch (atoi(buf))
+ {
+ case 1:
+ {
+ BYTE cmd[I4B_MON_DUMPRIGHTS_SIZE];
+ I4B_PREP_CMD(cmd, I4B_MON_DUMPRIGHTS_CODE);
+ write(monsock, cmd, I4B_MON_DUMPRIGHTS_SIZE);
+ }
+ break;
+
+ case 2:
+ {
+ BYTE cmd[I4B_MON_DUMPMCONS_SIZE];
+ I4B_PREP_CMD(cmd, I4B_MON_DUMPMCONS_CODE);
+ write(monsock, cmd, I4B_MON_DUMPMCONS_SIZE);
+ }
+ break;
+
+ case 3:
+ {
+ BYTE cmd[I4B_MON_CFGREREAD_SIZE];
+ I4B_PREP_CMD(cmd, I4B_MON_CFGREREAD_CODE);
+ write(monsock, cmd, I4B_MON_CFGREREAD_SIZE);
+ }
+ break;
+
+ case 4:
+ {
+ BYTE cmd[I4B_MON_HANGUP_SIZE];
+ I4B_PREP_CMD(cmd, I4B_MON_HANGUP_CODE);
+ printf("Which channel do you wish to hangup? ");
+ fgets(buf, sizeof buf, stdin);
+ channel = atoi(buf);
+ I4B_PUT_4B(cmd, I4B_MON_HANGUP_CHANNEL, channel);
+ write(monsock, cmd, I4B_MON_HANGUP_SIZE);
+ }
+ break;
+
+ case 9:
+ close(monsock);
+ exit(0);
+ break;
+
+ default:
+ print_menu();
+ break;
+ }
+}
+
+/*
+ * Display 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");
+}
diff --git a/usr.sbin/i4b/isdnmonitor/monitor.h b/usr.sbin/i4b/isdnmonitor/monitor.h
new file mode 100644
index 0000000..0025449
--- /dev/null
+++ b/usr.sbin/i4b/isdnmonitor/monitor.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1998 Martin Husemann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 4. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software and/or documentation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * i4b daemon - network monitor protocl definition
+ * -----------------------------------------------
+ *
+ * $Id: monitor.h,v 1.4 1998/08/10 13:55:32 hm Exp $
+ *
+ * last edit-date: [Mon Aug 3 06:52:06 1998]
+ *
+ * -mh created
+ * -hm checking in
+ * -hm ported to HPUX 10.10
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifndef MONITOR_H
+#define MONITOR_H
+
+#define DEF_MONPORT 451 /* default monitor TCP port */
+
+#ifdef __hpux
+#define u_int8_t ubit8
+#define u_int32_t ubit32
+#endif
+#ifdef _WIN32
+#define u_int8_t BYTE
+#define u_in32_t DWORD
+#endif
+
+/*
+ * The monitor client connects to the isdnd daemon process via a tcp/ip
+ * connection from a remote machine or via a local (unix domain) socket.
+ * The daemon accepts multiple connections and verifies access rights.
+ * On connection establishment the daemon sends initial data telling
+ * the client the current configuration: number and type of available
+ * controllers, current connections, channel and interface states
+ * and the clients access privileges. The client sends an event mask
+ * telling the daemon which events it is interested in. If the client
+ * has appropriate rights he may send commands to the daemon.
+ *
+ * All multi-byte values are in network byte order!
+ */
+
+/* All data packets transfered are declared as arrays of BYTE */
+#define BYTE u_int8_t
+
+/* max stringlength used in this protocol */
+#define I4B_MAX_MON_STRING 256
+
+/* max command size from client to server */
+#define I4B_MAX_MON_CLIENT_CMD 16
+
+/* Version of the monitor protocol described here */
+#define MPROT_VERSION 0 /* major version no */
+#define MPROT_REL 1 /* release no */
+/*
+ * We intend to keep different versions of monitor client and isdnd
+ * interoperable as long as possible. We do not, however, even try
+ * to do this during early alpha or beta release phases. If you run
+ * developement versions at this stage, make sure all your clients
+ * and servers run the same version!
+ */
+
+/*
+ * Client access rights
+ */
+#define I4B_CA_COMMAND_FULL 1 /* may send any command */
+#define I4B_CA_COMMAND_RESTRICTED 2 /* may send 'harmless' commands */
+#define I4B_CA_EVNT_CHANSTATE 16 /* may watch b-channel states */
+#define I4B_CA_EVNT_CALLIN 32 /* may watch incoming calls */
+#define I4B_CA_EVNT_CALLOUT 64 /* may watch outgoing calls */
+#define I4B_CA_EVNT_I4B 128 /* may watch isdnd actions */
+
+/*
+ * General layout of a command packet. All commands have this common
+ * prefix. It is prepared by the macro I4B_PREP_CMD (s.b.)
+ */
+#define I4B_MON_CMD 0 /* 2 byte: command code */
+#define I4B_MON_CMD_LEN 2 /* 2 byte: packet length */
+#define I4B_MON_CMD_HDR 4 /* size of header */
+
+/*
+ * Currently events look the same as commands. We do not make
+ * any guarantee this will remain the same, so a different set
+ * of macros is used when describing events. Events are prepared
+ * by I4B_PREP_EVNT (s.b.)
+ */
+#define I4B_MON_EVNT 0 /* 2 byte: event code */
+#define I4B_MON_EVNT_LEN 2 /* 2 byte: packet length */
+#define I4B_MON_EVNT_HDR 4 /* size of header */
+
+/* Initial data send by daemon after connection is established */
+#define I4B_MON_IDATA_SIZE I4B_MON_EVNT_HDR+10
+#define I4B_MON_IDATA_CODE 0 /* event code */
+#define I4B_MON_IDATA_VERSMAJOR I4B_MON_EVNT_HDR+0 /* 2 byte: isdnd major version */
+#define I4B_MON_IDATA_VERSMINOR I4B_MON_EVNT_HDR+2 /* 2 byte: isdnd minor version */
+#define I4B_MON_IDATA_NUMCTRL I4B_MON_EVNT_HDR+4 /* 2 byte: number of controllers */
+#define I4B_MON_IDATA_CLACCESS I4B_MON_EVNT_HDR+6 /* 4 byte: client rights */
+
+/* followed by this for every controller */
+#define I4B_MON_ICTRL_SIZE I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+8
+#define I4B_MON_ICTRL_CODE 1 /* event code */
+#define I4B_MON_ICTRL_NAME I4B_MON_EVNT_HDR+0 /* string: name of controller */
+#define I4B_MON_ICTRL_BUSID I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+0 /* 2 byte: isdn bus id (reservered) */
+#define I4B_MON_ICTRL_FLAGS I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+2 /* 4 byte: controller flags (not yet defined) */
+#define I4B_MON_ICTRL_NCHAN I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+6 /* 2 byte: number of b channels on this controller */
+
+/* The client sets it's protocol version and event mask (usualy once after
+ * connection establishement) */
+#define I4B_MON_CCMD_SETMASK 0x7e /* command code */
+#define I4B_MON_ICLIENT_SIZE I4B_MON_CMD_HDR+8
+#define I4B_MON_ICLIENT_VERMAJOR I4B_MON_CMD_HDR+0 /* 2 byte: protocol major version (always 0 for now) */
+#define I4B_MON_ICLIENT_VERMINOR I4B_MON_CMD_HDR+2 /* 2 byte: protocol minor version (always 0 for now) */
+#define I4B_MON_ICLIENT_EVENTS I4B_MON_CMD_HDR+4 /* 4 byte: client event mask */
+
+/* The client requests a list of monitor rights */
+#define I4B_MON_DUMPRIGHTS_CODE 1
+#define I4B_MON_DUMPRIGHTS_SIZE I4B_MON_CMD_HDR /* no parameters */
+
+/* in response to a I4B_MON_DUMPRIGHTS_CODE command, the daemon sends
+ * this event: */
+#define I4B_MON_DRINI_CODE 2 /* event code */
+#define I4B_MON_DRINI_SIZE I4B_MON_EVNT_HDR+2 /* size of packet */
+#define I4B_MON_DRINI_COUNT I4B_MON_EVNT_HDR+0 /* 2 byte: number of records */
+
+/* followed by this for each record anounced above */
+#define I4B_MON_DR_CODE 3
+#define I4B_MON_DR_SIZE I4B_MON_EVNT_HDR+13
+#define I4B_MON_DR_RIGHTS I4B_MON_EVNT_HDR+0 /* 4 byte: rights mask */
+#define I4B_MON_DR_NET I4B_MON_EVNT_HDR+4 /* 4 byte: network address */
+#define I4B_MON_DR_MASK I4B_MON_EVNT_HDR+8 /* 4 byte: network mask */
+#define I4B_MON_DR_LOCAL I4B_MON_EVNT_HDR+12 /* 1 byte: non-zero if local socket */
+
+/* The client requests a list of monitor connections */
+#define I4B_MON_DUMPMCONS_CODE 2
+#define I4B_MON_DUMPMCONS_SIZE I4B_MON_CMD_HDR /* no parameters */
+
+/* in response to a I4B_MON_DUMPMCONS_CODE command, the daemon sends
+ * this event: */
+#define I4B_MON_DCINI_CODE 4 /* event code */
+#define I4B_MON_DCINI_SIZE I4B_MON_EVNT_HDR+2 /* size of packet */
+#define I4B_MON_DCINI_COUNT I4B_MON_EVNT_HDR+0 /* 2 byte: number of records */
+
+/* followed by this for each record anounced above */
+#define I4B_MON_DC_CODE 5
+#define I4B_MON_DC_SIZE I4B_MON_EVNT_HDR+8
+#define I4B_MON_DC_RIGHTS I4B_MON_EVNT_HDR+0 /* 4 byte: rights mask */
+#define I4B_MON_DC_WHO I4B_MON_EVNT_HDR+4 /* 4 byte: network address */
+
+/* The client requests a config file rescan */
+#define I4B_MON_CFGREREAD_CODE 3
+#define I4B_MON_CFGREREAD_SIZE I4B_MON_CMD_HDR /* no parameters */
+
+/* The client requests to hangup a connection */
+#define I4B_MON_HANGUP_CODE 4
+#define I4B_MON_HANGUP_SIZE I4B_MON_CMD_HDR+4
+#define I4B_MON_HANGUP_CHANNEL I4B_MON_CMD_HDR+0 /* channel to drop */
+
+/* The daemon sends a logfile event */
+#define I4B_MON_LOGEVNT_CODE 6
+#define I4B_MON_LOGEVNT_SIZE I4B_MON_EVNT_HDR+8+2*I4B_MAX_MON_STRING
+#define I4B_MON_LOGEVNT_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: timestamp */
+#define I4B_MON_LOGEVNT_PRIO I4B_MON_EVNT_HDR+4 /* 4 byte: syslog priority */
+#define I4B_MON_LOGEVNT_WHAT I4B_MON_EVNT_HDR+8 /* followed by 2 strings: 'what' and 'message' */
+#define I4B_MON_LOGEVNT_MSG I4B_MON_EVNT_HDR+8+I4B_MAX_MON_STRING
+
+/* The daemon sends a charge event */
+#define I4B_MON_CHRG_CODE 7
+#define I4B_MON_CHRG_SIZE I4B_MON_EVNT_HDR+16
+#define I4B_MON_CHRG_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: timestamp */
+#define I4B_MON_CHRG_CHANNEL I4B_MON_EVNT_HDR+4 /* 4 byte: channel charged */
+#define I4B_MON_CHRG_UNITS I4B_MON_EVNT_HDR+8 /* 4 byte: new charge value */
+#define I4B_MON_CHRG_ESTIMATED I4B_MON_EVNT_HDR+12 /* 4 byte: 0 = charge by network, 1 = calculated estimate */
+
+/* The daemon sends a connect event */
+#define I4B_MON_CONNECT_CODE 8
+#define I4B_MON_CONNECT_SIZE I4B_MON_EVNT_HDR+12+4*I4B_MAX_MON_STRING
+#define I4B_MON_CONNECT_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
+#define I4B_MON_CONNECT_DIR I4B_MON_EVNT_HDR+4 /* 4 byte: direction (0 = incoming, 1 = outgoing) */
+#define I4B_MON_CONNECT_CHANNEL I4B_MON_EVNT_HDR+8 /* 4 byte: channel connected */
+#define I4B_MON_CONNECT_CFGNAME I4B_MON_EVNT_HDR+12 /* name of config entry */
+#define I4B_MON_CONNECT_DEVNAME I4B_MON_EVNT_HDR+12+I4B_MAX_MON_STRING /* name of device used for connection */
+#define I4B_MON_CONNECT_REMPHONE I4B_MON_EVNT_HDR+12+2*I4B_MAX_MON_STRING /* remote phone no. */
+#define I4B_MON_CONNECT_LOCPHONE I4B_MON_EVNT_HDR+12+3*I4B_MAX_MON_STRING /* local phone no. */
+
+/* The daemon sends a disconnect event */
+#define I4B_MON_DISCONNECT_CODE 9
+#define I4B_MON_DISCONNECT_SIZE I4B_MON_EVNT_HDR+8
+#define I4B_MON_DISCONNECT_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
+#define I4B_MON_DISCONNECT_CHANNEL I4B_MON_EVNT_HDR+4 /* 4 byte: channel disconnected */
+
+/* The daemon sends an up/down event */
+#define I4B_MON_UPDOWN_CODE 10
+#define I4B_MON_UPDOWN_SIZE I4B_MON_EVNT_HDR+12
+#define I4B_MON_UPDOWN_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
+#define I4B_MON_UPDOWN_CHANNEL I4B_MON_EVNT_HDR+4 /* 4 byte: channel disconnected */
+#define I4B_MON_UPDOWN_ISUP I4B_MON_EVNT_HDR+8 /* 4 byte: interface is up */
+
+/* macros for setup/decoding of protocol packets */
+
+/* clear a record */
+#define I4B_CLEAR(r) memset(&(r), 0, sizeof(r));
+
+/* prepare a record as event or command */
+#define I4B_PREP_EVNT(r, e) { \
+ I4B_CLEAR(r); \
+ I4B_PUT_2B(r, I4B_MON_EVNT, e); \
+ I4B_PUT_2B(r, I4B_MON_EVNT_LEN, sizeof(r)); \
+}
+#define I4B_PREP_CMD(r, c) { \
+ I4B_CLEAR(r); \
+ I4B_PUT_2B(r, I4B_MON_CMD, c); \
+ I4B_PUT_2B(r, I4B_MON_CMD_LEN, sizeof(r)); \
+}
+
+/* put 1, 2 or 4 bytes in network byte order into a record at offset off */
+#define I4B_PUT_1B(r, off, val) { ((BYTE*)(r))[off] = (val) & 0x00ff; }
+#define I4B_PUT_2B(r, off, val) { I4B_PUT_1B(r, off, val >> 8); I4B_PUT_1B(r, off+1, val); }
+#define I4B_PUT_4B(r, off, val) { I4B_PUT_1B(r, off, val >> 24); I4B_PUT_1B(r, off+1, val >> 16); I4B_PUT_1B(r, off+2, val >> 8); I4B_PUT_1B(r, off+3, val); }
+
+/* get 1, 2 or 4 bytes in network byte order from a record at offset off */
+#define I4B_GET_1B(r, off) (((BYTE*)(r))[off])
+#define I4B_GET_2B(r, off) ((((BYTE*)(r))[off]) << 8) | (((BYTE*)(r))[off+1])
+#define I4B_GET_4B(r, off) ((((BYTE*)(r))[off]) << 24) | ((((BYTE*)(r))[off+1]) << 16) | ((((BYTE*)(r))[off+2]) << 8) | (((BYTE*)(r))[off+3])
+
+/* put a string into recor r at offset off, make sure it's not to long
+ * and proper terminate it */
+#define I4B_PUT_STR(r, off, str) { \
+ strncpy(r+off, str, I4B_MAX_MON_STRING); \
+ r[off+I4B_MAX_MON_STRING-1] = (BYTE)0; }
+
+#endif /* MONITOR_H */
+
OpenPOWER on IntegriCloud