summaryrefslogtreecommitdiffstats
path: root/usr.sbin/i4b/isdntrace
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/isdntrace
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/isdntrace')
-rw-r--r--usr.sbin/i4b/isdntrace/1tr6.c754
-rw-r--r--usr.sbin/i4b/isdntrace/Makefile8
-rw-r--r--usr.sbin/i4b/isdntrace/cable.txt60
-rw-r--r--usr.sbin/i4b/isdntrace/isdntrace.8205
-rw-r--r--usr.sbin/i4b/isdntrace/pcause_1tr6.c164
-rw-r--r--usr.sbin/i4b/isdntrace/pcause_1tr6.h68
-rw-r--r--usr.sbin/i4b/isdntrace/pcause_q850.c328
-rw-r--r--usr.sbin/i4b/isdntrace/pcause_q850.h109
-rw-r--r--usr.sbin/i4b/isdntrace/q921.c275
-rw-r--r--usr.sbin/i4b/isdntrace/q931.c783
-rw-r--r--usr.sbin/i4b/isdntrace/q931_util.c697
-rw-r--r--usr.sbin/i4b/isdntrace/q932_fac.c926
-rw-r--r--usr.sbin/i4b/isdntrace/q932_fac.h174
-rw-r--r--usr.sbin/i4b/isdntrace/trace.c809
-rw-r--r--usr.sbin/i4b/isdntrace/trace.h90
15 files changed, 5450 insertions, 0 deletions
diff --git a/usr.sbin/i4b/isdntrace/1tr6.c b/usr.sbin/i4b/isdntrace/1tr6.c
new file mode 100644
index 0000000..1c8c184
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/1tr6.c
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * 1tr6.c - print 1TR6 protocol traces
+ * -----------------------------------
+ *
+ * $Id: 1tr6.c,v 1.4 1998/12/05 18:04:08 hm Exp $
+ *
+ * last edit-date: [Sat Dec 5 18:18:38 1998]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "trace.h"
+
+static int p_1tr6address(char *pbuf, unsigned char buf[]);
+static int p_1tr6cause(char *pbuf, unsigned char buf[]);
+
+/*---------------------------------------------------------------------------*
+ * decode the (german) national specific 1TR6 protocol
+ *---------------------------------------------------------------------------*/
+void
+decode_1tr6(char *pbuf, int n, int off, unsigned char *buf, int raw)
+{
+ int codeset = 0;
+ int oldcodeset = 0;
+ int codelock = 0;
+
+ int pd;
+ int len;
+ int j;
+ int i;
+
+ if(n <= 0)
+ return;
+
+ *pbuf = '\0';
+
+ if(raw)
+ {
+ for (i = 0; i < n; i += 16)
+ {
+ sprintf((pbuf+strlen(pbuf)),"Dump:%.3d ", i+off);
+ for (j = 0; j < 16; j++)
+ if (i + j < n)
+ sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
+ else
+ sprintf((pbuf+strlen(pbuf))," ");
+ sprintf((pbuf+strlen(pbuf))," ");
+ for (j = 0; j < 16 && i + j < n; j++)
+ if (isprint(buf[i + j]))
+ sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
+ else
+ sprintf((pbuf+strlen(pbuf)),".");
+ sprintf((pbuf+strlen(pbuf)),"\n");
+ }
+ }
+
+ sprintf((pbuf+strlen(pbuf)), "1TR6: ");
+
+ /* protocol discriminator */
+
+ i = 0;
+
+ pd = buf[i];
+
+ switch(pd)
+ {
+ case 0x40:
+ sprintf((pbuf+strlen(pbuf)), "pd=N0, ");
+ break;
+ case 0x41:
+ sprintf((pbuf+strlen(pbuf)), "pd=N1, ");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "pd=UNDEF (0x%02x), ",pd);
+ break;
+ }
+
+ /* call reference */
+
+ i++;
+
+ len = buf[i] & 0x0f;
+
+ switch(len)
+ {
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "cr=0x%02x %s, ", (buf[i+1] & 0x7f), (buf[i+1] & 0x80) ? "(from destination)" : "(from origination)");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "cr: LEN=%d %s 0x%02x 0x%02x, ", len, (buf[i+1] & 0x80) ? "org" : "dst", (buf[i+1] & 0x7f), (buf[i+2] & 0x7f));
+ break;
+ }
+
+ i += (len+1);
+
+ /* message type */
+
+ sprintf((pbuf+strlen(pbuf)), "message=");
+
+ if(pd == 0x40) /* protocol discriminator N0 */
+ {
+ switch(buf[i])
+ {
+ case 0x61:
+ sprintf((pbuf+strlen(pbuf)), "REGISTER INDICATION: ");
+ break;
+ case 0x62:
+ sprintf((pbuf+strlen(pbuf)), "CANCEL INDICATION: ");
+ break;
+ case 0x63:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY STATUS: ");
+ break;
+ case 0x64:
+ sprintf((pbuf+strlen(pbuf)), "STATUS ACKNOWLEDGE: ");
+ break;
+ case 0x65:
+ sprintf((pbuf+strlen(pbuf)), "STATUS REJECT: ");
+ break;
+ case 0x66:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY INFORMATION: ");
+ break;
+ case 0x67:
+ sprintf((pbuf+strlen(pbuf)), "INFORMATION ACKNOWLEDGE: ");
+ break;
+ case 0x68:
+ sprintf((pbuf+strlen(pbuf)), "INFORMATION REJECT: ");
+ break;
+ case 0x75:
+ sprintf((pbuf+strlen(pbuf)), "CLOSE: ");
+ break;
+ case 0x77:
+ sprintf((pbuf+strlen(pbuf)), "CLOSE ACKNOWLEDGE: ");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "ERROR: PD=0x40 MSG=0x%02x, ", buf[i]);
+ break;
+ }
+ }
+ else if(pd == 0x41)
+ {
+ switch(buf[i])
+ {
+ case 0x00:
+ sprintf((pbuf+strlen(pbuf)), "ESCAPE: ");
+ break;
+ case 0x01:
+ sprintf((pbuf+strlen(pbuf)), "ALERT: ");
+ break;
+ case 0x02:
+ sprintf((pbuf+strlen(pbuf)), "CALL SENT: ");
+ break;
+ case 0x07:
+ sprintf((pbuf+strlen(pbuf)), "CONNECT: ");
+ break;
+ case 0x0f:
+ sprintf((pbuf+strlen(pbuf)), "CONNECT ACKNOWLEDGE: ");
+ break;
+ case 0x05:
+ sprintf((pbuf+strlen(pbuf)), "SETUP: ");
+ break;
+ case 0x0d:
+ sprintf((pbuf+strlen(pbuf)), "SETUP ACKNOWLEDGE: ");
+ break;
+
+ case 0x26:
+ sprintf((pbuf+strlen(pbuf)), "RESUME: ");
+ break;
+ case 0x2e:
+ sprintf((pbuf+strlen(pbuf)), "RESUME ACKNOWLEDGE: ");
+ break;
+ case 0x22:
+ sprintf((pbuf+strlen(pbuf)), "RESUME REJECT: ");
+ break;
+ case 0x25:
+ sprintf((pbuf+strlen(pbuf)), "SUSPEND: ");
+ break;
+ case 0x2d:
+ sprintf((pbuf+strlen(pbuf)), "SUSPEND ACKNOWLEDGE: ");
+ break;
+ case 0x21:
+ sprintf((pbuf+strlen(pbuf)), "SUSPEND REJECT: ");
+ break;
+ case 0x20:
+ sprintf((pbuf+strlen(pbuf)), "USER INFORMATION: ");
+ break;
+
+ case 0x40:
+ sprintf((pbuf+strlen(pbuf)), "DETACH");
+ break;
+ case 0x45:
+ sprintf((pbuf+strlen(pbuf)), "DISCONNECT: ");
+ break;
+ case 0x4d:
+ sprintf((pbuf+strlen(pbuf)), "RELEASE: ");
+ break;
+ case 0x5a:
+ sprintf((pbuf+strlen(pbuf)), "RELEASE ACKNOWLEDGE");
+ break;
+
+ case 0x6e:
+ sprintf((pbuf+strlen(pbuf)), "CANCEL ACKNOWLEDGE: ");
+ break;
+ case 0x67:
+ sprintf((pbuf+strlen(pbuf)), "CANCEL REJECT: ");
+ break;
+ case 0x69:
+ sprintf((pbuf+strlen(pbuf)), "CONGESTION CONTROL: ");
+ break;
+ case 0x60:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY: ");
+ break;
+ case 0x68:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY ACKNOWLEDGE: ");
+ break;
+ case 0x66:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY CANCEL: ");
+ break;
+ case 0x64:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY REGISTER: ");
+ break;
+ case 0x65:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY REJECT: ");
+ break;
+ case 0x6d:
+ sprintf((pbuf+strlen(pbuf)), "INFORMATION: ");
+ break;
+ case 0x6c:
+ sprintf((pbuf+strlen(pbuf)), "REGISTER ACKNOWLEDGE: ");
+ break;
+ case 0x6f:
+ sprintf((pbuf+strlen(pbuf)), "REGISTER REJECT: ");
+ break;
+ case 0x63:
+ sprintf((pbuf+strlen(pbuf)), "STATUS: ");
+ break;
+
+ default:
+ sprintf((pbuf+strlen(pbuf)), "ERROR: PD=0x41 MSG=0x%02x, ", buf[i]);
+ break;
+ }
+ }
+ else
+ {
+ sprintf((pbuf+strlen(pbuf)), "ERROR: PD=0x%02x MSG=0x%02x, ", pd, buf[i]);
+ }
+
+ /* other information elements */
+
+ i++;
+
+ for (; i < n;)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\n ");
+
+ if(buf[i] & 0x80)
+ {
+ /* single octett info element */
+
+ switch(buf[i] & 0x70)
+ {
+ case 0x00: /* reserved */
+ sprintf((pbuf+strlen(pbuf)), "[reserved single octett info]");
+ break;
+
+ case 0x10: /* shift */
+ oldcodeset = codeset;
+ codeset = buf[i] & 0x07;
+ if(buf[i] & 0x08)
+ codelock = 0;
+ else
+ codelock = 1;
+ sprintf((pbuf+strlen(pbuf)), "[shift: codeset=%d lock=%d]", codeset, codelock);
+ break;
+
+ case 0x20: /* more data */
+ sprintf((pbuf+strlen(pbuf)), "[more data]");
+ break;
+
+ case 0x30: /* congestion level */
+ sprintf((pbuf+strlen(pbuf)), "[congestion level = %d]", buf[i] & 0x0f);
+ break;
+
+ default:
+ sprintf((pbuf+strlen(pbuf)), "[UNDEF SINGLE OCTET ELEMENT 0x%02x]", buf[i]);
+ break;
+ }
+
+ i++; /* next */
+
+ }
+ else
+ {
+ /* variable length info element */
+
+ if(codeset == 0)
+ {
+ switch(buf[i])
+ {
+ case 0x08:
+ sprintf((pbuf+strlen(pbuf)), "[cause: ");
+ i += p_1tr6cause(pbuf, &buf[i]);
+ goto next;
+ break;
+
+ case 0x0c:
+ sprintf((pbuf+strlen(pbuf)), "[connected address: ");
+ i += p_1tr6address(pbuf, &buf[i]);
+ goto next;
+ break;
+
+ case 0x10:
+ sprintf((pbuf+strlen(pbuf)), "[call identity: ");
+ break;
+ case 0x18:
+ sprintf((pbuf+strlen(pbuf)), "[channel id: channel=");
+ i += 2;
+ switch(buf[i] & 0x03)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "no channel");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "B-1");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "B-2");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "any channel");
+ break;
+ }
+ if(buf[i] & 0x08)
+ sprintf((pbuf+strlen(pbuf)), " (exclusive)]");
+ else
+ sprintf((pbuf+strlen(pbuf)), " (preferred)]");
+ i++;
+ goto next;
+ break;
+ case 0x20:
+ sprintf((pbuf+strlen(pbuf)), "[network specific facilities: ");
+ i++;
+ len = buf[i];
+ i+=2;
+ switch(buf[i])
+ {
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "Sperre");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "AWS 1");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "AWS 2");
+ break;
+ case 0xe:
+ sprintf((pbuf+strlen(pbuf)), "Konferenz");
+ break;
+ case 0xf:
+ sprintf((pbuf+strlen(pbuf)), "B-Kan uebern.");
+ break;
+ case 0x10:
+ sprintf((pbuf+strlen(pbuf)), "aktvrg. ghlt. Vbdg.");
+ break;
+ case 0x11:
+ sprintf((pbuf+strlen(pbuf)), "3er Konf");
+ break;
+ case 0x12:
+ sprintf((pbuf+strlen(pbuf)), "1seitg D/G Wechsel");
+ break;
+ case 0x13:
+ sprintf((pbuf+strlen(pbuf)), "2seitig D/G Wechsel");
+ break;
+ case 0x14:
+ sprintf((pbuf+strlen(pbuf)), "Rufnr. identifiz.");
+ break;
+ case 0x15:
+ sprintf((pbuf+strlen(pbuf)), "GBG");
+ break;
+ case 0x17:
+ sprintf((pbuf+strlen(pbuf)), "ueberg. Ruf");
+ break;
+ case 0x1a:
+ sprintf((pbuf+strlen(pbuf)), "um/weitergel. Ruf");
+ break;
+ case 0x1b:
+ sprintf((pbuf+strlen(pbuf)), "unterdr. A-Rufnr.");
+ break;
+ case 0x1e:
+ sprintf((pbuf+strlen(pbuf)), "Verbdg. deaktivieren");
+ break;
+ case 0x1d:
+ sprintf((pbuf+strlen(pbuf)), "Verbdg. aktivieren");
+ break;
+ case 0x1f:
+ sprintf((pbuf+strlen(pbuf)), "SPV");
+ break;
+ case 0x23:
+ sprintf((pbuf+strlen(pbuf)), "Rueckw. 2seitg. DW");
+ break;
+ case 0x24:
+ sprintf((pbuf+strlen(pbuf)), "Anrufumltg. priv. Netz");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "undefined");
+ break;
+ }
+ i++;
+ sprintf((pbuf+strlen(pbuf)), ", serv=%d", buf[i]);
+ i++;
+ sprintf((pbuf+strlen(pbuf)), ", ainfo=%d", buf[i]);
+ i++;
+ len-=4;
+ for(j = 0; j < len; j++)
+ {
+ sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
+ }
+ sprintf((pbuf+strlen(pbuf)),"]");
+ i += j;
+ goto next;
+ break;
+ case 0x28:
+ sprintf((pbuf+strlen(pbuf)), "[display: ");
+ break;
+ case 0x2c:
+ sprintf((pbuf+strlen(pbuf)), "[keypad: ");
+ break;
+ case 0x6c:
+ sprintf((pbuf+strlen(pbuf)), "[origination address: ");
+ i += p_1tr6address(pbuf, &buf[i]);
+ goto next;
+ break;
+ case 0x70:
+ sprintf((pbuf+strlen(pbuf)), "[destination address: ");
+ i += p_1tr6address(pbuf, &buf[i]);
+ goto next;
+ break;
+ case 0x7e:
+ sprintf((pbuf+strlen(pbuf)), "[user-user information: ");
+ break;
+ case 0x7f:
+ sprintf((pbuf+strlen(pbuf)), "[reserved: ");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "[UNKNOWN INFO-ELEMENT-ID");
+ break;
+ }
+ }
+ else if(codeset == 6)
+ {
+ switch(buf[i])
+ {
+ case 0x01:
+ sprintf((pbuf+strlen(pbuf)), "[service ind: serv=");
+ i+= 2;
+ switch(buf[i])
+ {
+ case 0x01:
+ sprintf((pbuf+strlen(pbuf)), "phone");
+ break;
+ case 0x02:
+ sprintf((pbuf+strlen(pbuf)), "a/b");
+ break;
+ case 0x03:
+ sprintf((pbuf+strlen(pbuf)), "X.21");
+ break;
+ case 0x04:
+ sprintf((pbuf+strlen(pbuf)), "fax g4");
+ break;
+ case 0x05:
+ sprintf((pbuf+strlen(pbuf)), "btx");
+ break;
+ case 0x07:
+ sprintf((pbuf+strlen(pbuf)), "64k data");
+ break;
+ case 0x08:
+ sprintf((pbuf+strlen(pbuf)), "X.25");
+ break;
+ case 0x09:
+ sprintf((pbuf+strlen(pbuf)), "teletex");
+ break;
+ case 0x0a:
+ sprintf((pbuf+strlen(pbuf)), "mixed");
+ break;
+ case 0x0d:
+ sprintf((pbuf+strlen(pbuf)), "temex");
+ break;
+ case 0x0e:
+ sprintf((pbuf+strlen(pbuf)), "picturephone");
+ break;
+ case 0x0f:
+ sprintf((pbuf+strlen(pbuf)), "btx (new)");
+ break;
+ case 0x10:
+ sprintf((pbuf+strlen(pbuf)), "videophone");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "undefined");
+ break;
+ }
+ i++;
+ sprintf((pbuf+strlen(pbuf)), ", ainfo=0x%02x]", buf[i]);
+ i++;
+ goto next;
+ break;
+ case 0x02:
+ sprintf((pbuf+strlen(pbuf)), "[charging information: ");
+ break;
+ case 0x03:
+ sprintf((pbuf+strlen(pbuf)), "[date: ");
+ i++;
+ len = buf[i];
+ i++;
+ for(j = 0; j < len; j++)
+ {
+ sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
+ }
+ sprintf((pbuf+strlen(pbuf)),"]");
+ i += j;
+ goto next;
+ break;
+ case 0x05:
+ sprintf((pbuf+strlen(pbuf)), "[facility select: ");
+ break;
+ case 0x06:
+ sprintf((pbuf+strlen(pbuf)), "[status of facilities: ");
+ break;
+ case 0x07:
+ sprintf((pbuf+strlen(pbuf)), "[status of called party: ");
+ i+=2;
+ switch(buf[i])
+ {
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "no information]");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "is being called]");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "undefined (0x%02x)]", buf[i]);
+ break;
+ }
+ i++;
+ goto next;
+ break;
+ case 0x08:
+ sprintf((pbuf+strlen(pbuf)), "[additional tx attributes: ");
+ i++;
+ len = buf[i];
+ i++;
+ for(j = 0; j < len; j++)
+ {
+ switch(buf[j+i] &0x70)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "no satellite link");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "one satellite link");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "two satellite links");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "three satellite links");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "undefined value");
+ break;
+ }
+ if(buf[j+i] & 0x80)
+ sprintf((pbuf+strlen(pbuf)),"(flag=req)]");
+ else
+ sprintf((pbuf+strlen(pbuf)),"(flag=ind)]");
+ }
+ i += j;
+ goto next;
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "[UNKNOWN INFO-ELEMENT-ID");
+ break;
+ }
+ }
+ else
+ {
+ sprintf((pbuf+strlen(pbuf)), "[ILLEGAL CODESET = 0x%02x", codeset);
+ }
+
+ i++; /* index -> length */
+
+ len = buf[i];
+
+ i++; /* index -> 1st param */
+
+ for(j = 0; j < len; j++)
+ {
+ sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
+ }
+
+ sprintf((pbuf+strlen(pbuf)),"]");
+
+ i += len;
+
+next:
+
+ if(!codelock && (codeset != oldcodeset))
+ codeset = oldcodeset;
+ }
+ }
+ sprintf((pbuf+strlen(pbuf)),"\n");
+}
+
+/*---------------------------------------------------------------------------*
+ * decode and print the cause
+ *---------------------------------------------------------------------------*/
+static int
+p_1tr6cause(char *pbuf, unsigned char buf[])
+{
+ int j;
+ int len;
+ int i = 0;
+
+ i++; /* index -> length */
+
+ len = buf[i];
+
+ switch(len)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "%s", print_cause_1tr6(0));
+ break;
+ case 1:
+ i++;
+ sprintf((pbuf+strlen(pbuf)), "%s", print_cause_1tr6(buf[i] & 0x7f));
+ break;
+ case 2:
+ i++;
+ sprintf((pbuf+strlen(pbuf)), "%s, location: ", print_cause_1tr6(buf[i] & 0x7f));
+ i++;
+ switch(buf[i] & 0x0f)
+ {
+ case 0x04:
+ sprintf((pbuf+strlen(pbuf)), "public network");
+ break;
+ case 0x05:
+ sprintf((pbuf+strlen(pbuf)), "private network");
+ break;
+ case 0x0f:
+ sprintf((pbuf+strlen(pbuf)), "no information");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
+ break;
+ }
+ break;
+ default:
+ i++; /* index -> length */
+ len = buf[i];
+ i++; /* index -> 1st param */
+ for(j = 0; j < len; j++)
+ {
+ sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
+ }
+ break;
+ }
+ i++;
+ sprintf((pbuf+strlen(pbuf)),"]");
+ return(i);
+}
+
+/*---------------------------------------------------------------------------*
+ * decode and print the ISDN (telephone) number
+ *---------------------------------------------------------------------------*/
+static int
+p_1tr6address(char *pbuf, unsigned char buf[])
+{
+ int j;
+ int len;
+ int i = 0;
+ int tp;
+
+ i++; /* index -> length */
+ len = buf[i];
+ i++; /* index -> 1st param */
+ tp = buf[i];
+
+ i++;
+ len--;
+
+ for(j = 0; j < len; j++)
+ {
+ sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
+ }
+
+ switch((tp & 0x70) >> 4)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), " (type=unknown, ");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), " (type=international, ");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), " (type=national, ");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), " (type=%d, ", ((tp & 0x70) >> 4));
+ break;
+ }
+
+ switch(tp & 0x0f)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "plan=unknown)");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "plan=ISDN)");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "plan=%d)", (tp & 0x0f));
+ break;
+ }
+
+ sprintf((pbuf+strlen(pbuf)),"]");
+
+ i += j;
+
+ return(i);
+}
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdntrace/Makefile b/usr.sbin/i4b/isdntrace/Makefile
new file mode 100644
index 0000000..150c18d
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/Makefile
@@ -0,0 +1,8 @@
+PROG = isdntrace
+SRCS = q921.c q931.c q931_util.c q932_fac.c 1tr6.c trace.c \
+ pcause_1tr6.c pcause_q850.c
+#CFLAGS += -Wall -g
+MAN8 = isdntrace.8
+
+.include <bsd.prog.mk>
+
diff --git a/usr.sbin/i4b/isdntrace/cable.txt b/usr.sbin/i4b/isdntrace/cable.txt
new file mode 100644
index 0000000..890d8d4
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/cable.txt
@@ -0,0 +1,60 @@
+ *---------------------------------------------------------------------------
+ *
+ * Custom cable to trace an ISDN S0 bus with two passive (!) ISDN boards
+ * ---------------------------------------------------------------------
+ *
+ * $Id: cable.txt,v 1.2 1998/01/22 20:39:49 hm Exp $
+ *
+ * last edit-date: [Thu Jan 22 19:57:50 1998]
+ *
+ * -hm documentation of analyze mode
+ *
+ *---------------------------------------------------------------------------*/
+
+The cable consists of a RJ-45 plug with both tx and rx connected and
+two jacks; the tx cables from the plug are wired to one jack and the
+rx cables from the plug are wired to the other jack.
+
+The computer must be equipped with two (!) supported passive cards and
+the cable from one card is plugged into one of the jacks while the cable
+to from the other card is plugged into the other jack.
+
+Now one card monitors the tx part of the S0 bus and the other card
+monitors the rx part.
+
+Which card functions as the rx side and which as the tx side can be
+specified as options to the isdntrace utility (-R and -T) which has
+to be run in analyzer mode (-a) to support this configuration.
+
+
+ 1
+ 2
+ 3
+ +--------------4 receiving-side board
+ S0-bus +--|--------------5 in computer (jack for
+ to analyze | | 6 cable to passive controller)
+ 8 | | 7
+ 7 | | 8
+ transmit - 6------------|--|--+
+ receive - 5------------+ | |
+ receive + 4---------------+ |
+ transmit + 3------------+ |
+ 2 | | 1
+ 1 | | 2
+ plug into | | 3
+ S0 bus +-----|-----------4 transmitting-side board
+ +-----------5 in computer (jack for
+ 6 cable to passive controller)
+ 7
+ 8
+
+
+
+ RJ-45 plug RJ-45 jack
+ view from the front view from the front
+ cable goes out to the rear
+
+ /--------- / ----------
+ | 87654321 | | 12345678 |
+ |__ __|/ |/_ /_|
+ |____|/ |/___|
diff --git a/usr.sbin/i4b/isdntrace/isdntrace.8 b/usr.sbin/i4b/isdntrace/isdntrace.8
new file mode 100644
index 0000000..62c5d07
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/isdntrace.8
@@ -0,0 +1,205 @@
+.\"
+.\" Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+.\"
+.\" 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.
+.\"
+.\" $Id: isdntrace.8,v 1.9 1998/12/05 18:04:10 hm Exp $
+.\"
+.\" last edit-date: [Sat Dec 5 18:18:59 1998]
+.\"
+.Dd October 19, 1998
+.Dt isdntrace 8
+.Sh NAME
+.Nm isdntrace
+.Nd isdn4bsd ISDN protocol trace utility
+.Sh SYNOPSIS
+.Nm isdntrace
+.Op Fl a
+.Op Fl b
+.Op Fl d
+.Op Fl f Ar filename
+.Op Fl h
+.Op Fl i
+.Op Fl l
+.Op Fl n Ar number
+.Op Fl o
+.Op Fl p Ar filename
+.Op Fl r
+.Op Fl u Ar number
+.Op Fl B
+.Op Fl F
+.Op Fl P
+.Op Fl R Ar unit
+.Op Fl T Ar unit
+.Sh DESCRIPTION
+.Nm isdntrace
+is part of the isdn4bsd package and is used to provide the user with a
+mnemonic display of the layers 1, 2 and 3 protocol activities on
+the D channel and hex dump of the B channel(s) activities.
+.Pp
+Together with two passive supported cards and an easy to build cable it can
+also be used to monitor the complete traffic on a S0 bus providing S0 bus
+analyzer features.
+.Pp
+The
+.Nm
+utility is only available for passive supported cards.
+.Pp
+The following options can be used:
+.Bl -tag -width Ds
+.It Fl a
+Run
+.Nm
+in analyzer mode by using two passive cards and a custom cable which can
+be build as described in the file
+.Em cable.txt
+in the isdn4bsd source distribution. One card acts as a receiver for the
+transmitting direction on the S0 bus while the other card acts as a receiver
+for the receiving direction on the S0 bus. Complete traffic monitoring is
+possible using this setup.
+.It Fl b
+switch B channel tracing on (default off).
+.It Fl d
+switch D channel tracing off (default on).
+.It Fl f
+Use
+.Ar filename
+as the name of a file into which to write tracing output (default filename is
+isdntrace<n> where n is the number of the unit to trace).
+.It Fl h
+switch display of header off (default on).
+.It Fl i
+print layer 1 (I.430) INFO signals to monitor layer 1 activity (default off).
+.It Fl l
+switch displaying of Layer 2 (Q.921) frames off (default on).
+.It Fl n
+This option takes a numeric argument specifying the minimum
+frame size in octetts a frame must have to be displayed. (default 0)
+.It Fl o
+switch off writing trace output to a file (default on).
+.It Fl p
+Use
+.Ar filename
+as the name of a file used for the -B and -P options (default filename
+is isdntracebin<n> where n is the number of the unit to trace).
+.It Fl r
+Switch off printing a raw hexadecimal dump of the packets preceding
+the decoded protocol information (default on).
+.It Fl u
+Use
+.Ar number
+as the unit number of the controller card to trace (default 0).
+.It Fl B
+Write undecoded binary trace data to a file for later or remote
+analyzing (default off).
+.It Fl F
+This option can only be used when option -P (playback from binary data file)
+is used. The -F option causes playback not to stop at end of file but rather
+to wait for additional data to be available from the input file.
+.Pp
+This option is useful when trace data is accumulated in binary format (to
+save disk space) but a monitoring functionality is desired.
+(default off).
+.It Fl P
+Read undecoded binary trace data from file instead from device (default off).
+.It Fl R
+Use
+.Ar unit
+as the receiving interface unit number in analyze mode.
+.It Fl T
+Use
+.Ar unit
+as the transmitting interface unit number in analyze mode.
+.El
+.Pp
+When the USR1 signal is sent to a
+.Nm
+process, the currently used logfiles are reopened, so that logfile
+rotation becomes possible.
+.Pp
+The trace output should be obvious. It is very handy to have the following
+standard texts available when tracing ISDN protocols:
+.Pp
+.Bl -tag -width Ds -compact -offset indent
+.It Ar I.430
+ISDN BRI layer 1 protocol description.
+.It Ar Q.921
+ISDN D-channel layer 2 protocol description.
+.It Ar Q.931
+ISDN D-channel layer 3 protocol description.
+.It Ar 1TR6
+German-specific ISDN layer 3 protocol description. (NOTICE: decoding
+of the 1TR6 protocol is included but not supported since i dont have
+any longer access to a 1TR6 based ISDN installation.)
+.El
+.Pp
+
+.Nm Isdntrace
+automatically detects the layer 3 protocol being used by looking at the
+Protocol Discriminator (see: Q.931/1993 pp. 53).
+.Pp
+
+
+.Sh FILES
+.Bl -tag -width daddeldi -compact
+.It Pa /dev/i4btrc<n>
+The devicefile(s) used to get the trace messages for ISDN card unit <n>
+out of the kernel.
+.El
+
+.Sh EXAMPLES
+The command:
+.Bd -literal -offset indent
+isdntrace -f /var/tmp/isdn.trace
+.Ed
+.Pp
+will start D channel tracing on passive controller 0 with all except B
+channel tracing enabled and logs everything into the output file
+/tmp/isdn.trace.
+
+.Sh SEE ALSO
+.Xr isdnd 8
+
+.Sh BUGS
+Still some or more left.
+
+.Sh STANDARDS
+ITU Recommendations I.430, Q.920, Q.921, Q.930, Q.931
+.Pp
+FTZ Richtlinie 1TR3, Band III
+.Pp
+ITU Recommendation Q.932 (03/93), Q.950 (03/93)
+.Pp
+ETSI Recommendation ETS 300 179 (10/92), ETS 300 180 (10/92)
+.Pp
+ETSI Recommendation ETS 300 181 (04/93), ETS 300 182 (04/93)
+.Pp
+ITU Recommendation X.208, X.209
+
+.Sh AUTHOR
+The
+.Nm
+utility was written by Gary Jennejohn and Hellmuth Michaelis.
+.Pp
+This manual page was written by Hellmuth Michaelis, he can be reached
+at hm@kts.org.
+
diff --git a/usr.sbin/i4b/isdntrace/pcause_1tr6.c b/usr.sbin/i4b/isdntrace/pcause_1tr6.c
new file mode 100644
index 0000000..42f244d
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/pcause_1tr6.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * printing cause values
+ * ---------------------
+ *
+ * $Id: pcause_1tr6.c,v 1.4 1998/12/23 10:03:55 hm Exp $
+ *
+ * last edit-date: [Wed Dec 23 10:57:11 1998]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "trace.h"
+#include "pcause_1tr6.h"
+
+char *
+print_cause_1tr6(unsigned char code)
+{
+ static char error_message[120];
+ char *e;
+
+ switch(code)
+ {
+ case CAUSE_1TR6_SHUTDN:
+ e = "normal D-channel shutdown";
+ break;
+
+ case CAUSE_1TR6_ICRV:
+ e = "invalid call reference value";
+ break;
+
+ case CAUSE_1TR6_BSNI:
+ e = "bearer service not implemented";
+ break;
+
+ case CAUSE_1TR6_CIDNE:
+ e = "call identity does not exist";
+ break;
+
+ case CAUSE_1TR6_CIIU:
+ e = "call identity in use";
+ break;
+
+ case CAUSE_1TR6_NCA:
+ e = "no channel available";
+ break;
+
+ case CAUSE_1TR6_RFNI:
+ e = "requested facility not implemented";
+ break;
+
+ case CAUSE_1TR6_RFNS:
+ e = "requested facility not subscribed";
+ break;
+
+ case CAUSE_1TR6_OCB:
+ e = "outgoing calls barred";
+ break;
+
+ case CAUSE_1TR6_UAB:
+ e = "user access busy";
+ break;
+
+ case CAUSE_1TR6_NECUG:
+ e = "non existent CUG";
+ break;
+
+ case CAUSE_1TR6_NECUG1:
+ e = "non existent CUG";
+ break;
+
+ case CAUSE_1TR6_SPV:
+ e = "kommunikationsbeziehung als SPV nicht erlaubt";
+ break;
+
+ case CAUSE_1TR6_DNO:
+ e = "destination not obtainable";
+ break;
+
+ case CAUSE_1TR6_NC:
+ e = "number changed";
+ break;
+
+ case CAUSE_1TR6_OOO:
+ e = "out of order";
+ break;
+
+ case CAUSE_1TR6_NUR:
+ e = "no user responding";
+ break;
+
+ case CAUSE_1TR6_UB:
+ e = "user busy";
+ break;
+
+ case CAUSE_1TR6_ICB:
+ e = "incoming calls barred";
+ break;
+
+ case CAUSE_1TR6_CR:
+ e = "call rejected";
+ break;
+
+ case CAUSE_1TR6_NCO:
+ e = "network congestion";
+ break;
+
+ case CAUSE_1TR6_RUI:
+ e = "remote user initiated";
+ break;
+
+ case CAUSE_1TR6_LPE:
+ e = "local procedure error";
+ break;
+
+ case CAUSE_1TR6_RPE:
+ e = "remote procedure error";
+ break;
+
+ case CAUSE_1TR6_RUS:
+ e = "remote user suspended";
+ break;
+
+ case CAUSE_1TR6_RUR:
+ e = "remote user resumed";
+ break;
+
+ case CAUSE_1TR6_UIDL:
+ e = "user info discharded locally";
+ break;
+
+ default:
+ e = "UNKNOWN error occured";
+ break;
+ }
+
+ sprintf(error_message, "0x%02x: %s", code & 0x7f, e);
+ return(error_message);
+}
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdntrace/pcause_1tr6.h b/usr.sbin/i4b/isdntrace/pcause_1tr6.h
new file mode 100644
index 0000000..f327cc7
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/pcause_1tr6.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * pcause1tr6.h - 1TR6 causes definitions
+ * --------------------------------------
+ *
+ * $Id: pcause_1tr6.h,v 1.3 1998/12/05 18:04:13 hm Exp $
+ *
+ * last edit-date: [Sat Dec 5 18:19:39 1998]
+ *
+ *---------------------------------------------------------------------------*/
+
+char *print_cause_1tr6(unsigned char code);
+
+/* 1TR6 protocol causes */
+
+#define CAUSE_1TR6_SHUTDN 0x00 /* normal D-channel shutdown */
+#define CAUSE_1TR6_ICRV 0x01 /* invalid call reference value */
+#define CAUSE_1TR6_BSNI 0x03 /* bearer service not implemented */
+#define CAUSE_1TR6_CIDNE 0x07 /* call identity does not exist */
+#define CAUSE_1TR6_CIIU 0x08 /* call identity in use */
+#define CAUSE_1TR6_NCA 0x0A /* no channel available */
+#define CAUSE_1TR6_RFNI 0x10 /* requested facility not implemented */
+#define CAUSE_1TR6_RFNS 0x11 /* requested facility not subscribed */
+#define CAUSE_1TR6_OCB 0x20 /* outgoing calls barred */
+#define CAUSE_1TR6_UAB 0x21 /* user access busy */
+#define CAUSE_1TR6_NECUG 0x22 /* non existent CUG */
+#define CAUSE_1TR6_NECUG1 0x23 /* non existent CUG */
+#define CAUSE_1TR6_SPV 0x25 /* kommunikationsbeziehung als SPV nicht erlaubt */
+#define CAUSE_1TR6_DNO 0x35 /* destination not obtainable */
+#define CAUSE_1TR6_NC 0x38 /* number changed */
+#define CAUSE_1TR6_OOO 0x39 /* out of order */
+#define CAUSE_1TR6_NUR 0x3A /* no user responding */
+#define CAUSE_1TR6_UB 0x3B /* user busy */
+#define CAUSE_1TR6_ICB 0x3D /* incoming calls barred */
+#define CAUSE_1TR6_CR 0x3E /* call rejected */
+#define CAUSE_1TR6_NCO 0x59 /* network congestion */
+#define CAUSE_1TR6_RUI 0x5A /* remote user initiated */
+#define CAUSE_1TR6_LPE 0x70 /* local procedure error */
+#define CAUSE_1TR6_RPE 0x71 /* remote procedure error */
+#define CAUSE_1TR6_RUS 0x72 /* remote user suspended */
+#define CAUSE_1TR6_RUR 0x73 /* remote user resumed */
+#define CAUSE_1TR6_UIDL 0x7F /* user info discharded locally */
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdntrace/pcause_q850.c b/usr.sbin/i4b/isdntrace/pcause_q850.c
new file mode 100644
index 0000000..1c98388
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/pcause_q850.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * printing cause values
+ * ---------------------
+ *
+ * $Id: pcause_q850.c,v 1.4 1998/12/23 10:03:55 hm Exp $
+ *
+ * last edit-date: [Wed Dec 23 10:57:36 1998]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "trace.h"
+#include "pcause_q850.h"
+
+char *
+print_cause_q850(unsigned char code)
+{
+ static char error_message[120];
+ char *e;
+
+ switch(code)
+ {
+ case CAUSE_Q850_SHUTDN:
+ e = "normal D-channel shutdown";
+ break;
+
+ case CAUSE_Q850_NUNALLC:
+ e = "Unallocated (unassigned) number";
+ break;
+
+ case CAUSE_Q850_NRTTN:
+ e = "No route to specified transit network";
+ break;
+
+ case CAUSE_Q850_NRTDST:
+ e = "No route to destination";
+ break;
+
+ case CAUSE_Q850_SSINFTN:
+ e = "Send special information tone";
+ break;
+
+ case CAUSE_Q850_MDIALTP:
+ e = "Misdialled trunk prefix";
+ break;
+
+ case CAUSE_Q850_CHUNACC:
+ e = "Channel unacceptable";
+ break;
+
+ case CAUSE_Q850_CALLAWD:
+ e = "Call awarded and being delivered in an established channel";
+ break;
+
+ case CAUSE_Q850_PREEMPT:
+ e = "Preemption";
+ break;
+
+ case CAUSE_Q850_PREECRR:
+ e = "Preemption - circuit reserved for reuse";
+ break;
+
+ case CAUSE_Q850_NCCLR:
+ e = "Normal call clearing";
+ break;
+
+ case CAUSE_Q850_USRBSY:
+ e = "User busy";
+ break;
+
+ case CAUSE_Q850_NOUSRRSP:
+ e = "No user responding";
+ break;
+
+ case CAUSE_Q850_NOANSWR:
+ e = "No answer from user (user alerted)";
+ break;
+
+ case CAUSE_Q850_SUBSABS:
+ e = "Subscriber absent";
+ break;
+
+ case CAUSE_Q850_CALLREJ:
+ e = "Call rejected";
+ break;
+
+ case CAUSE_Q850_NUCHNG:
+ e = "Number changed";
+ break;
+
+ case CAUSE_Q850_NONSELUC:
+ e = "Non-selected user clearing";
+ break;
+
+ case CAUSE_Q850_DSTOOORDR:
+ e = "Destination out of order";
+ break;
+
+ case CAUSE_Q850_INVNUFMT:
+ e = "Invalid number format";
+ break;
+
+ case CAUSE_Q850_FACREJ:
+ e = "Facility rejected";
+ break;
+
+ case CAUSE_Q850_STENQRSP:
+ e = "Response to STATUS ENQUIRY";
+ break;
+
+ case CAUSE_Q850_NORMUNSP:
+ e = "Normal, unspecified";
+ break;
+
+ case CAUSE_Q850_NOCAVAIL:
+ e = "No circuit / channel available";
+ break;
+
+ case CAUSE_Q850_NETOOORDR:
+ e = "Network out of order";
+ break;
+
+ case CAUSE_Q850_PFMCDOOSERV:
+ e = "Permanent frame mode connection out of service";
+ break;
+
+ case CAUSE_Q850_PFMCOPER:
+ e = "Permanent frame mode connection operational";
+ break;
+
+ case CAUSE_Q850_TMPFAIL:
+ e = "Temporary failure";
+ break;
+
+ case CAUSE_Q850_SWEQCONG:
+ e = "Switching equipment congestion";
+ break;
+
+ case CAUSE_Q850_ACCINFDIS:
+ e = "Access information discarded";
+ break;
+
+ case CAUSE_Q850_REQCNOTAV:
+ e = "Requested circuit/channel not available";
+ break;
+
+ case CAUSE_Q850_PRECALBLK:
+ e = "Precedence call blocked";
+ break;
+
+ case CAUSE_Q850_RESUNAVAIL:
+ e = "Resources unavailable, unspecified";
+ break;
+
+ case CAUSE_Q850_QOSUNAVAIL:
+ e = "Quality of service unavailable";
+ break;
+
+ case CAUSE_Q850_REQSERVNS:
+ e = "Requested facility not subscribed";
+ break;
+
+ case CAUSE_Q850_OCBARRCUG:
+ e = "Outgoing calls barred within CUG";
+ break;
+
+ case CAUSE_Q850_ICBARRCUG:
+ e = "Incoming calls barred within CUG";
+ break;
+
+ case CAUSE_Q850_BCAPNAUTH:
+ e = "Bearer capability not authorized";
+ break;
+
+ case CAUSE_Q850_BCAPNAVAIL:
+ e = "Bearer capability not presently available";
+ break;
+
+ case CAUSE_Q850_INCSTOACISC:
+ e = "Inconsistenciy in designated outg. access info and subscriber class";
+ break;
+
+ case CAUSE_Q850_SOONOTAVAIL:
+ e = "Service or option not available, unspecified";
+ break;
+
+ case CAUSE_Q850_BCAPNOTIMPL:
+ e = "Bearer capability not implemented";
+ break;
+
+ case CAUSE_Q850_CHTYPNIMPL:
+ e = "Channel type not implemented";
+ break;
+
+ case CAUSE_Q850_REQFACNIMPL:
+ e = "Requested facility not implemented";
+ break;
+
+ case CAUSE_Q850_ORDINBCAVL:
+ e = "Only restricted digital information bearer capability is available";
+ break;
+
+ case CAUSE_Q850_SOONOTIMPL:
+ e = "Service or option not implemented, unspecified";
+ break;
+
+ case CAUSE_Q850_INVCLRFVAL:
+ e = "Invalid call reference value";
+ break;
+
+ case CAUSE_Q850_IDCHDNOEX:
+ e = "Identified channel does not exist";
+ break;
+
+ case CAUSE_Q850_SUSCAEXIN:
+ e = "A suspended call exists, but this call identity does not";
+ break;
+
+ case CAUSE_Q850_CLIDINUSE:
+ e = "Call identity in use";
+ break;
+
+ case CAUSE_Q850_NOCLSUSP:
+ e = "No call suspended";
+ break;
+
+ case CAUSE_Q850_CLIDCLRD:
+ e = "Call having the requested call identity has been cleared";
+ break;
+
+ case CAUSE_Q850_UNOTMEMCUG:
+ e = "User not member of CUG";
+ break;
+
+ case CAUSE_Q850_INCDEST:
+ e = "Incompatible destination";
+ break;
+
+ case CAUSE_Q850_NONEXCUG:
+ e = "Non-existent CUG";
+ break;
+
+ case CAUSE_Q850_INVNTWSEL:
+ e = "Invalid transit network selection";
+ break;
+
+ case CAUSE_Q850_INVMSG:
+ e = "Invalid message, unspecified";
+ break;
+
+ case CAUSE_Q850_MIEMISS:
+ e = "Mandatory information element is missing";
+ break;
+
+ case CAUSE_Q850_MSGTNI:
+ e = "Message type non-existent or not implemented";
+ break;
+
+ case CAUSE_Q850_MSGNCMPT:
+ e = "Msg incompatible with call state/message type non-existent/not implemented";
+ break;
+
+ case CAUSE_Q850_IENENI:
+ e = "Information element/parameter non-existent or not implemented";
+ break;
+
+ case CAUSE_Q850_INVIEC:
+ e = "Invalid information element contents";
+ break;
+
+ case CAUSE_Q850_MSGNCWCS:
+ e = "Message not compatible with call state";
+ break;
+
+ case CAUSE_Q850_RECOTIMEXP:
+ e = "Recovery on timer expiry";
+ break;
+
+ case CAUSE_Q850_PARMNENIPO:
+ e = "Parameter non-existent or not implemented, passed on";
+ break;
+
+ case CAUSE_Q850_MSGUNRDPRM:
+ e = "Message with unrecognized parameter, discarded";
+ break;
+
+ case CAUSE_Q850_PROTERR:
+ e = "Protocol error, unspecified";
+ break;
+
+ case CAUSE_Q850_INTWRKU:
+ e = "Interworking, unspecified";
+ break;
+
+ default:
+ e = "ERROR, unknown cause value!";
+ break;
+ }
+
+ sprintf(error_message, "%d: %s (Q.850)", code, e);
+ return(error_message);
+}
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdntrace/pcause_q850.h b/usr.sbin/i4b/isdntrace/pcause_q850.h
new file mode 100644
index 0000000..a6b947f
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/pcause_q850.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * pcauseq850.h - Q.850 causes definitions
+ * ---------------------------------------
+ *
+ * $Id: pcause_q850.h,v 1.3 1998/12/05 18:04:18 hm Exp $
+ *
+ * last edit-date: [Sat Dec 5 18:20:05 1998]
+ *
+ *---------------------------------------------------------------------------*/
+
+char *print_cause_q850(unsigned char code);
+
+/* Q.850 causes */
+
+#define CAUSE_Q850_SHUTDN 0x00 /* normal D-channel shutdown */
+#define CAUSE_Q850_NUNALLC 0x01 /* Unallocated (unassigned) number */
+#define CAUSE_Q850_NRTTN 0x02 /* No route to specified transit network */
+#define CAUSE_Q850_NRTDST 0x03 /* No route to destination */
+#define CAUSE_Q850_SSINFTN 0x04 /* Send special information tone */
+#define CAUSE_Q850_MDIALTP 0x05 /* Misdialled trunk prefix */
+#define CAUSE_Q850_CHUNACC 0x06 /* Channel unacceptable */
+#define CAUSE_Q850_CALLAWD 0x07 /* Call awarded and being delivered in an established channel */
+#define CAUSE_Q850_PREEMPT 0x08 /* Preemption */
+#define CAUSE_Q850_PREECRR 0x09 /* Preemption - circuit reserved for reuse */
+#define CAUSE_Q850_NCCLR 0x10 /* Normal call clearing */
+#define CAUSE_Q850_USRBSY 0x11 /* User busy */
+#define CAUSE_Q850_NOUSRRSP 0x12 /* No user responding */
+#define CAUSE_Q850_NOANSWR 0x13 /* No answer from user (user alerted) */
+#define CAUSE_Q850_SUBSABS 0x14 /* Subscriber absent */
+#define CAUSE_Q850_CALLREJ 0x15 /* Call rejected */
+#define CAUSE_Q850_NUCHNG 0x16 /* Number changed */
+#define CAUSE_Q850_NONSELUC 0x1A /* Non-selected user clearing */
+#define CAUSE_Q850_DSTOOORDR 0x1B /* Destination out of order */
+#define CAUSE_Q850_INVNUFMT 0x1C /* Invalid number format */
+#define CAUSE_Q850_FACREJ 0x1D /* Facility rejected */
+#define CAUSE_Q850_STENQRSP 0x1E /* Response to STATUS ENQUIRY */
+#define CAUSE_Q850_NORMUNSP 0x1F /* Normal, unspecified */
+#define CAUSE_Q850_NOCAVAIL 0x22 /* No circuit / channel available */
+#define CAUSE_Q850_NETOOORDR 0x26 /* Network out of order */
+#define CAUSE_Q850_PFMCDOOSERV 0x27 /* Permanent frame mode connection out of service */
+#define CAUSE_Q850_PFMCOPER 0x28 /* Permanent frame mode connection operational */
+#define CAUSE_Q850_TMPFAIL 0x29 /* Temporary failure */
+#define CAUSE_Q850_SWEQCONG 0x2A /* Switching equipment congestion */
+#define CAUSE_Q850_ACCINFDIS 0x2B /* Access information discarded */
+#define CAUSE_Q850_REQCNOTAV 0x2C /* Requested circuit/channel not available */
+#define CAUSE_Q850_PRECALBLK 0x2E /* Precedence call blocked */
+#define CAUSE_Q850_RESUNAVAIL 0x2F /* Resources unavailable, unspecified */
+#define CAUSE_Q850_QOSUNAVAIL 0x31 /* Quality of service unavailable */
+#define CAUSE_Q850_REQSERVNS 0x32 /* Requested facility not subscribed */
+#define CAUSE_Q850_OCBARRCUG 0x35 /* Outgoing calls barred within CUG */
+#define CAUSE_Q850_ICBARRCUG 0x36 /* Incoming calls barred within CUG */
+#define CAUSE_Q850_BCAPNAUTH 0x39 /* Bearer capability not authorized */
+#define CAUSE_Q850_BCAPNAVAIL 0x3A /* Bearer capability not presently available */
+#define CAUSE_Q850_INCSTOACISC 0x3E /* Inconsistenciy in designated outgoing access information and subscriber class */
+#define CAUSE_Q850_SOONOTAVAIL 0x3F /* Service or option not available, unspecified */
+#define CAUSE_Q850_BCAPNOTIMPL 0x41 /* Bearer capability not implemented */
+#define CAUSE_Q850_CHTYPNIMPL 0x42 /* Channel type not implemented */
+#define CAUSE_Q850_REQFACNIMPL 0x45 /* Requested facility not implemented */
+#define CAUSE_Q850_ORDINBCAVL 0x46 /* Only restricted digital information bearer capability is available */
+#define CAUSE_Q850_SOONOTIMPL 0x4F /* Service or option not implemented, unspecified */
+#define CAUSE_Q850_INVCLRFVAL 0x51 /* Invalid call reference value */
+#define CAUSE_Q850_IDCHDNOEX 0x52 /* Identified channel does not exist */
+#define CAUSE_Q850_SUSCAEXIN 0x53 /* A suspended call exists, but this call identity does not */
+#define CAUSE_Q850_CLIDINUSE 0x54 /* Call identity in use */
+#define CAUSE_Q850_NOCLSUSP 0x55 /* No call suspended */
+#define CAUSE_Q850_CLIDCLRD 0x56 /* Call having the requested call identity has been cleared */
+#define CAUSE_Q850_UNOTMEMCUG 0x57 /* User not member of CUG */
+#define CAUSE_Q850_INCDEST 0x58 /* Incompatible destination */
+#define CAUSE_Q850_NONEXCUG 0x5A /* Non-existent CUG */
+#define CAUSE_Q850_INVNTWSEL 0x5B /* Invalid transit network selection */
+#define CAUSE_Q850_INVMSG 0x5F /* Invalid message, unspecified */
+#define CAUSE_Q850_MIEMISS 0x60 /* Mandatory information element is missing */
+#define CAUSE_Q850_MSGTNI 0x61 /* Message type non-existent or not implemented */
+#define CAUSE_Q850_MSGNCMPT 0x62 /* Message not compatible with call state or message type non-existent or not implemented */
+#define CAUSE_Q850_IENENI 0x63 /* Information element/parameter non-existent or not implemented */
+#define CAUSE_Q850_INVIEC 0x64 /* Invalid information element contents */
+#define CAUSE_Q850_MSGNCWCS 0x65 /* Message not compatible with call state */
+#define CAUSE_Q850_RECOTIMEXP 0x66 /* Recovery on timer expiry */
+#define CAUSE_Q850_PARMNENIPO 0x67 /* Parameter non-existent or not implemented, passed on */
+#define CAUSE_Q850_MSGUNRDPRM 0x6E /* Message with unrecognized parameter, discarded */
+#define CAUSE_Q850_PROTERR 0x6F /* Protocol error, unspecified */
+#define CAUSE_Q850_INTWRKU 0x7F /* Interworking, unspecified */
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdntrace/q921.c b/usr.sbin/i4b/isdntrace/q921.c
new file mode 100644
index 0000000..df007a4
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/q921.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 1996 Gary Jennejohn. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------*
+ *
+ * q.921.c - print Q.921 traces
+ * ----------------------------
+ *
+ * $Id: q921.c,v 1.2 1998/04/16 15:27:02 hm Exp $
+ *
+ * last edit-date: [Thu Apr 16 15:38:34 1998]
+ *
+ * -hm splitting
+ * -hm printing to buffer
+ * -hm slightly reformatted TEI management proc output
+ * -hm minor fixes
+ * -hm fixing response/command
+ * -hm fixing count off by one
+ * -hm dump only Q.921 part of frame
+ * -hm cleanup
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "trace.h"
+
+/*---------------------------------------------------------------------------*
+ * decode LAPD (Q.921) protocol
+ *---------------------------------------------------------------------------*/
+int
+decode_lapd(char *pbuf, int n, unsigned char *buf, int dir, int raw, int printit)
+{
+ int sap, tei, cmd, p_f;
+ int cnt = 0;
+ int i;
+ char locbuf[32000];
+ char *lbufp = &locbuf[0];
+
+ *lbufp = '\0';
+ *pbuf = '\0';
+
+ sap = (buf[0] >> 2) & 0x3f;
+ cnt++;
+
+ tei = buf[1] >> 1;
+ cnt++;
+
+ if(dir == FROM_TE)
+ cmd = !(buf[0] & 2);
+ else
+ cmd = buf[0] & 2;
+
+ switch (sap)
+ {
+ /* SAPI control procedures */
+ case 0:
+ {
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "Q921: SAP=%d (Call Control), %c, TEI=%d, ", sap, cmd?'C':'R', tei);
+
+ if((buf[2] & 0x01) == 0)
+ {
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "I-Frame: ");
+
+ p_f = buf [3] & 1;
+
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "N(S) %d N(R) %d P %d ", buf [2] >> 1, buf [3] >> 1, p_f);
+
+ cnt += 2;
+ }
+ else if((buf[2] & 0x03) == 0x01)
+ {
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "S-Frame: ");
+
+ p_f = buf [3] & 1;
+ cmd = buf [2] & 0x0c;
+
+ if(printit)
+ {
+ if (cmd == 0)
+ sprintf((lbufp+strlen(lbufp)), "RR N(R) %d PF %d ", buf [3] >> 1, p_f);
+ if (cmd == 4)
+ sprintf((lbufp+strlen(lbufp)), "RNR N(R) %d PF %d ", buf [3] >> 1, p_f);
+ if (cmd == 8)
+ sprintf((lbufp+strlen(lbufp)), "REJ N(R) %d PF %d ", buf [3] >> 1, p_f);
+ }
+ cnt += 2;
+ }
+ else if((buf[2] & 0x03) == 0x03)
+ {
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "U-Frame: ");
+
+ p_f = (buf [2] & 0x10) >> 4;
+ cmd = buf [2] & 0xec;
+
+ if(printit)
+ {
+ if (cmd == 0x6c)
+ sprintf((lbufp+strlen(lbufp)), "SABME PF %d ", p_f);
+ if (cmd == 0x0c)
+ sprintf((lbufp+strlen(lbufp)), "DM PF %d ", p_f);
+ if (cmd == 0)
+ sprintf((lbufp+strlen(lbufp)), "UI PF %d ", p_f);
+ if (cmd == 0x40)
+ sprintf((lbufp+strlen(lbufp)), "DISC PF %d ", p_f);
+ if (cmd == 0x60)
+ sprintf((lbufp+strlen(lbufp)), "UA PF %d ", p_f);
+ if (cmd == 0x84)
+ sprintf((lbufp+strlen(lbufp)), "FRMR PF %d ", p_f);
+ if (cmd == 0xac)
+ sprintf((lbufp+strlen(lbufp)), "XID PF %d ", p_f);
+ /* information field ??? */
+ }
+ cnt++;
+ }
+ break;
+ }
+
+ /* D channel X.25 */
+
+ case 16:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "Q921: SAP=%d (X.25), %c, TEI=%d, ", sap, cmd?'C':'R', tei);
+ cnt = n;
+ goto dump;
+
+ /* Loopback test */
+
+ case 32:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "Q921: SAP=%d (Loopbacktest), %c, TEI=%d, ", sap, cmd?'C':'R', tei);
+ cnt = n;
+ goto dump;
+
+ /* SAPI layer 2 management functions */
+
+ case 63:
+ {
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "Q921: SAP=%d (TEI-Management), %c, TEI=%d, ", sap, cmd?'C':'R', tei);
+
+ if (tei != 127)
+ {
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "ILLEGAL TEI\n");
+ cnt = n;
+ goto dump;
+ }
+
+ if (buf [2] != 3 && buf [3] != 0xf)
+ {
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "invalid format!\n");
+ cnt = n;
+ goto dump;
+ }
+ cnt+= 2; /* UI + MEI */
+
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "Ri=0x%04hx, ", *(short *)&buf[4]);
+ cnt += 2; /* Ri */
+
+ switch (buf[6])
+ {
+ case 1:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "IdRequest, Ai=%d", (buf [7] >> 1));
+ cnt += 2;
+ break;
+ case 2:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "IdAssign, Ai=%d", (buf [7] >> 1));
+ cnt += 2;
+ break;
+ case 3:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "IdDenied, Ai=%d", (buf [7] >> 1));
+ cnt += 2;
+ break;
+ case 4:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "IdCheckReq, Ai=%d", (buf [7] >> 1));
+ cnt += 2;
+ break;
+ case 5:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "IdCheckResp, Ai=%d", (buf [7] >> 1));
+ cnt += 2;
+ break;
+ case 6:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "IdRemove, Ai=%d", (buf [7] >> 1));
+ cnt += 2;
+ break;
+ case 7:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "IdVerify, Ai=%d", (buf [7] >> 1));
+ cnt += 2;
+ break;
+ default:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "Unknown Msg Type\n");
+ cnt = n;
+ goto dump;
+ }
+ break;
+ }
+
+ /* Illegal SAPI */
+
+ default:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "Q921: ERROR, SAP=%d (Illegal SAPI), %c, TEI=%d\n", sap, cmd?'C':'R', tei);
+ cnt = n;
+ goto dump;
+ }
+
+dump:
+ if(printit)
+ sprintf((lbufp+strlen(lbufp)), "\n");
+
+ if(raw && printit)
+ {
+ int j;
+ for (i = 0; i < cnt; i += 16)
+ {
+ sprintf((pbuf+strlen(pbuf)),"Dump:%.3d ", i);
+ for (j = 0; j < 16; j++)
+ if (i + j < cnt)
+ sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
+ else
+ sprintf((pbuf+strlen(pbuf))," ");
+ sprintf((pbuf+strlen(pbuf))," ");
+ for (j = 0; j < 16 && i + j < cnt; j++)
+ if (isprint(buf[i + j]))
+ sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
+ else
+ sprintf((pbuf+strlen(pbuf)),".");
+ sprintf((pbuf+strlen(pbuf)),"\n");
+ }
+ }
+
+ sprintf((pbuf+strlen(pbuf)),"%s", &locbuf[0]);
+
+ return (cnt);
+}
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdntrace/q931.c b/usr.sbin/i4b/isdntrace/q931.c
new file mode 100644
index 0000000..3cc2a38
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/q931.c
@@ -0,0 +1,783 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * q931.c - print Q.931 traces
+ * ---------------------------
+ *
+ * $Id: q931.c,v 1.4 1998/12/05 18:04:19 hm Exp $
+ *
+ * last edit-date: [Sat Dec 5 18:20:31 1998]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "trace.h"
+
+/*---------------------------------------------------------------------------*
+ * decode Q.931 protocol
+ *---------------------------------------------------------------------------*/
+void
+decode_q931(char *pbuf, int n, int off, unsigned char *buf, int raw)
+{
+ int codeset = 0;
+ int codelock = 0;
+ int oldcodeset = 0;
+
+ int pd;
+ int len;
+ int j;
+ int i;
+
+ if(n <= 0)
+ return;
+
+ *pbuf = '\0';
+
+ if(raw)
+ {
+
+ for (i = 0; i < n; i += 16)
+ {
+ sprintf((pbuf+strlen(pbuf)),"Dump:%.3d ", i+off);
+ for (j = 0; j < 16; j++)
+ if (i + j < n)
+ sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
+ else
+ sprintf((pbuf+strlen(pbuf))," ");
+ sprintf((pbuf+strlen(pbuf))," ");
+ for (j = 0; j < 16 && i + j < n; j++)
+ if (isprint(buf[i + j]))
+ sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
+ else
+ sprintf((pbuf+strlen(pbuf)),".");
+ sprintf((pbuf+strlen(pbuf)),"\n");
+ }
+ }
+
+ i = 0;
+
+ sprintf((pbuf+strlen(pbuf)), "Q931: ");
+
+ /* protocol discriminator */
+
+ pd = buf[i];
+
+ if(pd >= 0x00 && pd <= 0x07)
+ sprintf((pbuf+strlen(pbuf)), "pd=User-User (0x%02x), ",pd);
+ else if(pd == 0x08)
+ sprintf((pbuf+strlen(pbuf)), "pd=Q.931/I.451, ");
+ else if(pd >= 0x10 && pd <= 0x3f)
+ sprintf((pbuf+strlen(pbuf)), "pd=Other Layer 3 or X.25 (0x%02x), ",pd);
+ else if(pd >= 0x40 && pd <= 0x4f)
+ sprintf((pbuf+strlen(pbuf)), "pd=National Use (0x%02x), ",pd);
+ else if(pd >= 0x50 && pd <= 0xfe)
+ sprintf((pbuf+strlen(pbuf)), "pd=Other Layer 3 or X.25 (0x%02x), ",pd);
+ else
+ sprintf((pbuf+strlen(pbuf)), "pd=Reserved (0x%02x), ",pd);
+
+ /* call reference */
+
+ i++;
+
+ len = buf[i] & 0x0f;
+
+ switch(len)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "cr=Dummy, ");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "cr=0x%02x %s, ", (buf[i+1] & 0x7f), (buf[i+1] & 0x80) ? "(from destination)" : "(from origination)");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "cr=0x%02x 0x%02x %s, ", (buf[i+1] & 0x7f), (buf[i+2] & 0x7f), (buf[i+1] & 0x80) ? "(org)" : "(dst)");
+ break;
+ }
+
+ i += (len+1);
+
+ /* message type */
+
+ sprintf((pbuf+strlen(pbuf)), "message=");
+
+ switch(buf[i])
+ {
+ /* escape to nationally specific message type */
+
+ case 0x00:
+ sprintf((pbuf+strlen(pbuf)), "ESCAPE: ");
+ break;
+
+ /* call establishment */
+
+ case 0x01:
+ sprintf((pbuf+strlen(pbuf)), "ALERTING: ");
+ break;
+ case 0x02:
+ sprintf((pbuf+strlen(pbuf)), "CALL PROCEEDING: ");
+ break;
+ case 0x03:
+ sprintf((pbuf+strlen(pbuf)), "PROGRESS: ");
+ break;
+ case 0x05:
+ sprintf((pbuf+strlen(pbuf)), "SETUP: ");
+ break;
+ case 0x07:
+ sprintf((pbuf+strlen(pbuf)), "CONNECT: ");
+ break;
+ case 0x0d:
+ sprintf((pbuf+strlen(pbuf)), "SETUP ACKNOWLEDGE: ");
+ break;
+ case 0x0f:
+ sprintf((pbuf+strlen(pbuf)), "CONNECT ACKNOWLEDGE: ");
+ break;
+
+ /* call information phase */
+
+ case 0x20:
+ sprintf((pbuf+strlen(pbuf)), "USER INFORMATION: ");
+ break;
+ case 0x21:
+ sprintf((pbuf+strlen(pbuf)), "SUSPEND REJECT: ");
+ break;
+ case 0x22:
+ sprintf((pbuf+strlen(pbuf)), "RESUME REJECT: ");
+ break;
+ case 0x24:
+ sprintf((pbuf+strlen(pbuf)), "HOLD (Q.932): ");
+ break;
+ case 0x25:
+ sprintf((pbuf+strlen(pbuf)), "SUSPEND: ");
+ break;
+ case 0x26:
+ sprintf((pbuf+strlen(pbuf)), "RESUME: ");
+ break;
+ case 0x28:
+ sprintf((pbuf+strlen(pbuf)), "HOLD ACKNOWLEDGE (Q.932): ");
+ break;
+ case 0x2d:
+ sprintf((pbuf+strlen(pbuf)), "SUSPEND ACKNOWLEDGE: ");
+ break;
+ case 0x2e:
+ sprintf((pbuf+strlen(pbuf)), "RESUME ACKNOWLEDGE: ");
+ break;
+ case 0x30:
+ sprintf((pbuf+strlen(pbuf)), "HOLD REJECT (Q.932): ");
+ break;
+ case 0x31:
+ sprintf((pbuf+strlen(pbuf)), "RETRIEVE (Q.932): ");
+ break;
+ case 0x32:
+ sprintf((pbuf+strlen(pbuf)), "RETRIEVE ACKNOWLEDGE (Q.932): ");
+ break;
+ case 0x37:
+ sprintf((pbuf+strlen(pbuf)), "RETRIEVE REJECT (Q.932): ");
+ break;
+
+ /* call clearing */
+
+ case 0x40:
+ sprintf((pbuf+strlen(pbuf)), "DETACH: ");
+ break;
+ case 0x45:
+ sprintf((pbuf+strlen(pbuf)), "DISCONNECT: ");
+ break;
+ case 0x46:
+ sprintf((pbuf+strlen(pbuf)), "RESTART: ");
+ break;
+ case 0x48:
+ sprintf((pbuf+strlen(pbuf)), "DETACH ACKNOWLEDGE: ");
+ break;
+ case 0x4d:
+ sprintf((pbuf+strlen(pbuf)), "RELEASE: ");
+ break;
+ case 0x4e:
+ sprintf((pbuf+strlen(pbuf)), "RESTART ACKNOWLEDGE: ");
+ break;
+ case 0x5a:
+ sprintf((pbuf+strlen(pbuf)), "RELEASE COMPLETE: ");
+ break;
+
+ /* misc messages */
+
+ case 0x60:
+ sprintf((pbuf+strlen(pbuf)), "SEGMENT: ");
+ break;
+ case 0x62:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY (Q.932): ");
+ break;
+ case 0x64:
+ sprintf((pbuf+strlen(pbuf)), "REGISTER (Q.932): ");
+ break;
+ case 0x68:
+ sprintf((pbuf+strlen(pbuf)), "CANCEL ACKNOWLEDGE: ");
+ break;
+ case 0x6a:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY ACKNOWLEDGE: ");
+ break;
+ case 0x6c:
+ sprintf((pbuf+strlen(pbuf)), "REGISTER ACKNOWLEDGE: ");
+ break;
+ case 0x6e:
+ sprintf((pbuf+strlen(pbuf)), "NOTIFY: ");
+ break;
+ case 0x70:
+ sprintf((pbuf+strlen(pbuf)), "CANCEL REJECT: ");
+ break;
+ case 0x72:
+ sprintf((pbuf+strlen(pbuf)), "FACILITY REJECT: ");
+ break;
+ case 0x74:
+ sprintf((pbuf+strlen(pbuf)), "REGISTER REJECT: ");
+ break;
+ case 0x75:
+ sprintf((pbuf+strlen(pbuf)), "STATUS ENQIRY: ");
+ break;
+ case 0x79:
+ sprintf((pbuf+strlen(pbuf)), "CONGESTION CONTROL: ");
+ break;
+ case 0x7b:
+ sprintf((pbuf+strlen(pbuf)), "INFORMATION: ");
+ break;
+ case 0x7d:
+ sprintf((pbuf+strlen(pbuf)), "STATUS: ");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "UNDEFINED, TYPE=0x%02x, ", buf[i]);
+ break;
+ }
+
+ /* other information elements */
+
+ i++;
+
+ for (; i < n;)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\n ");
+
+ if(buf[i] & 0x80)
+ {
+ /* single octett info element */
+
+ switch(buf[i] & 0x70)
+ {
+ case 0x00: /* reserved */
+ sprintf((pbuf+strlen(pbuf)), "[reserved single octett info]");
+ break;
+
+ case 0x10: /* shift */
+ oldcodeset = codeset;
+ codeset = buf[i] & 0x07;
+ if(buf[i] & 0x08)
+ codelock = 0;
+ else
+ codelock = 1;
+ sprintf((pbuf+strlen(pbuf)), "[shift: codeset=%d lock=%d]", codeset, codelock);
+ break;
+
+ case 0x20: /* more data */
+ if(buf[i] & 0x01)
+ sprintf((pbuf+strlen(pbuf)), "[sending complete]");
+ else
+ sprintf((pbuf+strlen(pbuf)), "[more data]");
+ break;
+
+ case 0x30: /* congestion level */
+ sprintf((pbuf+strlen(pbuf)), "[congestion level=");
+ switch(buf[i] & 0x0f)
+ {
+ case 0x00:
+ sprintf((pbuf+strlen(pbuf)), "rx-ready]");
+ break;
+ case 0x0f:
+ sprintf((pbuf+strlen(pbuf)), "rx-not-ready]");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)]", buf[i] & 0x0f);
+ break;
+ }
+ break;
+
+ case 0x50: /* repeat ind */
+ sprintf((pbuf+strlen(pbuf)), "[repeat indicator]");
+ break;
+
+ default:
+ sprintf((pbuf+strlen(pbuf)), "[UNKNOWN SINGLE OCTET ELEMENT 0x%02x]", buf[i]);
+ break;
+ }
+
+ i++; /* next */
+
+ }
+ else
+ {
+ /* variable length info element */
+
+ if(codeset == 0)
+ {
+ switch(buf[i])
+ {
+ case 0x00:
+ sprintf((pbuf+strlen(pbuf)), "[segmented message: ");
+ break;
+ case 0x04:
+ sprintf((pbuf+strlen(pbuf)), "[bearer capability: ");
+ i += p_q931bc(pbuf, &buf[i]);
+ goto next;
+ break;
+ case 0x08:
+ sprintf((pbuf+strlen(pbuf)), "[cause: ");
+ i += p_q931cause(pbuf, &buf[i]);
+ goto next;
+ break;
+ case 0x0c:
+ sprintf((pbuf+strlen(pbuf)), "[connected address (old): ");
+ break;
+ case 0x0d:
+ sprintf((pbuf+strlen(pbuf)), "[extended facility (Q.932: )");
+ break;
+ case 0x10:
+ sprintf((pbuf+strlen(pbuf)), "[call identity: ");
+ break;
+ case 0x14:
+ sprintf((pbuf+strlen(pbuf)), "[call state: ");
+ i++;
+ len = buf[i];
+ i++;
+ sprintf((pbuf+strlen(pbuf)), "Std=");
+ switch((buf[i] & 0x60) >> 5)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "CCITT");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "ISO/IEC");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "National");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "Special");
+ break;
+ }
+ sprintf((pbuf+strlen(pbuf)), ", State=");
+
+ switch((buf[i] & 0x3f))
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "Null");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "Call initiated");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "Overlap sending");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "Outgoing call proceeding");
+ break;
+ case 4:
+ sprintf((pbuf+strlen(pbuf)), "Call delivered");
+ break;
+ case 6:
+ sprintf((pbuf+strlen(pbuf)), "Call present");
+ break;
+ case 7:
+ sprintf((pbuf+strlen(pbuf)), "Call received");
+ break;
+ case 8:
+ sprintf((pbuf+strlen(pbuf)), "Connect request");
+ break;
+ case 9:
+ sprintf((pbuf+strlen(pbuf)), "Incoming call proceeding");
+ break;
+ case 10:
+ sprintf((pbuf+strlen(pbuf)), "Active");
+ break;
+ case 11:
+ sprintf((pbuf+strlen(pbuf)), "Disconnect request");
+ break;
+ case 12:
+ sprintf((pbuf+strlen(pbuf)), "Disconnect indication");
+ break;
+ case 15:
+ sprintf((pbuf+strlen(pbuf)), "Suspend request");
+ break;
+ case 17:
+ sprintf((pbuf+strlen(pbuf)), "Resume request");
+ break;
+ case 19:
+ sprintf((pbuf+strlen(pbuf)), "Release request");
+ break;
+ case 22:
+ sprintf((pbuf+strlen(pbuf)), "Call abort");
+ break;
+ case 25:
+ sprintf((pbuf+strlen(pbuf)), "Overlap receiving");
+ break;
+ case 0x3d:
+ sprintf((pbuf+strlen(pbuf)), "Restart request");
+ break;
+ case 0x3e:
+ sprintf((pbuf+strlen(pbuf)), "Restart");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved");
+ break;
+ }
+ sprintf((pbuf+strlen(pbuf)), "]");
+ i++;
+ goto next;
+ break;
+ case 0x18:
+ sprintf((pbuf+strlen(pbuf)), "[channel id: channel=");
+ i++;
+ len = buf[i];
+ i++;
+ switch(buf[i] & 0x03)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "no channel");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "B-1");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "B-2");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "any channel");
+ break;
+ }
+ if(buf[i] & 0x08)
+ sprintf((pbuf+strlen(pbuf)), " (exclusive)]");
+ else
+ sprintf((pbuf+strlen(pbuf)), " (preferred)]");
+ i++;
+ goto next;
+ break;
+ case 0x19:
+ sprintf((pbuf+strlen(pbuf)), "[data link connection id (Q.933): ");
+ break;
+ case 0x1c:
+ i += q932_facility(pbuf, &buf[i]);
+ goto next;
+ break;
+ case 0x1e:
+ sprintf((pbuf+strlen(pbuf)), "[progress ind: ");
+ i++;
+ len = buf[i];
+ i++;
+ sprintf((pbuf+strlen(pbuf)), "Std=");
+ switch((buf[i] & 0x60) >> 5)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "CCITT");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "ISO/IEC");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "National");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "Local");
+ break;
+ }
+ sprintf((pbuf+strlen(pbuf)), ", Loc=");
+
+ switch((buf[i] & 0x0f))
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "User");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "Private network serving local user");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "Public network serving local user");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "Transit network");
+ break;
+ case 4:
+ sprintf((pbuf+strlen(pbuf)), "Public network serving remote user");
+ break;
+ case 5:
+ sprintf((pbuf+strlen(pbuf)), "Private network serving remote user");
+ break;
+ case 6:
+ sprintf((pbuf+strlen(pbuf)), "Network beyond interworking point");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved");
+ break;
+ }
+
+ i++;
+
+ sprintf((pbuf+strlen(pbuf)), "\n Description: ");
+
+ switch((buf[i] & 0x7f))
+ {
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "Call is not end-to-end ISDN");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "Destination address is non-ISDN");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "Origination address is non-ISDN");
+ break;
+ case 4:
+ sprintf((pbuf+strlen(pbuf)), "Call has returned to the ISDN");
+ break;
+ case 5:
+ sprintf((pbuf+strlen(pbuf)), "Interworking occured, Service change");
+ break;
+ case 8:
+ sprintf((pbuf+strlen(pbuf)), "In-band info or appropriate pattern now available");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved");
+ break;
+ }
+ sprintf((pbuf+strlen(pbuf)), "]");
+ i++;
+ goto next;
+ break;
+ case 0x20:
+ sprintf((pbuf+strlen(pbuf)), "[network specific facilities: ");
+ break;
+ case 0x24:
+ sprintf((pbuf+strlen(pbuf)), "[terminal capabilities: ");
+ break;
+ case 0x27:
+ sprintf((pbuf+strlen(pbuf)), "[notification ind: ");
+ break;
+ case 0x28:
+ sprintf((pbuf+strlen(pbuf)), "[display: ");
+ i++;
+ len = buf[i];
+ i++;
+ for(j = 0; j < len; j++)
+ {
+ sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
+ }
+ sprintf((pbuf+strlen(pbuf)),"]");
+ i += j;
+ goto next;
+ break;
+ case 0x29:
+ sprintf((pbuf+strlen(pbuf)), "[date/time: ");
+ i++;
+ len = buf[i];
+ i++;
+ j = 0;
+ sprintf((pbuf+strlen(pbuf)),"%.2d.%.2d.%.2d",
+ buf[i+2], buf[i+1], buf[i]);
+ j+=3;
+ if(j < len)
+ {
+ sprintf((pbuf+strlen(pbuf))," %.2d", buf[i+3]);
+ j++;
+ }
+ if(j < len)
+ {
+ sprintf((pbuf+strlen(pbuf)),":%.2d", buf[i+4]);
+ j++;
+ }
+ if(j < len)
+ {
+ sprintf((pbuf+strlen(pbuf)),":%.2d", buf[i+5]);
+ j++;
+ }
+ sprintf((pbuf+strlen(pbuf)),"]");
+ i += len;
+ goto next;
+ break;
+ case 0x2c:
+ sprintf((pbuf+strlen(pbuf)), "[keypad: ");
+ break;
+ case 0x30:
+ sprintf((pbuf+strlen(pbuf)), "[keypad echo: ");
+ break;
+ case 0x32:
+ sprintf((pbuf+strlen(pbuf)), "[information req (Q.932): ");
+ break;
+ case 0x34:
+ sprintf((pbuf+strlen(pbuf)), "[signal: ");
+ break;
+ case 0x36:
+ sprintf((pbuf+strlen(pbuf)), "[switchhook: ");
+ break;
+ case 0x38:
+ sprintf((pbuf+strlen(pbuf)), "[feature activation (Q.932): ");
+ break;
+ case 0x39:
+ sprintf((pbuf+strlen(pbuf)), "[feature ind (Q.932): ");
+ break;
+ case 0x3a:
+ sprintf((pbuf+strlen(pbuf)), "[service profile id (Q.932): ");
+ break;
+ case 0x3b:
+ sprintf((pbuf+strlen(pbuf)), "[endpoint id (Q.932): ");
+ break;
+ case 0x40:
+ sprintf((pbuf+strlen(pbuf)), "[information rate: ");
+ break;
+ case 0x41:
+ sprintf((pbuf+strlen(pbuf)), "[precedence level (Q.955): ");
+ break;
+ case 0x42:
+ sprintf((pbuf+strlen(pbuf)), "[end-to-end transit delay: ");
+ break;
+ case 0x43:
+ sprintf((pbuf+strlen(pbuf)), "[transit delay detection and indication: ");
+ break;
+ case 0x44:
+ sprintf((pbuf+strlen(pbuf)), "[packet layer binary parameters: ");
+ break;
+ case 0x45:
+ sprintf((pbuf+strlen(pbuf)), "[packet layer window size: ");
+ break;
+ case 0x46:
+ sprintf((pbuf+strlen(pbuf)), "[packet size: ");
+ break;
+ case 0x47:
+ sprintf((pbuf+strlen(pbuf)), "[closed user group: ");
+ break;
+ case 0x48:
+ sprintf((pbuf+strlen(pbuf)), "[link layer core parameters (Q.933): ");
+ break;
+ case 0x49:
+ sprintf((pbuf+strlen(pbuf)), "[link layer protocol parameters (Q.933): ");
+ break;
+ case 0x4a:
+ sprintf((pbuf+strlen(pbuf)), "[reverse charging information: ");
+ break;
+ case 0x4c:
+ sprintf((pbuf+strlen(pbuf)), "[connected number (Q.951): ");
+ i += p_q931address(pbuf, &buf[i]);
+ goto next;
+ break;
+
+ break;
+ case 0x4d:
+ sprintf((pbuf+strlen(pbuf)), "[connected subaddress (Q.951): ");
+ break;
+ case 0x50:
+ sprintf((pbuf+strlen(pbuf)), "[X.213 priority (Q.933): ");
+ break;
+ case 0x51:
+ sprintf((pbuf+strlen(pbuf)), "[report type (Q.933): ");
+ break;
+ case 0x53:
+ sprintf((pbuf+strlen(pbuf)), "[link integrity verification (Q.933): ");
+ break;
+ case 0x57:
+ sprintf((pbuf+strlen(pbuf)), "[PVC status (Q.933): ");
+ break;
+ case 0x6c:
+ sprintf((pbuf+strlen(pbuf)), "[calling party number: ");
+ i += p_q931address(pbuf, &buf[i]);
+ goto next;
+ break;
+ case 0x6d:
+ sprintf((pbuf+strlen(pbuf)), "[calling party subaddress: ");
+ break;
+ case 0x70:
+ sprintf((pbuf+strlen(pbuf)), "[called party number: ");
+ i += p_q931address(pbuf, &buf[i]);
+ goto next;
+ break;
+ case 0x71:
+ sprintf((pbuf+strlen(pbuf)), "[called party subaddress: ");
+ break;
+ case 0x74:
+ sprintf((pbuf+strlen(pbuf)), "[redirecting number: ");
+ break;
+ case 0x76:
+ sprintf((pbuf+strlen(pbuf)), "[redirection number: ");
+ break;
+ case 0x78:
+ sprintf((pbuf+strlen(pbuf)), "[transit network selection: ");
+ break;
+ case 0x79:
+ sprintf((pbuf+strlen(pbuf)), "[restart indicator: ");
+ break;
+ case 0x7c:
+ sprintf((pbuf+strlen(pbuf)), "[low layer compatibility: ");
+ break;
+ case 0x7d:
+ sprintf((pbuf+strlen(pbuf)), "[high layer compatibility:");
+ i += p_q931high_compat(pbuf, &buf[i]);
+ goto next;
+ break;
+ case 0x7e:
+ sprintf((pbuf+strlen(pbuf)), "[user-user: ");
+ break;
+ case 0x7f:
+ sprintf((pbuf+strlen(pbuf)), "[escape for extension: ");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "[UNKNOWN INFO-ELEMENT-ID=0x%02x: ", buf[i]);
+ break;
+ }
+ }
+ else
+ {
+ sprintf((pbuf+strlen(pbuf)), "[UNKNOWN CODESET=%d, IE=0x%02x: ", codeset, buf[i]);
+ }
+
+ i++; /* index -> length */
+
+ len = buf[i];
+
+ sprintf((pbuf+strlen(pbuf)), "LEN=0x%02x, DATA=", len);
+
+ i++; /* index -> 1st param */
+
+ for(j = 0; j < len; j++)
+ {
+ sprintf((pbuf+strlen(pbuf)),"0x%02x ", buf[j+i]);
+ }
+
+ sprintf((pbuf+strlen(pbuf)),"]");
+
+ i += len;
+
+next:
+
+ if(!codelock && (codeset != oldcodeset))
+ codeset = oldcodeset;
+ }
+ }
+ sprintf((pbuf+strlen(pbuf)),"\n");
+}
+
+/* EOF */
+
diff --git a/usr.sbin/i4b/isdntrace/q931_util.c b/usr.sbin/i4b/isdntrace/q931_util.c
new file mode 100644
index 0000000..1b2ab09
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/q931_util.c
@@ -0,0 +1,697 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * q931_util.c - utility functions to print Q.931 traces
+ * -----------------------------------------------------
+ *
+ * $Id: q931_util.c,v 1.4 1998/12/05 18:04:21 hm Exp $
+ *
+ * last edit-date: [Sat Dec 5 18:20:43 1998]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "trace.h"
+
+/*---------------------------------------------------------------------------*
+ * decode and print the cause
+ *---------------------------------------------------------------------------*/
+int
+p_q931cause(char *pbuf, unsigned char *buf)
+{
+ int j;
+ int len;
+ int i = 0;
+ int ls;
+ int r = 0;
+ int rflag = 0;
+
+ i++; /* index -> length */
+
+ len = buf[i];
+
+ i++; /* coding/location */
+ len--;
+
+ ls = buf[i];
+
+ i++;
+ len--;
+
+ if(!(buf[i-1] & 0x80))
+ {
+ r = buf[i];
+ rflag = 1;
+ i++;
+ len--;
+ }
+
+ sprintf((pbuf+strlen(pbuf)), "%s ", print_cause_q850(buf[i] & 0x7f));
+
+ sprintf((pbuf+strlen(pbuf)), "\n (location=");
+
+ switch(ls & 0x0f)
+ {
+ case 0x00:
+ sprintf((pbuf+strlen(pbuf)), "user");
+ break;
+ case 0x01:
+ sprintf((pbuf+strlen(pbuf)), "private network serving local user");
+ break;
+ case 0x02:
+ sprintf((pbuf+strlen(pbuf)), "public network serving local user");
+ break;
+ case 0x03:
+ sprintf((pbuf+strlen(pbuf)), "transit network");
+ break;
+ case 0x04:
+ sprintf((pbuf+strlen(pbuf)), "public network serving remote user");
+ break;
+ case 0x05:
+ sprintf((pbuf+strlen(pbuf)), "private network serving remote user");
+ break;
+ case 0x07:
+ sprintf((pbuf+strlen(pbuf)), "international network");
+ break;
+ case 0x0a:
+ sprintf((pbuf+strlen(pbuf)), "network beyond interworking point");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", ls & 0x0f);
+ break;
+ }
+
+ sprintf((pbuf+strlen(pbuf)), ", std=");
+
+ switch((ls & 0x60) >> 5)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "CCITT");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "ISO/IEC");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "National");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "Local");
+ break;
+ }
+
+ if(rflag)
+ {
+ sprintf((pbuf+strlen(pbuf)), ", rec=");
+
+ switch(r & 0x7f)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "Q.931");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "X.21");
+ break;
+ case 4:
+ sprintf((pbuf+strlen(pbuf)), "X.25");
+ break;
+ case 5:
+ sprintf((pbuf+strlen(pbuf)), "Q.1031/Q.1051");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "Reserved");
+ break;
+ }
+ }
+
+ sprintf((pbuf+strlen(pbuf)),")");
+
+ i++;
+ len--;
+
+ for(j = 0; j < len; j++)
+ sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
+
+ sprintf((pbuf+strlen(pbuf)),"]");
+
+ i += (len+1);
+
+ return(i);
+}
+
+/*---------------------------------------------------------------------------*
+ * decode and print the bearer capability
+ *---------------------------------------------------------------------------*/
+int
+p_q931bc(char *pbuf, unsigned char *buf)
+{
+ int len;
+ int i = 0;
+ int mr = 0;
+
+ i++; /* index -> length */
+
+ len = buf[i];
+
+ i++;
+
+ sprintf((pbuf+strlen(pbuf)), "\n cap=");
+
+ switch(buf[i] & 0x1f)
+ {
+ case 0x00:
+ sprintf((pbuf+strlen(pbuf)), "speech");
+ break;
+ case 0x08:
+ sprintf((pbuf+strlen(pbuf)), "unrestricted digital information");
+ break;
+ case 0x09:
+ sprintf((pbuf+strlen(pbuf)), "restricted digital information");
+ break;
+ case 0x10:
+ sprintf((pbuf+strlen(pbuf)), "3.1 kHz audio");
+ break;
+ case 0x11:
+ sprintf((pbuf+strlen(pbuf)), "unrestricted digital information with tones");
+ break;
+ case 0x18:
+ sprintf((pbuf+strlen(pbuf)), "video");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
+ break;
+ }
+
+ sprintf((pbuf+strlen(pbuf)), "\n std=");
+
+ switch((buf[i] & 0x60) >> 5)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "CCITT");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "ISO/IEC");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "National");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "NSI Std");
+ break;
+ }
+
+ i++;
+ len--;
+
+ sprintf((pbuf+strlen(pbuf)), "\n rate=");
+
+ switch(buf[i] & 0x1f)
+ {
+ case 0x00:
+ sprintf((pbuf+strlen(pbuf)), "packet mode");
+ break;
+ case 0x10:
+ sprintf((pbuf+strlen(pbuf)), "64 kbit/s");
+ break;
+ case 0x11:
+ sprintf((pbuf+strlen(pbuf)), "2 x 64 kbit/s");
+ break;
+ case 0x13:
+ sprintf((pbuf+strlen(pbuf)), "384 kbit/s");
+ break;
+ case 0x15:
+ sprintf((pbuf+strlen(pbuf)), "1536 kbit/s");
+ break;
+ case 0x17:
+ sprintf((pbuf+strlen(pbuf)), "1920 kbit/s");
+ break;
+ case 0x18:
+ sprintf((pbuf+strlen(pbuf)), "Multirate");
+ mr = 1;
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
+ break;
+ }
+
+ sprintf((pbuf+strlen(pbuf)), "\n mode=");
+
+ switch((buf[i] & 0x60) >> 5)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "circuit");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "packet");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", ((buf[i] & 0x60) >> 5));
+ break;
+ }
+
+ i++;
+ len--;
+
+ if(!len)
+ goto exit;
+
+ if(mr)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\n rate multiplier=%d", buf[i] & 0x7f);
+ i++;
+ len--;
+ }
+
+ if(!len)
+ goto exit;
+
+ sprintf((pbuf+strlen(pbuf)), "\n layer1=");
+
+ switch(buf[i] & 0x1f)
+ {
+ case 0x01:
+ sprintf((pbuf+strlen(pbuf)), "V.110");
+ break;
+ case 0x02:
+ sprintf((pbuf+strlen(pbuf)), "G.711 u-law");
+ break;
+ case 0x03:
+ sprintf((pbuf+strlen(pbuf)), "G.711 A-law");
+ break;
+ case 0x04:
+ sprintf((pbuf+strlen(pbuf)), "G.721");
+ break;
+ case 0x05:
+ sprintf((pbuf+strlen(pbuf)), "H.221/H.242");
+ break;
+ case 0x07:
+ sprintf((pbuf+strlen(pbuf)), "Non-Std");
+ break;
+ case 0x08:
+ sprintf((pbuf+strlen(pbuf)), "V.120");
+ break;
+ case 0x09:
+ sprintf((pbuf+strlen(pbuf)), "X.31");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
+ break;
+ }
+ i++;
+ len--;
+
+ if(!len)
+ goto exit;
+
+ if(!(buf[i-1] & 0x80))
+ {
+ sprintf((pbuf+strlen(pbuf)), "\n user rate=0x%02x ", buf[i] & 0x1f);
+
+ if(buf[i] & 0x40)
+ sprintf((pbuf+strlen(pbuf)), "(async,");
+ else
+ sprintf((pbuf+strlen(pbuf)), "(sync,");
+
+ if(buf[i] & 0x20)
+ sprintf((pbuf+strlen(pbuf)), "in-band neg. possible)");
+ else
+ sprintf((pbuf+strlen(pbuf)), "in-band neg not possible)");
+
+ i++;
+ len--;
+ }
+
+ if(!len)
+ goto exit;
+
+ if(!(buf[i-1] & 0x80))
+ {
+ sprintf((pbuf+strlen(pbuf)), "\n clk/flow=0x%02x", buf[i] & 0x1f);
+
+ sprintf((pbuf+strlen(pbuf)), "\n intermediate rate=");
+
+ switch((buf[i] & 0x60) >> 5)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "not used");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "8 kbit/s");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "16 kbit/s");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "32 kbit/s");
+ break;
+ }
+ i++;
+ len--;
+ }
+
+ if(!len)
+ goto exit;
+
+ if(!(buf[i-1] & 0x80))
+ {
+ sprintf((pbuf+strlen(pbuf)), "\n hdr/mfrm/etc.=0x%02x", buf[i]);
+ i++;
+ len--;
+ }
+
+ if(!len)
+ goto exit;
+
+ if(!(buf[i-1] & 0x80))
+ {
+ sprintf((pbuf+strlen(pbuf)), "\n stop/data/parity=0x%02x", buf[i]);
+ i++;
+ len--;
+ }
+
+ if(!len)
+ goto exit;
+
+ if(!(buf[i-1] & 0x80))
+ {
+ sprintf((pbuf+strlen(pbuf)), "\n modemtype=0x%02x", buf[i]);
+ i++;
+ len--;
+ }
+
+ if(!len)
+ goto exit;
+
+ switch(buf[i] & 0x7f)
+ {
+ case 0x42:
+ sprintf((pbuf+strlen(pbuf)), "\n layer2=Q.921/I.441");
+ break;
+ case 0x46:
+ sprintf((pbuf+strlen(pbuf)), "\n layer2=X.25 link");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "\n layer2=0x%02x",(buf[i] & 0x7f));
+ break;
+ }
+ i++;
+ len--;
+
+ if(!len)
+ goto exit;
+
+ switch(buf[i] & 0x7f)
+ {
+ case 0x62:
+ sprintf((pbuf+strlen(pbuf)), "\n layer3=Q.921/I.441");
+ break;
+ case 0x66:
+ sprintf((pbuf+strlen(pbuf)), "\n layer3=X.25 packet");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "\n layer3=0x%02x",(buf[i] & 0x7f));
+ break;
+ }
+ i++;
+ len--;
+
+exit:
+ sprintf((pbuf+strlen(pbuf)), "]");
+ return(i);
+}
+
+/*---------------------------------------------------------------------------*
+ * decode and print the ISDN (telephone) number
+ *---------------------------------------------------------------------------*/
+int
+p_q931address(char *pbuf, unsigned char *buf)
+{
+ int j;
+ int len;
+ int i = 0;
+ int tp;
+ int ind = 0;
+ int indflag = 0;
+
+ i++; /* index -> length */
+ len = buf[i];
+
+ i++; /* index -> type/plan */
+ tp = buf[i];
+
+ i++;
+ len--;
+
+ if(!(tp & 0x80))
+ {
+ ind = buf[i];
+ indflag = 1;
+ i++;
+ len--;
+ }
+
+ for(j = 0; j < len; j++)
+ {
+ sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
+ }
+
+ switch((tp & 0x70) >> 4)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), " (type=unknown, ");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), " (type=international, ");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), " (type=national, ");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), " (type=network specific, ");
+ break;
+ case 4:
+ sprintf((pbuf+strlen(pbuf)), " (type=subscriber, ");
+ break;
+ case 6:
+ sprintf((pbuf+strlen(pbuf)), " (type=abbreviated, ");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), " (type=reserved (%d), ", ((tp & 0x70) >> 4));
+ break;
+ }
+
+ switch(tp & 0x0f)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "plan=unknown");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "plan=ISDN");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "plan=Data");
+ break;
+ case 4:
+ sprintf((pbuf+strlen(pbuf)), "plan=Telex");
+ break;
+ case 8:
+ sprintf((pbuf+strlen(pbuf)), "plan=National");
+ break;
+ case 9:
+ sprintf((pbuf+strlen(pbuf)), "plan=private");
+ break;
+ default:
+ sprintf((pbuf+strlen(pbuf)), "plan=reserved (%d)", (tp & 0x0f));
+ break;
+ }
+
+ if(indflag)
+ {
+ sprintf((pbuf+strlen(pbuf)), ",\n ");
+ switch((ind & 0x60) >> 5)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "presentation allowed, ");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "presentation restricted, ");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "number not available, ");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "reserved, ");
+ break;
+ }
+
+ switch(ind & 0x03)
+ {
+ case 0:
+ sprintf((pbuf+strlen(pbuf)), "screening user provided: not screened");
+ break;
+ case 1:
+ sprintf((pbuf+strlen(pbuf)), "screening user provided: verified & passed");
+ break;
+ case 2:
+ sprintf((pbuf+strlen(pbuf)), "screening user provided: verified & failed");
+ break;
+ case 3:
+ sprintf((pbuf+strlen(pbuf)), "screening network provided");
+ break;
+ }
+ }
+
+ sprintf((pbuf+strlen(pbuf)),")]");
+
+ i += j;
+
+ return(i);
+}
+
+/*---------------------------------------------------------------------------*
+ * decode and print HL comatibility
+ *---------------------------------------------------------------------------*/
+int
+p_q931high_compat(char *pbuf, unsigned char *buf)
+{
+ int len = buf[1];
+
+ sprintf(pbuf+strlen(pbuf), " standard=");
+
+ switch ((buf[2] >> 5) & 0x03)
+ {
+ case 0: sprintf(pbuf+strlen(pbuf), "CCITT");
+ break;
+ case 1: sprintf(pbuf+strlen(pbuf), "unknown international standard");
+ break;
+ case 2: sprintf(pbuf+strlen(pbuf), "unknown national standard");
+ break;
+ case 3: sprintf(pbuf+strlen(pbuf), "local network standard");
+ }
+
+ len--;
+
+ sprintf(pbuf+strlen(pbuf), ", characteristics=");
+
+ switch (buf[3] & 0x7f)
+ {
+ case 0x01:
+ sprintf(pbuf+strlen(pbuf), "Telephony");
+ break;
+ case 0x04:
+ sprintf(pbuf+strlen(pbuf), "Fax Group 2/3");
+ break;
+ case 0x21:
+ sprintf(pbuf+strlen(pbuf), "Fax Group 4 Class I (F.184)");
+ break;
+ case 0x24:
+ sprintf(pbuf+strlen(pbuf), "Teletex basic/mixed (F.230) or Fax Group 4 Class II/III (F.184)");
+ break;
+ case 0x28:
+ sprintf(pbuf+strlen(pbuf), "Teletex basic/processable (F.220)");
+ break;
+ case 0x31:
+ sprintf(pbuf+strlen(pbuf), "Teletex basic mode (F.200)");
+ break;
+ case 0x32:
+ sprintf(pbuf+strlen(pbuf), "Videotex (F.300 and T.101)");
+ break;
+ case 0x35:
+ sprintf(pbuf+strlen(pbuf), "Telex (F.60)");
+ break;
+ case 0x38:
+ sprintf(pbuf+strlen(pbuf), "MHS (X.400 series)");
+ break;
+ case 0x41:
+ sprintf(pbuf+strlen(pbuf), "OSI application (X.200 series)");
+ break;
+ case 0x5e:
+ sprintf(pbuf+strlen(pbuf), "Maintenance");
+ break;
+ case 0x5f:
+ sprintf(pbuf+strlen(pbuf), "Management");
+ break;
+ case 0x7f:
+ sprintf(pbuf+strlen(pbuf), "reserved");
+ break;
+ default:
+ sprintf(pbuf+strlen(pbuf), "UNKNOWN (0x%02x)", buf[3]);
+ break;
+ }
+
+ len--;
+
+ if (!len)
+ {
+ sprintf(pbuf+strlen(pbuf), "]");
+ return 4;
+ }
+
+ sprintf(pbuf+strlen(pbuf), " of ");
+
+ switch (buf[4] & 0x7f)
+ {
+ case 0x01:
+ sprintf(pbuf+strlen(pbuf), "Telephony");
+ break;
+ case 0x04:
+ sprintf(pbuf+strlen(pbuf), "Fax Group 2/3");
+ break;
+ case 0x21:
+ sprintf(pbuf+strlen(pbuf), "Fax Group 4 Class I (F.184)");
+ break;
+ case 0x24:
+ sprintf(pbuf+strlen(pbuf), "Teletex basic/mixed (F.230) or Fax Group 4 Class II/III (F.184)");
+ break;
+ case 0x28:
+ sprintf(pbuf+strlen(pbuf), "Teletex basic/processable (F.220)");
+ break;
+ case 0x31:
+ sprintf(pbuf+strlen(pbuf), "Teletex basic mode (F.200)");
+ break;
+ case 0x32:
+ sprintf(pbuf+strlen(pbuf), "Videotex (F.300 and T.101)");
+ break;
+ case 0x35:
+ sprintf(pbuf+strlen(pbuf), "Telex (F.60)");
+ break;
+ case 0x38:
+ sprintf(pbuf+strlen(pbuf), "MHS (X.400 series)");
+ break;
+ case 0x41:
+ sprintf(pbuf+strlen(pbuf), "OSI application (X.200 series)");
+ break;
+ case 0x7f:
+ sprintf(pbuf+strlen(pbuf), "reserved");
+ break;
+ default:
+ sprintf(pbuf+strlen(pbuf), "UNKNOWN (0x%02x)", buf[3]);
+ break;
+ }
+ sprintf(pbuf+strlen(pbuf), "]");
+ return 5;
+}
+
+/* EOF */
+
diff --git a/usr.sbin/i4b/isdntrace/q932_fac.c b/usr.sbin/i4b/isdntrace/q932_fac.c
new file mode 100644
index 0000000..ba3f59d
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/q932_fac.c
@@ -0,0 +1,926 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * q932_fac.c - decode Q.932 facilities
+ * ------------------------------------
+ *
+ * $Id: q932_fac.c,v 1.4 1998/12/05 18:04:22 hm Exp $
+ *
+ * last edit-date: [Sat Dec 5 18:20:58 1998]
+ *
+ *---------------------------------------------------------------------------
+ *
+ * - Q.932 (03/93) Generic Procedures for the Control of
+ * ISDN Supplementaty Services
+ * - Q.950 (03/93) Supplementary Services Protocols, Structure and
+ * General Principles
+ * - ETS 300 179 (10/92) Advice Of Charge: charging information during
+ * the call (AOC-D) supplementary service Service description
+ * - ETS 300 180 (10/92) Advice Of Charge: charging information at the
+ * end of call (AOC-E) supplementary service Service description
+ * - ETS 300 181 (04/93) Advice Of Charge (AOC) supplementary service
+ * Functional capabilities and information flows
+ * - ETS 300 182 (04/93) Advice Of Charge (AOC) supplementary service
+ * Digital Subscriber Signalling System No. one (DSS1) protocol
+ * - X.208 Specification of Abstract Syntax Notation One (ASN.1)
+ * - X.209 Specification of Basic Encoding Rules for
+ * Abstract Syntax Notation One (ASN.1)
+ * - "ASN.1 Abstract Syntax Notation One", Walter Gora, DATACOM-Verlag
+ * 1992, 3rd Edition (ISBN 3-89238-062-7) (german !)
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "trace.h"
+#include "q932_fac.h"
+
+static int do_component(int length, char *pbuf);
+static char *uni_str(int code);
+static char *opval_str(int val);
+static char *bid_str(int val);
+static void next_state(char *pbuf, int class, int form, int code, int val);
+
+static int byte_len;
+static unsigned char *byte_buf;
+static int state;
+
+/*---------------------------------------------------------------------------*
+ * decode Q.931/Q.932 facility info element
+ *---------------------------------------------------------------------------*/
+int
+q932_facility(char *pbuf, unsigned char *buf)
+{
+ int len;
+
+ sprintf((pbuf+strlen(pbuf)), "[facility (Q.932): ");
+
+ buf++; /* length */
+
+ len = *buf;
+
+ buf++; /* protocol profile */
+
+ sprintf((pbuf+strlen(pbuf)), "Protocol=");
+
+ switch(*buf & 0x1f)
+ {
+ case FAC_PROTO_ROP:
+ sprintf((pbuf+strlen(pbuf)), "Remote Operations Protocol\n");
+ break;
+
+ case FAC_PROTO_CMIP:
+ sprintf((pbuf+strlen(pbuf)), "CMIP Protocol (Q.941), UNSUPPORTED!\n");
+ return(len+2);
+ break;
+
+ case FAC_PROTO_ACSE:
+ sprintf((pbuf+strlen(pbuf)), "ACSE Protocol (X.217/X.227), UNSUPPORTED!\n");
+ return(len+2);
+ break;
+
+ default:
+ sprintf((pbuf+strlen(pbuf)), "Unknown Protocol (val = 0x%x), UNSUPPORTED!\n", *buf & 0x1f);
+ return(len+2);
+ break;
+ }
+
+ /* next byte */
+
+ buf++;
+ len--;
+
+ /* initialize variables for do_component */
+
+ byte_len = 0;
+ byte_buf = buf;
+ state = ST_EXP_COMP_TYP;
+
+ /* decode facility */
+
+ do_component(len, pbuf);
+
+ sprintf((pbuf+(strlen(pbuf)-1)), "]"); /* XXX replace last newline */
+
+ return(len+3);
+}
+
+/*---------------------------------------------------------------------------*
+ * handle a component recursively
+ *---------------------------------------------------------------------------*/
+static int
+do_component(int length, char *pbuf)
+{
+ int comp_tag_class; /* component tag class */
+ int comp_tag_form; /* component form: constructor or primitive */
+ int comp_tag_code; /* component code depending on class */
+ int comp_length = 0; /* component length */
+
+#ifdef FAC_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "ENTER - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
+#endif
+
+again:
+
+#ifdef FAC_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "AGAIN - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
+#endif
+
+ /*----------------------------------------*/
+ /* first component element: component tag */
+ /*----------------------------------------*/
+
+ /* tag class bits */
+
+ sprintf((pbuf+strlen(pbuf)), "\t0x%02x Tag: ", *byte_buf);
+
+ comp_tag_class = (*byte_buf & 0xc0) >> 6;
+
+ switch(comp_tag_class)
+ {
+ case FAC_TAGCLASS_UNI:
+ sprintf((pbuf+strlen(pbuf)), "Universal");
+ break;
+ case FAC_TAGCLASS_APW:
+ sprintf((pbuf+strlen(pbuf)), "Applic-wide");
+ break;
+ case FAC_TAGCLASS_COS:
+ sprintf((pbuf+strlen(pbuf)), "Context-spec");
+ break;
+ case FAC_TAGCLASS_PRU:
+ sprintf((pbuf+strlen(pbuf)), "Private");
+ break;
+ }
+
+ /* tag form bit */
+
+ comp_tag_form = (*byte_buf & 0x20) > 5;
+
+ sprintf((pbuf+strlen(pbuf)), ", ");
+
+ if(comp_tag_form == FAC_TAGFORM_CON)
+ {
+ sprintf((pbuf+strlen(pbuf)), "Constructor");
+ }
+ else
+ {
+ sprintf((pbuf+strlen(pbuf)), "Primitive");
+ }
+
+ /* tag code bits */
+
+ comp_tag_code = *byte_buf & 0x1f;
+
+ sprintf((pbuf+strlen(pbuf)), ", ");
+
+ if(comp_tag_code == 0x1f)
+ {
+ comp_tag_code = 0;
+
+ byte_buf++;
+ byte_len++;
+
+ while(*byte_buf & 0x80)
+ {
+ comp_tag_code += (*byte_buf & 0x7f);
+ byte_buf++;
+ byte_len++;
+ }
+ comp_tag_code += (*byte_buf & 0x7f);
+ sprintf((pbuf+strlen(pbuf)), "%d (ext)\n", comp_tag_code);
+ }
+ else
+ {
+ comp_tag_code = (*byte_buf & 0x1f);
+
+ if(comp_tag_class == FAC_TAGCLASS_UNI)
+ {
+ sprintf((pbuf+strlen(pbuf)), "%s (%d)\n", uni_str(comp_tag_code), comp_tag_code);
+ }
+ else
+ {
+ sprintf((pbuf+strlen(pbuf)), "code = %d\n", comp_tag_code);
+ }
+ }
+
+ byte_buf++;
+ byte_len++;
+
+ /*--------------------------------------------*/
+ /* second component element: component length */
+ /*--------------------------------------------*/
+
+ sprintf((pbuf+strlen(pbuf)), "\t0x%02x Len: ", *byte_buf);
+
+ comp_length = 0;
+
+ if(*byte_buf & 0x80)
+ {
+ int i = *byte_buf & 0x7f;
+
+ byte_len += i;
+
+ for(;i > 0;i++)
+ {
+ byte_buf++;
+ comp_length += (*byte_buf * (i*256));
+ }
+ sprintf((pbuf+strlen(pbuf)), "%d (long form)\n", comp_length);
+ }
+ else
+ {
+ comp_length = *byte_buf & 0x7f;
+ sprintf((pbuf+strlen(pbuf)), "%d (short form)\n", comp_length);
+ }
+
+ next_state(pbuf, comp_tag_class, comp_tag_form, comp_tag_code, -1);
+
+ byte_len++;
+ byte_buf++;
+
+ if(comp_length)
+ {
+
+ /*---------------------------------------------*/
+ /* third component element: component contents */
+ /*---------------------------------------------*/
+
+ if(comp_tag_form) /* == constructor */
+ {
+ do_component(comp_length, pbuf);
+ }
+ else
+ {
+ int val = 0;
+ if(comp_tag_class == FAC_TAGCLASS_UNI)
+ {
+ switch(comp_tag_code)
+ {
+ case FAC_CODEUNI_INT:
+ case FAC_CODEUNI_ENUM:
+ case FAC_CODEUNI_BOOL:
+ if(comp_length)
+ {
+ int i;
+
+ sprintf((pbuf+strlen(pbuf)), "\t");
+
+ for(i = comp_length-1; i >= 0; i--)
+ {
+ sprintf((pbuf+strlen(pbuf)), "0x%02x ", *byte_buf);
+ val += (*byte_buf + (i*255));
+ byte_buf++;
+ byte_len++;
+ if(i)
+ sprintf((pbuf+strlen(pbuf)), "\n\t");
+ }
+ sprintf((pbuf+strlen(pbuf)), "Val: %d\n", val);
+ }
+ break;
+ default:
+ if(comp_length)
+ {
+ int i;
+
+ sprintf((pbuf+strlen(pbuf)), "\t");
+
+ for(i = comp_length-1; i >= 0; i--)
+ {
+ sprintf((pbuf+strlen(pbuf)), "0x%02x = %d", *byte_buf, *byte_buf);
+ if(isprint(*byte_buf))
+ sprintf((pbuf+strlen(pbuf)), " = '%c'", *byte_buf);
+ byte_buf++;
+ byte_len++;
+ if(i)
+ sprintf((pbuf+strlen(pbuf)), "\n\t");
+ }
+ }
+ break;
+ }
+ }
+
+ else /* comp_tag_class != FAC_TAGCLASS_UNI */
+ {
+ if(comp_length)
+ {
+ int i;
+
+ sprintf((pbuf+strlen(pbuf)), "\t");
+
+ for(i = comp_length-1; i >= 0; i--)
+ {
+ sprintf((pbuf+strlen(pbuf)), "0x%02x", *byte_buf);
+ val += (*byte_buf + (i*255));
+ byte_buf++;
+ byte_len++;
+ if(i)
+ sprintf((pbuf+strlen(pbuf)), "\n\t");
+ }
+ sprintf((pbuf+strlen(pbuf)), "\n");
+ }
+ }
+ next_state(pbuf, comp_tag_class, comp_tag_form, comp_tag_code, val);
+ }
+ }
+
+#ifdef FAC_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "PREGOTO - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
+#endif
+ if(byte_len < length)
+ goto again;
+#ifdef FAC_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "RETURN - comp_length = %d, byte_len = %d, length =%d\n", comp_length, byte_len, length);
+#endif
+ return(byte_len);
+}
+
+/*---------------------------------------------------------------------------*
+ * print universal id type
+ *---------------------------------------------------------------------------*/
+static char *uni_str(int code)
+{
+ static char *tbl[] = {
+ "BOOLEAN",
+ "INTEGER",
+ "BIT STRING",
+ "OCTET STRING",
+ "NULL",
+ "OBJECT IDENTIFIER",
+ "OBJECT DESCRIPTOR",
+ "EXTERNAL",
+ "REAL",
+ "ENUMERATED",
+ "RESERVED11",
+ "RESERVED12",
+ "RESERVED13",
+ "RESERVED14",
+ "RESERVED15",
+ "SEQUENCE",
+ "SET",
+ "NUMERIC STRING",
+ "PRINTABLE STRING",
+ "TELETEX STRING",
+ "ISO646 STRING",
+ "IA5 STRING",
+ "GRAPHIC STRING",
+ "GENERAL STRING"
+ };
+
+ if(code >= 1 && code <= FAC_CODEUNI_GNSTR)
+ return(tbl[code-1]);
+ else
+ return("ERROR, Value out of Range!");
+}
+
+/*---------------------------------------------------------------------------*
+ * print operation value
+ *---------------------------------------------------------------------------*/
+static char *opval_str(int val)
+{
+ static char buffer[80];
+ char *r;
+
+ switch(val)
+ {
+ case FAC_OPVAL_UUS:
+ r = "uUs";
+ break;
+ case FAC_OPVAL_CUG:
+ r = "cUGCall";
+ break;
+ case FAC_OPVAL_MCID:
+ r = "mCIDRequest";
+ break;
+ case FAC_OPVAL_BTPY:
+ r = "beginTPY";
+ break;
+ case FAC_OPVAL_ETPY:
+ r = "endTPY";
+ break;
+ case FAC_OPVAL_ECT:
+ r = "eCTRequest";
+ break;
+ case FAC_OPVAL_DIV_ACT:
+ r = "activationDiversion";
+ break;
+ case FAC_OPVAL_DIV_DEACT:
+ r = "deactivationDiversion";
+ break;
+ case FAC_OPVAL_DIV_ACTSN:
+ r = "activationStatusNotificationDiv";
+ break;
+ case FAC_OPVAL_DIV_DEACTSN:
+ r = "deactivationStatusNotificationDiv";
+ break;
+ case FAC_OPVAL_DIV_INTER:
+ r = "interrogationDiversion";
+ break;
+ case FAC_OPVAL_DIV_INFO:
+ r = "diversionInformation";
+ break;
+ case FAC_OPVAL_DIV_CALLDEF:
+ r = "callDeflection";
+ break;
+ case FAC_OPVAL_DIV_CALLRER:
+ r = "callRerouting";
+ break;
+ case FAC_OPVAL_DIV_LINF2:
+ r = "divertingLegInformation2";
+ break;
+ case FAC_OPVAL_DIV_INVS:
+ r = "invokeStatus";
+ break;
+ case FAC_OPVAL_DIV_INTER1:
+ r = "interrogationDiversion1";
+ break;
+ case FAC_OPVAL_DIV_LINF1:
+ r = "divertingLegInformation1";
+ break;
+ case FAC_OPVAL_DIV_LINF3:
+ r = "divertingLegInformation3";
+ break;
+ case FAC_OPVAL_ER_CRCO:
+ r = "explicitReservationCreationControl";
+ break;
+ case FAC_OPVAL_ER_MGMT:
+ r = "explicitReservationManagement";
+ break;
+ case FAC_OPVAL_ER_CANC:
+ r = "explicitReservationCancel";
+ break;
+ case FAC_OPVAL_MLPP_QUERY:
+ r = "mLPP lfb Query";
+ break;
+ case FAC_OPVAL_MLPP_CALLR:
+ r = "mLPP Call Request";
+ break;
+ case FAC_OPVAL_MLPP_CALLP:
+ r = "mLPP Call Preemption";
+ break;
+ case FAC_OPVAL_AOC_REQ:
+ r = "chargingRequest";
+ break;
+ case FAC_OPVAL_AOC_S_CUR:
+ r = "aOCSCurrency";
+ break;
+ case FAC_OPVAL_AOC_S_SPC:
+ r = "aOCSSpecialArrangement";
+ break;
+ case FAC_OPVAL_AOC_D_CUR:
+ r = "aOCDCurrency";
+ break;
+ case FAC_OPVAL_AOC_D_UNIT:
+ r = "aOCDChargingUnit";
+ break;
+ case FAC_OPVAL_AOC_E_CUR:
+ r = "aOCECurrency";
+ break;
+ case FAC_OPVAL_AOC_E_UNIT:
+ r = "aOCEChargingUnit";
+ break;
+ case FAC_OPVAL_AOC_IDOFCRG:
+ r = "identificationOfCharge";
+ break;
+ case FAC_OPVAL_CONF_BEG:
+ r = "beginConf";
+ break;
+ case FAC_OPVAL_CONF_ADD:
+ r = "addConf";
+ break;
+ case FAC_OPVAL_CONF_SPLIT:
+ r = "splitConf";
+ break;
+ case FAC_OPVAL_CONF_DROP:
+ r = "dropConf";
+ break;
+ case FAC_OPVAL_CONF_ISOLATE:
+ r = "isolateConf";
+ break;
+ case FAC_OPVAL_CONF_REATT:
+ r = "reattachConf";
+ break;
+ case FAC_OPVAL_CONF_PDISC:
+ r = "partyDISC";
+ break;
+ case FAC_OPVAL_CONF_FCONF:
+ r = "floatConf";
+ break;
+ case FAC_OPVAL_CONF_END:
+ r = "endConf";
+ break;
+ case FAC_OPVAL_CONF_IDCFE:
+ r = "indentifyConferee";
+ break;
+ case FAC_OPVAL_REVC_REQ:
+ r = "requestREV";
+ break;
+ default:
+ sprintf(buffer, "unknown operation value %d!", val);
+ r = buffer;
+ }
+ return(r);
+}
+
+/*---------------------------------------------------------------------------*
+ * billing id string
+ *---------------------------------------------------------------------------*/
+static char *bid_str(int val)
+{
+ static char buffer[80];
+ char *r;
+
+ switch(val)
+ {
+ case 0:
+ r = "normalCharging";
+ break;
+ case 1:
+ r = "reverseCharging";
+ break;
+ case 2:
+ r = "creditCardCharging";
+ break;
+ case 3:
+ r = "callForwardingUnconditional";
+ break;
+ case 4:
+ r = "callForwardingBusy";
+ break;
+ case 5:
+ r = "callForwardingNoReply";
+ break;
+ case 6:
+ r = "callDeflection";
+ break;
+ case 7:
+ r = "callTransfer";
+ break;
+ default:
+ sprintf(buffer, "unknown billing-id value %d!", val);
+ r = buffer;
+ }
+ return(r);
+}
+
+/*---------------------------------------------------------------------------*
+ * invoke component
+ *---------------------------------------------------------------------------*/
+static void
+F_1_1(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_1, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t invokeComponent\n");
+ state = ST_EXP_INV_ID;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * return result
+ *---------------------------------------------------------------------------*/
+static void
+F_1_2(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_2, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t returnResult\n");
+ state = ST_EXP_RR_INV_ID;
+ }
+}
+/*---------------------------------------------------------------------------*
+ * return error
+ *---------------------------------------------------------------------------*/
+static void
+F_1_3(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_3, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t returnError\n");
+ state = ST_EXP_NIX;
+ }
+}
+/*---------------------------------------------------------------------------*
+ * reject
+ *---------------------------------------------------------------------------*/
+static void
+F_1_4(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_1_4, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t reject\n");
+ state = ST_EXP_NIX;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * invoke component: invoke id
+ *---------------------------------------------------------------------------*/
+static void
+F_2(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_2, val = %d\n", val);
+#endif
+ if(val != -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t InvokeIdentifier = %d\n", val);
+ state = ST_EXP_OP_VAL;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * return result: invoke id
+ *---------------------------------------------------------------------------*/
+static void
+F_RR2(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RR2, val = %d\n", val);
+#endif
+ if(val != -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t InvokeIdentifier = %d\n", val);
+ state = ST_EXP_RR_OP_VAL;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * invoke component: operation value
+ *---------------------------------------------------------------------------*/
+static void
+F_3(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_3, val = %d\n", val);
+#endif
+ if(val != -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t Operation Value = %s (%d)\n", opval_str(val), val);
+ state = ST_EXP_INFO;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * return result: operation value
+ *---------------------------------------------------------------------------*/
+static void
+F_RR3(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RR3, val = %d\n", val);
+#endif
+ if(val != -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t Operation Value = %s (%d)\n", opval_str(val), val);
+ state = ST_EXP_RR_RESULT;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * return result: RESULT
+ *---------------------------------------------------------------------------*/
+static void
+F_RRR(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_RRR, val = %d\n", val);
+#endif
+ state = ST_EXP_NIX;
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+static void
+F_4(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t specificChargingUnits\n");
+ state = ST_EXP_RUL;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+static void
+F_4_1(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4_1, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t freeOfCharge\n");
+ state = ST_EXP_NIX;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+static void
+F_4_2(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_4_2, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t chargeNotAvailable\n");
+ state = ST_EXP_NIX;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+static void
+F_5(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_5, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t recordedUnitsList [1]\n");
+ state = ST_EXP_RU;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+static void
+F_6(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_6, val = %d\n", val);
+#endif
+ if(val == -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t RecordedUnits\n");
+ state = ST_EXP_RNOU;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+static void
+F_7(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_7, val = %d\n", val);
+#endif
+ if(val != -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t NumberOfUnits = %d\n", val);
+ state = ST_EXP_TOCI;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+static void
+F_8(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_8, val = %d\n", val);
+#endif
+ if(val != -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t typeOfChargingInfo = %s\n", val == 0 ? "subTotal" : "total");
+ state = ST_EXP_DBID;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+static void
+F_9(char *pbuf, int val)
+{
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: exec F_9, val = %d\n", val);
+#endif
+ if(val != -1)
+ {
+ sprintf((pbuf+strlen(pbuf)), "\t AOCDBillingId = %s (%d)\n", bid_str(val), val);
+ state = ST_EXP_NIX;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * state table
+ *---------------------------------------------------------------------------*/
+static struct statetab {
+ int currstate; /* input: current state we are in */
+ int form; /* input: current tag form */
+ int class; /* input: current tag class */
+ int code; /* input: current tag code */
+ void (*func)(char *,int); /* output: func to exec */
+} statetab[] = {
+
+/* current state tag form tag class tag code function */
+/* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
+
+/* invoke */
+
+ {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_1_1 },
+ {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 2, F_1_2 },
+ {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 3, F_1_3 },
+ {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 4, F_1_4 },
+ {ST_EXP_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_2 },
+ {ST_EXP_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_3 },
+ {ST_EXP_INFO, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_4 },
+ {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_NULL, F_4_1 },
+ {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 1, F_4_2 },
+ {ST_EXP_RUL, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_5 },
+ {ST_EXP_RU, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_6 },
+ {ST_EXP_RNOU, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_7 },
+ {ST_EXP_TOCI, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 2, F_8 },
+ {ST_EXP_DBID, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 3, F_9 },
+
+/* return result */
+
+ {ST_EXP_RR_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_RR2 },
+ {ST_EXP_RR_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_RR3 },
+ {ST_EXP_RR_RESULT, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SET, F_RRR },
+
+/* end */
+
+ {-1, -1, -1, -1, NULL }
+};
+
+/*---------------------------------------------------------------------------*
+ * state decode for do_component
+ *---------------------------------------------------------------------------*/
+static void
+next_state(char *pbuf, int class, int form, int code, int val)
+{
+ int i;
+
+#ifdef ST_DEBUG
+ sprintf((pbuf+strlen(pbuf)), "next_state: class=%d, form=%d, code=%d, val=%d\n", class, form, code, val);
+#endif
+
+ for(i=0; ; i++)
+ {
+ if((statetab[i].currstate > state) ||
+ (statetab[i].currstate == -1))
+ {
+ break;
+ }
+
+ if((statetab[i].currstate == state) &&
+ (statetab[i].form == form) &&
+ (statetab[i].class == class) &&
+ (statetab[i].code == code))
+ {
+ (*statetab[i].func)(pbuf, val);
+ break;
+ }
+ }
+}
+
+/* EOF */
+
diff --git a/usr.sbin/i4b/isdntrace/q932_fac.h b/usr.sbin/i4b/isdntrace/q932_fac.h
new file mode 100644
index 0000000..feae448
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/q932_fac.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 1997, 1998 Hellmuth Michaelis. 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.
+ *
+ * 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * q932_fac.h - facility header file
+ * ---------------------------------
+ *
+ * $Id: q932_fac.h,v 1.4 1998/12/05 18:04:24 hm Exp $
+ *
+ * last edit-date: [Sat Dec 5 18:21:17 1998]
+ *
+ *---------------------------------------------------------------------------
+ *
+ * - Q.932 (03/93) Generic Procedures for the Control of
+ * ISDN Supplementaty Services
+ * - Q.950 (03/93) Supplementary Services Protocols, Structure and
+ * General Principles
+ * - ETS 300 179 (10/92) Advice Of Charge: charging information during
+ * the call (AOC-D) supplementary service Service description
+ * - ETS 300 180 (10/92) Advice Of Charge: charging information at the
+ * end of call (AOC-E) supplementary service Service description
+ * - ETS 300 181 (04/93) Advice Of Charge (AOC) supplementary service
+ * Functional capabilities and information flows
+ * - ETS 300 182 (04/93) Advice Of Charge (AOC) supplementary service
+ * Digital Subscriber Signalling System No. one (DSS1) protocol
+ * - X.208 Specification of Abstract Syntax Notation One (ASN.1)
+ * - X.209 Specification of Basic Encoding Rules for
+ * Abstract Syntax Notation One (ASN.1)
+ * - "ASN.1 Abstract Syntax Notation One", Walter Gora, DATACOM-Verlag
+ * 1992, 3rd Edition (ISBN 3-89238-062-7) (german !)
+ *
+ *---------------------------------------------------------------------------*/
+
+/* #define FAC_DEBUG */
+/* #define ST_DEBUG */
+
+/* protocols */
+#define FAC_PROTO_ROP 0x11
+#define FAC_PROTO_CMIP 0x12
+#define FAC_PROTO_ACSE 0x13
+
+/* tag classes */
+#define FAC_TAGCLASS_UNI 0x00
+#define FAC_TAGCLASS_APW 0x01
+#define FAC_TAGCLASS_COS 0x02
+#define FAC_TAGCLASS_PRU 0x03
+
+/* tag forms */
+#define FAC_TAGFORM_PRI 0x00
+#define FAC_TAGFORM_CON 0x01
+
+/* class UNIVERSAL values */
+#define FAC_CODEUNI_BOOL 1
+#define FAC_CODEUNI_INT 2
+#define FAC_CODEUNI_BITS 3
+#define FAC_CODEUNI_OCTS 4
+#define FAC_CODEUNI_NULL 5
+#define FAC_CODEUNI_OBJI 6
+#define FAC_CODEUNI_OBJD 7
+#define FAC_CODEUNI_EXT 8
+#define FAC_CODEUNI_REAL 9
+#define FAC_CODEUNI_ENUM 10
+#define FAC_CODEUNI_R11 11
+#define FAC_CODEUNI_R12 12
+#define FAC_CODEUNI_R13 13
+#define FAC_CODEUNI_R14 14
+#define FAC_CODEUNI_R15 15
+#define FAC_CODEUNI_SEQ 16
+#define FAC_CODEUNI_SET 17
+#define FAC_CODEUNI_NSTR 18
+#define FAC_CODEUNI_PSTR 19
+#define FAC_CODEUNI_TSTR 20
+#define FAC_CODEUNI_VSTR 21
+#define FAC_CODEUNI_ISTR 22
+#define FAC_CODEUNI_UTIME 23
+#define FAC_CODEUNI_GTIME 24
+#define FAC_CODEUNI_GSTR 25
+#define FAC_CODEUNI_VISTR 26
+#define FAC_CODEUNI_GNSTR 27
+
+/* operation values */
+#define FAC_OPVAL_UUS 1
+#define FAC_OPVAL_CUG 2
+#define FAC_OPVAL_MCID 3
+#define FAC_OPVAL_BTPY 4
+#define FAC_OPVAL_ETPY 5
+#define FAC_OPVAL_ECT 6
+
+#define FAC_OPVAL_DIV_ACT 7
+#define FAC_OPVAL_DIV_DEACT 8
+#define FAC_OPVAL_DIV_ACTSN 9
+#define FAC_OPVAL_DIV_DEACTSN 10
+#define FAC_OPVAL_DIV_INTER 11
+#define FAC_OPVAL_DIV_INFO 12
+#define FAC_OPVAL_DIV_CALLDEF 13
+#define FAC_OPVAL_DIV_CALLRER 14
+#define FAC_OPVAL_DIV_LINF2 15
+#define FAC_OPVAL_DIV_INVS 16
+#define FAC_OPVAL_DIV_INTER1 17
+#define FAC_OPVAL_DIV_LINF1 18
+#define FAC_OPVAL_DIV_LINF3 19
+
+#define FAC_OPVAL_ER_CRCO 20
+#define FAC_OPVAL_ER_MGMT 21
+#define FAC_OPVAL_ER_CANC 22
+
+#define FAC_OPVAL_MLPP_QUERY 24
+#define FAC_OPVAL_MLPP_CALLR 25
+#define FAC_OPVAL_MLPP_CALLP 26
+
+#define FAC_OPVAL_AOC_REQ 30
+#define FAC_OPVAL_AOC_S_CUR 31
+#define FAC_OPVAL_AOC_S_SPC 32
+#define FAC_OPVAL_AOC_D_CUR 33
+#define FAC_OPVAL_AOC_D_UNIT 34
+#define FAC_OPVAL_AOC_E_CUR 35
+#define FAC_OPVAL_AOC_E_UNIT 36
+#define FAC_OPVAL_AOC_IDOFCRG 37
+
+#define FAC_OPVAL_CONF_BEG 40
+#define FAC_OPVAL_CONF_ADD 41
+#define FAC_OPVAL_CONF_SPLIT 42
+#define FAC_OPVAL_CONF_DROP 43
+#define FAC_OPVAL_CONF_ISOLATE 44
+#define FAC_OPVAL_CONF_REATT 45
+#define FAC_OPVAL_CONF_PDISC 46
+#define FAC_OPVAL_CONF_FCONF 47
+#define FAC_OPVAL_CONF_END 48
+#define FAC_OPVAL_CONF_IDCFE 49
+
+#define FAC_OPVAL_REVC_REQ 60
+
+enum states {
+ ST_EXP_COMP_TYP,
+ ST_EXP_INV_ID,
+ ST_EXP_OP_VAL,
+ ST_EXP_INFO,
+ ST_EXP_RUL,
+ ST_EXP_RU,
+ ST_EXP_RNOU,
+ ST_EXP_TOCI,
+ ST_EXP_DBID,
+
+ ST_EXP_RR_INV_ID,
+ ST_EXP_RR_OP_VAL,
+ ST_EXP_RR_RESULT,
+
+ ST_EXP_NIX
+};
+
+/* EOF */
+
diff --git a/usr.sbin/i4b/isdntrace/trace.c b/usr.sbin/i4b/isdntrace/trace.c
new file mode 100644
index 0000000..a9dde80
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/trace.c
@@ -0,0 +1,809 @@
+/*
+ * Copyright (c) 1996, 1998 Hellmuth Michaelis. All rights reserved.
+ *
+ * Copyright (c) 1996 Gary Jennejohn. 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.
+ *
+ *---------------------------------------------------------------------------*
+ *
+ * trace.c - print traces of D (B) channel activity for isdn4bsd
+ * -------------------------------------------------------------
+ *
+ * $Id: trace.c,v 1.10 1998/10/19 12:32:21 hm Exp $
+ *
+ * last edit-date: [Mon Oct 19 14:30:58 1998]
+ *
+ * -hm rewriting for isic and new trace format
+ * -hm new option -f, use automatic name for -o
+ * -hm changed default option setting
+ * -hm multi unit support
+ * -hm analyzer functionality
+ * -hm binary record/playback
+ * -hm -p option
+ * -hm cleanup
+ * -hm adding date to timestamp field
+ * -hm reopen files on SIGUSR1 for rotation
+ * -hm Joerg reported a bug with commandline options
+ * -hm I.430 INFO signals from layer 1
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "trace.h"
+
+unsigned char buf[BSIZE];
+FILE *Fout = NULL;
+FILE *BP = NULL;
+int outflag = 1;
+int header = 1;
+int print_q921 = 1;
+int unit = 0;
+int dchan = 0;
+int bchan = 0;
+int traceon = 0;
+int analyze = 0;
+int Rx = RxUDEF;
+int Tx = TxUDEF;
+int f;
+int Bopt = 0;
+int Popt = 0;
+int bpopt = 0;
+int info = 0;
+int Fopt = 0;
+
+static char outfilename[1024];
+static char BPfilename[1024];
+static struct stat fst;
+
+static void dumpbuf( int n, unsigned char *buf, i4b_trace_hdr_t *hdr, int raw );
+static int switch_driver( int value, int rx, int tx );
+static void usage( void );
+static void exit_hdl( void );
+static void reopenfiles( int );
+
+/*---------------------------------------------------------------------------*
+ * usage instructions
+ *---------------------------------------------------------------------------*/
+void
+usage(void)
+{
+ fprintf(stderr,"\n");
+ fprintf(stderr,"isdntrace - i4b package ISDN trace facility for passive cards (%02d.%02d.%d)\n", VERSION, REL, STEP);
+ fprintf(stderr,"usage: isdntrace -a -b -d -f <file> -h -i -l -n <val> -o -p <file> -r -u <unit>\n");
+ fprintf(stderr," -B -F -P -R <unit> -T <unit>\n");
+ fprintf(stderr," -a analyzer mode ................................... (default off)\n");
+ fprintf(stderr," -b switch B channel trace on ....................... (default off)\n");
+ fprintf(stderr," -d switch D channel trace off ....................... (default on)\n");
+ fprintf(stderr," -f <file> write output to file filename ............ (default %s0)\n", TRACE_FILE_NAME);
+ fprintf(stderr," -h don't print header for each message ............. (default off)\n");
+ fprintf(stderr," -i print I.430 (layer 1) INFO signals .............. (default off)\n");
+ fprintf(stderr," -l don't decode low layer Q.921 messages ........... (default off)\n");
+ fprintf(stderr," -n <val> process packet if it is longer than <val> octetts . (default 0)\n");
+ fprintf(stderr," -o don't write output to a file .................... (default off)\n");
+ fprintf(stderr," -p <file> specify filename for -B and -P ........ (default %s0)\n", BIN_FILE_NAME);
+ fprintf(stderr," -r don't print raw hex/ASCII dump of protocol ...... (default off)\n");
+ fprintf(stderr," -u <unit> specify controller unit number ............... (default unit 0)\n");
+ fprintf(stderr," -B write binary trace data to file filename ........ (default off)\n");
+ fprintf(stderr," -F with -P and -p: wait for more data at EOF ....... (default off)\n");
+ fprintf(stderr," -P playback from binary trace data file ............ (default off)\n");
+ fprintf(stderr," -R <unit> analyze Rx controller unit number (for -a) ... (default unit %d)\n", RxUDEF);
+ fprintf(stderr," -T <unit> analyze Tx controller unit number (for -a) ... (default unit %d)\n", TxUDEF);
+ fprintf(stderr,"\n");
+ exit(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * main
+ *---------------------------------------------------------------------------*/
+int
+main(int argc, char *argv[])
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+ char devicename[80];
+ char headerbuf[256];
+
+ int n;
+ int c;
+ char *b;
+
+ int enable_trace = TRACE_D_RX | TRACE_D_TX;
+ char *outfile = TRACE_FILE_NAME;
+ char *binfile = BIN_FILE_NAME;
+ int outfileset = 0;
+ int raw = 1;
+ int noct = -1;
+ time_t tm;
+ i4b_trace_hdr_t *ithp = NULL;
+ int l;
+ static struct stat fstnew;
+
+ b = &buf[sizeof(i4b_trace_hdr_t)];
+
+ while( (c = getopt(argc, argv, "abdf:hiln:op:ru:BFPR:T:?")) != EOF)
+ {
+ switch(c)
+ {
+ case 'a':
+ analyze = 1;
+ break;
+
+ case 'b':
+ enable_trace |= (TRACE_B_RX | TRACE_B_TX);
+ break;
+
+ case 'd':
+ enable_trace &= (~(TRACE_D_TX | TRACE_D_RX));
+ break;
+
+ case 'o':
+ outflag = 0;
+ break;
+
+ case 'f':
+ outfile = optarg;
+ outfileset = 1;
+ break;
+
+ case 'n':
+ noct = atoi(optarg);
+ break;
+
+ case 'h':
+ header = 0;
+ break;
+
+ case 'i':
+ enable_trace |= TRACE_I;
+ info = 1;
+ break;
+
+ case 'l':
+ print_q921 = 0;
+ break;
+
+ case 'p':
+ binfile = optarg;
+ bpopt = 1;
+ break;
+
+ case 'r':
+ raw = 0;
+ break;
+
+ case 'u':
+ unit = atoi(optarg);
+ if(unit < 0 || unit >= MAX_CONTROLLERS)
+ usage();
+ break;
+
+ case 'B':
+ Bopt = 1;
+ break;
+
+ case 'F':
+ Fopt = 1;
+ break;
+
+ case 'P':
+ Popt = 1;
+ break;
+
+ case 'R':
+ Rx = atoi(optarg);
+ if(Rx < 0 || Rx >= MAX_CONTROLLERS)
+ usage();
+ break;
+
+ case 'T':
+ Tx = atoi(optarg);
+ if(Tx < 0 || Tx >= MAX_CONTROLLERS)
+ usage();
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if(enable_trace == 0)
+ usage();
+
+ if(Bopt && Popt)
+ usage();
+
+ atexit(exit_hdl);
+
+ if(Bopt)
+ {
+ if(bpopt)
+ sprintf(BPfilename, "%s", binfile);
+ else
+ sprintf(BPfilename, "%s%d", BIN_FILE_NAME, unit);
+
+ if((BP = fopen(BPfilename, "r")) != NULL)
+ {
+ char buffer[1024];
+ fclose(BP);
+ sprintf(buffer, "%s%s", BPfilename, TRACE_FILE_NAME_BAK);
+ rename(BPfilename, buffer);
+ }
+ if((BP = fopen(BPfilename, "w")) == NULL)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error opening file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+
+ if((setvbuf(BP, (char *)NULL, _IONBF, 0)) != 0)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error setting file [%s] to unbuffered", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+ }
+
+ if(Popt)
+ {
+ if(bpopt)
+ sprintf(BPfilename, "%s", binfile);
+ else
+ sprintf(BPfilename, "%s%d", BIN_FILE_NAME, unit);
+
+ if((BP = fopen(BPfilename, "r")) == NULL)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error opening file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+ if(Fopt)
+ {
+ if(fstat(fileno(BP), &fst))
+ {
+ char buffer[80];
+ sprintf(buffer, "Error fstat file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+ }
+ }
+ else
+ {
+ sprintf(devicename, "%s%d", I4BTRC_DEVICE, unit);
+
+ if((f = open(devicename, O_RDWR)) < 0)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error opening trace device [%s]", devicename);
+ perror(buffer);
+ exit(1);
+ }
+ }
+
+ if(outflag)
+ {
+ if(outfileset == 0)
+ sprintf(outfilename, "%s%d", TRACE_FILE_NAME, unit);
+ else
+ strcpy(outfilename, outfile);
+
+
+ if((Fout = fopen(outfilename, "r")) != NULL)
+ {
+ char buffer[1024];
+ fclose(Fout);
+ sprintf(buffer, "%s%s", outfilename, TRACE_FILE_NAME_BAK);
+ rename(outfilename, buffer);
+ }
+
+ if((Fout = fopen(outfilename, "w")) == NULL)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error opening file [%s]", outfilename);
+ perror(buffer);
+ exit(1);
+ }
+
+ if((setvbuf(Fout, (char *)NULL, _IONBF, 0)) != 0)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error setting file [%s] to unbuffered", outfile);
+ perror(buffer);
+ exit(1);
+ }
+ }
+
+ if((setvbuf(stdout, (char *)NULL, _IOLBF, 0)) != 0)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error setting stdout to line-buffered");
+ perror(buffer);
+ exit(1);
+ }
+
+ if(!Popt)
+ {
+ if((switch_driver(enable_trace, Rx, Tx)) == -1)
+ exit(1);
+ else
+ traceon = 1;
+ }
+
+ signal(SIGHUP, SIG_IGN); /* ignore hangup signal */
+ signal(SIGUSR1, reopenfiles); /* rotate logfile(s) */
+
+ time(&tm);
+
+ if(analyze)
+ {
+ sprintf(headerbuf, "\n==== isdnanalyze controller rx #%d - tx #%d ==== started %s",
+ Rx, Tx, ctime(&tm));
+ }
+ else
+ {
+ sprintf(headerbuf, "\n=========== isdntrace controller #%d =========== started %s",
+ unit, ctime(&tm));
+ }
+
+ printf("%s", headerbuf);
+
+ if(outflag)
+ fprintf(Fout, "%s", headerbuf);
+
+ for (;;)
+ {
+ if(Popt == 0)
+ {
+ n = read(f, buf, BSIZE);
+
+ if(Bopt)
+ {
+ if((fwrite(buf, 1, n, BP)) != n)
+ {
+ char buffer[80];
+ sprintf(buffer, "Error writing file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+ }
+
+ n -= sizeof(i4b_trace_hdr_t);
+ }
+ else
+ {
+again:
+ if((fread(buf, 1, sizeof(i4b_trace_hdr_t), BP)) != sizeof(i4b_trace_hdr_t))
+ {
+ if(feof(BP))
+ {
+ if(Fopt)
+ {
+ if(ferror(BP))
+ {
+ char buffer[80];
+ sprintf(buffer, "Error reading hdr from file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+
+ usleep(250000);
+ clearerr(BP);
+
+ if(stat(BPfilename, &fstnew) != -1)
+ {
+ if((fst.st_ino != fstnew.st_ino) ||
+ (fstnew.st_nlink == 0))
+ {
+ if((BP = freopen(BPfilename, "r", BP)) == NULL)
+ {
+ char buffer[80];
+ sprintf(buffer, "Error reopening file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+ stat(BPfilename, &fst);
+ }
+ }
+ goto again;
+ }
+ else
+ {
+ printf("\nEnd of playback input file reached.\n");
+ exit(0);
+ }
+ }
+ else
+ {
+ char buffer[80];
+ sprintf(buffer, "Error reading hdr from file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+ }
+
+ ithp = (i4b_trace_hdr_t *)buf;
+ l = ithp->length - sizeof(i4b_trace_hdr_t);
+
+ if((n = fread(buf+sizeof(i4b_trace_hdr_t), 1, l , BP)) != l)
+ {
+ char buffer[80];
+ sprintf(buffer, "Error reading data from file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+
+ }
+
+ if((n > 0) && (n > noct))
+ {
+ dumpbuf(n, b, (i4b_trace_hdr_t *)buf, raw);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * format header into static buffer, return buffer address
+ *---------------------------------------------------------------------------*/
+char *
+fmt_hdr(i4b_trace_hdr_t *hdr, int frm_len)
+{
+ struct tm *s;
+ static char hbuf[256];
+ int i = 0;
+
+ s = localtime(&(hdr->time.tv_sec));
+
+ if(hdr->type == TRC_CH_I) /* Layer 1 INFO's */
+ {
+ sprintf(hbuf,"\n-- %s - unit:%d ---------------- time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%6u ",
+ ((hdr->dir) ? "NT->TE" : "TE->NT"),
+ hdr->unit,
+ s->tm_mday,
+ s->tm_mon + 1,
+ s->tm_hour,
+ s->tm_min,
+ s->tm_sec,
+ (u_int32_t)hdr->time.tv_usec);
+ }
+ else
+ {
+ if(hdr->trunc > 0)
+ {
+ sprintf(hbuf,"\n-- %s - unit:%d - frame:%6.6u - time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%6u - length:%d (%d) ",
+ ((hdr->dir) ? "NT->TE" : "TE->NT"),
+ hdr->unit,
+ hdr->count,
+ s->tm_mday,
+ s->tm_mon + 1,
+ s->tm_hour,
+ s->tm_min,
+ s->tm_sec,
+ (u_int32_t)hdr->time.tv_usec,
+ frm_len,
+ hdr->trunc);
+ }
+ else
+ {
+ sprintf(hbuf,"\n-- %s - unit:%d - frame:%6.6u - time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%6u - length:%d ",
+ ((hdr->dir) ? "NT->TE" : "TE->NT"),
+ hdr->unit,
+ hdr->count,
+ s->tm_mday,
+ s->tm_mon + 1,
+ s->tm_hour,
+ s->tm_min,
+ s->tm_sec,
+ (u_int32_t)hdr->time.tv_usec,
+ frm_len);
+ }
+ }
+
+ for(i=strlen(hbuf); i <= NCOLS;)
+ hbuf[i++] = '-';
+
+ hbuf[i++] = '\n';
+ hbuf[i] = '\0';
+
+ return(hbuf);
+}
+
+/*---------------------------------------------------------------------------*
+ * decode protocol and output to file(s)
+ *---------------------------------------------------------------------------*/
+static void
+dumpbuf(int n, unsigned char *buf, i4b_trace_hdr_t *hdr, int raw)
+{
+ static char l1buf[128];
+ static unsigned char l2buf[32000];
+ static unsigned char l3buf[32000];
+ int cnt;
+ int nsave = n;
+ char *pbuf;
+ int i, j;
+
+ l1buf[0] = '\0';
+ l2buf[0] = '\0';
+ l3buf[0] = '\0';
+
+ switch(hdr->type)
+ {
+ case TRC_CH_I: /* Layer 1 INFO's */
+ pbuf = &l1buf[0];
+
+ switch(buf[0])
+ {
+ case INFO0:
+ sprintf((pbuf+strlen(pbuf)),"I430: INFO0 (No Signal)\n");
+ break;
+
+ case INFO1_8:
+ sprintf((pbuf+strlen(pbuf)),"I430: INFO1 (Activation Request, Priority = 8, from TE)\n");
+ break;
+
+ case INFO1_10:
+ sprintf((pbuf+strlen(pbuf)),"I430: INFO1 (Activation Request, Priority = 10, from TE)\n");
+ break;
+
+ case INFO2:
+ sprintf((pbuf+strlen(pbuf)),"I430: INFO2 (Pending Activation, from NT)\n");
+ break;
+
+ case INFO3:
+ sprintf((pbuf+strlen(pbuf)),"I430: INFO3 (Synchronized, from TE)\n");
+ break;
+
+ case INFO4_8:
+ sprintf((pbuf+strlen(pbuf)),"I430: INFO4 (Activated, Priority = 8/9, from NT)\n");
+ break;
+
+ case INFO4_10:
+ sprintf((pbuf+strlen(pbuf)),"I430: INFO4 (Activated, Priority = 10/11, from NT)\n");
+ break;
+
+ default:
+ sprintf((pbuf+strlen(pbuf)),"I430: ERROR, invalid INFO value 0x%x!\n", buf[0]);
+ break;
+ }
+ break;
+
+ case TRC_CH_D: /* D-channel data */
+
+ cnt = decode_lapd(l2buf, n, buf, hdr->dir, raw, print_q921);
+
+ n -= cnt;
+ buf += cnt;
+
+ if(n)
+ {
+ switch(*buf)
+ {
+ case 0x40:
+ case 0x41:
+ decode_1tr6(l3buf, n, cnt, buf, raw);
+ break;
+
+ default:
+ decode_q931(l3buf, n, cnt, buf, raw);
+ break;
+ }
+ }
+ break;
+
+ default: /* B-channel data */
+
+ pbuf = &l2buf[0];
+
+ for (i = 0; i < n; i += 16)
+ {
+ sprintf((pbuf+strlen(pbuf)),"B%d:%.3x ", hdr->type, i);
+
+ for (j = 0; j < 16; j++)
+ if (i + j < n)
+ sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
+ else
+ sprintf((pbuf+strlen(pbuf))," ");
+
+ sprintf((pbuf+strlen(pbuf))," ");
+
+ for (j = 0; j < 16 && i + j < n; j++)
+ if (isprint(buf[i + j]))
+ sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
+ else
+ sprintf((pbuf+strlen(pbuf)),".");
+
+ sprintf((pbuf+strlen(pbuf)),"\n");
+ }
+ break;
+ }
+
+ if(header && ((l1buf[0] != '\0' || l2buf[0] != '\0') || (l3buf[0] != 0)))
+ {
+ char *p;
+ p = fmt_hdr(hdr, nsave);
+ printf("%s", p);
+ if(outflag)
+ fprintf(Fout, "%s", p);
+ }
+
+ if(l1buf[0] != '\0')
+ {
+ printf("%s", l1buf);
+ if(outflag)
+ fprintf(Fout, "%s", l1buf);
+ }
+
+ if(l2buf[0] != '\0')
+ {
+ printf("%s", l2buf);
+ if(outflag)
+ fprintf(Fout, "%s", l2buf);
+ }
+
+ if(l3buf[0] != '\0')
+ {
+ printf("%s", l3buf);
+ if(outflag)
+ fprintf(Fout, "%s", l3buf);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * exit handler function to be called at program exit
+ *---------------------------------------------------------------------------*/
+void
+exit_hdl()
+{
+ if(traceon)
+ switch_driver(TRACE_OFF, Rx, Tx);
+}
+
+/*---------------------------------------------------------------------------*
+ * switch driver debugging output on/off
+ *---------------------------------------------------------------------------*/
+static int
+switch_driver(int value, int rx, int tx)
+{
+ char buffer[80];
+ int v = value;
+
+ if(analyze == 0)
+ {
+ if(ioctl(f, I4B_TRC_SET, &v) < 0)
+ {
+ sprintf(buffer, "Error ioctl I4B_TRC_SET, val = %d", v);
+ perror(buffer);
+ return(-1);
+ }
+ }
+ else
+ {
+ if(value == TRACE_OFF)
+ {
+ if(ioctl(f, I4B_TRC_RESETA, &v) < 0)
+ {
+ sprintf(buffer, "Error ioctl I4B_TRC_RESETA - ");
+ perror(buffer);
+ return(-1);
+ }
+ }
+ else
+ {
+ i4b_trace_setupa_t tsa;
+
+ tsa.rxunit = rx;
+ tsa.rxflags = value;
+ tsa.txunit = tx;
+ tsa.txflags = value;
+
+ if(ioctl(f, I4B_TRC_SETA, &tsa) < 0)
+ {
+ sprintf(buffer, "Error ioctl I4B_TRC_SETA, val = %d", v);
+ perror(buffer);
+ return(-1);
+ }
+ }
+ }
+ return(0);
+}
+
+/*---------------------------------------------------------------------------*
+ * reopen files to support rotating logfile(s) on SIGUSR1
+ *
+ * based on an idea from Ripley (ripley@nostromo.in-berlin.de)
+ *
+ * close file and reopen it for append. this will be a nop
+ * if the previously opened file hasn't moved but will open
+ * a new one otherwise, thus enabling a rotation...
+ *
+ *---------------------------------------------------------------------------*/
+static void
+reopenfiles(int dummy)
+{
+ if(outflag)
+ {
+ fclose(Fout);
+
+ if((Fout = fopen(outfilename, "a")) == NULL)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error re-opening file [%s]", outfilename);
+ perror(buffer);
+ exit(1);
+ }
+
+ if((setvbuf(Fout, (char *)NULL, _IONBF, 0)) != 0)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error re-setting file [%s] to unbuffered", outfilename);
+ perror(buffer);
+ exit(1);
+ }
+ }
+
+ if(Bopt)
+ {
+
+ fclose(BP);
+
+ if((BP = fopen(BPfilename, "a")) == NULL)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error re-opening file [%s]", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+
+ if((setvbuf(BP, (char *)NULL, _IONBF, 0)) != 0)
+ {
+ char buffer[80];
+
+ sprintf(buffer, "Error re-setting file [%s] to unbuffered", BPfilename);
+ perror(buffer);
+ exit(1);
+ }
+ }
+}
+
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdntrace/trace.h b/usr.sbin/i4b/isdntrace/trace.h
new file mode 100644
index 0000000..e4c5b5a
--- /dev/null
+++ b/usr.sbin/i4b/isdntrace/trace.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1996, 1998 Hellmuth Michaelis. All rights reserved.
+ *
+ * Copyright (c) 1996 Gary Jennejohn. 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * trace.h - header file for isdn trace
+ * ------------------------------------
+ *
+ * $Id: trace.h,v 1.7 1998/10/19 12:32:23 hm Exp $
+ *
+ * last edit-date: [Mon Oct 19 14:27:21 1998]
+ *
+ * -hm splitting
+ * -hm new filenames
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <machine/i4b_ioctl.h>
+#include <machine/i4b_trace.h>
+
+#include "pcause_1tr6.h" /* obsolete german national ISDN */
+#include "pcause_q850.h"
+
+#define I4BTRC_DEVICE "/dev/i4btrc" /* trace device file */
+#define TRACE_FILE_NAME "isdntrace" /* default output filename */
+#define TRACE_FILE_NAME_BAK ".last" /* backup filename trailer */
+#define BIN_FILE_NAME "isdntracebin" /* default binary filename */
+
+#define BSIZE 4096 /* read buffer size */
+#define NCOLS 80 /* screen width */
+
+#define RxUDEF 0 /* analyze mode, default unit for receiver side */
+#define TxUDEF 1 /* analyze mode, default unit for transmitter side */
+
+int decode_lapd(char *pbuf, int n, unsigned char *buf, int is_te, int raw, int printit);
+void decode_q931(char *pbuf, int n, int off, unsigned char *buf, int raw);
+void decode_1tr6(char *pbuf, int n, int off, unsigned char *buf, int raw);
+char *print_error(int prot, unsigned char code);
+int q931_facility(char *pbuf, unsigned char *buf);
+int p_q931cause(char *pbuf, unsigned char *buf);
+int p_q931address(char *pbuf, unsigned char *buf);
+int p_q931bc(char *pbuf, unsigned char *buf);
+int p_q931high_compat(char *pbuf, unsigned char *buf);
+int q932_facility(char *pbuf, unsigned char *buf);
+
+/* EOF */
OpenPOWER on IntegriCloud