Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.sbin / i4b / isdntrace / q921.c
1 /*
2  * Copyright (c) 1996 Gary Jennejohn.  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  * 3. Neither the name of the author nor the names of any co-contributors
13  *    may be used to endorse or promote products derived from this software
14  *    without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  *---------------------------------------------------------------------------*
29  *
30  *      q.921.c - print Q.921 traces
31  *      ----------------------------
32  *
33  *      $Id: q921.c,v 1.4 1999/12/13 21:25:26 hm Exp $ 
34  *
35  * $FreeBSD: src/usr.sbin/i4b/isdntrace/q921.c,v 1.6.2.1 2001/08/01 17:45:08 obrien Exp $
36  *
37  *      last edit-date: [Mon Dec 13 21:56:46 1999]
38  *
39  *---------------------------------------------------------------------------*/
40
41 #include "trace.h"
42
43 /*---------------------------------------------------------------------------*
44  *      decode LAPD (Q.921) protocol
45  *---------------------------------------------------------------------------*/
46 int
47 decode_lapd(char *pbuf, int n, unsigned char *buf, int dir, int raw, int printit)
48 {
49         int sap, tei, cmd, p_f;
50         int cnt = 0;
51         int i;
52         char locbuf[32000];
53         char *lbufp = &locbuf[0];
54
55         *lbufp = '\0';
56         *pbuf = '\0';
57         
58         sap = (buf[0] >> 2) & 0x3f;
59         cnt++;
60
61         tei = buf[1] >> 1;
62         cnt++;
63
64         if(dir == FROM_TE)
65                 cmd = !(buf[0] & 2);
66         else
67                 cmd = buf[0] & 2;
68
69         switch (sap)
70         {
71                 /* SAPI control procedures */
72                 case 0:
73                 {
74                         if(printit)
75                                 sprintf((lbufp+strlen(lbufp)), "Q921: SAP=%d (Call Control), %c, TEI=%d, ", sap, cmd?'C':'R', tei);
76
77                         if((buf[2] & 0x01) == 0)
78                         {
79                                 if(printit)
80                                         sprintf((lbufp+strlen(lbufp)), "I-Frame: ");
81
82                                 p_f = buf [3] & 1;
83
84                                 if(printit)
85                                         sprintf((lbufp+strlen(lbufp)), "N(S) %d N(R) %d P %d ", buf [2] >> 1, buf [3] >> 1, p_f);
86
87                                 cnt += 2;
88                         }
89                         else if((buf[2] & 0x03) == 0x01)
90                         {
91                                 if(printit)
92                                         sprintf((lbufp+strlen(lbufp)), "S-Frame: ");
93
94                                 p_f = buf [3] & 1;
95                                 cmd = buf [2] & 0x0c;
96
97                                 if(printit)
98                                 {
99                                         if (cmd == 0)
100                                                 sprintf((lbufp+strlen(lbufp)), "RR N(R) %d PF %d ", buf [3] >> 1, p_f);
101                                         if (cmd == 4)
102                                                 sprintf((lbufp+strlen(lbufp)), "RNR N(R) %d PF %d ", buf [3] >> 1, p_f);
103                                         if (cmd == 8)
104                                                 sprintf((lbufp+strlen(lbufp)), "REJ N(R) %d PF %d ", buf [3] >> 1, p_f);
105                                 }
106                                 cnt += 2;
107                         }
108                         else if((buf[2] & 0x03) == 0x03)
109                         {
110                                 if(printit)
111                                         sprintf((lbufp+strlen(lbufp)), "U-Frame: ");
112
113                                 p_f = (buf [2] & 0x10) >> 4;
114                                 cmd = buf [2] & 0xec;
115
116                                 if(printit)
117                                 {
118                                         if (cmd == 0x6c)
119                                                 sprintf((lbufp+strlen(lbufp)), "SABME PF %d ", p_f);
120                                         if (cmd == 0x0c)
121                                                 sprintf((lbufp+strlen(lbufp)), "DM PF %d ", p_f);
122                                         if (cmd == 0)
123                                                 sprintf((lbufp+strlen(lbufp)), "UI PF %d ", p_f);
124                                         if (cmd == 0x40)
125                                                 sprintf((lbufp+strlen(lbufp)), "DISC PF %d ", p_f);
126                                         if (cmd == 0x60)
127                                                 sprintf((lbufp+strlen(lbufp)), "UA PF %d ", p_f);
128                                         if (cmd == 0x84)
129                                                 sprintf((lbufp+strlen(lbufp)), "FRMR PF %d ", p_f);
130                                         if (cmd == 0xac)
131                                                 sprintf((lbufp+strlen(lbufp)), "XID PF %d ", p_f);
132                                         /* information field ??? */
133                                 }
134                                 cnt++;
135                         }
136                         break;
137                 }
138
139                 /* D channel X.25 */
140                 
141                 case 16:
142                         if(printit)
143                                 sprintf((lbufp+strlen(lbufp)), "Q921: SAP=%d (X.25), %c, TEI=%d, ", sap, cmd?'C':'R', tei);
144                         cnt = n;
145                         goto dump;                              
146
147                 /* Loopback test */
148                 
149                 case 32:
150                         if(printit)
151                                 sprintf((lbufp+strlen(lbufp)), "Q921: SAP=%d (Loopbacktest), %c, TEI=%d, ", sap, cmd?'C':'R', tei);
152                         cnt = n;
153                         goto dump;                              
154
155                 /* SAPI layer 2 management functions */
156
157                 case 63:
158                 {
159                         if(printit)
160                                 sprintf((lbufp+strlen(lbufp)), "Q921: SAP=%d (TEI-Management), %c, TEI=%d, ", sap, cmd?'C':'R', tei);
161
162                         if (tei != 127)
163                         {
164                                 if(printit)
165                                         sprintf((lbufp+strlen(lbufp)), "ILLEGAL TEI\n");
166                                 cnt = n;
167                                 goto dump;                              
168                         }
169
170                         if (buf [2] != 3 && buf [3] != 0xf)
171                         {
172                                 if(printit)
173                                         sprintf((lbufp+strlen(lbufp)), "invalid format!\n");
174                                 cnt = n;
175                                 goto dump;                              
176                         }
177                         cnt+= 2; /* UI + MEI */
178
179                         if(printit)
180                                 sprintf((lbufp+strlen(lbufp)), "Ri=0x%04hx, ", *(short *)&buf[4]);
181                         cnt += 2; /* Ri */
182                         
183                         switch (buf[6])
184                         {
185                                 case 1: 
186                                         if(printit)
187                                                 sprintf((lbufp+strlen(lbufp)), "IdRequest, Ai=%d", (buf [7] >> 1));
188                                         cnt += 2;
189                                         break;
190                                 case 2:
191                                         if(printit)
192                                                 sprintf((lbufp+strlen(lbufp)), "IdAssign, Ai=%d", (buf [7] >> 1));
193                                         cnt += 2;
194                                         break;
195                                 case 3:
196                                         if(printit)
197                                                 sprintf((lbufp+strlen(lbufp)), "IdDenied, Ai=%d", (buf [7] >> 1));
198                                         cnt += 2;
199                                         break;
200                                 case 4:
201                                         if(printit)
202                                                 sprintf((lbufp+strlen(lbufp)), "IdCheckReq, Ai=%d", (buf [7] >> 1));
203                                         cnt += 2;
204                                         break;
205                                 case 5:
206                                         if(printit)
207                                                 sprintf((lbufp+strlen(lbufp)), "IdCheckResp, Ai=%d", (buf [7] >> 1));
208                                         cnt += 2;
209                                         break;
210                                 case 6:
211                                         if(printit)
212                                                 sprintf((lbufp+strlen(lbufp)), "IdRemove, Ai=%d", (buf [7] >> 1));
213                                         cnt += 2;
214                                         break;
215                                 case 7:
216                                         if(printit)
217                                                 sprintf((lbufp+strlen(lbufp)), "IdVerify, Ai=%d", (buf [7] >> 1));
218                                         cnt += 2;
219                                         break;
220                                 default:
221                                         if(printit)
222                                                 sprintf((lbufp+strlen(lbufp)), "Unknown Msg Type\n");
223                                         cnt = n;
224                                         goto dump;                              
225                         }
226                         break;
227                 }
228
229                 /* Illegal SAPI */
230                 
231                 default:
232                         if(printit)
233                                 sprintf((lbufp+strlen(lbufp)), "Q921: ERROR, SAP=%d (Illegal SAPI), %c, TEI=%d\n", sap, cmd?'C':'R', tei);
234                         cnt = n;
235                         goto dump;                              
236         }
237
238 dump:   
239         if(printit)
240                 sprintf((lbufp+strlen(lbufp)), "\n");
241
242         if(raw && printit)
243         {
244                 int j;
245                 for (i = 0; i < cnt; i += 16)
246                 {
247                         sprintf((pbuf+strlen(pbuf)),"Dump:%.3d  ", i);
248                         for (j = 0; j < 16; j++)
249                                 if (i + j < cnt)
250                                         sprintf((pbuf+strlen(pbuf)),"%02x ", buf[i + j]);
251                                 else
252                                         sprintf((pbuf+strlen(pbuf)),"   ");
253                         sprintf((pbuf+strlen(pbuf)),"      ");
254                         for (j = 0; j < 16 && i + j < cnt; j++)
255                                 if (isprint(buf[i + j]))
256                                         sprintf((pbuf+strlen(pbuf)),"%c", buf[i + j]);
257                                 else
258                                         sprintf((pbuf+strlen(pbuf)),".");
259                         sprintf((pbuf+strlen(pbuf)),"\n");
260                 }
261         }
262
263         sprintf((pbuf+strlen(pbuf)),"%s", &locbuf[0]);
264         
265         return (cnt);
266 }
267
268 /* EOF */