diff options
author | phk <phk@FreeBSD.org> | 1998-12-27 21:47:14 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1998-12-27 21:47:14 +0000 |
commit | c7ecc129d72ba32b5d83c9a6019e93fd181d719c (patch) | |
tree | 8d5099bc7ef24151b4f6deb00d1d34a7e7ac694a /usr.sbin/i4b/isdndecode | |
parent | 3f431df8ec46b86090ad59ee153872c45d4d429d (diff) | |
download | FreeBSD-src-c7ecc129d72ba32b5d83c9a6019e93fd181d719c.zip FreeBSD-src-c7ecc129d72ba32b5d83c9a6019e93fd181d719c.tar.gz |
Initial entry of ISDN4BSD into the FreeBSD tree.
ISDN4BSD is the work of our brand-new comitter: Hellmuth Michaelis,
who has done a tremendous amount of work to bring us this far.
There are still some outstanding issues and files to bring into
the tree, and for now it will be needed to pick up all the extra
docs from the isdn4bsd release.
It is probably also a very good idea to subscribe to the isdn@freebsd.org
mailing list before you try this out.
These files correspond to release "beta Version 0.70.00 / December
1998" from Hellmuth.
Diffstat (limited to 'usr.sbin/i4b/isdndecode')
-rw-r--r-- | usr.sbin/i4b/isdndecode/Makefile | 7 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/decode.h | 74 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/facility.c | 906 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/facility.h | 154 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/isdndecode.8 | 190 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/layer1.c | 80 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/layer2.c | 298 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/layer3.c | 508 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/layer3_subr.c | 1045 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/main.c | 774 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/pcause.c | 328 | ||||
-rw-r--r-- | usr.sbin/i4b/isdndecode/pcause.h | 109 |
12 files changed, 4473 insertions, 0 deletions
diff --git a/usr.sbin/i4b/isdndecode/Makefile b/usr.sbin/i4b/isdndecode/Makefile new file mode 100644 index 0000000..cad91437 --- /dev/null +++ b/usr.sbin/i4b/isdndecode/Makefile @@ -0,0 +1,7 @@ +PROG = isdndecode +SRCS = main.c layer1.c layer2.c layer3.c \ + layer3_subr.c facility.c pcause.c +MAN8 = isdndecode.8 + +.include <bsd.prog.mk> + diff --git a/usr.sbin/i4b/isdndecode/decode.h b/usr.sbin/i4b/isdndecode/decode.h new file mode 100644 index 0000000..0eec0ab --- /dev/null +++ b/usr.sbin/i4b/isdndecode/decode.h @@ -0,0 +1,74 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * decode.h - isdndecode header file + * --------------------------------- + * + * $Id: decode.h,v 1.4 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:10:13 1998] + * + *---------------------------------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.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 <machine/i4b_ioctl.h> +#include <machine/i4b_trace.h> + +#include "pcause.h" + +#define I4BTRC_DEVICE "/dev/i4btrc" /* trace device file */ +#define DECODE_FILE_NAME "isdndecode" /* default output filename */ +#define DECODE_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 */ + +void layer1(char *pbuf, unsigned char *buf); +int layer2(char *pbuf, unsigned char *buf, int is_te, int printit); +void layer3(char *pbuf, int n, int off, unsigned char *buf); +int q932_facility(char *pbuf, unsigned char *buf); +void sprintline(int, char *, int, int, int, const char *, ...); +void extension(int, char *, int, unsigned char, unsigned char); + +/* EOF */ diff --git a/usr.sbin/i4b/isdndecode/facility.c b/usr.sbin/i4b/isdndecode/facility.c new file mode 100644 index 0000000..5735abb --- /dev/null +++ b/usr.sbin/i4b/isdndecode/facility.c @@ -0,0 +1,906 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * facility.c - decode Q.932 facilities + * ------------------------------------ + * + * $Id: facility.c,v 1.2 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:10:32 1998] + * + *---------------------------------------------------------------------------*/ + +#include "decode.h" +#include "facility.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/isdndecode/facility.h b/usr.sbin/i4b/isdndecode/facility.h new file mode 100644 index 0000000..7080c22 --- /dev/null +++ b/usr.sbin/i4b/isdndecode/facility.h @@ -0,0 +1,154 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * facility.h - Q.932 facility header file + * --------------------------------------- + * + * $Id: facility.h,v 1.2 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:10:48 1998] + * + *---------------------------------------------------------------------------*/ + +/* #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/isdndecode/isdndecode.8 b/usr.sbin/i4b/isdndecode/isdndecode.8 new file mode 100644 index 0000000..8594686 --- /dev/null +++ b/usr.sbin/i4b/isdndecode/isdndecode.8 @@ -0,0 +1,190 @@ +.\" +.\" Copyright (c) 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: isdndecode.8,v 1.3 1998/12/18 17:09:38 hm Exp $ +.\" +.\" last edit-date: [Fri Dec 18 18:11:31 1998] +.\" +.\" -hm writing manual page +.\" +.Dd September 17, 1998 +.Dt isdndecode 8 +.Sh NAME +.Nm isdndecode +.Nd isdn4bsd ISDN protocol decode utility +.Sh SYNOPSIS +.Nm isdndecode +.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 o +.Op Fl p Ar filename +.Op Fl u Ar number +.Op Fl B +.Op Fl P +.Op Fl R Ar unit +.Op Fl T Ar unit +.Sh DESCRIPTION +.Nm isdndecode +is part of the isdn4bsd package and is used to provide the user with a +detailed 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 +isdndecode<n> where n is the number of the unit to decode). + +.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 o +switch off writing decode 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 decode). + +.It Fl u +Use +.Ar number +as the unit number of the controller card to decode (default 0). + +.It Fl B +Write undecoded binary decode data to a file for later or remote +analyzing (default off). + +.It Fl P +Read undecoded binary decode 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. + +.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 decode 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. +.El +.Pp + +.Sh FILES +.Bl -tag -width daddeldi -compact +.It Pa /dev/i4btrc<n> +The devicefile(s) used to get the decode messages for ISDN card unit <n> +out of the kernel. +.El + +.Sh EXAMPLES +The command: +.Bd -literal -offset indent +isdndecode -f /var/tmp/isdn.decode +.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.decode. + +.Sh SEE ALSO +.Xr isdnd 8 + +.Sh BUGS +Still one left. + +.Sh STANDARDS +ITU Recommendations I.430, Q.920, Q.921, Q.930, Q.931 +.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 and this manual page was written by Hellmuth Michaelis, +he can be reached at hm@kts.org. + diff --git a/usr.sbin/i4b/isdndecode/layer1.c b/usr.sbin/i4b/isdndecode/layer1.c new file mode 100644 index 0000000..8dee4b7 --- /dev/null +++ b/usr.sbin/i4b/isdndecode/layer1.c @@ -0,0 +1,80 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * layer1.c - isdndecode, decode and print layer 1 information + * ----------------------------------------------------------- + * + * $Id: layer1.c,v 1.2 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:11:55 1998] + * + *---------------------------------------------------------------------------*/ + +#include "decode.h" + +/*---------------------------------------------------------------------------* + * decode layer 1 information + *---------------------------------------------------------------------------*/ +void +layer1(char *buffer, unsigned char *buf) +{ + switch(*buf) + { + case INFO0: + strcpy(buffer,"L1 INFO0 (No Signal)\n"); + break; + + case INFO1_8: + strcpy(buffer,"L1 INFO1 (Activation Request, Priority = 8)\n"); + break; + + case INFO1_10: + strcpy(buffer,"L1 INFO1 (Activation Request, Priority = 10)\n"); + break; + + case INFO2: + strcpy(buffer,"L1 INFO2 (Pending Activation)\n"); + break; + + case INFO3: + strcpy(buffer,"L1 INFO3 (Synchronized)\n"); + break; + + case INFO4_8: + strcpy(buffer,"L1 INFO4 (Activated, Priority = 8/9)\n"); + break; + + case INFO4_10: + strcpy(buffer,"L1 INFO4 (Activated, Priority = 10/11)\n"); + break; + + default: + sprintf(buffer,"L1 ERROR, invalid INFO value 0x%x!\n", *buf); + break; + } +} + +/* EOF */ diff --git a/usr.sbin/i4b/isdndecode/layer2.c b/usr.sbin/i4b/isdndecode/layer2.c new file mode 100644 index 0000000..b7997dd --- /dev/null +++ b/usr.sbin/i4b/isdndecode/layer2.c @@ -0,0 +1,298 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * layer2.c - decode and print layer 2 (Q.921) information + * ------------------------------------------------------- + * + * $Id: layer2.c,v 1.3 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:12:09 1998] + * + *---------------------------------------------------------------------------*/ + +#include "decode.h" + +/*---------------------------------------------------------------------------* + * decode poll bit + *---------------------------------------------------------------------------*/ +static void +poll(int layer, char *buffer, int cnt, unsigned char value, unsigned char mask) +{ + sprintline(layer, buffer, cnt, value, mask, "P/F, Poll = %s", (value & mask) ? "Immediate Response Required" : "No Immediate Response Required"); +} + +/*---------------------------------------------------------------------------* + * decode final bit + *---------------------------------------------------------------------------*/ +static void +final(int layer, char *buffer, int cnt, unsigned char value, unsigned char mask) +{ + sprintline(layer, buffer, cnt, value, mask, "P/F, Final = %s", (value & mask) ? "Result of Poll" : "No Result of Poll"); +} + +/*---------------------------------------------------------------------------* + * decode protocol specified in Q.921 + *---------------------------------------------------------------------------*/ +int +layer2(char *pbuf, unsigned char *buf, int dir, int printit) +{ + int sap, tei, cmd; + int cnt = 0; + char locbuf[32000]; + char *lbufp = &locbuf[0]; + char buffer[80]; + + *lbufp = '\0'; + *pbuf = '\0'; + + /* address high */ + + sap = (buf[0] >> 2) & 0x3f; + + if(sap == 0) + strcpy(buffer, "Call Control"); + else if((sap >= 1) && (sap <= 15)) + strcpy(buffer, "Reserved"); + else if(sap == 16) + strcpy(buffer, "X.25"); + else if((sap >= 17) && (sap <= 31)) + strcpy(buffer, "Reserved"); + else if(sap == 63) + strcpy(buffer, "Layer 2 Management"); + else + strcpy(buffer, "Not available for Q.921"); + sprintline(2, lbufp+strlen(lbufp), cnt, buf[0], 0xfc, "SAPI = %d (%s)", sap, buffer); + + if(dir == FROM_TE) + cmd = !(buf[0] & 0x02); + else + cmd = buf[0] & 0x02; + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[0], 0x02, "C/R = %s", cmd ? "Command" : "Response"); + extension(2, lbufp+strlen(lbufp), cnt, buf[0], 0x01); + cnt++; + + /* address low */ + + tei = buf[1] >> 1; + + if((tei >= 0) && (tei <= 63)) + strcpy(buffer, "Non-automatic TEI"); + else if((tei >= 64) && (tei <= 126)) + strcpy(buffer, "Automatic TEI"); + if(tei == 127) + strcpy(buffer, "Group TEI"); + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[1], 0xfe, "TEI = %d (%s)", tei, buffer); + extension(2, lbufp+strlen(lbufp), cnt, buf[1], 0x01); + cnt++; + + /* control 1 */ + + if((buf[2] & 0x03) == 0x03) + { + /* U-frame */ + + if((buf[2] & 0xef) == 0x6f) + { + /* SABME */ + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: SABME (Set Asynchonous Balanced Mode)"); + poll(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10); + cnt++; + } + else if((buf[2] & 0xef) == 0x0f) + { + /* DM */ + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: DM (Disconnected Mode)"); + final(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10); + cnt++; + } + else if((buf[2] & 0xef) == 0x03) + { + /* UI */ + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: UI (Unnumbered Information)"); + poll(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10); + cnt++; + + if(sap == 63 && (buf[3] == 0x0f)) /* TEI management */ + { + sprintline(2, lbufp+strlen(lbufp), cnt, buf[3], 0xff, "MEI (Management Entity Identifier)"); + cnt++; + sprintline(2, lbufp+strlen(lbufp), cnt, buf[4], 0xff, "Ri = 0x%04x (Reference number high)", (buf[4] << 8) | buf[5]); + cnt++; + sprintline(2, lbufp+strlen(lbufp), cnt, buf[5], 0xff, "Ri (Reference Number low)"); + cnt++; + + switch(buf[6]) + { + case 0x01: + strcpy(buffer, "Identity Request"); + break; + case 0x02: + strcpy(buffer, "Identity Assigned"); + break; + case 0x03: + strcpy(buffer, "Identity denied"); + break; + case 0x04: + strcpy(buffer, "Identity Check Request"); + break; + case 0x05: + strcpy(buffer, "Identity Check Response"); + break; + case 0x06: + strcpy(buffer, "Identity Remove"); + break; + case 0x07: + strcpy(buffer, "Identity Verify"); + break; + default: + strcpy(buffer, "undefined"); + break; + } + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[6], 0xff, "TEI %s (Message Type %d)", buffer, buf[6]); + cnt++; + + switch(buf[6]) + { + case 0x01: + strcpy(buffer, "Any TEI value acceptable"); + break; + case 0x02: + strcpy(buffer, ""); + break; + case 0x03: + strcpy(buffer, "No TEI Value available"); + break; + case 0x04: + strcpy(buffer, "Check all TEI values"); + break; + case 0x05: + strcpy(buffer, ""); + break; + case 0x06: + strcpy(buffer, "Request for removal of all TEI values"); + break; + case 0x07: + strcpy(buffer, ""); + break; + default: + strcpy(buffer, ""); + break; + } + if(((buf[7] >> 1) & 0x7f) == 127) + sprintline(2, lbufp+strlen(lbufp), cnt, buf[7], 0xfe, "Ai = %d (Action Indicator = %s)", (buf[7] >> 1) & 0x7f, buffer); + else + sprintline(2, lbufp+strlen(lbufp), cnt, buf[7], 0xfe, "Ai = %d (Action Indicator)", (buf[7] >> 1) & 0x7f); + extension(2, lbufp+strlen(lbufp), cnt, buf[7], 0x01); + cnt++; + } + } + else if((buf[2] & 0xef) == 0x43) + { + /* DISC */ + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: DISC (Disconnect)"); + poll(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10); + cnt++; + } + else if((buf[2] & 0xef) == 0x63) + { + /* UA */ + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: UA (Unnumbered Acknowledge)"); + final(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10); + cnt++; + } + else if((buf[2] & 0xef) == 0x87) + { + /* FRMR */ + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: FRMR (Frame Reject)"); + final(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10); + cnt++; + } + else if((buf[2] & 0xef) == 0x9f) + { + /* XID */ + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: XID (Exchange Identification)"); + if(cmd) + poll(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10); + else + final(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10); + cnt++; + } + + } + else if((buf[2] & 0x03) == 0x01) + { + /* S-frame */ + + if(buf[2] == 0x01) + strcpy(buffer, "RR (Receiver Ready)"); + else if(buf[2] == 0x05) + strcpy(buffer, "RNR (Receiver Not Ready)"); + else if(buf[2] == 0x09) + strcpy(buffer, "REJ (Reject)"); + else + strcpy(buffer, "Unknown"); + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xff, "S-Frame: %s", buffer); + cnt++; + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[3], 0xfe, "N(R) = %d (receive sequence number)", (buf[3] >> 1) & 0x7f); + if(cmd) + poll(2, lbufp+strlen(lbufp), cnt, buf[3], 0x01); + else + final(2, lbufp+strlen(lbufp), cnt, buf[3], 0x01); + cnt++; + + } + else if((buf[2] & 0x01) == 0x00) + { + /* I-frame */ + + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xfe, "N(S) = %d (send sequence number)", (buf[2] >> 1) & 0x7f); + sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0x01, "I-Frame: Information transfer"); + cnt++; + + sprintf(buffer, "N(R) = %d", (buf[3] >> 1) & 0x7f); + sprintline(2, lbufp+strlen(lbufp), cnt, buf[3], 0xfe, "N(R) = %d (receive sequence number)", (buf[3] >> 1) & 0x7f); + poll(2, lbufp+strlen(lbufp), cnt, buf[3], 0x01); + cnt++; + + } + + sprintf((pbuf+strlen(pbuf)),"%s", &locbuf[0]); + return (cnt); +} + +/* EOF */ diff --git a/usr.sbin/i4b/isdndecode/layer3.c b/usr.sbin/i4b/isdndecode/layer3.c new file mode 100644 index 0000000..6376a13 --- /dev/null +++ b/usr.sbin/i4b/isdndecode/layer3.c @@ -0,0 +1,508 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * layer3.c - decode and print layer 3 (Q.931) information + * ------------------------------------------------------- + * + * $Id: layer3.c,v 1.5 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:12:21 1998] + * + *---------------------------------------------------------------------------*/ + +#include "decode.h" + +char *mttab[] = { + +/* 0x00 */ /* call establishment group */ + + "ESCAPE", + "ALERTING", + "CALL PROCEEDING", + "PROGRESS", + "undefined (0x04)", + "SETUP", + "undefined (0x06)", + "CONNECT", + "undefined (0x08)", + "undefined (0x09)", + "undefined (0x0a)", + "undefined (0x0b)", + "undefined (0x0c)", + "SETUP ACKNOWLEDGE", + "undefined (0x0e)", + "CONNECT ACKNOWLEDGE", + +/* 0x10 */ + "undefined (0x10)", + "undefined (0x11)", + "undefined (0x12)", + "undefined (0x13)", + "undefined (0x14)", + "undefined (0x15)", + "undefined (0x16)", + "undefined (0x17)", + "undefined (0x18)", + "undefined (0x19)", + "undefined (0x1a)", + "undefined (0x1b)", + "undefined (0x1c)", + "undefined (0x1d)", + "undefined (0x1e)", + "undefined (0x1f)", + +/* 0x20 */ + + "USER INFORMATION", /* call information phase */ + "SUSPEND REJECT", + "RESUME REJECT", + "undefined (0x23)", + "HOLD", + "SUSPEND", + "RESUME", + "undefined (0x27)", + "HOLD ACKNOWLEDGE", + "undefined (0x29)", + "undefined (0x2a)", + "undefined (0x2b)", + "undefined (0x2c)", + "SUSPEND ACKNOWLEDGE", + "RESUME ACKNOWLEDGE", + "undefined (0x2f)", + +/* 0x30 */ + + "HOLD REJECT", + "RETRIEVE", + "undefined (0x32)", + "RETRIEVE ACKNOWLEDGE", + "undefined (0x34)", + "undefined (0x35)", + "undefined (0x36)", + "RETRIEVE REJECT", + "undefined (0x38)", + "undefined (0x39)", + "undefined (0x3a)", + "undefined (0x3b)", + "undefined (0x3c)", + "undefined (0x3d)", + "undefined (0x3e)", + "undefined (0x3f)", + +/* 0x40 */ + + "DETACH", /* call clearing */ + "undefined (0x41)", + "undefined (0x42)", + "undefined (0x43)", + "undefined (0x44)", + "DISCONNECT", + "RESTART", + "undefined (0x47)", + "DETACH ACKNOWLEDGE", + "undefined (0x49)", + "undefined (0x4a)", + "undefined (0x4b)", + "undefined (0x4c)", + "RELEASE", + "RESTART ACKNOWLEDGE", + "undefined (0x4f)", + +/* 0x50 */ + + "undefined (0x50)", + "undefined (0x51)", + "undefined (0x52)", + "undefined (0x53)", + "undefined (0x54)", + "undefined (0x55)", + "undefined (0x56)", + "undefined (0x57)", + "undefined (0x58)", + "undefined (0x59)", + "RELEASE COMPLETE", + "undefined (0x5b)", + "undefined (0x5c)", + "undefined (0x5d)", + "undefined (0x5e)", + "undefined (0x5f)", + +/* 0x60 */ + + "SEGMENT", /* misc messages */ + "undefined (0x61)", + "FACILITY", + "undefined (0x63)", + "REGISTER", + "undefined (0x65)", + "undefined (0x66)", + "undefined (0x67)", + "CANCEL ACKNOWLEDGE", + "undefined (0x69)", + "FACILITY ACKNOWLEDGE", + "undefined (0x6b)", + "REGISTER ACKNOWLEDGE", + "undefined (0x6d)", + "NOTIFY", + "undefined (0x6f)", + +/* 0x70 */ + + "CANCEL REJECT", + "undefined (0x71)", + "FACILITY REJECT", + "undefined (0x73)", + "REGISTER REJECT", + "STATUS ENQIRY", + "undefined (0x76)", + "undefined (0x77)", + "undefined (0x78)", + "CONGESTION CONTROL", + "undefined (0x7a)", + "INFORMATION", + "undefined (0x7c)", + "STATUS", + "undefined (0x7e)", + "undefined (0x7f)", +}; + +#define MTTAB_MAX 0x7f + +extern int f_null(char *pbuf, unsigned char *buf, int off); +extern int f_bc(char *pbuf, unsigned char *buf, int off); +extern int f_cause(char *pbuf, unsigned char *buf, int off); +extern int f_cstat(char *pbuf, unsigned char *buf, int off); +extern int f_chid(char *pbuf, unsigned char *buf, int off); +extern int f_fac(char *pbuf, unsigned char *buf, int off); +extern int f_progi(char *pbuf, unsigned char *buf, int off); +extern int f_displ(char *pbuf, unsigned char *buf, int off); +extern int f_date(char *pbuf, unsigned char *buf, int off); +extern int f_cnu(char *pbuf, unsigned char *buf, int off); +extern int f_cgpn(char *pbuf, unsigned char *buf, int off); +extern int f_cdpn(char *pbuf, unsigned char *buf, int off); +extern int f_hlc(char *pbuf, unsigned char *buf, int off); + +struct ie { + unsigned char code; /* information element identifier code */ + char *name; /* ie name */ + int (*func) (char *pbuf, unsigned char *buf, int off); /* decode function */ +} ietab[] = { + { 0x00, "segmented message", f_null }, + { 0x04, "bearer capability", f_bc }, + { 0x08, "cause", f_cause }, + { 0x0c, "connected address", f_null }, + { 0x0d, "extended facility", f_null }, + { 0x10, "call identity", f_null }, + { 0x14, "call state", f_cstat }, + { 0x18, "channel id", f_chid }, + { 0x19, "data link connection id", f_null }, + { 0x1c, "facility", f_fac }, + { 0x1e, "progress indicator", f_progi }, + { 0x20, "network specific facilities", f_null }, + { 0x24, "terminal capabilities", f_null }, + { 0x27, "notification indicator", f_null }, + { 0x28, "display", f_displ }, + { 0x29, "date/time", f_date }, + { 0x2c, "keypad", f_null }, + { 0x30, "keypad echo", f_null }, + { 0x32, "information request", f_null }, + { 0x34, "signal", f_null }, + { 0x36, "switchhook", f_null }, + { 0x38, "feature activation", f_null }, + { 0x39, "feature indication", f_null }, + { 0x3a, "service profile id", f_null }, + { 0x3b, "endpoint identifier", f_null }, + { 0x40, "information rate", f_null }, + { 0x41, "precedence level", f_null }, + { 0x42, "end-to-end transit delay", f_null }, + { 0x43, "transit delay detection", f_null }, + { 0x44, "packet layer binary parms", f_null }, + { 0x45, "packet layer window size", f_null }, + { 0x46, "packet size", f_null }, + { 0x47, "closed user group", f_null }, + { 0x48, "link layer core parameters", f_null }, + { 0x49, "link layer protocol parms", f_null }, + { 0x4a, "reverse charging information", f_null }, + { 0x4c, "connected number", f_cnu }, + { 0x4d, "connected subaddress", f_null }, + { 0x50, "X.213 priority", f_null }, + { 0x51, "report type", f_null }, + { 0x53, "link integrity verification", f_null }, + { 0x57, "PVC status", f_null }, + { 0x6c, "calling party number", f_cnu }, + { 0x6d, "calling party subaddress", f_null }, + { 0x70, "called party number", f_cnu }, + { 0x71, "called party subaddress", f_null }, + { 0x74, "redirecting number", f_null }, + { 0x78, "transit network selection", f_null }, + { 0x79, "restart indicator", f_null }, + { 0x7c, "low layer compatibility", f_null }, + { 0x7d, "high layer compatibility", f_hlc }, + { 0x7e, "user-user", f_null }, + { 0x7f, "escape for extension", f_null }, + { 0xff, "unknown information element", f_null } +}; + +/*---------------------------------------------------------------------------* + * decode Q.931 protocol + *---------------------------------------------------------------------------*/ +void +layer3(char *pbuf, int n, int off, unsigned char *buf) +{ + char buffer[256]; + int codeset = 0; + int codelock = 0; + int oldcodeset = 0; + + int pd; + int len; + int j; + int i; + + if(n <= 0) + return; + + *pbuf = '\0'; + + i = 0; + + /* protocol discriminator */ + + pd = buf[i]; + + if(pd >= 0x00 && pd <= 0x07) + sprintf(buffer, "User-User IE (0x%02x)",pd); + else if(pd == 0x08) + sprintf(buffer, "Q.931/I.451"); + else if(pd >= 0x10 && pd <= 0x3f) + sprintf(buffer, "Other Layer 3 or X.25 (0x%02x)",pd); + else if(pd >= 0x40 && pd <= 0x4f) + sprintf(buffer, "National Use (0x%02x)",pd); + else if(pd >= 0x50 && pd <= 0xfe) + sprintf(buffer, "Other Layer 3 or X.25 (0x%02x)",pd); + else + sprintf(buffer, "Reserved (0x%02x)",pd); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, pd, 0xff, "Protocol discriminator = %s", buffer); + i++; + + /* call reference */ + + len = buf[i] & 0x0f; + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xf0, "Call Reference"); + + switch(len) + { + case 0: + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x0f, "Length of Call Reference = 0 (Dummy CR)"); + break; + case 1: + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x0f, "Length of Call Reference = 1"); + i++; + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x80, "Call Reference sent %s origination side", (buf[i] & 0x80) ? "to" : "from"); + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "Call Reference = %d = 0x%02x", (buf[i] & 0x7f), (buf[i] & 0x7f)); + break; + case 2: + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x0f, "Length of Call Reference = 2"); + i++; + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x80, "Call Reference sent %s origination side", (buf[i] & 0x80) ? "to" : "from"); + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "Call reference = %d = %02x", (buf[i] & 0x7f)); + i++; + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xff, "Call reference = %d = %02x", (buf[i])); + break; + } + i++; + + /* message type */ + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x80, "Message type extension = %d", buf[i] & 0x80 ? 1 : 0); + + if(buf[i] <= MTTAB_MAX) + strcpy(buffer, mttab[buf[i]]); + else + sprintf(buffer, "unknown (0x%02x)", buf[i]); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "Message type = %s", buffer); + i++; + + /* information elements */ + + for (; i < n;) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x80, "%s Information element", buf[i] & 0x80 ? "Single octet" : "Variable length"); + + if(buf[i] & 0x80) + { + /* single octett info element type 1 */ + + if((buf[i] & 0x70) == 0x00) + { + strcpy(buffer, "Reserved"); + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x70, "Reserved"); + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x0f, "Reserved, content of IE"); + } + else if((buf[i] & 0x70) == 0x10) + { + strcpy(buffer, "Shift"); + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x70, "Shift"); + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x08, "%s shift", buf[i] & 0x08 ? "Non-locking" : "Locking"); + + switch(buf[i] & 0x07) + { + case 0: + strcpy(buffer, "Not applicable"); + break; + case 1: + case 2: + case 3: + sprintf(buffer, "Reserved (%d)", buf[i] & 0x07); + break; + case 4: + strcpy(buffer, "Codeset 4 (ISO/IEC)"); + break; + case 5: + strcpy(buffer, "Codeset 5 (National use)"); + break; + case 6: + strcpy(buffer, "Codeset 6 (Local network specific)"); + break; + case 7: + strcpy(buffer, "Codeset 7 (User specific)"); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x07, "%s", buffer); + break; + } + else if((buf[i] & 0x70) == 0x30) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x70, "Congestion Level"); + switch(buf[i] & 0x0f) + { + case 0x00: + strcpy(buffer, "receiver ready"); + break; + case 0x0f: + strcpy(buffer, "receiver not ready"); + break; + default: + sprintf(buffer, "reserved (0x%02x)", buf[i] & 0x0f); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x0f, "Congestion Level = ", buffer); + break; + } + else if((buf[i] & 0x70) == 0x50) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x70, "Repeat Indicator"); + switch(buf[i] & 0x0f) + { + case 0x02: + strcpy(buffer, "Prioritized list for selecting one possibility"); + break; + default: + sprintf(buffer, "reserved (0x%02x)", buf[i] & 0x0f); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x0f, "Repeat indication = ", buffer); + break; + } + + /* single octett info element type 2 */ + + else if((buf[i] & 0x7f) == 0x20) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "More data"); + } + else if((buf[i] & 0x7f) == 0x21) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "Sending complete"); + } + else + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xff, "UNKNOWN single octet IE = 0x%02x", buf[i]); + } + i++; /* next */ + } + else + { + if(codeset == 0) + { + struct ie *iep = &ietab[0]; + + for(;;) + { + if((iep->code == buf[i]) || + (iep->code == 0xff)) + break; + iep++; + } + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "IE = %s", iep->name); + sprintline(3, pbuf+strlen(pbuf), off+i+1, buf[i+1], 0xff, "IE Length = %d", buf[i+1]); + + if(iep->func == f_null) + { + } + else + { + i += (iep->func)(pbuf, &buf[i], off+i); + goto next; + } + } + 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/isdndecode/layer3_subr.c b/usr.sbin/i4b/isdndecode/layer3_subr.c new file mode 100644 index 0000000..e1480b6 --- /dev/null +++ b/usr.sbin/i4b/isdndecode/layer3_subr.c @@ -0,0 +1,1045 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * layer3_subr.c - subroutines for IE decoding + * ------------------------------------------- + * + * $Id: layer3_subr.c,v 1.4 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:12:37 1998] + * + *---------------------------------------------------------------------------*/ + +#include "decode.h" + +/*---------------------------------------------------------------------------* + * dummy function + *---------------------------------------------------------------------------*/ +int +f_null(char *pbuf, unsigned char *buf, int off) +{ + return(0); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +f_cstat(char *pbuf, unsigned char *buf, int off) +{ + int i = 0; + int len = 0; + char buffer[256]; + + i++; + len = buf[i]; + i++; + sprintf((pbuf+strlen(pbuf)), "Std="); + switch((buf[i] & 0x60) >> 5) + { + case 0: + strcpy(buffer, "CCITT"); + break; + case 1: + strcpy(buffer, "ISO/IEC"); + break; + case 2: + strcpy(buffer, "National"); + break; + case 3: + strcpy(buffer, "Special"); + break; + } + sprintf((pbuf+strlen(pbuf)), ", State="); + + switch((buf[i] & 0x3f)) + { + case 0: + strcpy(buffer, "Null"); + break; + case 1: + strcpy(buffer, "Call initiated"); + break; + case 2: + strcpy(buffer, "Overlap sending"); + break; + case 3: + strcpy(buffer, "Outgoing call proceeding"); + break; + case 4: + strcpy(buffer, "Call delivered"); + break; + case 6: + strcpy(buffer, "Call present"); + break; + case 7: + strcpy(buffer, "Call received"); + break; + case 8: + strcpy(buffer, "Connect request"); + break; + case 9: + strcpy(buffer, "Incoming call proceeding"); + break; + case 10: + strcpy(buffer, "Active"); + break; + case 11: + strcpy(buffer, "Disconnect request"); + break; + case 12: + strcpy(buffer, "Disconnect indication"); + break; + case 15: + strcpy(buffer, "Suspend request"); + break; + case 17: + strcpy(buffer, "Resume request"); + break; + case 19: + strcpy(buffer, "Release request"); + break; + case 22: + strcpy(buffer, "Call abort"); + break; + case 25: + strcpy(buffer, "Overlap receiving"); + break; + case 0x3d: + strcpy(buffer, "Restart request"); + break; + case 0x3e: + strcpy(buffer, "Restart"); + break; + default: + strcpy(buffer, "ERROR: undefined/reserved"); + break; + } + sprintf((pbuf+strlen(pbuf)), "]"); + i++; + return(i); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +f_chid(char *pbuf, unsigned char *buf, int off) +{ + int i = 0; + int len = 0; + char buffer[256]; + + i++; + len = buf[i]; + i++; + + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x40, "Interface Id present = %s", buf[i] & 0x40 ? "Yes" : "No"); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x20, "Interface Type = %s", buf[i] & 0x20 ? "Other (PRI)" : "BRI"); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x10, "Spare"); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x08, "Channel = %s", buf[i] & 0x08 ? "exclusive" : "preferred"); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x04, "Channel is%s the D-Channel", buf[i] & 0x04 ? "" : " not"); + + switch(buf[i] & 0x03) + { + case 0: + strcpy(buffer, "no channel"); + break; + case 1: + strcpy(buffer, "B-1"); + break; + case 2: + strcpy(buffer, "B-2"); + break; + case 3: + strcpy(buffer, "any channel"); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x03, "Channel = %s", buffer); + + i++; + return(i); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +f_fac(char *pbuf, unsigned char *buf, int off) +{ + return(q932_facility(pbuf, buf)); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +f_progi(char *pbuf, unsigned char *buf, int off) +{ + int i = 0; + int len = 0; + char buffer[256]; + + i++; + len = buf[i]; + i++; + sprintf((pbuf+strlen(pbuf)), "Std="); + switch((buf[i] & 0x60) >> 5) + { + case 0: + strcpy(buffer, "CCITT"); + break; + case 1: + strcpy(buffer, "ISO/IEC"); + break; + case 2: + strcpy(buffer, "National"); + break; + case 3: + strcpy(buffer, "Local"); + break; + } + sprintf((pbuf+strlen(pbuf)), ", Loc="); + + switch((buf[i] & 0x0f)) + { + case 0: + strcpy(buffer, "User"); + break; + case 1: + strcpy(buffer, "Private network serving local user"); + break; + case 2: + strcpy(buffer, "Public network serving local user"); + break; + case 3: + strcpy(buffer, "Transit network"); + break; + case 4: + strcpy(buffer, "Public network serving remote user"); + break; + case 5: + strcpy(buffer, "Private network serving remote user"); + break; + case 6: + strcpy(buffer, "Network beyond interworking point"); + break; + default: + strcpy(buffer, "ERROR: undefined/reserved"); + break; + } + + i++; + + sprintf((pbuf+strlen(pbuf)), "\n Description"); + + switch((buf[i] & 0x7f)) + { + case 1: + strcpy(buffer, "Call is not end-to-end ISDN"); + break; + case 2: + strcpy(buffer, "Destination address is non-ISDN"); + break; + case 3: + strcpy(buffer, "Origination address is non-ISDN"); + break; + case 4: + strcpy(buffer, "Call has returned to the ISDN"); + break; + case 5: + strcpy(buffer, "Interworking occured, Service change"); + break; + case 8: + strcpy(buffer, "In-band info or appropriate pattern now available"); + break; + default: + strcpy(buffer, "ERROR: undefined/reserved"); + break; + } + sprintf((pbuf+strlen(pbuf)), "]"); + i++; + + return(i); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +f_displ(char *pbuf, unsigned char *buf, int off) +{ + int i = 0; + int j = 0; + int len = 0; + + 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; + + return(i); +} + +/*---------------------------------------------------------------------------* + * + *---------------------------------------------------------------------------*/ +int +f_date(char *pbuf, unsigned char *buf, int off) +{ + int i = 0; + int j = 0; + int len = 0; + + i++; + len = buf[i]; + i++; + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xff, "Year = %02d", buf[i]); + i++; + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xff, "Month = %02d", buf[i]); + i++; + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xff, "Day = %02d", buf[i]); + i++; + + j=3; + if(j < len) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xff, "Hour = %02d", buf[i]); + i++; + j++; + } + if(j < len) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xff, "Minute = %02d", buf[i]); + i++; + j++; + } + if(j < len) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0xff, "Second = %02d", buf[i]); + i++; + j++; + } + i += len; + return(i); +} + +/*---------------------------------------------------------------------------* + * decode and print the cause + *---------------------------------------------------------------------------*/ +int +f_cause(char *pbuf, unsigned char *buf, int off) +{ + int j; + int len; + int i = 0; + int ls; + char buffer[256]; + + i++; /* index -> length */ + + len = buf[i]; + + i++; /* coding/location */ + len--; + + ls = buf[i]; + + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch((ls & 0x60) >> 5) + { + case 0: + strcpy(buffer, "CCITT"); + break; + case 1: + strcpy(buffer, "ISO/IEC"); + break; + case 2: + strcpy(buffer, "National"); + break; + case 3: + strcpy(buffer, "Local"); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x60, "Coding Standard = %s", buffer); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x10, "Spare"); + + switch(ls & 0x0f) + { + case 0x00: + strcpy(buffer, "user"); + break; + case 0x01: + strcpy(buffer, "private network serving local user"); + break; + case 0x02: + strcpy(buffer, "public network serving local user"); + break; + case 0x03: + strcpy(buffer, "transit network"); + break; + case 0x04: + strcpy(buffer, "public network serving remote user"); + break; + case 0x05: + strcpy(buffer, "private network serving remote user"); + break; + case 0x07: + strcpy(buffer, "international network"); + break; + case 0x0a: + strcpy(buffer, "network beyond interworking point"); + break; + default: + sprintf(buffer, "reserved (0x%02x)", ls & 0x0f); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x0f, "Location = %s", buffer); + + i++; + len--; + + if(!(ls & 0x80)) + { + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch(buf[i] & 0x7f) + { + case 0: + strcpy(buffer, "Q.931"); + break; + case 3: + strcpy(buffer, "X.21"); + break; + case 4: + strcpy(buffer, "X.25"); + break; + case 5: + strcpy(buffer, "Q.1031/Q.1051"); + break; + default: + strcpy(buffer, "Reserved"); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "Recommendation = %s", buffer); + i++; + len--; + } + + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "Cause = %s", print_cause_q850(buf[i] & 0x7f)); + + i++; + len--; + + for(j = 0; j < len; j++) + sprintline(3, (pbuf+strlen(pbuf)), off+i+j, buf[i+j], 0xff, "Diagnostics = %02d %s", buf[i+j]); + + i += (len+1); + + return(i); +} + +/*---------------------------------------------------------------------------* + * decode and print the bearer capability + *---------------------------------------------------------------------------*/ +int +f_bc(char *pbuf, unsigned char *buf, int off) +{ + int len; + int i = 0; + int mr = 0; + char buffer[256]; + + i++; /* index -> length */ + + len = buf[i]; + i++; + + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch((buf[i] & 0x60) >> 5) + { + case 0: + strcpy(buffer, "CCITT"); + break; + case 1: + strcpy(buffer, "ISO/IEC"); + break; + case 2: + strcpy(buffer, "National"); + break; + case 3: + strcpy(buffer, "NSI Std"); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x60, "Coding standard = %s", buffer); + + switch(buf[i] & 0x1f) + { + case 0x00: + strcpy(buffer, "speech"); + break; + case 0x08: + strcpy(buffer, "unrestricted digital information"); + break; + case 0x09: + strcpy(buffer, "restricted digital information"); + break; + case 0x10: + strcpy(buffer, "3.1 kHz audio"); + break; + case 0x11: + strcpy(buffer, "unrestricted digital information with tones"); + break; + case 0x18: + strcpy(buffer, "video"); + break; + default: + sprintf(buffer, "reserved (0x%02x)", buf[i] & 0x0f); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x1f, "Capability = %s", buffer); + + i++; + len--; + + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch((buf[i] & 0x60) >> 5) + { + case 0: + strcpy(buffer, "circuit"); + break; + case 2: + strcpy(buffer, "packet"); + break; + default: + sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", ((buf[i] & 0x60) >> 5)); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x60, "Mode = %s", buffer); + + switch(buf[i] & 0x1f) + { + case 0x00: + strcpy(buffer, "packet mode"); + break; + case 0x10: + strcpy(buffer, "64 kbit/s"); + break; + case 0x11: + strcpy(buffer, "2 x 64 kbit/s"); + break; + case 0x13: + strcpy(buffer, "384 kbit/s"); + break; + case 0x15: + strcpy(buffer, "1536 kbit/s"); + break; + case 0x17: + strcpy(buffer, "1920 kbit/s"); + break; + case 0x18: + strcpy(buffer, "Multirate"); + mr = 1; + break; + default: + sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x1f, "Rate = %s", buffer); + + i++; + len--; + + if(!len) + goto exit; + + if(mr) + { + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x60, "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: + + return(i); +} + +/*---------------------------------------------------------------------------* + * decode and print the ISDN (telephone) number + *---------------------------------------------------------------------------*/ +int +f_cnu(char *pbuf, unsigned char *buf, int off) +{ + int j; + int len; + int i = 0; + int tp; + int ind = 0; + char buffer[256]; + + i++; /* index -> length */ + len = buf[i]; + + i++; /* index -> type/plan */ + tp = buf[i]; + + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch((tp & 0x70) >> 4) + { + case 0: + strcpy(buffer, "Unknown"); + break; + case 1: + strcpy(buffer, "International number"); + break; + case 2: + strcpy(buffer, "National number"); + break; + case 3: + strcpy(buffer, "Network specific number"); + break; + case 4: + strcpy(buffer, "Subscriber number"); + break; + case 6: + strcpy(buffer, "Abbreviated number"); + break; + default: + sprintf(buffer, "Reserved (%d), ", ((tp & 0x70) >> 4)); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x60, "Type = %s", buffer); + + switch(tp & 0x0f) + { + case 0: + strcpy(buffer, "Unknown"); + break; + case 1: + strcpy(buffer, "ISDN (E.164)"); + break; + case 3: + strcpy(buffer, "Data (X.121)"); + break; + case 4: + strcpy(buffer, "Telex (F.69)"); + break; + case 8: + strcpy(buffer, "National"); + break; + case 9: + strcpy(buffer, "Private"); + break; + default: + sprintf(buffer, "Reserved (%d)", (tp & 0x0f)); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x0f, "Plan = %s", buffer); + + i++; + len--; + + if(!(tp & 0x80)) + { + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch((buf[i] & 0x60) >> 5) + { + case 0: + strcpy(buffer, "allowed"); + break; + case 1: + strcpy(buffer, "restricted"); + break; + case 2: + strcpy(buffer, "number not available"); + break; + case 3: + strcpy(buffer, "reserved"); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x60, "Presentation = %s", buffer); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x1c, "Spare"); + + switch(ind & 0x03) + { + case 0: + strcpy(buffer, "user provided, not screened"); + break; + case 1: + strcpy(buffer, "user provided, verified & passed"); + break; + case 2: + strcpy(buffer, "user provided, verified & failed"); + break; + case 3: + strcpy(buffer, "network provided"); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x03, "Screening = %s", buffer); + i++; + len--; + } + + for(j = 0; j < len; j++) + { + sprintline(3, (pbuf+strlen(pbuf)), off+i+j, buf[i+j], 0xff, "Number digit = %c", buf[i+j]); + } + + i += j; + + return(i); +} + +/*---------------------------------------------------------------------------* + * decode and print HL comatibility + *---------------------------------------------------------------------------*/ +int +f_hlc(char *pbuf, unsigned char *buf, int off) +{ + int i = 0; + int len = 0; + char buffer[256]; + + i++; + len = buf[i]; + + i++; + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch((buf[i] >> 5) & 0x03) + { + case 0: strcpy(buffer, "CCITT"); + break; + case 1: strcpy(buffer, "ISO/IEC"); + break; + case 2: strcpy(buffer, "National"); + break; + case 3: strcpy(buffer, "Network"); + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x60, "Coding standard = %s", buffer); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x1c, "Interpretation = %s", ((buf[i] >> 2) & 0x07) == 0x04 ? "first" : "reserved"); + + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x03, "Presentation = %s", ((buf[i]) & 0x03) == 0x01 ? "High layer protocol profile" : "reserved"); + + i++; + len--; + + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch(buf[i] & 0x7f) + { + case 0x01: + strcpy(buffer, "Telephony"); + break; + case 0x04: + strcpy(buffer, "Fax Group 2/3 (F.182)"); + break; + case 0x21: + strcpy(buffer, "Fax Group 4 I (F.184)"); + break; + case 0x24: + strcpy(buffer, "Teletex (F.230) or Fax Group 4 II/III (F.184)"); + break; + case 0x28: + strcpy(buffer, "Teletex (F.220)"); + break; + case 0x31: + strcpy(buffer, "Teletex (F.200)"); + break; + case 0x32: + strcpy(buffer, "Videotex (F.300/T.102)"); + break; + case 0x33: + strcpy(buffer, "Videotex (F.300/T.101)"); + break; + case 0x35: + strcpy(buffer, "Telex (F.60)"); + break; + case 0x38: + strcpy(buffer, "MHS (X.400)"); + break; + case 0x41: + strcpy(buffer, "OSI (X.200)"); + break; + case 0x5e: + strcpy(buffer, "Maintenance"); + break; + case 0x5f: + strcpy(buffer, "Management"); + break; + case 0x60: + strcpy(buffer, "Audio visual (F.721)"); + break; + default: + sprintf(buffer, "Reserved (0x%02x)", buf[i] & 0x7f); + break; + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "Characteristics = %s", buffer); + i++; + len--; + + if(buf[i-1] & 0x80) + { + return(i); + } + + extension(3, pbuf+strlen(pbuf), off+i, buf[i], 0x80); + + switch(buf[i] & 0x7f) + { + case 0x01: + strcpy(buffer, "Telephony"); + break; + case 0x04: + strcpy(buffer, "Fax Group 2/3 (F.182)"); + break; + case 0x21: + strcpy(buffer, "Fax Group 4 I (F.184)"); + break; + case 0x24: + strcpy(buffer, "Teletex (F.230) or Fax Group 4 II/III (F.184)"); + break; + case 0x28: + strcpy(buffer, "Teletex (F.220)"); + break; + case 0x31: + strcpy(buffer, "Teletex (F.200)"); + break; + case 0x32: + strcpy(buffer, "Videotex (F.300/T.102)"); + break; + case 0x33: + strcpy(buffer, "Videotex (F.300/T.101)"); + break; + case 0x35: + strcpy(buffer, "Telex (F.60)"); + break; + case 0x38: + strcpy(buffer, "MHS (X.400)"); + break; + case 0x41: + strcpy(buffer, "OSI (X.200)"); + break; + case 0x5e: + strcpy(buffer, "Maintenance"); + break; + case 0x5f: + strcpy(buffer, "Management"); + break; + case 0x60: + strcpy(buffer, "Audio visual (F.721)"); + break; + default: + sprintf(buffer, "Reserved (0x%02x)", buf[i] & 0x7f); + break; + + } + sprintline(3, (pbuf+strlen(pbuf)), off+i, buf[i], 0x7f, "Ext. characteristics = %s", buffer); + i++; + return(i); +} + +/* EOF */ + diff --git a/usr.sbin/i4b/isdndecode/main.c b/usr.sbin/i4b/isdndecode/main.c new file mode 100644 index 0000000..a73d708 --- /dev/null +++ b/usr.sbin/i4b/isdndecode/main.c @@ -0,0 +1,774 @@ +/* + * 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. + * + *--------------------------------------------------------------------------- + * + * main.c - isdndecode main program file + * ------------------------------------- + * + * $Id: main.c,v 1.6 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:12:52 1998] + * + *---------------------------------------------------------------------------*/ + +#include "decode.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; + +static char outfilename[1024]; +static char BPfilename[1024]; + +static void dumpbuf( int n, unsigned char *buf, i4b_trace_hdr_t *hdr); +static int switch_driver( int value, int rx, int tx ); +static void usage( void ); +static void exit_hdl( void ); +static void reopenfiles( int ); + +/*---------------------------------------------------------------------------* + * 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 = DECODE_FILE_NAME; + char *binfile = BIN_FILE_NAME; + int outfileset = 0; + time_t tm; + + i4b_trace_hdr_t *ithp = NULL; + int l; + + b = &buf[sizeof(i4b_trace_hdr_t)]; + + while( (c = getopt(argc, argv, "abdf:hiln:op:u:BPR: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 '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 'u': + unit = atoi(optarg); + if(unit < 0 || unit >= MAX_CONTROLLERS) + usage(); + break; + + case 'B': + Bopt = 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, DECODE_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); + } + } + 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", DECODE_FILE_NAME, unit); + else + strcpy(outfilename, outfile); + + + if((Fout = fopen(outfilename, "r")) != NULL) + { + char buffer[1024]; + fclose(Fout); + sprintf(buffer, "%s%s", outfilename, DECODE_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 + { + if((fread(buf, 1, sizeof(i4b_trace_hdr_t), BP)) != sizeof(i4b_trace_hdr_t)) + { + if(feof(BP)) + { + 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) + { + dumpbuf(n, b, (i4b_trace_hdr_t *)buf); + } + } +} + +/*---------------------------------------------------------------------------* + * 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.%06u ", + ((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.%06u - 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.%06u - 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) +{ + 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 */ + layer1(l1buf, buf); + break; + + case TRC_CH_D: /* D-channel data */ + cnt = layer2(l2buf, buf, hdr->dir, print_q921); + + n -= cnt; + buf += cnt; + + if(n) + layer3(l3buf, n, cnt, buf); + 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); + } + } +} + +/*---------------------------------------------------------------------------* + * decode extension bit + *---------------------------------------------------------------------------*/ +void +extension(int layer, char *buffer, int cnt, unsigned char value, unsigned char mask) +{ + sprintline(layer, buffer, cnt, value, mask, "Extension Bit = %c (%s)", + (value & mask) ? '1' : '0', + (value & mask) ? "no extension, final octet" : "with extension, octet follows"); +} + +/*---------------------------------------------------------------------------* + * print bits as 0/1 available for mask + *---------------------------------------------------------------------------*/ +static char * +print_bits(unsigned char val, unsigned char mask) +{ + static char buffer[10]; + int i = 0; + int length = 8; + + while(length--) + { + if(mask & 0x80) + { + if(val & 0x80) + buffer[i++] = '1'; + else + buffer[i++] = '0'; + } + else + { + buffer[i++] = '-'; + } + val = val << 1; + mask = mask << 1; + } + buffer[i] = '\0'; + return(buffer); +} + +/*---------------------------------------------------------------------------* + * print one decoded output line + *---------------------------------------------------------------------------*/ +void +sprintline(int layer, char *buffer, int oct_count, int oct_val, + int oct_mask, const char *fmt, ...) +{ + char lbuffer[256]; + static int lastcount = -1; + char *ptr; + va_list ap; + + va_start(ap, fmt); + + if(oct_count != lastcount) + { + lastcount = oct_count; + + sprintf(lbuffer, "L%d %2d %02X %s ", + layer, + oct_count, + oct_val, + print_bits(oct_val, oct_mask)); + } + else + { + sprintf(lbuffer, " %s ", + print_bits(oct_val, oct_mask)); + } + + vsprintf(lbuffer+strlen(lbuffer), fmt, ap); + + va_end(ap); + + sprintf(lbuffer+strlen(lbuffer), "\n"); + + if((ptr = rindex(lbuffer, '(')) != NULL) + { + char *s = lbuffer; + char *b = buffer; + int len = strlen(lbuffer); + int i; + + for(s = lbuffer; s < ptr; *b++ = *s++) + ; + for(i = 0;(i+len) <= NCOLS; *b++ = ' ', i++) + ; + for(; *s; *b++ = *s++) + ; + *b = '\0'; + } + else + { + strcpy(buffer, lbuffer); + } +} + +/*---------------------------------------------------------------------------* + * usage intructions + *---------------------------------------------------------------------------*/ +void +usage(void) +{ + fprintf(stderr,"\n"); + fprintf(stderr,"isdndecode - isdn4bsd package ISDN decoder for passive cards (%02d.%02d)\n", VERSION, REL); + fprintf(stderr,"usage: isdntrace -a -b -d -f <file> -h -i -l -n <val> -o -p <file> -r -u <unit>\n"); + fprintf(stderr," -B -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", DECODE_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," -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," -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," -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); +} + +/* EOF */ diff --git a/usr.sbin/i4b/isdndecode/pcause.c b/usr.sbin/i4b/isdndecode/pcause.c new file mode 100644 index 0000000..9c5535e --- /dev/null +++ b/usr.sbin/i4b/isdndecode/pcause.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. + * + *--------------------------------------------------------------------------- + * + * pcause.c - printing cause values + * -------------------------------- + * + * $Id: pcause.c,v 1.3 1998/12/23 10:03:55 hm Exp $ + * + * last edit-date: [Wed Dec 23 10:59:54 1998] + * + *---------------------------------------------------------------------------*/ + +#include "decode.h" +#include "pcause.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/isdndecode/pcause.h b/usr.sbin/i4b/isdndecode/pcause.h new file mode 100644 index 0000000..6b6627b --- /dev/null +++ b/usr.sbin/i4b/isdndecode/pcause.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. + * + *--------------------------------------------------------------------------- + * + * pcause.h - Q.850 causes definitions + * ----------------------------------- + * + * $Id: pcause.h,v 1.2 1998/12/18 17:09:38 hm Exp $ + * + * last edit-date: [Fri Dec 18 18:13:23 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 */ |