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");