2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 *---------------------------------------------------------------------------
27 * main.c - isdndecode main program file
28 * -------------------------------------
30 * $Id: main.c,v 1.13 2000/02/21 15:17:17 hm Exp $
32 * $FreeBSD: src/usr.sbin/i4b/isdndecode/main.c,v 1.8.2.1 2001/08/01 17:45:05 obrien Exp $
34 * last edit-date: [Mon Feb 21 16:19:30 2000]
36 *---------------------------------------------------------------------------*/
40 unsigned char buf[BSIZE];
60 int enable_trace = TRACE_D_RX | TRACE_D_TX;
62 static char outfilename[1024];
63 static char BPfilename[1024];
65 static void dumpbuf( int n, unsigned char *buf, i4b_trace_hdr_t *hdr);
66 static int switch_driver( int value, int rx, int tx );
67 static void usage( void );
68 static void exit_hdl( void );
69 static void reopenfiles( int );
72 /*---------------------------------------------------------------------------*
74 *---------------------------------------------------------------------------*/
79 fprintf(stderr,"isdndecode - isdn4bsd package ISDN decoder for passive cards (%d.%d.%d)\n", VERSION, REL, STEP);
80 fprintf(stderr,"usage: isdntrace -a -b -d -f <file> -h -i -l -n <val> -o -p <file> -r -u <unit>\n");
81 fprintf(stderr," -x -B -P -R <unit> -T <unit>\n");
82 fprintf(stderr," -a analyzer mode ................................... (default off)\n");
83 fprintf(stderr," -b switch B channel trace on ....................... (default off)\n");
84 fprintf(stderr," -d switch D channel trace off ....................... (default on)\n");
85 fprintf(stderr," -f <file> write output to file filename ........... (default %s0)\n", DECODE_FILE_NAME);
86 fprintf(stderr," -h don't print header for each message ............. (default off)\n");
87 fprintf(stderr," -i print I.430 (layer 1) INFO signals .............. (default off)\n");
88 fprintf(stderr," -l don't decode low layer Q.921 messages ........... (default off)\n");
89 fprintf(stderr," -o don't write output to a file .................... (default off)\n");
90 fprintf(stderr," -p <file> specify filename for -B and -P ........ (default %s0)\n", BIN_FILE_NAME);
91 fprintf(stderr," -u <unit> specify controller unit number ............... (default unit 0)\n");
92 fprintf(stderr," -x print packets with unknown protocoldiscriminator (default off)\n");
93 fprintf(stderr," -B write binary trace data to file filename ........ (default off)\n");
94 fprintf(stderr," -P playback from binary trace data file ............ (default off)\n");
95 fprintf(stderr," -R <unit> analyze Rx controller unit number (for -a) ... (default unit %d)\n", RxUDEF);
96 fprintf(stderr," -T <unit> analyze Tx controller unit number (for -a) ... (default unit %d)\n", TxUDEF);
101 /*---------------------------------------------------------------------------*
103 *---------------------------------------------------------------------------*/
105 main(int argc, char *argv[])
117 char *outfile = DECODE_FILE_NAME;
118 char *binfile = BIN_FILE_NAME;
122 i4b_trace_hdr_t *ithp = NULL;
125 b = &buf[sizeof(i4b_trace_hdr_t)];
127 while( (c = getopt(argc, argv, "abdf:hiln:op:u:xBPR:T:")) != -1)
136 enable_trace |= (TRACE_B_RX | TRACE_B_TX);
140 enable_trace &= (~(TRACE_D_TX | TRACE_D_RX));
157 enable_trace |= TRACE_I;
172 if(unit < 0 || unit >= MAX_CONTROLLERS)
190 if(Rx < 0 || Rx >= MAX_CONTROLLERS)
196 if(Tx < 0 || Tx >= MAX_CONTROLLERS)
207 if(enable_trace == 0)
218 sprintf(BPfilename, "%s", binfile);
220 sprintf(BPfilename, "%s%d", BIN_FILE_NAME, unit);
222 if((BP = fopen(BPfilename, "r")) != NULL)
226 sprintf(buffer, "%s%s", BPfilename, DECODE_FILE_NAME_BAK);
227 rename(BPfilename, buffer);
229 if((BP = fopen(BPfilename, "w")) == NULL)
233 sprintf(buffer, "Error opening file [%s]", BPfilename);
238 if((setvbuf(BP, (char *)NULL, _IONBF, 0)) != 0)
242 sprintf(buffer, "Error setting file [%s] to unbuffered", BPfilename);
251 sprintf(BPfilename, "%s", binfile);
253 sprintf(BPfilename, "%s%d", BIN_FILE_NAME, unit);
255 if((BP = fopen(BPfilename, "r")) == NULL)
259 sprintf(buffer, "Error opening file [%s]", BPfilename);
266 sprintf(devicename, "%s%d", I4BTRC_DEVICE, unit);
268 if((f = open(devicename, O_RDWR)) < 0)
272 sprintf(buffer, "Error opening trace device [%s]", devicename);
281 sprintf(outfilename, "%s%d", DECODE_FILE_NAME, unit);
283 strcpy(outfilename, outfile);
286 if((Fout = fopen(outfilename, "r")) != NULL)
290 sprintf(buffer, "%s%s", outfilename, DECODE_FILE_NAME_BAK);
291 rename(outfilename, buffer);
294 if((Fout = fopen(outfilename, "w")) == NULL)
298 sprintf(buffer, "Error opening file [%s]", outfilename);
303 if((setvbuf(Fout, (char *)NULL, _IONBF, 0)) != 0)
307 sprintf(buffer, "Error setting file [%s] to unbuffered", outfile);
313 if((setvbuf(stdout, (char *)NULL, _IOLBF, 0)) != 0)
317 sprintf(buffer, "Error setting stdout to line-buffered");
324 if((switch_driver(enable_trace, Rx, Tx)) == -1)
330 signal(SIGHUP, SIG_IGN); /* ignore hangup signal */
331 signal(SIGUSR1, reopenfiles); /* rotate logfile(s) */
337 sprintf(headerbuf, "\n==== isdnanalyze controller rx #%d - tx #%d ==== started %s",
342 sprintf(headerbuf, "\n=========== isdntrace controller #%d =========== started %s",
346 printf("%s", headerbuf);
349 fprintf(Fout, "%s", headerbuf);
355 n = read(f, buf, BSIZE);
359 if((fwrite(buf, 1, n, BP)) != n)
362 sprintf(buffer, "Error writing file [%s]", BPfilename);
368 n -= sizeof(i4b_trace_hdr_t);
372 if((fread(buf, 1, sizeof(i4b_trace_hdr_t), BP)) != sizeof(i4b_trace_hdr_t))
376 printf("\nEnd of playback input file reached.\n");
382 sprintf(buffer, "Error reading hdr from file [%s]", BPfilename);
388 ithp = (i4b_trace_hdr_t *)buf;
389 l = ithp->length - sizeof(i4b_trace_hdr_t);
391 if((n = fread(buf+sizeof(i4b_trace_hdr_t), 1, l , BP)) != l)
394 sprintf(buffer, "Error reading data from file [%s]", BPfilename);
403 dumpbuf(n, b, (i4b_trace_hdr_t *)buf);
408 /*---------------------------------------------------------------------------*
409 * format header into static buffer, return buffer address
410 *---------------------------------------------------------------------------*/
412 fmt_hdr(i4b_trace_hdr_t *hdr, int frm_len)
415 static char hbuf[256];
418 s = localtime((time_t *)&(hdr->time.tv_sec));
420 if(hdr->type == TRC_CH_I) /* Layer 1 INFO's */
422 sprintf(hbuf,"\n-- %s - unit:%d ---------------- time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u ",
423 ((hdr->dir) ? "NT->TE" : "TE->NT"),
430 (u_int32_t)hdr->time.tv_usec);
436 sprintf(hbuf,"\n-- %s - unit:%d - frame:%6.6u - time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u - length:%d (%d) ",
437 ((hdr->dir) ? "NT->TE" : "TE->NT"),
445 (u_int32_t)hdr->time.tv_usec,
451 sprintf(hbuf,"\n-- %s - unit:%d - frame:%6.6u - time:%2.2d.%2.2d %2.2d:%2.2d:%2.2d.%06u - length:%d ",
452 ((hdr->dir) ? "NT->TE" : "TE->NT"),
460 (u_int32_t)hdr->time.tv_usec,
465 for(i=strlen(hbuf); i <= NCOLS;)
474 /*---------------------------------------------------------------------------*
475 * decode protocol and output to file(s)
476 *---------------------------------------------------------------------------*/
478 dumpbuf(int n, unsigned char *buf, i4b_trace_hdr_t *hdr)
480 static char l1buf[128];
481 static unsigned char l2buf[32000];
482 static unsigned char l3buf[32000];
494 case TRC_CH_I: /* Layer 1 INFO's */
495 if(enable_trace & TRACE_I)
499 case TRC_CH_D: /* D-channel data */
500 cnt = layer2(l2buf, buf, hdr->dir, print_q921);
510 if((*buf != 0x08) && (xflag == 0))
516 layer3(l3buf, n, cnt, buf);
520 default: /* B-channel data */
524 for (i = 0; i < n; i += 16)
526 sprintf((pbuf+strlen(pbuf)),"B%d:%.3x ", hdr->type, i);
528 for (j = 0; j < 16; j++)
530 sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
532 sprintf((pbuf+strlen(pbuf))," ");
534 sprintf((pbuf+strlen(pbuf))," ");
536 for (j = 0; j < 16 && i + j < n; j++)
537 if (isprint(buf[i + j]))
538 sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
540 sprintf((pbuf+strlen(pbuf)),".");
542 sprintf((pbuf+strlen(pbuf)),"\n");
547 if(header && ((l1buf[0] != '\0' || l2buf[0] != '\0') || (l3buf[0] != 0)))
550 p = fmt_hdr(hdr, nsave);
553 fprintf(Fout, "%s", p);
560 fprintf(Fout, "%s", l1buf);
567 fprintf(Fout, "%s", l2buf);
574 fprintf(Fout, "%s", l3buf);
578 /*---------------------------------------------------------------------------*
579 * exit handler function to be called at program exit
580 *---------------------------------------------------------------------------*/
585 switch_driver(TRACE_OFF, Rx, Tx);
588 /*---------------------------------------------------------------------------*
589 * switch driver debugging output on/off
590 *---------------------------------------------------------------------------*/
592 switch_driver(int value, int rx, int tx)
599 if(ioctl(f, I4B_TRC_SET, &v) < 0)
601 sprintf(buffer, "Error ioctl I4B_TRC_SET, val = %d", v);
608 if(value == TRACE_OFF)
610 if(ioctl(f, I4B_TRC_RESETA, &v) < 0)
612 sprintf(buffer, "Error ioctl I4B_TRC_RESETA - ");
619 i4b_trace_setupa_t tsa;
626 if(ioctl(f, I4B_TRC_SETA, &tsa) < 0)
628 sprintf(buffer, "Error ioctl I4B_TRC_SETA, val = %d", v);
637 /*---------------------------------------------------------------------------*
638 * reopen files to support rotating logfile(s) on SIGUSR1
640 * based on an idea from Ripley (ripley@nostromo.in-berlin.de)
642 * close file and reopen it for append. this will be a nop
643 * if the previously opened file hasn't moved but will open
644 * a new one otherwise, thus enabling a rotation...
646 *---------------------------------------------------------------------------*/
648 reopenfiles(int dummy)
654 if((Fout = fopen(outfilename, "a")) == NULL)
658 sprintf(buffer, "Error re-opening file [%s]", outfilename);
663 if((setvbuf(Fout, (char *)NULL, _IONBF, 0)) != 0)
667 sprintf(buffer, "Error re-setting file [%s] to unbuffered", outfilename);
678 if((BP = fopen(BPfilename, "a")) == NULL)
682 sprintf(buffer, "Error re-opening file [%s]", BPfilename);
687 if((setvbuf(BP, (char *)NULL, _IONBF, 0)) != 0)
691 sprintf(buffer, "Error re-setting file [%s] to unbuffered", BPfilename);
698 /*---------------------------------------------------------------------------*
699 * decode extension bit
700 *---------------------------------------------------------------------------*/
702 extension(int layer, char *buffer, int cnt, unsigned char value, unsigned char mask)
704 sprintline(layer, buffer, cnt, value, mask, "Extension Bit = %c (%s)",
705 (value & mask) ? '1' : '0',
706 (value & mask) ? "no extension, final octet" : "with extension, octet follows");
709 /*---------------------------------------------------------------------------*
710 * print bits as 0/1 available for mask
711 *---------------------------------------------------------------------------*/
713 print_bits(unsigned char val, unsigned char mask)
715 static char buffer[10];
739 /*---------------------------------------------------------------------------*
740 * print one decoded output line
741 *---------------------------------------------------------------------------*/
743 sprintline(int layer, char *buffer, int oct_count, int oct_val,
744 int oct_mask, const char *fmt, ...)
747 static int lastcount = -1;
753 if(oct_count != lastcount)
755 lastcount = oct_count;
757 sprintf(lbuffer, "L%d %2d %02X %s ",
761 print_bits(oct_val, oct_mask));
765 sprintf(lbuffer, " %s ",
766 print_bits(oct_val, oct_mask));
769 vsprintf(lbuffer+strlen(lbuffer), fmt, ap);
773 sprintf(lbuffer+strlen(lbuffer), "\n");
775 if((ptr = rindex(lbuffer, '(')) != NULL)
779 int len = strlen(lbuffer);
782 for(s = lbuffer; s < ptr; *b++ = *s++)
784 for(i = 0;(i+len) <= NCOLS; *b++ = ' ', i++)
786 for(; *s; *b++ = *s++)
792 strcpy(buffer, lbuffer);