2 * Copyright (c) 1997, 2001 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 * q931.c - print Q.931 traces
28 * ---------------------------
30 * $FreeBSD: src/usr.sbin/i4b/isdntrace/q931.c,v 1.6.2.2 2001/12/10 09:34:39 hm Exp $
31 * $DragonFly: src/usr.sbin/i4b/isdntrace/q931.c,v 1.3 2007/05/13 18:33:59 swildner Exp $
33 * last edit-date: [Mon Dec 10 10:32:33 2001]
35 *---------------------------------------------------------------------------*/
39 /*---------------------------------------------------------------------------*
40 * decode Q.931 protocol
41 *---------------------------------------------------------------------------*/
43 decode_q931(char *pbuf, int n, int off, unsigned char *buf, int raw)
61 for (i = 0; i < n; i += 16)
63 sprintf((pbuf+strlen(pbuf)),"Dump:%.3d ", i+off);
64 for (j = 0; j < 16; j++)
66 sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
68 sprintf((pbuf+strlen(pbuf))," ");
69 sprintf((pbuf+strlen(pbuf))," ");
70 for (j = 0; j < 16 && i + j < n; j++)
71 if (isprint(buf[i + j]))
72 sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
74 sprintf((pbuf+strlen(pbuf)),".");
75 sprintf((pbuf+strlen(pbuf)),"\n");
81 sprintf((pbuf+strlen(pbuf)), "Q931: ");
83 /* protocol discriminator */
87 if(pd >= 0x00 && pd <= 0x07)
88 sprintf((pbuf+strlen(pbuf)), "pd=User-User (0x%02x)\n",pd);
90 sprintf((pbuf+strlen(pbuf)), "pd=Q.931/I.451, ");
91 else if(pd >= 0x10 && pd <= 0x3f)
92 sprintf((pbuf+strlen(pbuf)), "pd=Other Layer 3 or X.25 (0x%02x)\n",pd);
93 else if(pd >= 0x40 && pd <= 0x4f)
94 sprintf((pbuf+strlen(pbuf)), "pd=National Use (0x%02x)\n",pd);
95 else if(pd >= 0x50 && pd <= 0xfe)
96 sprintf((pbuf+strlen(pbuf)), "pd=Other Layer 3 or X.25 (0x%02x)\n",pd);
98 sprintf((pbuf+strlen(pbuf)), "pd=Reserved (0x%02x)\n",pd);
109 sprintf((pbuf+strlen(pbuf)), "cr=Dummy, ");
112 sprintf((pbuf+strlen(pbuf)), "cr=0x%02x %s, ", (buf[i+1] & 0x7f), (buf[i+1] & 0x80) ? "(from destination)" : "(from origination)");
115 sprintf((pbuf+strlen(pbuf)), "cr=0x%02x 0x%02x %s, ", (buf[i+1] & 0x7f), (buf[i+2] & 0x7f), (buf[i+1] & 0x80) ? "(org)" : "(dst)");
123 sprintf((pbuf+strlen(pbuf)), "message=");
127 /* escape to nationally specific message type */
130 sprintf((pbuf+strlen(pbuf)), "ESCAPE: ");
133 /* call establishment */
136 sprintf((pbuf+strlen(pbuf)), "ALERTING: ");
139 sprintf((pbuf+strlen(pbuf)), "CALL PROCEEDING: ");
142 sprintf((pbuf+strlen(pbuf)), "PROGRESS: ");
145 sprintf((pbuf+strlen(pbuf)), "SETUP: ");
148 sprintf((pbuf+strlen(pbuf)), "CONNECT: ");
151 sprintf((pbuf+strlen(pbuf)), "SETUP ACKNOWLEDGE: ");
154 sprintf((pbuf+strlen(pbuf)), "CONNECT ACKNOWLEDGE: ");
157 /* call information phase */
160 sprintf((pbuf+strlen(pbuf)), "USER INFORMATION: ");
163 sprintf((pbuf+strlen(pbuf)), "SUSPEND REJECT: ");
166 sprintf((pbuf+strlen(pbuf)), "RESUME REJECT: ");
169 sprintf((pbuf+strlen(pbuf)), "HOLD: ");
172 sprintf((pbuf+strlen(pbuf)), "SUSPEND: ");
175 sprintf((pbuf+strlen(pbuf)), "RESUME: ");
178 sprintf((pbuf+strlen(pbuf)), "HOLD ACKNOWLEDGE: ");
181 sprintf((pbuf+strlen(pbuf)), "SUSPEND ACKNOWLEDGE: ");
184 sprintf((pbuf+strlen(pbuf)), "RESUME ACKNOWLEDGE: ");
187 sprintf((pbuf+strlen(pbuf)), "HOLD REJECT (Q.932): ");
190 sprintf((pbuf+strlen(pbuf)), "RETRIEVE (Q.932): ");
193 sprintf((pbuf+strlen(pbuf)), "RETRIEVE ACKNOWLEDGE (Q.932): ");
196 sprintf((pbuf+strlen(pbuf)), "RETRIEVE REJECT (Q.932): ");
202 sprintf((pbuf+strlen(pbuf)), "DETACH: ");
205 sprintf((pbuf+strlen(pbuf)), "DISCONNECT: ");
208 sprintf((pbuf+strlen(pbuf)), "RESTART: ");
211 sprintf((pbuf+strlen(pbuf)), "DETACH ACKNOWLEDGE: ");
214 sprintf((pbuf+strlen(pbuf)), "RELEASE: ");
217 sprintf((pbuf+strlen(pbuf)), "RESTART ACKNOWLEDGE: ");
220 sprintf((pbuf+strlen(pbuf)), "RELEASE COMPLETE: ");
226 sprintf((pbuf+strlen(pbuf)), "SEGMENT: ");
229 sprintf((pbuf+strlen(pbuf)), "FACILITY (Q.932): ");
232 sprintf((pbuf+strlen(pbuf)), "REGISTER (Q.932): ");
235 sprintf((pbuf+strlen(pbuf)), "CANCEL ACKNOWLEDGE: ");
238 sprintf((pbuf+strlen(pbuf)), "FACILITY ACKNOWLEDGE: ");
241 sprintf((pbuf+strlen(pbuf)), "REGISTER ACKNOWLEDGE: ");
244 sprintf((pbuf+strlen(pbuf)), "NOTIFY: ");
247 sprintf((pbuf+strlen(pbuf)), "CANCEL REJECT: ");
250 sprintf((pbuf+strlen(pbuf)), "FACILITY REJECT: ");
253 sprintf((pbuf+strlen(pbuf)), "REGISTER REJECT: ");
256 sprintf((pbuf+strlen(pbuf)), "STATUS ENQIRY: ");
259 sprintf((pbuf+strlen(pbuf)), "CONGESTION CONTROL: ");
262 sprintf((pbuf+strlen(pbuf)), "INFORMATION: ");
265 sprintf((pbuf+strlen(pbuf)), "STATUS: ");
268 sprintf((pbuf+strlen(pbuf)), "UNDEFINED, TYPE=0x%02x, ", buf[i]);
272 /* other information elements */
278 sprintf((pbuf+strlen(pbuf)), "\n ");
282 /* single octett info element */
284 switch(buf[i] & 0x70)
286 case 0x00: /* reserved */
287 sprintf((pbuf+strlen(pbuf)), "[reserved single octett info]");
290 case 0x10: /* shift */
291 oldcodeset = codeset;
292 codeset = buf[i] & 0x07;
297 sprintf((pbuf+strlen(pbuf)), "[shift: codeset=%d lock=%d]", codeset, codelock);
300 case 0x20: /* more data */
302 sprintf((pbuf+strlen(pbuf)), "[sending complete]");
304 sprintf((pbuf+strlen(pbuf)), "[more data]");
307 case 0x30: /* congestion level */
308 sprintf((pbuf+strlen(pbuf)), "[congestion level=");
309 switch(buf[i] & 0x0f)
312 sprintf((pbuf+strlen(pbuf)), "rx-ready]");
315 sprintf((pbuf+strlen(pbuf)), "rx-not-ready]");
318 sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)]", buf[i] & 0x0f);
323 case 0x50: /* repeat ind */
324 sprintf((pbuf+strlen(pbuf)), "[repeat indicator]");
328 sprintf((pbuf+strlen(pbuf)), "[UNKNOWN SINGLE OCTET ELEMENT 0x%02x]", buf[i]);
337 /* variable length info element */
344 sprintf((pbuf+strlen(pbuf)), "[segmented message: ");
347 sprintf((pbuf+strlen(pbuf)), "[bearer capability: ");
348 i += p_q931bc(pbuf, &buf[i]);
352 sprintf((pbuf+strlen(pbuf)), "[cause: ");
353 i += p_q931cause(pbuf, &buf[i]);
357 sprintf((pbuf+strlen(pbuf)), "[connected address (old): ");
360 sprintf((pbuf+strlen(pbuf)), "[extended facility (Q.932: )");
363 sprintf((pbuf+strlen(pbuf)), "[call identity: ");
366 sprintf((pbuf+strlen(pbuf)), "[call state: ");
370 sprintf((pbuf+strlen(pbuf)), "Std=");
371 switch((buf[i] & 0x60) >> 5)
374 sprintf((pbuf+strlen(pbuf)), "CCITT");
377 sprintf((pbuf+strlen(pbuf)), "ISO/IEC");
380 sprintf((pbuf+strlen(pbuf)), "National");
383 sprintf((pbuf+strlen(pbuf)), "Special");
386 sprintf((pbuf+strlen(pbuf)), ", State=");
388 switch((buf[i] & 0x3f))
391 sprintf((pbuf+strlen(pbuf)), "Null");
394 sprintf((pbuf+strlen(pbuf)), "Call initiated");
397 sprintf((pbuf+strlen(pbuf)), "Overlap sending");
400 sprintf((pbuf+strlen(pbuf)), "Outgoing call proceeding");
403 sprintf((pbuf+strlen(pbuf)), "Call delivered");
406 sprintf((pbuf+strlen(pbuf)), "Call present");
409 sprintf((pbuf+strlen(pbuf)), "Call received");
412 sprintf((pbuf+strlen(pbuf)), "Connect request");
415 sprintf((pbuf+strlen(pbuf)), "Incoming call proceeding");
418 sprintf((pbuf+strlen(pbuf)), "Active");
421 sprintf((pbuf+strlen(pbuf)), "Disconnect request");
424 sprintf((pbuf+strlen(pbuf)), "Disconnect indication");
427 sprintf((pbuf+strlen(pbuf)), "Suspend request");
430 sprintf((pbuf+strlen(pbuf)), "Resume request");
433 sprintf((pbuf+strlen(pbuf)), "Release request");
436 sprintf((pbuf+strlen(pbuf)), "Call abort");
439 sprintf((pbuf+strlen(pbuf)), "Overlap receiving");
442 sprintf((pbuf+strlen(pbuf)), "Restart request");
445 sprintf((pbuf+strlen(pbuf)), "Restart");
448 sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved");
451 sprintf((pbuf+strlen(pbuf)), "]");
456 sprintf((pbuf+strlen(pbuf)), "[channel id: channel=");
460 switch(buf[i] & 0x03)
463 sprintf((pbuf+strlen(pbuf)), "no channel");
466 sprintf((pbuf+strlen(pbuf)), "B-1");
469 sprintf((pbuf+strlen(pbuf)), "B-2");
472 sprintf((pbuf+strlen(pbuf)), "any channel");
476 sprintf((pbuf+strlen(pbuf)), " (exclusive)]");
478 sprintf((pbuf+strlen(pbuf)), " (preferred)]");
483 sprintf((pbuf+strlen(pbuf)), "[data link connection id (Q.933): ");
486 i += q932_facility(pbuf, &buf[i]);
490 sprintf((pbuf+strlen(pbuf)), "[progress ind: ");
494 sprintf((pbuf+strlen(pbuf)), "Std=");
495 switch((buf[i] & 0x60) >> 5)
498 sprintf((pbuf+strlen(pbuf)), "CCITT");
501 sprintf((pbuf+strlen(pbuf)), "ISO/IEC");
504 sprintf((pbuf+strlen(pbuf)), "National");
507 sprintf((pbuf+strlen(pbuf)), "Local");
510 sprintf((pbuf+strlen(pbuf)), ", Loc=");
512 switch((buf[i] & 0x0f))
515 sprintf((pbuf+strlen(pbuf)), "User");
518 sprintf((pbuf+strlen(pbuf)), "Private network serving local user");
521 sprintf((pbuf+strlen(pbuf)), "Public network serving local user");
524 sprintf((pbuf+strlen(pbuf)), "Transit network");
527 sprintf((pbuf+strlen(pbuf)), "Public network serving remote user");
530 sprintf((pbuf+strlen(pbuf)), "Private network serving remote user");
533 sprintf((pbuf+strlen(pbuf)), "Network beyond interworking point");
536 sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved");
542 sprintf((pbuf+strlen(pbuf)), "\n Description: ");
544 switch((buf[i] & 0x7f))
547 sprintf((pbuf+strlen(pbuf)), "Call is not end-to-end ISDN");
550 sprintf((pbuf+strlen(pbuf)), "Destination address is non-ISDN");
553 sprintf((pbuf+strlen(pbuf)), "Origination address is non-ISDN");
556 sprintf((pbuf+strlen(pbuf)), "Call has returned to the ISDN");
559 sprintf((pbuf+strlen(pbuf)), "Interworking occurred, Service change");
562 sprintf((pbuf+strlen(pbuf)), "In-band info or appropriate pattern now available");
565 sprintf((pbuf+strlen(pbuf)), "ERROR: undefined/reserved");
568 sprintf((pbuf+strlen(pbuf)), "]");
573 sprintf((pbuf+strlen(pbuf)), "[network specific facilities: ");
576 sprintf((pbuf+strlen(pbuf)), "[terminal capabilities: ");
579 sprintf((pbuf+strlen(pbuf)), "[notification indicator: ");
580 i += p_q931notification(pbuf, &buf[i]);
584 sprintf((pbuf+strlen(pbuf)), "[display: ");
588 for(j = 0; j < len; j++)
590 sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
592 sprintf((pbuf+strlen(pbuf)),"]");
597 sprintf((pbuf+strlen(pbuf)), "[date/time: ");
602 sprintf((pbuf+strlen(pbuf)),"%.2d.%.2d.%.2d",
603 buf[i+2], buf[i+1], buf[i]);
607 sprintf((pbuf+strlen(pbuf))," %.2d", buf[i+3]);
612 sprintf((pbuf+strlen(pbuf)),":%.2d", buf[i+4]);
617 sprintf((pbuf+strlen(pbuf)),":%.2d", buf[i+5]);
620 sprintf((pbuf+strlen(pbuf)),"]");
625 sprintf((pbuf+strlen(pbuf)), "[keypad: ");
629 for(j = 0; j < len; j++)
631 sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
633 sprintf((pbuf+strlen(pbuf)),"]");
638 sprintf((pbuf+strlen(pbuf)), "[keypad echo: ");
641 sprintf((pbuf+strlen(pbuf)), "[information req (Q.932): ");
644 sprintf((pbuf+strlen(pbuf)), "[signal: ");
647 sprintf((pbuf+strlen(pbuf)), "[switchhook: ");
650 sprintf((pbuf+strlen(pbuf)), "[feature activation (Q.932): ");
653 sprintf((pbuf+strlen(pbuf)), "[feature ind (Q.932): ");
656 sprintf((pbuf+strlen(pbuf)), "[service profile id (Q.932): ");
659 sprintf((pbuf+strlen(pbuf)), "[endpoint id (Q.932): ");
662 sprintf((pbuf+strlen(pbuf)), "[information rate: ");
665 sprintf((pbuf+strlen(pbuf)), "[precedence level (Q.955): ");
668 sprintf((pbuf+strlen(pbuf)), "[end-to-end transit delay: ");
671 sprintf((pbuf+strlen(pbuf)), "[transit delay detection and indication: ");
674 sprintf((pbuf+strlen(pbuf)), "[packet layer binary parameters: ");
677 sprintf((pbuf+strlen(pbuf)), "[packet layer window size: ");
680 sprintf((pbuf+strlen(pbuf)), "[packet size: ");
683 sprintf((pbuf+strlen(pbuf)), "[closed user group: ");
686 sprintf((pbuf+strlen(pbuf)), "[link layer core parameters (Q.933): ");
689 sprintf((pbuf+strlen(pbuf)), "[link layer protocol parameters (Q.933): ");
692 sprintf((pbuf+strlen(pbuf)), "[reverse charging information: ");
695 sprintf((pbuf+strlen(pbuf)), "[connected number (Q.951): ");
696 i += p_q931address(pbuf, &buf[i]);
702 sprintf((pbuf+strlen(pbuf)), "[connected subaddress (Q.951): ");
705 sprintf((pbuf+strlen(pbuf)), "[X.213 priority (Q.933): ");
708 sprintf((pbuf+strlen(pbuf)), "[report type (Q.933): ");
711 sprintf((pbuf+strlen(pbuf)), "[link integrity verification (Q.933): ");
714 sprintf((pbuf+strlen(pbuf)), "[PVC status (Q.933): ");
717 sprintf((pbuf+strlen(pbuf)), "[calling party number: ");
718 i += p_q931address(pbuf, &buf[i]);
722 sprintf((pbuf+strlen(pbuf)), "[calling party subaddress: ");
725 sprintf((pbuf+strlen(pbuf)), "[called party number: ");
726 i += p_q931address(pbuf, &buf[i]);
730 sprintf((pbuf+strlen(pbuf)), "[called party subaddress: ");
733 sprintf((pbuf+strlen(pbuf)), "[redirecting number: ");
734 i += p_q931redir(pbuf, &buf[i]);
738 sprintf((pbuf+strlen(pbuf)), "[redirection number: ");
739 i += p_q931redir(pbuf, &buf[i]);
743 sprintf((pbuf+strlen(pbuf)), "[transit network selection: ");
746 sprintf((pbuf+strlen(pbuf)), "[restart indicator: ");
749 sprintf((pbuf+strlen(pbuf)), "[low layer compatibility: ");
752 sprintf((pbuf+strlen(pbuf)), "[high layer compatibility:");
753 i += p_q931high_compat(pbuf, &buf[i]);
757 sprintf((pbuf+strlen(pbuf)), "[user-user: ");
758 i += p_q931user_user(pbuf, &buf[i]);
762 sprintf((pbuf+strlen(pbuf)), "[escape for extension: ");
765 sprintf((pbuf+strlen(pbuf)), "[UNKNOWN INFO-ELEMENT-ID=0x%02x: ", buf[i]);
771 sprintf((pbuf+strlen(pbuf)), "[UNKNOWN CODESET=%d, IE=0x%02x: ", codeset, buf[i]);
774 i++; /* index -> length */
778 sprintf((pbuf+strlen(pbuf)), "LEN=0x%02x, DATA=", len);
780 i++; /* index -> 1st param */
782 for(j = 0; j < len; j++)
784 sprintf((pbuf+strlen(pbuf)),"0x%02x ", buf[j+i]);
787 sprintf((pbuf+strlen(pbuf)),"]");
793 if(!codelock && (codeset != oldcodeset))
794 codeset = oldcodeset;
797 sprintf((pbuf+strlen(pbuf)),"\n");