diff options
Diffstat (limited to 'usr.sbin/i4b/isdntrace')
-rw-r--r-- | usr.sbin/i4b/isdntrace/1tr6.c | 754 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/cable.txt | 60 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/isdntrace.8 | 205 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/pcause_1tr6.c | 164 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/pcause_1tr6.h | 68 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/pcause_q850.c | 328 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/pcause_q850.h | 109 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/q921.c | 275 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/q931.c | 783 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/q931_util.c | 697 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/q932_fac.c | 926 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/q932_fac.h | 174 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/trace.c | 809 | ||||
-rw-r--r-- | usr.sbin/i4b/isdntrace/trace.h | 90 |
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 */ |