2 * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 *---------------------------------------------------------------------------
27 * layer3.c - decode and print layer 3 (Q.931) information
28 * -------------------------------------------------------
30 * $Id: layer3.c,v 1.9 2000/02/21 15:17:17 hm Exp $
32 * $FreeBSD: src/usr.sbin/i4b/isdndecode/layer3.c,v 1.6.2.2 2001/08/01 17:45:05 obrien Exp $
33 * $DragonFly: src/usr.sbin/i4b/isdndecode/layer3.c,v 1.2 2003/06/17 04:29:55 dillon Exp $
35 * last edit-date: [Mon Feb 21 15:54:58 2000]
37 *---------------------------------------------------------------------------*/
43 /* 0x00 */ /* call establishment group */
60 "CONNECT ACKNOWLEDGE",
82 "USER INFORMATION", /* call information phase */
95 "SUSPEND ACKNOWLEDGE",
104 "RETRIEVE ACKNOWLEDGE",
120 "DETACH", /* call clearing */
128 "DETACH ACKNOWLEDGE",
134 "RESTART ACKNOWLEDGE",
158 "SEGMENT", /* misc messages */
166 "CANCEL ACKNOWLEDGE",
168 "FACILITY ACKNOWLEDGE",
170 "REGISTER ACKNOWLEDGE",
186 "CONGESTION CONTROL",
195 #define MTTAB_MAX 0x7f
197 extern int f_null(char *pbuf
, unsigned char *buf
, int off
);
198 extern int f_bc(char *pbuf
, unsigned char *buf
, int off
);
199 extern int f_cause(char *pbuf
, unsigned char *buf
, int off
);
200 extern int f_cstat(char *pbuf
, unsigned char *buf
, int off
);
201 extern int f_chid(char *pbuf
, unsigned char *buf
, int off
);
202 extern int f_fac(char *pbuf
, unsigned char *buf
, int off
);
203 extern int f_progi(char *pbuf
, unsigned char *buf
, int off
);
204 extern int f_displ(char *pbuf
, unsigned char *buf
, int off
);
205 extern int f_date(char *pbuf
, unsigned char *buf
, int off
);
206 extern int f_cnu(char *pbuf
, unsigned char *buf
, int off
);
207 extern int f_cgpn(char *pbuf
, unsigned char *buf
, int off
);
208 extern int f_cdpn(char *pbuf
, unsigned char *buf
, int off
);
209 extern int f_hlc(char *pbuf
, unsigned char *buf
, int off
);
210 extern int f_uu(char *pbuf
, unsigned char *buf
, int off
);
213 unsigned char code
; /* information element identifier code */
214 char *name
; /* ie name */
215 int (*func
) (char *pbuf
, unsigned char *buf
, int off
); /* decode function */
217 { 0x00, "segmented message", f_null
},
218 { 0x04, "bearer capability", f_bc
},
219 { 0x08, "cause", f_cause
},
220 { 0x0c, "connected address", f_null
},
221 { 0x0d, "extended facility", f_null
},
222 { 0x10, "call identity", f_null
},
223 { 0x14, "call state", f_cstat
},
224 { 0x18, "channel id", f_chid
},
225 { 0x19, "data link connection id", f_null
},
226 { 0x1c, "facility", f_fac
},
227 { 0x1e, "progress indicator", f_progi
},
228 { 0x20, "network specific facilities", f_null
},
229 { 0x24, "terminal capabilities", f_null
},
230 { 0x27, "notification indicator", f_null
},
231 { 0x28, "display", f_displ
},
232 { 0x29, "date/time", f_date
},
233 { 0x2c, "keypad", f_null
},
234 { 0x30, "keypad echo", f_null
},
235 { 0x32, "information request", f_null
},
236 { 0x34, "signal", f_null
},
237 { 0x36, "switchhook", f_null
},
238 { 0x38, "feature activation", f_null
},
239 { 0x39, "feature indication", f_null
},
240 { 0x3a, "service profile id", f_null
},
241 { 0x3b, "endpoint identifier", f_null
},
242 { 0x40, "information rate", f_null
},
243 { 0x41, "precedence level", f_null
},
244 { 0x42, "end-to-end transit delay", f_null
},
245 { 0x43, "transit delay detection", f_null
},
246 { 0x44, "packet layer binary parms", f_null
},
247 { 0x45, "packet layer window size", f_null
},
248 { 0x46, "packet size", f_null
},
249 { 0x47, "closed user group", f_null
},
250 { 0x48, "link layer core parameters", f_null
},
251 { 0x49, "link layer protocol parms", f_null
},
252 { 0x4a, "reverse charging information", f_null
},
253 { 0x4c, "connected number", f_cnu
},
254 { 0x4d, "connected subaddress", f_null
},
255 { 0x50, "X.213 priority", f_null
},
256 { 0x51, "report type", f_null
},
257 { 0x53, "link integrity verification", f_null
},
258 { 0x57, "PVC status", f_null
},
259 { 0x6c, "calling party number", f_cnu
},
260 { 0x6d, "calling party subaddress", f_null
},
261 { 0x70, "called party number", f_cnu
},
262 { 0x71, "called party subaddress", f_null
},
263 { 0x74, "redirecting number", f_null
},
264 { 0x78, "transit network selection", f_null
},
265 { 0x79, "restart indicator", f_null
},
266 { 0x7c, "low layer compatibility", f_null
},
267 { 0x7d, "high layer compatibility", f_hlc
},
268 { 0x7e, "user-user", f_uu
},
269 { 0x7f, "escape for extension", f_null
},
270 { 0xff, "unknown information element", f_null
}
273 /*---------------------------------------------------------------------------*
274 * decode Q.931 protocol
275 *---------------------------------------------------------------------------*/
277 layer3(char *pbuf
, int n
, int off
, unsigned char *buf
)
296 /* protocol discriminator */
300 if(pd
>= 0x00 && pd
<= 0x07)
301 sprintf(buffer
, "User-User IE (0x%02x)",pd
);
303 sprintf(buffer
, "Q.931/I.451");
304 else if(pd
>= 0x10 && pd
<= 0x3f)
305 sprintf(buffer
, "Other Layer 3 or X.25 (0x%02x)",pd
);
306 else if(pd
>= 0x40 && pd
<= 0x4f)
307 sprintf(buffer
, "National Use (0x%02x)",pd
);
308 else if(pd
>= 0x50 && pd
<= 0xfe)
309 sprintf(buffer
, "Other Layer 3 or X.25 (0x%02x)",pd
);
311 sprintf(buffer
, "Reserved (0x%02x)",pd
);
313 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, pd
, 0xff, "Protocol discriminator = %s", buffer
);
319 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0xff, "-");
327 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0xf0, "Call Reference");
332 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x0f, "Length of Call Reference = 0 (Dummy CR)");
335 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x0f, "Length of Call Reference = 1");
337 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x80, "Call Reference sent %s origination side", (buf
[i
] & 0x80) ? "to" : "from");
338 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x7f, "Call Reference = %d = 0x%02x", (buf
[i
] & 0x7f), (buf
[i
] & 0x7f));
341 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x0f, "Length of Call Reference = 2");
343 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x80, "Call Reference sent %s origination side", (buf
[i
] & 0x80) ? "to" : "from");
344 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x7f, "Call reference = %d = %02x", (buf
[i
] & 0x7f), (buf
[i
] & 0x7f));
346 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0xff, "Call reference = %d = %02x", (buf
[i
]), (buf
[i
]));
353 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x80, "Message type extension = %d", buf
[i
] & 0x80 ? 1 : 0);
355 if(buf
[i
] <= MTTAB_MAX
)
356 strcpy(buffer
, mttab
[buf
[i
]]);
358 sprintf(buffer
, "unknown (0x%02x)", buf
[i
]);
360 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x7f, "Message type = %s", buffer
);
363 /* information elements */
367 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x80, "%s Information element", buf
[i
] & 0x80 ? "Single octet" : "Variable length");
371 /* single octett info element type 1 */
373 if((buf
[i
] & 0x70) == 0x00)
375 strcpy(buffer
, "Reserved");
376 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x70, "Reserved");
377 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x0f, "Reserved, content of IE");
379 else if((buf
[i
] & 0x70) == 0x10)
381 strcpy(buffer
, "Shift");
382 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x70, "Shift");
383 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x08, "%s shift", buf
[i
] & 0x08 ? "Non-locking" : "Locking");
385 switch(buf
[i
] & 0x07)
388 strcpy(buffer
, "Not applicable");
393 sprintf(buffer
, "Reserved (%d)", buf
[i
] & 0x07);
396 strcpy(buffer
, "Codeset 4 (ISO/IEC)");
399 strcpy(buffer
, "Codeset 5 (National use)");
402 strcpy(buffer
, "Codeset 6 (Local network specific)");
405 strcpy(buffer
, "Codeset 7 (User specific)");
408 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x07, "%s", buffer
);
411 else if((buf
[i
] & 0x70) == 0x30)
413 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x70, "Congestion Level");
414 switch(buf
[i
] & 0x0f)
417 strcpy(buffer
, "receiver ready");
420 strcpy(buffer
, "receiver not ready");
423 sprintf(buffer
, "reserved (0x%02x)", buf
[i
] & 0x0f);
426 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x0f, "Congestion Level = ", buffer
);
429 else if((buf
[i
] & 0x70) == 0x50)
431 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x70, "Repeat Indicator");
432 switch(buf
[i
] & 0x0f)
435 strcpy(buffer
, "Prioritized list for selecting one possibility");
438 sprintf(buffer
, "reserved (0x%02x)", buf
[i
] & 0x0f);
441 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x0f, "Repeat indication = ", buffer
);
445 /* single octett info element type 2 */
447 else if((buf
[i
] & 0x7f) == 0x20)
449 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x7f, "More data");
451 else if((buf
[i
] & 0x7f) == 0x21)
453 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x7f, "Sending complete");
457 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0xff, "UNKNOWN single octet IE = 0x%02x", buf
[i
]);
465 struct ie
*iep
= &ietab
[0];
469 if((iep
->code
== buf
[i
]) ||
475 sprintline(3, (pbuf
+strlen(pbuf
)), off
+i
, buf
[i
], 0x7f, "IE = %s", iep
->name
);
476 sprintline(3, pbuf
+strlen(pbuf
), off
+i
+1, buf
[i
+1], 0xff, "IE Length = %d", buf
[i
+1]);
478 if(iep
->func
== f_null
)
483 i
+= (iep
->func
)(pbuf
, &buf
[i
], off
+i
);
489 sprintf((pbuf
+strlen(pbuf
)), "UNKNOWN CODESET=%d, IE=0x%02x", codeset
, buf
[i
]);
492 i
++; /* index -> length */
496 sprintf((pbuf
+strlen(pbuf
)), "LEN=0x%02x, DATA=", len
);
498 i
++; /* index -> 1st param */
500 for(j
= 0; j
< len
; j
++)
502 sprintf((pbuf
+strlen(pbuf
)),"0x%02x ", buf
[j
+i
]);
505 sprintf((pbuf
+strlen(pbuf
)),"]");
511 if(!codelock
&& (codeset
!= oldcodeset
))
512 codeset
= oldcodeset
;
515 /* sprintf((pbuf+strlen(pbuf)),"\n"); */