Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.sbin / i4b / isdntrace / q931_util.c
1 /*
2  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      q931_util.c - utility functions to print Q.931 traces
28  *      -----------------------------------------------------
29  *
30  *      $Id: q931_util.c,v 1.11 2000/02/15 12:48:14 hm Exp $ 
31  *
32  * $FreeBSD: src/usr.sbin/i4b/isdntrace/q931_util.c,v 1.6.2.1 2001/08/01 17:45:08 obrien Exp $
33  *
34  *      last edit-date: [Tue Feb 15 13:52:09 2000]
35  *
36  *---------------------------------------------------------------------------*/
37
38 #include "trace.h"
39
40 /*---------------------------------------------------------------------------*
41  *      decode and print the cause
42  *---------------------------------------------------------------------------*/
43 int
44 p_q931cause(char *pbuf, unsigned char *buf)
45 {
46         int j;
47         int len;
48         int i = 0;
49         int ls;
50         int r = 0;
51         int rflag = 0;
52         
53         i++;    /* index -> length */
54
55         len = buf[i];
56
57         i++;    /* coding/location */
58         len--;
59
60         ls = buf[i];
61         
62         i++;
63         len--;
64         
65         if(!(buf[i-1] & 0x80))
66         {
67                 r = buf[i];             
68                 rflag = 1;
69                 i++;
70                 len--;
71         }
72
73         sprintf((pbuf+strlen(pbuf)), "%s ", print_cause_q850(buf[i] & 0x7f));
74
75         sprintf((pbuf+strlen(pbuf)), "\n          (location=");
76         
77         switch(ls & 0x0f)
78         {
79                 case 0x00:
80                         sprintf((pbuf+strlen(pbuf)), "user");
81                         break;
82                 case 0x01:
83                         sprintf((pbuf+strlen(pbuf)), "private network serving local user");
84                         break;
85                 case 0x02:
86                         sprintf((pbuf+strlen(pbuf)), "public network serving local user");
87                         break;
88                 case 0x03:
89                         sprintf((pbuf+strlen(pbuf)), "transit network");
90                         break;
91                 case 0x04:
92                         sprintf((pbuf+strlen(pbuf)), "public network serving remote user");
93                         break;
94                 case 0x05:
95                         sprintf((pbuf+strlen(pbuf)), "private network serving remote user");
96                         break;
97                 case 0x07:
98                         sprintf((pbuf+strlen(pbuf)), "international network");
99                         break;
100                 case 0x0a:
101                         sprintf((pbuf+strlen(pbuf)), "network beyond interworking point");
102                         break;
103                 default:
104                         sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", ls & 0x0f);
105                         break;
106         }
107
108         sprintf((pbuf+strlen(pbuf)), ", std=");
109
110         switch((ls & 0x60) >> 5)
111         {
112                 case 0:
113                         sprintf((pbuf+strlen(pbuf)), "CCITT");
114                         break;
115                 case 1:
116                         sprintf((pbuf+strlen(pbuf)), "ISO/IEC");
117                         break;
118                 case 2:
119                         sprintf((pbuf+strlen(pbuf)), "National");
120                         break;
121                 case 3:
122                         sprintf((pbuf+strlen(pbuf)), "Local");
123                         break;
124         }
125
126         if(rflag)
127         {
128                 sprintf((pbuf+strlen(pbuf)), ", rec=");
129
130                 switch(r & 0x7f)
131                 {
132                         case 0:
133                                 sprintf((pbuf+strlen(pbuf)), "Q.931");
134                                 break;
135                         case 3:
136                                 sprintf((pbuf+strlen(pbuf)), "X.21");
137                                 break;
138                         case 4:
139                                 sprintf((pbuf+strlen(pbuf)), "X.25");
140                                 break;
141                         case 5:
142                                 sprintf((pbuf+strlen(pbuf)), "Q.1031/Q.1051");
143                                 break;
144                         default:
145                                 sprintf((pbuf+strlen(pbuf)), "Reserved");
146                                 break;
147                 }
148         }
149
150         sprintf((pbuf+strlen(pbuf)),")");
151         
152         i++;
153         len--;
154         
155         for(j = 0; j < len; j++)
156                 sprintf((pbuf+strlen(pbuf))," 0x%02x", buf[j+i]);
157         
158         sprintf((pbuf+strlen(pbuf)),"]");
159
160         i += (len+1);
161         
162         return(i);
163 }
164
165 /*---------------------------------------------------------------------------*
166  *      decode and print the bearer capability
167  *---------------------------------------------------------------------------*/
168 int
169 p_q931bc(char *pbuf, unsigned char *buf)
170 {
171         int len;
172         int i = 0;
173         int mr = 0;
174         
175         i++;    /* index -> length */
176
177         len = buf[i];
178
179         i++;
180
181         sprintf((pbuf+strlen(pbuf)), "\n          cap=");
182         
183         switch(buf[i] & 0x1f)
184         {
185                 case 0x00:
186                         sprintf((pbuf+strlen(pbuf)), "speech");
187                         break;
188                 case 0x08:
189                         sprintf((pbuf+strlen(pbuf)), "unrestricted digital information");
190                         break;
191                 case 0x09:
192                         sprintf((pbuf+strlen(pbuf)), "restricted digital information");
193                         break;
194                 case 0x10:
195                         sprintf((pbuf+strlen(pbuf)), "3.1 kHz audio");
196                         break;
197                 case 0x11:
198                         sprintf((pbuf+strlen(pbuf)), "unrestricted digital information with tones");
199                         break;
200                 case 0x18:
201                         sprintf((pbuf+strlen(pbuf)), "video");
202                         break;
203                 default:
204                         sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
205                         break;
206         }
207
208         sprintf((pbuf+strlen(pbuf)), "\n          std=");
209
210         switch((buf[i] & 0x60) >> 5)
211         {
212                 case 0:
213                         sprintf((pbuf+strlen(pbuf)), "CCITT");
214                         break;
215                 case 1:
216                         sprintf((pbuf+strlen(pbuf)), "ISO/IEC");
217                         break;
218                 case 2:
219                         sprintf((pbuf+strlen(pbuf)), "National");
220                         break;
221                 case 3:
222                         sprintf((pbuf+strlen(pbuf)), "NSI Std");
223                         break;
224         }
225
226         i++;
227         len--;
228         
229         sprintf((pbuf+strlen(pbuf)), "\n          rate=");
230         
231         switch(buf[i] & 0x1f)
232         {
233                 case 0x00:
234                         sprintf((pbuf+strlen(pbuf)), "packet mode");
235                         break;
236                 case 0x10:
237                         sprintf((pbuf+strlen(pbuf)), "64 kbit/s");
238                         break;
239                 case 0x11:
240                         sprintf((pbuf+strlen(pbuf)), "2 x 64 kbit/s");
241                         break;
242                 case 0x13:
243                         sprintf((pbuf+strlen(pbuf)), "384 kbit/s");
244                         break;
245                 case 0x15:
246                         sprintf((pbuf+strlen(pbuf)), "1536 kbit/s");
247                         break;
248                 case 0x17:
249                         sprintf((pbuf+strlen(pbuf)), "1920 kbit/s");
250                         break;
251                 case 0x18:
252                         sprintf((pbuf+strlen(pbuf)), "Multirate");
253                         mr = 1;
254                         break;
255                 default:
256                         sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
257                         break;
258         }
259
260         sprintf((pbuf+strlen(pbuf)), "\n          mode=");
261
262         switch((buf[i] & 0x60) >> 5)
263         {
264                 case 0:
265                         sprintf((pbuf+strlen(pbuf)), "circuit");
266                         break;
267                 case 2:
268                         sprintf((pbuf+strlen(pbuf)), "packet");
269                         break;
270                 default:
271                         sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", ((buf[i] & 0x60) >> 5));
272                         break;
273         }
274
275         i++;
276         len--;
277
278         if(!len)
279                 goto exit;
280         
281         if(mr)
282         {
283                 sprintf((pbuf+strlen(pbuf)), "\n          rate multiplier=%d", buf[i] & 0x7f);
284                 i++;
285                 len--;
286         }
287
288         if(!len)
289                 goto exit;
290         
291                         sprintf((pbuf+strlen(pbuf)), "\n          layer1=");
292         
293                         switch(buf[i] & 0x1f)
294                         {
295                                 case 0x01:
296                                         sprintf((pbuf+strlen(pbuf)), "V.110");
297                                         break;
298                                 case 0x02:
299                                         sprintf((pbuf+strlen(pbuf)), "G.711 u-law");
300                                         break;
301                                 case 0x03:
302                                         sprintf((pbuf+strlen(pbuf)), "G.711 A-law");
303                                         break;
304                                 case 0x04:
305                                         sprintf((pbuf+strlen(pbuf)), "G.721");
306                                         break;
307                                 case 0x05:
308                                         sprintf((pbuf+strlen(pbuf)), "H.221/H.242");
309                                         break;
310                                 case 0x07:
311                                         sprintf((pbuf+strlen(pbuf)), "Non-Std");
312                                         break;
313                                 case 0x08:
314                                         sprintf((pbuf+strlen(pbuf)), "V.120");
315                                         break;
316                                 case 0x09:
317                                         sprintf((pbuf+strlen(pbuf)), "X.31");
318                                         break;
319                                 default:
320                                         sprintf((pbuf+strlen(pbuf)), "reserved (0x%02x)", buf[i] & 0x0f);
321                                         break;
322                         }
323                         i++;
324                         len--;
325         
326                 if(!len)
327                         goto exit;
328
329         if(!(buf[i-1] & 0x80))
330                 {
331                         sprintf((pbuf+strlen(pbuf)), "\n          user rate=0x%02x ", buf[i] & 0x1f);
332         
333                         if(buf[i] & 0x40)
334                                 sprintf((pbuf+strlen(pbuf)), "(async,");
335                         else
336                                 sprintf((pbuf+strlen(pbuf)), "(sync,");         
337         
338                         if(buf[i] & 0x20)
339                                 sprintf((pbuf+strlen(pbuf)), "in-band neg. possible)");
340                         else
341                                 sprintf((pbuf+strlen(pbuf)), "in-band neg not possible)");
342                         
343                         i++;
344                         len--;
345                 }
346         
347                 if(!len)
348                         goto exit;
349
350         if(!(buf[i-1] & 0x80))
351                 {
352                         sprintf((pbuf+strlen(pbuf)), "\n          clk/flow=0x%02x", buf[i] & 0x1f);
353         
354                         sprintf((pbuf+strlen(pbuf)), "\n          intermediate rate=");
355                         
356                         switch((buf[i] & 0x60) >> 5)
357                         {
358                                 case 0:
359                                         sprintf((pbuf+strlen(pbuf)), "not used");
360                                         break;
361                                 case 1:
362                                         sprintf((pbuf+strlen(pbuf)), "8 kbit/s");
363                                         break;
364                                 case 2:
365                                         sprintf((pbuf+strlen(pbuf)), "16 kbit/s");
366                                         break;
367                                 case 3:
368                                         sprintf((pbuf+strlen(pbuf)), "32 kbit/s");
369                                         break;
370                         }
371                         i++;
372                         len--;
373                 }
374         
375                 if(!len)
376                         goto exit;
377
378         if(!(buf[i-1] & 0x80))
379                 {
380                         sprintf((pbuf+strlen(pbuf)), "\n          hdr/mfrm/etc.=0x%02x", buf[i]);
381                         i++;
382                         len--;
383                 }
384         
385                 if(!len)
386                         goto exit;
387
388         if(!(buf[i-1] & 0x80))
389                 {
390                         sprintf((pbuf+strlen(pbuf)), "\n          stop/data/parity=0x%02x", buf[i]);
391                         i++;
392                         len--;
393                 }
394         
395                 if(!len)
396                         goto exit;
397
398         if(!(buf[i-1] & 0x80))
399                 {
400                         sprintf((pbuf+strlen(pbuf)), "\n          modemtype=0x%02x", buf[i]);
401                         i++;
402                         len--;
403                 }
404
405         if(!len)
406                 goto exit;
407
408                 switch(buf[i] & 0x7f)
409                 {
410                         case 0x42:
411                                 sprintf((pbuf+strlen(pbuf)), "\n          layer2=Q.921/I.441");
412                                 break;
413                         case 0x46:
414                                 sprintf((pbuf+strlen(pbuf)), "\n          layer2=X.25 link");
415                                 break;
416                         default:
417                                 sprintf((pbuf+strlen(pbuf)), "\n          layer2=0x%02x",(buf[i] & 0x7f));
418                                 break;
419                 }
420                 i++;
421                 len--;
422
423         if(!len)
424                 goto exit;
425         
426                 switch(buf[i] & 0x7f)
427                 {
428                         case 0x62:
429                                 sprintf((pbuf+strlen(pbuf)), "\n          layer3=Q.921/I.441");
430                                 break;
431                         case 0x66:
432                                 sprintf((pbuf+strlen(pbuf)), "\n          layer3=X.25 packet");
433                                 break;
434                         default:
435                                 sprintf((pbuf+strlen(pbuf)), "\n          layer3=0x%02x",(buf[i] & 0x7f));
436                                 break;
437                 }
438                 i++;
439                 len--;
440
441 exit:   
442         sprintf((pbuf+strlen(pbuf)), "]");      
443         return(i);
444 }
445
446 /*---------------------------------------------------------------------------*
447  *      decode and print the ISDN (telephone) number
448  *---------------------------------------------------------------------------*/
449 int
450 p_q931address(char *pbuf, unsigned char *buf)
451 {
452         int j;
453         int len;
454         int i = 0;
455         int tp;
456         int ind = 0;
457         int indflag = 0;
458         
459         i++;    /* index -> length */
460         len = buf[i];
461
462         i++;    /* index -> type/plan */
463         tp = buf[i];
464         
465         i++;
466         len--;
467         
468         if(!(tp & 0x80))
469         {
470                 ind = buf[i];           
471                 indflag = 1;
472                 i++;
473                 len--;
474         }
475
476         for(j = 0; j < len; j++)
477         {
478                 sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
479         }
480
481         switch((tp & 0x70) >> 4)
482         {
483                 case 0:
484                         sprintf((pbuf+strlen(pbuf)), " (type=unknown, ");
485                         break;
486                 case 1:
487                         sprintf((pbuf+strlen(pbuf)), " (type=international, ");
488                         break;
489                 case 2:
490                         sprintf((pbuf+strlen(pbuf)), " (type=national, ");
491                         break;
492                 case 3:
493                         sprintf((pbuf+strlen(pbuf)), " (type=network specific, ");
494                         break;
495                 case 4:
496                         sprintf((pbuf+strlen(pbuf)), " (type=subscriber, ");
497                         break;
498                 case 6:
499                         sprintf((pbuf+strlen(pbuf)), " (type=abbreviated, ");
500                         break;
501                 default:
502                         sprintf((pbuf+strlen(pbuf)), " (type=reserved (%d), ", ((tp & 0x70) >> 4));
503                         break;
504         }
505
506         switch(tp & 0x0f)
507         {
508                 case 0:
509                         sprintf((pbuf+strlen(pbuf)), "plan=unknown");
510                         break;
511                 case 1:
512                         sprintf((pbuf+strlen(pbuf)), "plan=ISDN");
513                         break;
514                 case 3:
515                         sprintf((pbuf+strlen(pbuf)), "plan=Data");
516                         break;
517                 case 4:
518                         sprintf((pbuf+strlen(pbuf)), "plan=Telex");
519                         break;
520                 case 8:
521                         sprintf((pbuf+strlen(pbuf)), "plan=National");
522                         break;
523                 case 9:
524                         sprintf((pbuf+strlen(pbuf)), "plan=private");
525                         break;
526                 default:
527                         sprintf((pbuf+strlen(pbuf)), "plan=reserved (%d)", (tp & 0x0f));
528                         break;
529         }
530
531         if(indflag)
532         {
533                 sprintf((pbuf+strlen(pbuf)), ",\n          ");
534                 switch((ind & 0x60) >> 5)
535                 {
536                         case 0:
537                                 sprintf((pbuf+strlen(pbuf)), "presentation allowed, ");
538                                 break;
539                         case 1:
540                                 sprintf((pbuf+strlen(pbuf)), "presentation restricted, ");
541                                 break;
542                         case 2:
543                                 sprintf((pbuf+strlen(pbuf)), "number not available, ");
544                                 break;
545                         case 3:
546                                 sprintf((pbuf+strlen(pbuf)), "reserved, ");
547                                 break;
548                 }
549
550                 switch(ind & 0x03)
551                 {
552                         case 0:
553                                 sprintf((pbuf+strlen(pbuf)), "screening user provided: not screened");
554                                 break;
555                         case 1:
556                                 sprintf((pbuf+strlen(pbuf)), "screening user provided: verified & passed");
557                                 break;
558                         case 2:
559                                 sprintf((pbuf+strlen(pbuf)), "screening user provided: verified & failed");
560                                 break;
561                         case 3:
562                                 sprintf((pbuf+strlen(pbuf)), "screening network provided");
563                                 break;
564                 }
565         }               
566
567         sprintf((pbuf+strlen(pbuf)),")]");
568
569         i += j;
570
571         return(i);
572 }
573
574 /*---------------------------------------------------------------------------*
575  *      decode and print HL comatibility
576  *---------------------------------------------------------------------------*/
577 int
578 p_q931high_compat(char *pbuf, unsigned char *buf)
579 {
580         int len = buf[1];
581
582         sprintf(pbuf+strlen(pbuf), " standard=");
583
584         switch ((buf[2] >> 5) & 0x03)
585         {
586                 case 0: sprintf(pbuf+strlen(pbuf), "CCITT");
587                         break;
588                 case 1: sprintf(pbuf+strlen(pbuf), "unknown international standard");
589                         break;
590                 case 2: sprintf(pbuf+strlen(pbuf), "unknown national standard");
591                         break;
592                 case 3: sprintf(pbuf+strlen(pbuf), "local network standard");
593         }
594
595         len--;
596
597         sprintf(pbuf+strlen(pbuf), ", characteristics=");
598
599         switch (buf[3] & 0x7f)
600         {
601                 case 0x01:
602                         sprintf(pbuf+strlen(pbuf), "Telephony");
603                         break;
604                 case 0x04:
605                         sprintf(pbuf+strlen(pbuf), "Fax Group 2/3");
606                         break;
607                 case 0x21:
608                         sprintf(pbuf+strlen(pbuf), "Fax Group 4 Class I (F.184)");
609                         break;
610                 case 0x24:
611                         sprintf(pbuf+strlen(pbuf), "Teletex basic/mixed (F.230) or Fax Group 4 Class II/III (F.184)");
612                         break;
613                 case 0x28:
614                         sprintf(pbuf+strlen(pbuf), "Teletex basic/processable (F.220)");
615                         break;
616                 case 0x31:
617                         sprintf(pbuf+strlen(pbuf), "Teletex basic mode (F.200)");
618                         break;
619                 case 0x32:
620                         sprintf(pbuf+strlen(pbuf), "Videotex (F.300 and T.101)");
621                         break;
622                 case 0x35:
623                         sprintf(pbuf+strlen(pbuf), "Telex (F.60)");
624                         break;
625                 case 0x38:
626                         sprintf(pbuf+strlen(pbuf), "MHS (X.400 series)");
627                         break;
628                 case 0x41:
629                         sprintf(pbuf+strlen(pbuf), "OSI application (X.200 series)");
630                         break;
631                 case 0x5e:
632                         sprintf(pbuf+strlen(pbuf), "Maintenance");
633                         break;
634                 case 0x5f:
635                         sprintf(pbuf+strlen(pbuf), "Management");
636                         break;
637                 case 0x7f:
638                         sprintf(pbuf+strlen(pbuf), "reserved");
639                         break;
640                 default:
641                         sprintf(pbuf+strlen(pbuf), "UNKNOWN (0x%02x)", buf[3]);
642                         break;
643         }
644
645         len--;
646
647         if (!len)
648         {
649                 sprintf(pbuf+strlen(pbuf), "]");
650                 return 4;
651         }
652         
653         sprintf(pbuf+strlen(pbuf), " of ");
654
655         switch (buf[4] & 0x7f)
656         {
657                 case 0x01:
658                         sprintf(pbuf+strlen(pbuf), "Telephony");
659                         break;
660                 case 0x04:
661                         sprintf(pbuf+strlen(pbuf), "Fax Group 2/3");
662                         break;
663                 case 0x21:
664                         sprintf(pbuf+strlen(pbuf), "Fax Group 4 Class I (F.184)");
665                         break;
666                 case 0x24:
667                         sprintf(pbuf+strlen(pbuf), "Teletex basic/mixed (F.230) or Fax Group 4 Class II/III (F.184)");
668                         break;
669                 case 0x28:
670                         sprintf(pbuf+strlen(pbuf), "Teletex basic/processable (F.220)");
671                         break;
672                 case 0x31:
673                         sprintf(pbuf+strlen(pbuf), "Teletex basic mode (F.200)");
674                         break;
675                 case 0x32:
676                         sprintf(pbuf+strlen(pbuf), "Videotex (F.300 and T.101)");
677                         break;
678                 case 0x35:
679                         sprintf(pbuf+strlen(pbuf), "Telex (F.60)");
680                         break;
681                 case 0x38:
682                         sprintf(pbuf+strlen(pbuf), "MHS (X.400 series)");
683                         break;
684                 case 0x41:
685                         sprintf(pbuf+strlen(pbuf), "OSI application (X.200 series)");
686                         break;
687                 case 0x7f:
688                         sprintf(pbuf+strlen(pbuf), "reserved");
689                         break;
690                 default:
691                         sprintf(pbuf+strlen(pbuf), "UNKNOWN (0x%02x)", buf[3]);
692                         break;
693         }
694         sprintf(pbuf+strlen(pbuf), "]");
695         return 5;
696 }
697
698 /*---------------------------------------------------------------------------*
699  *      decode and print user-user IE
700  *---------------------------------------------------------------------------*/
701 int
702 p_q931user_user(char *pbuf, unsigned char *buf)
703 {
704         int j;
705         int len;
706         int i = 0;
707         int pd;
708         
709         i++;    /* index -> length */
710         len = buf[i];
711
712         i++;    /* index -> protocoldiscriminator */
713         pd = buf[i];
714         
715         switch(pd)
716         {
717                 case 0:
718                         sprintf((pbuf+strlen(pbuf)), "(pd=user-specific");
719                         break;
720                 case 1:
721                         sprintf((pbuf+strlen(pbuf)), "(pd=OSI high-layer protocols");
722                         break;
723                 case 2:
724                         sprintf((pbuf+strlen(pbuf)), "(pd=X.244");
725                         break;
726                 case 3:
727                         sprintf((pbuf+strlen(pbuf)), "(pd=reserved for system management");
728                         break;
729                 case 4:
730                         sprintf((pbuf+strlen(pbuf)), "(pd=IA5 characters");
731                         break;
732                 case 6:
733                         sprintf((pbuf+strlen(pbuf)), "(pd=X.208/X.209 coded user info");
734                         break;
735                 case 7:
736                         sprintf((pbuf+strlen(pbuf)), "(pd=V.120 rate adaption");
737                         break;
738                 case 8:
739                         sprintf((pbuf+strlen(pbuf)), "(pd=Q.931/I.451 user network call control messages");
740                         break;
741                 default:
742                         if(pd >= 0x10 && pd <= 0x3f)
743                                 sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=reserved for other L3 protocols incl. X.25", pd);
744                         else if(pd >= 0x40 && pd <= 0x47)
745                                 sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=national use", pd);
746                         else if(pd >= 0x48 && pd <= 0x4f)
747                                 sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=reserved for ETSI", pd);
748                         else if(pd >= 0x50 && pd <= 0xfe)
749                                 sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=reserved for other L3 protocols incl. X.25", pd);
750                         else
751                                 sprintf((pbuf+strlen(pbuf)), "(pd=0x%x=reserved", pd);
752                         break;
753         }
754
755         i++;
756         len--;
757
758         sprintf((pbuf+strlen(pbuf)),": (");
759         
760         for(j = 0; j < len; j++)
761         {
762                 if(pd == 4)
763                         sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
764                 else
765                         sprintf((pbuf+strlen(pbuf)),"0x%2x", buf[j+i]);
766         }
767
768         sprintf((pbuf+strlen(pbuf)),"))]");
769
770         i += j;
771
772         return(i);
773 }
774
775 /*---------------------------------------------------------------------------*
776  *      decode and notification indicator IE (Q.932, p44)
777  *---------------------------------------------------------------------------*/
778 int
779 p_q931notification(char *pbuf, unsigned char *buf)
780 {
781         int j = 0;
782         int len;
783         int i = 0;
784         int nd;
785         
786         i++;    /* index -> length */
787         len = buf[i];
788
789         i++;    /* index -> notification description */
790         nd = buf[i];
791         
792         switch(nd)
793         {
794                 case 0x80:
795                         sprintf((pbuf+strlen(pbuf)), "0x%2x, user suspended", nd);
796                         break;
797                 case 0x81:
798                         sprintf((pbuf+strlen(pbuf)), "0x%2x, user resumed", nd);
799                         break;
800                 case 0x82:
801                         sprintf((pbuf+strlen(pbuf)), "0x%2x, bearer service changed", nd);
802                         break;
803
804                 case 0x83:
805                         sprintf((pbuf+strlen(pbuf)), "0x%2x, BER coded information", nd);
806                         break;
807
808                 case 0xc2:
809                         sprintf((pbuf+strlen(pbuf)), "0x%2x, conference established", nd);
810                         break;
811                 case 0xc3:
812                         sprintf((pbuf+strlen(pbuf)), "0x%2x, conference disconnected", nd);
813                         break;
814                 case 0xc4:
815                         sprintf((pbuf+strlen(pbuf)), "0x%2x, other party added", nd);
816                         break;
817                 case 0xc5:
818                         sprintf((pbuf+strlen(pbuf)), "0x%2x, isolated", nd);
819                         break;
820                 case 0xc6:
821                         sprintf((pbuf+strlen(pbuf)), "0x%2x, reattached", nd);
822                         break;
823                 case 0xc7:
824                         sprintf((pbuf+strlen(pbuf)), "0x%2x, other party isolated", nd);
825                         break;
826                 case 0xc8:
827                         sprintf((pbuf+strlen(pbuf)), "0x%2x, other party reattached", nd);
828                         break;
829                 case 0xc9:
830                         sprintf((pbuf+strlen(pbuf)), "0x%2x, other party split", nd);
831                         break;
832                 case 0xca:
833                         sprintf((pbuf+strlen(pbuf)), "0x%2x, other party disconnected", nd);
834                         break;
835                 case 0xcb:
836                         sprintf((pbuf+strlen(pbuf)), "0x%2x, conference floating", nd);
837                         break;
838                 case 0xcc:
839                         sprintf((pbuf+strlen(pbuf)), "0x%2x, conference disconnected, preemption", nd);
840                         break;
841                 case 0xcf:
842                         sprintf((pbuf+strlen(pbuf)), "0x%2x, conference floating, server user preempted", nd);
843                         break;
844
845                 case 0xe0:
846                         sprintf((pbuf+strlen(pbuf)), "0x%2x, call is a waiting call", nd);
847                         break;                  
848                 case 0xe8:
849                         sprintf((pbuf+strlen(pbuf)), "0x%2x, diversion activated", nd);
850                         break;                  
851                 case 0xe9:      /* ECT, EN 300 369-1 V1.2.4 p12) */
852                         sprintf((pbuf+strlen(pbuf)), "0x%2x, call transferred, alerting", nd);
853                         break;
854                 case 0xea:      /* ECT, EN 300 369-1 V1.2.4 p12) */
855                         sprintf((pbuf+strlen(pbuf)), "0x%2x, call transferred, active", nd);
856                         break;
857                 case 0xee:
858                         sprintf((pbuf+strlen(pbuf)), "0x%2x, reverse charging", nd);
859                         break;
860
861                 case 0xf9:
862                         sprintf((pbuf+strlen(pbuf)), "0x%2x, remote hold", nd);
863                         break;
864                 case 0xfa:
865                         sprintf((pbuf+strlen(pbuf)), "0x%2x, remote retrieval", nd);
866                         break;
867                 case 0xfb:
868                         sprintf((pbuf+strlen(pbuf)), "0x%2x, call is diverting", nd);
869                         break;
870                 default:
871                         sprintf((pbuf+strlen(pbuf)), "0x%2x, undefined", nd);
872                         break;
873         }
874
875         i++;
876         len--;
877
878         if(len)
879         {
880                 sprintf((pbuf+strlen(pbuf)),": (");
881                 
882                 for(; j < len; j++)
883                 {
884                         if(nd == 4)
885                                 sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
886                         else
887                                 sprintf((pbuf+strlen(pbuf)),"0x%2x", buf[j+i]);
888                 }
889         
890                 sprintf((pbuf+strlen(pbuf)),")");
891         }
892         sprintf((pbuf+strlen(pbuf)),"]");
893         i += j;
894
895         return(i);
896 }
897
898 /*---------------------------------------------------------------------------*
899  *      decode and print redirecting/redirection number
900  *---------------------------------------------------------------------------*/
901 int
902 p_q931redir(char *pbuf, unsigned char *buf)
903 {
904         int j;
905         int len;
906         int i = 0;
907         int tp;
908         int ind = 0;
909         int indflag = 0;
910         int reas = 0;
911         int reasflag = 0;
912         
913         i++;    /* index -> length */
914         len = buf[i];
915
916         i++;    /* index -> type/plan */
917         tp = buf[i];
918         
919         i++;
920         len--;
921         
922         if(!(tp & 0x80))
923         {
924                 ind = buf[i];           
925                 indflag = 1;
926                 i++;
927                 len--;
928
929                 if(!(ind & 0x80))
930                 {
931                         reas = buf[i];          
932                         reasflag = 1;
933                         i++;
934                         len--;
935                 }
936         }
937
938         for(j = 0; j < len; j++)
939         {
940                 sprintf((pbuf+strlen(pbuf)),"%c", buf[j+i]);
941         }
942
943         switch((tp & 0x70) >> 4)
944         {
945                 case 0:
946                         sprintf((pbuf+strlen(pbuf)), " (type=unknown, ");
947                         break;
948                 case 1:
949                         sprintf((pbuf+strlen(pbuf)), " (type=international, ");
950                         break;
951                 case 2:
952                         sprintf((pbuf+strlen(pbuf)), " (type=national, ");
953                         break;
954                 case 3:
955                         sprintf((pbuf+strlen(pbuf)), " (type=network specific, ");
956                         break;
957                 case 4:
958                         sprintf((pbuf+strlen(pbuf)), " (type=subscriber, ");
959                         break;
960                 case 6:
961                         sprintf((pbuf+strlen(pbuf)), " (type=abbreviated, ");
962                         break;
963                 default:
964                         sprintf((pbuf+strlen(pbuf)), " (type=reserved (%d), ", ((tp & 0x70) >> 4));
965                         break;
966         }
967
968         switch(tp & 0x0f)
969         {
970                 case 0:
971                         sprintf((pbuf+strlen(pbuf)), "plan=unknown");
972                         break;
973                 case 1:
974                         sprintf((pbuf+strlen(pbuf)), "plan=ISDN");
975                         break;
976                 case 3:
977                         sprintf((pbuf+strlen(pbuf)), "plan=Data");
978                         break;
979                 case 4:
980                         sprintf((pbuf+strlen(pbuf)), "plan=Telex");
981                         break;
982                 case 8:
983                         sprintf((pbuf+strlen(pbuf)), "plan=National");
984                         break;
985                 case 9:
986                         sprintf((pbuf+strlen(pbuf)), "plan=private");
987                         break;
988                 default:
989                         sprintf((pbuf+strlen(pbuf)), "plan=reserved (%d)", (tp & 0x0f));
990                         break;
991         }
992
993         if(indflag)
994         {
995                 sprintf((pbuf+strlen(pbuf)), ",\n          ");
996                 switch((ind & 0x60) >> 5)
997                 {
998                         case 0:
999                                 sprintf((pbuf+strlen(pbuf)), "presentation allowed");
1000                                 break;
1001                         case 1:
1002                                 sprintf((pbuf+strlen(pbuf)), "presentation restricted");
1003                                 break;
1004                         case 2:
1005                                 sprintf((pbuf+strlen(pbuf)), "number not available");
1006                                 break;
1007                         case 3:
1008                                 sprintf((pbuf+strlen(pbuf)), "reserved");
1009                                 break;
1010                 }
1011         }               
1012
1013         if(reasflag)
1014         {
1015                 sprintf((pbuf+strlen(pbuf)), ",\n          ");
1016                 switch(reas & 0x0f)
1017                 {
1018                         case 0:
1019                                 sprintf((pbuf+strlen(pbuf)), "reason for diversion: unknown");
1020                                 break;
1021                         case 1:
1022                                 sprintf((pbuf+strlen(pbuf)), "reason for diversion: call forwarding busy");
1023                                 break;
1024                         case 2:
1025                                 sprintf((pbuf+strlen(pbuf)), "reason for diversion: call forwarding unconditional");
1026                                 break;
1027                         case 0xa:
1028                                 sprintf((pbuf+strlen(pbuf)), "reason for diversion: called DTE");
1029                                 break;
1030                         case 0xf:
1031                                 sprintf((pbuf+strlen(pbuf)), "reason for diversion: call forwarding unconditional");
1032                                 break;
1033                         default:
1034                                 sprintf((pbuf+strlen(pbuf)), "reason for diversion: reserved (0x%2x)",reas & 0x0f);
1035                                 break;
1036                 }
1037         }               
1038
1039         sprintf((pbuf+strlen(pbuf)),")]");
1040
1041         i += j;
1042
1043         return(i);
1044 }
1045
1046 /* EOF */
1047