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