2 * Copyright (c) 1997, 1999 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 * 1tr6.c - print 1TR6 protocol traces
28 * -----------------------------------
30 * $Id: 1tr6.c,v 1.6 1999/12/13 21:25:26 hm Exp $
32 * $FreeBSD: src/usr.sbin/i4b/isdntrace/1tr6.c,v 1.6.2.1 2001/08/01 17:45:08 obrien Exp $
33 * $DragonFly: src/usr.sbin/i4b/isdntrace/1tr6.c,v 1.2 2003/06/17 04:29:55 dillon Exp $
35 * last edit-date: [Mon Dec 13 21:55:31 1999]
37 *---------------------------------------------------------------------------*/
41 static int p_1tr6address(char *pbuf, unsigned char buf[]);
42 static int p_1tr6cause(char *pbuf, unsigned char buf[]);
44 /*---------------------------------------------------------------------------*
45 * decode the (german) national specific 1TR6 protocol
46 *---------------------------------------------------------------------------*/
48 decode_1tr6(char *pbuf, int n, int off, unsigned char *buf, int raw)
66 for (i = 0; i < n; i += 16)
68 sprintf((pbuf+strlen(pbuf)),"Dump:%.3d ", i+off);
69 for (j = 0; j < 16; j++)
71 sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
73 sprintf((pbuf+strlen(pbuf))," ");
74 sprintf((pbuf+strlen(pbuf))," ");
75 for (j = 0; j < 16 && i + j < n; j++)
76 if (isprint(buf[i + j]))
77 sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
79 sprintf((pbuf+strlen(pbuf)),".");
80 sprintf((pbuf+strlen(pbuf)),"\n");
84 sprintf((pbuf+strlen(pbuf)), "1TR6: ");
86 /* protocol discriminator */
95 sprintf((pbuf+strlen(pbuf)), "pd=N0, ");
98 sprintf((pbuf+strlen(pbuf)), "pd=N1, ");
101 sprintf((pbuf+strlen(pbuf)), "pd=UNDEF (0x%02x), ",pd);
114 sprintf((pbuf+strlen(pbuf)), "cr=0x%02x %s, ", (buf[i+1] & 0x7f), (buf[i+1] & 0x80) ? "(from destination)" : "(from origination)");
117 sprintf((pbuf+strlen(pbuf)), "cr: LEN=%d %s 0x%02x 0x%02x, ", len, (buf[i+1] & 0x80) ? "org" : "dst", (buf[i+1] & 0x7f), (buf[i+2] & 0x7f));
125 sprintf((pbuf+strlen(pbuf)), "message=");
127 if(pd == 0x40) /* protocol discriminator N0 */
132 sprintf((pbuf+strlen(pbuf)), "REGISTER INDICATION: ");
135 sprintf((pbuf+strlen(pbuf)), "CANCEL INDICATION: ");
138 sprintf((pbuf+strlen(pbuf)), "FACILITY STATUS: ");
141 sprintf((pbuf+strlen(pbuf)), "STATUS ACKNOWLEDGE: ");
144 sprintf((pbuf+strlen(pbuf)), "STATUS REJECT: ");
147 sprintf((pbuf+strlen(pbuf)), "FACILITY INFORMATION: ");
150 sprintf((pbuf+strlen(pbuf)), "INFORMATION ACKNOWLEDGE: ");
153 sprintf((pbuf+strlen(pbuf)), "INFORMATION REJECT: ");
156 sprintf((pbuf+strlen(pbuf)), "CLOSE: ");
159 sprintf((pbuf+strlen(pbuf)), "CLOSE ACKNOWLEDGE: ");
162 sprintf((pbuf+strlen(pbuf)), "ERROR: PD=0x40 MSG=0x%02x, ", buf[i]);
171 sprintf((pbuf+strlen(pbuf)), "ESCAPE: ");
174 sprintf((pbuf+strlen(pbuf)), "ALERT: ");
177 sprintf((pbuf+strlen(pbuf)), "CALL SENT: ");
180 sprintf((pbuf+strlen(pbuf)), "CONNECT: ");
183 sprintf((pbuf+strlen(pbuf)), "CONNECT ACKNOWLEDGE: ");
186 sprintf((pbuf+strlen(pbuf)), "SETUP: ");
189 sprintf((pbuf+strlen(pbuf)), "SETUP ACKNOWLEDGE: ");
193 sprintf((pbuf+strlen(pbuf)), "RESUME: ");
196 sprintf((pbuf+strlen(pbuf)), "RESUME ACKNOWLEDGE: ");
199 sprintf((pbuf+strlen(pbuf)), "RESUME REJECT: ");
202 sprintf((pbuf+strlen(pbuf)), "SUSPEND: ");
205 sprintf((pbuf+strlen(pbuf)), "SUSPEND ACKNOWLEDGE: ");
208 sprintf((pbuf+strlen(pbuf)), "SUSPEND REJECT: ");
211 sprintf((pbuf+strlen(pbuf)), "USER INFORMATION: ");
215 sprintf((pbuf+strlen(pbuf)), "DETACH");
218 sprintf((pbuf+strlen(pbuf)), "DISCONNECT: ");
221 sprintf((pbuf+strlen(pbuf)), "RELEASE: ");
224 sprintf((pbuf+strlen(pbuf)), "RELEASE ACKNOWLEDGE");
228 sprintf((pbuf+strlen(pbuf)), "CANCEL ACKNOWLEDGE: ");
231 sprintf((pbuf+strlen(pbuf)), "CANCEL REJECT: ");
234 sprintf((pbuf+strlen(pbuf)), "CONGESTION CONTROL: ");
237 sprintf((pbuf+strlen(pbuf)), "FACILITY: ");
240 sprintf((pbuf+strlen(pbuf)), "FACILITY ACKNOWLEDGE: ");
243 sprintf((pbuf+strlen(pbuf)), "FACILITY CANCEL: ");
246 sprintf((pbuf+strlen(pbuf)), "FACILITY REGISTER: ");
249 sprintf((pbuf+strlen(pbuf)), "FACILITY REJECT: ");
252 sprintf((pbuf+strlen(pbuf)), "INFORMATION: ");
255 sprintf((pbuf+strlen(pbuf)), "REGISTER ACKNOWLEDGE: ");
258 sprintf((pbuf+strlen(pbuf)), "REGISTER REJECT: ");
261 sprintf((pbuf+strlen(pbuf)), "STATUS: ");
265 sprintf((pbuf+strlen(pbuf)), "ERROR: PD=0x41 MSG=0x%02x, ", buf[i]);
271 sprintf((pbuf+strlen(pbuf)), "ERROR: PD=0x%02x MSG=0x%02x, ", pd, buf[i]);
274 /* other information elements */
280 sprintf((pbuf+strlen(pbuf)), "\n ");
284 /* single octett info element */
286 switch(buf[i] & 0x70)
288 case 0x00: /* reserved */
289 sprintf((pbuf+strlen(pbuf)), "[reserved single octett info]");
292 case 0x10: /* shift */
293 oldcodeset = codeset;
294 codeset = buf[i] & 0x07;
299 sprintf((pbuf+strlen(pbuf)), "[shift: codeset=%d lock=%d]", codeset, codelock);
302 case 0x20: /* more data */
303 sprintf((pbuf+strlen(pbuf)), "[more data]");
306 case 0x30: /* congestion level */
307 sprintf((pbuf+strlen(pbuf)), "[congestion level = %d]", buf[i] & 0x0f);
311 sprintf((pbuf+strlen(pbuf)), "[UNDEF SINGLE OCTET ELEMENT 0x%02x]", buf[i]);
320 /* variable length info element */
327 sprintf((pbuf+strlen(pbuf)), "[cause: ");
328 i += p_1tr6cause(pbuf, &buf[i]);
333 sprintf((pbuf+strlen(pbuf)), "[connected address: ");
334 i += p_1tr6address(pbuf, &buf[i]);
339 sprintf((pbuf+strlen(pbuf)), "[call identity: ");
342 sprintf((pbuf+strlen(pbuf)), "[channel id: channel=");
344 switch(buf[i] & 0x03)
347 sprintf((pbuf+strlen(pbuf)), "no channel");
350 sprintf((pbuf+strlen(pbuf)), "B-1");
353 sprintf((pbuf+strlen(pbuf)), "B-2");
356 sprintf((pbuf+strlen(pbuf)), "any channel");
360 sprintf((pbuf+strlen(pbuf)), " (exclusive)]");
362 sprintf((pbuf+strlen(pbuf)), " (preferred)]");
367 sprintf((pbuf+strlen(pbuf)), "[network specific facilities: ");
374 sprintf((pbuf+strlen(pbuf)), "Sperre");
377 sprintf((pbuf+strlen(pbuf)), "AWS 1");
380 sprintf((pbuf+strlen(pbuf)), "AWS 2");
383 sprintf((pbuf+strlen(pbuf)), "Konferenz");
386 sprintf((pbuf+strlen(pbuf)), "B-Kan uebern.");
389 sprintf((pbuf+strlen(pbuf)), "aktvrg. ghlt. Vbdg.");
392 sprintf((pbuf+strlen(pbuf)), "3er Konf");
395 sprintf((pbuf+strlen(pbuf)), "1seitg D/G Wechsel");
398 sprintf((pbuf+strlen(pbuf)), "2seitig D/G Wechsel");
401 sprintf((pbuf+strlen(pbuf)), "Rufnr. identifiz.");
404 sprintf((pbuf+strlen(pbuf)), "GBG");
407 sprintf((pbuf+strlen(pbuf)), "ueberg. Ruf");
410 sprintf((pbuf+strlen(pbuf)), "um/weitergel. Ruf");
413 sprintf((pbuf+strlen(pbuf)), "unterdr. A-Rufnr.");
416 sprintf((pbuf+strlen(pbuf)), "Verbdg. deaktivieren");
419 sprintf((pbuf+strlen(pbuf)), "Verbdg. aktivieren");
422 sprintf((pbuf+strlen(pbuf)), "SPV");
425 sprintf((pbuf+strlen(pbuf)), "Rueckw. 2seitg. DW");
428 sprintf((pbuf+strlen(pbuf)), "Anrufumltg. priv. Netz");
431 sprintf((pbuf+strlen(pbuf)), "undefined");
435 sprintf((pbuf+strlen(pbuf)), ", serv=%d", buf[i]);
437 sprintf((pbuf+strlen(pbuf)), ", ainfo=%d", buf[i]);
440 for(j = 0; j < len; j++)
442 sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
444 sprintf((pbuf+strlen(pbuf)),"]");
449 sprintf((pbuf+strlen(pbuf)), "[display: ");
452 sprintf((pbuf+strlen(pbuf)), "[keypad: ");
455 sprintf((pbuf+strlen(pbuf)), "[origination address: ");
456 i += p_1tr6address(pbuf, &buf[i]);
460 sprintf((pbuf+strlen(pbuf)), "[destination address: ");
461 i += p_1tr6address(pbuf, &buf[i]);
465 sprintf((pbuf+strlen(pbuf)), "[user-user information: ");
468 sprintf((pbuf+strlen(pbuf)), "[reserved: ");
471 sprintf((pbuf+strlen(pbuf)), "[UNKNOWN INFO-ELEMENT-ID");
475 else if(codeset == 6)
480 sprintf((pbuf+strlen(pbuf)), "[service ind: serv=");
485 sprintf((pbuf+strlen(pbuf)), "phone");
488 sprintf((pbuf+strlen(pbuf)), "a/b");
491 sprintf((pbuf+strlen(pbuf)), "X.21");
494 sprintf((pbuf+strlen(pbuf)), "fax g4");
497 sprintf((pbuf+strlen(pbuf)), "btx");
500 sprintf((pbuf+strlen(pbuf)), "64k data");
503 sprintf((pbuf+strlen(pbuf)), "X.25");
506 sprintf((pbuf+strlen(pbuf)), "teletex");
509 sprintf((pbuf+strlen(pbuf)), "mixed");
512 sprintf((pbuf+strlen(pbuf)), "temex");
515 sprintf((pbuf+strlen(pbuf)), "picturephone");
518 sprintf((pbuf+strlen(pbuf)), "btx (new)");
521 sprintf((pbuf+strlen(pbuf)), "videophone");
524 sprintf((pbuf+strlen(pbuf)), "undefined");
528 sprintf((pbuf+strlen(pbuf)), ", ainfo=0x%02x]", buf[i]);
533 sprintf((pbuf+strlen(pbuf)), "[charging information: ");
536 sprintf((pbuf+strlen(pbuf)), "[date: ");
540 for(j = 0; j < len; j++)
542 sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
544 sprintf((pbuf+strlen(pbuf)),"]");
549 sprintf((pbuf+strlen(pbuf)), "[facility select: ");
552 sprintf((pbuf+strlen(pbuf)), "[status of facilities: ");
555 sprintf((pbuf+strlen(pbuf)), "[status of called party: ");
560 sprintf((pbuf+strlen(pbuf)), "no information]");
563 sprintf((pbuf+strlen(pbuf)), "is being called]");
566 sprintf((pbuf+strlen(pbuf)), "undefined (0x%02x)]", buf[i]);
573 sprintf((pbuf+strlen(pbuf)), "[additional tx attributes: ");
577 for(j = 0; j < len; j++)
579 switch(buf[j+i] &0x70)
582 sprintf((pbuf+strlen(pbuf)), "no satellite link");
585 sprintf((pbuf+strlen(pbuf)), "one satellite link");
588 sprintf((pbuf+strlen(pbuf)), "two satellite links");
591 sprintf((pbuf+strlen(pbuf)), "three satellite links");
594 sprintf((pbuf+strlen(pbuf)), "undefined value");
598 sprintf((pbuf+strlen(pbuf)),"(flag=req)]");
600 sprintf((pbuf+strlen(pbuf)),"(flag=ind)]");
606 sprintf((pbuf+strlen(pbuf)), "[UNKNOWN INFO-ELEMENT-ID");
612 sprintf((pbuf+strlen(pbuf)), "[ILLEGAL CODESET = 0x%02x", codeset);
615 i++; /* index -> length */
619 i++; /* index -> 1st param */
621 for(j = 0; j < len; j++)
623 sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
626 sprintf((pbuf+strlen(pbuf)),"]");
632 if(!codelock && (codeset != oldcodeset))
633 codeset = oldcodeset;
636 sprintf((pbuf+strlen(pbuf)),"\n");
639 /*---------------------------------------------------------------------------*
640 * decode and print the cause
641 *---------------------------------------------------------------------------*/
643 p_1tr6cause(char *pbuf, unsigned char buf[])
649 i++; /* index -> length */
656 sprintf((pbuf+strlen(pbuf)), "%s", print_cause_1tr6(0));
660 sprintf((pbuf+strlen(pbuf)), "%s", print_cause_1tr6(buf[i] & 0x7f));
664 sprintf((pbuf+strlen(pbuf)), "%s, location: ", print_cause_1tr6(buf[i] & 0x7f));
666 switch(buf[i] & 0x0f)
669 sprintf((pbuf+strlen(pbuf)), "public network");
672 sprintf((pbuf+strlen(pbuf)), "private network");
675 sprintf((pbuf+strlen(pbuf)), "no information");
678 sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
683 i++; /* index -> length */
685 i++; /* index -> 1st param */
686 for(j = 0; j < len; j++)
688 sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
693 sprintf((pbuf+strlen(pbuf)),"]");
697 /*---------------------------------------------------------------------------*
698 * decode and print the ISDN (telephone) number
699 *---------------------------------------------------------------------------*/
701 p_1tr6address(char *pbuf, unsigned char buf[])
708 i++; /* index -> length */
710 i++; /* index -> 1st param */
716 for(j = 0; j < len; j++)
718 sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
721 switch((tp & 0x70) >> 4)
724 sprintf((pbuf+strlen(pbuf)), " (type=unknown, ");
727 sprintf((pbuf+strlen(pbuf)), " (type=international, ");
730 sprintf((pbuf+strlen(pbuf)), " (type=national, ");
733 sprintf((pbuf+strlen(pbuf)), " (type=%d, ", ((tp & 0x70) >> 4));
740 sprintf((pbuf+strlen(pbuf)), "plan=unknown)");
743 sprintf((pbuf+strlen(pbuf)), "plan=ISDN)");
746 sprintf((pbuf+strlen(pbuf)), "plan=%d)", (tp & 0x0f));
750 sprintf((pbuf+strlen(pbuf)),"]");