Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.sbin / i4b / isdndecode / layer2.c
1 /*
2  * Copyright (c) 1997, 1999 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  *      layer2.c - decode and print layer 2 (Q.921) information
28  *      -------------------------------------------------------
29  *
30  *      $Id: layer2.c,v 1.5 1999/12/13 21:25:25 hm Exp $
31  *
32  * $FreeBSD: src/usr.sbin/i4b/isdndecode/layer2.c,v 1.6.2.1 2001/08/01 17:45:05 obrien Exp $
33  *
34  *      last edit-date: [Mon Dec 13 21:50:41 1999]
35  *
36  *---------------------------------------------------------------------------*/
37
38 #include "decode.h"
39                 
40 /*---------------------------------------------------------------------------*
41  *      decode poll bit
42  *---------------------------------------------------------------------------*/
43 static void
44 poll(int layer, char *buffer, int cnt, unsigned char value, unsigned char mask)
45 {
46         sprintline(layer, buffer, cnt, value, mask, "P/F, Poll = %s", (value & mask) ? "Immediate Response Required" : "No Immediate Response Required");
47 }       
48
49 /*---------------------------------------------------------------------------*
50  *      decode final bit
51  *---------------------------------------------------------------------------*/
52 static void
53 final(int layer, char *buffer, int cnt, unsigned char value, unsigned char mask)
54 {
55         sprintline(layer, buffer, cnt, value, mask, "P/F, Final = %s", (value & mask) ? "Result of Poll" : "No Result of Poll");
56 }       
57
58 /*---------------------------------------------------------------------------*
59  *      decode protocol specified in Q.921
60  *---------------------------------------------------------------------------*/
61 int
62 layer2(char *pbuf, unsigned char *buf, int dir, int printit)
63 {
64         int sap, tei, cmd;
65         int cnt = 0;
66         char locbuf[32000];
67         char *lbufp = &locbuf[0];
68         char buffer[80];
69         
70         *lbufp = '\0';
71         *pbuf = '\0';
72         
73         /* address high */
74
75         sap = (buf[0] >> 2) & 0x3f;
76
77         if(sap == 0)
78                 strcpy(buffer, "Call Control");
79         else if((sap >= 1) && (sap <= 15))
80                 strcpy(buffer, "Reserved");
81         else if(sap == 16)
82                 strcpy(buffer, "X.25");
83         else if((sap >= 17) && (sap <= 31))
84                 strcpy(buffer, "Reserved");
85         else if(sap == 63)
86                 strcpy(buffer, "Layer 2 Management");
87         else
88                 strcpy(buffer, "Not available for Q.921");
89         sprintline(2, lbufp+strlen(lbufp), cnt, buf[0], 0xfc, "SAPI = %d (%s)", sap, buffer);
90
91         if(dir == FROM_TE)
92                 cmd = !(buf[0] & 0x02);
93         else
94                 cmd = buf[0] & 0x02;
95
96         sprintline(2, lbufp+strlen(lbufp), cnt, buf[0], 0x02, "C/R = %s", cmd ? "Command" : "Response");
97         extension(2, lbufp+strlen(lbufp), cnt, buf[0], 0x01);
98         cnt++;
99
100         /* address low */
101
102         tei = buf[1] >> 1;
103
104         if((tei >= 0) && (tei <= 63))
105                 strcpy(buffer, "Non-automatic TEI");
106         else if((tei >= 64) && (tei <= 126))
107                 strcpy(buffer, "Automatic TEI");
108         if(tei == 127)
109                 strcpy(buffer, "Group TEI");
110                 
111         sprintline(2, lbufp+strlen(lbufp), cnt, buf[1], 0xfe, "TEI = %d (%s)", tei, buffer);
112         extension(2, lbufp+strlen(lbufp), cnt, buf[1], 0x01);
113         cnt++;
114
115         /* control 1 */
116         
117         if((buf[2] & 0x03) == 0x03)
118         {
119                 /* U-frame */
120
121                 if((buf[2] & 0xef) == 0x6f)
122                 {
123                         /* SABME */
124                         
125                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: SABME (Set Asynchonous Balanced Mode)");
126                         poll(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10);
127                         cnt++;
128                 }
129                 else if((buf[2] & 0xef) == 0x0f)
130                 {
131                         /* DM */
132
133                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: DM (Disconnected Mode)");
134                         final(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10);
135                         cnt++;
136                 }
137                 else if((buf[2] & 0xef) == 0x03)
138                 {
139                         /* UI */
140
141                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: UI (Unnumbered Information)");
142                         poll(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10);
143                         cnt++;
144         
145                         if(sap == 63 && (buf[3] == 0x0f))       /* TEI management */
146                         {
147                                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[3], 0xff, "MEI (Management Entity Identifier)");
148                                 cnt++;
149                                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[4], 0xff, "Ri = 0x%04x (Reference number high)", (buf[4] << 8) | buf[5]);
150                                 cnt++;
151                                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[5], 0xff, "Ri (Reference Number low)");
152                                 cnt++;
153         
154                                 switch(buf[6])
155                                 {
156                                         case 0x01:
157                                                 strcpy(buffer, "Identity Request");
158                                                 break;
159                                         case 0x02:
160                                                 strcpy(buffer, "Identity Assigned");
161                                                 break;
162                                         case 0x03:
163                                                 strcpy(buffer, "Identity denied");
164                                                 break;
165                                         case 0x04:
166                                                 strcpy(buffer, "Identity Check Request");
167                                                 break;
168                                         case 0x05:
169                                                 strcpy(buffer, "Identity Check Response");
170                                                 break;
171                                         case 0x06:
172                                                 strcpy(buffer, "Identity Remove");
173                                                 break;
174                                         case 0x07:
175                                                 strcpy(buffer, "Identity Verify");
176                                                 break;
177                                         default:
178                                                 strcpy(buffer, "undefined");
179                                                 break;
180                                 }
181                                 
182                                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[6], 0xff, "TEI %s (Message Type %d)", buffer, buf[6]);
183                                 cnt++;
184         
185                                 switch(buf[6])
186                                 {
187                                         case 0x01:
188                                                 strcpy(buffer, "Any TEI value acceptable");
189                                                 break;
190                                         case 0x02:
191                                                 strcpy(buffer, "");
192                                                 break;
193                                         case 0x03:
194                                                 strcpy(buffer, "No TEI Value available");
195                                                 break;
196                                         case 0x04:
197                                                 strcpy(buffer, "Check all TEI values");
198                                                 break;
199                                         case 0x05:
200                                                 strcpy(buffer, "");
201                                                 break;
202                                         case 0x06:
203                                                 strcpy(buffer, "Request for removal of all TEI values");
204                                                 break;
205                                         case 0x07:
206                                                 strcpy(buffer, "");
207                                                 break;
208                                         default:
209                                                 strcpy(buffer, "");
210                                                 break;
211                                 }
212                                 if(((buf[7] >> 1) & 0x7f) == 127)
213                                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[7], 0xfe, "Ai = %d (Action Indicator = %s)", (buf[7] >> 1) & 0x7f, buffer);
214                                 else
215                                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[7], 0xfe, "Ai = %d (Action Indicator)", (buf[7] >> 1) & 0x7f);
216                                 extension(2, lbufp+strlen(lbufp), cnt, buf[7], 0x01);
217                                 cnt++;
218                         }
219                 }
220                 else if((buf[2] & 0xef) == 0x43)
221                 {
222                         /* DISC */
223
224                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: DISC (Disconnect)");
225                         poll(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10);
226                         cnt++;
227                 }
228                 else if((buf[2] & 0xef) == 0x63)
229                 {
230                         /* UA */
231
232                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: UA (Unnumbered Acknowledge)");
233                         final(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10);
234                         cnt++;
235                 }
236                 else if((buf[2] & 0xef) == 0x87)
237                 {
238                         /* FRMR */
239
240                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: FRMR (Frame Reject)");
241                         final(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10);
242                         cnt++;
243                 }
244                 else if((buf[2] & 0xef) == 0x9f)
245                 {
246                         /* XID */
247
248                         sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xef, "U-Frame: XID (Exchange Identification)");
249                         if(cmd)                 
250                                 poll(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10);
251                         else
252                                 final(2, lbufp+strlen(lbufp), cnt, buf[2], 0x10);
253                         cnt++;
254                 }
255                 
256         }
257         else if((buf[2] & 0x03) == 0x01)
258         {
259                 /* S-frame */
260
261                 if(buf[2] == 0x01)
262                         strcpy(buffer, "RR (Receiver Ready)");
263                 else if(buf[2] == 0x05)
264                         strcpy(buffer, "RNR (Receiver Not Ready)");
265                 else if(buf[2] == 0x09)
266                         strcpy(buffer, "REJ (Reject)");
267                 else
268                         strcpy(buffer, "Unknown");
269                         
270                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xff, "S-Frame: %s", buffer);
271                 cnt++;
272                 
273                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[3], 0xfe, "N(R) = %d (receive sequence number)", (buf[3] >> 1) & 0x7f);
274                 if(cmd)         
275                         poll(2, lbufp+strlen(lbufp), cnt, buf[3], 0x01);
276                 else
277                         final(2, lbufp+strlen(lbufp), cnt, buf[3], 0x01);
278                 cnt++;
279                 
280         }
281         else if((buf[2] & 0x01) == 0x00)
282         {
283                 /* I-frame */
284
285                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0xfe, "N(S) = %d (send sequence number)", (buf[2] >> 1) & 0x7f);
286                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[2], 0x01, "I-Frame: Information transfer");
287                 cnt++;
288                 
289                 sprintf(buffer, "N(R) = %d", (buf[3] >> 1) & 0x7f);
290                 sprintline(2, lbufp+strlen(lbufp), cnt, buf[3], 0xfe, "N(R) = %d (receive sequence number)", (buf[3] >> 1) & 0x7f);
291                 poll(2, lbufp+strlen(lbufp), cnt, buf[3], 0x01);
292                 cnt++;
293
294         }
295
296         sprintf((pbuf+strlen(pbuf)),"%s", &locbuf[0]);
297         return (cnt);
298 }
299
300 /* EOF */