Deleted Added
full compact
1/*
2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * $FreeBSD: head/contrib/tcpdump/print-fr.c 66644 2000-10-05 02:49:49Z kris $
22 */
23
24#ifndef lint
25static char rcsid[] =
26 "@(#)$Header: /home/ncvs/src/contrib/tcpdump/print-fr.c,v 1.1 1997/12/31 21:50:31 pst Exp $ (LBL)";
27#endif
28
29#ifdef PPP
30#include <sys/param.h>
31#include <sys/time.h>
32#include <sys/socket.h>
33#include <sys/file.h>
34#include <sys/ioctl.h>
35
36#if __STDC__
37struct mbuf;
38struct rtentry;
39#endif
40#include <net/if.h>
41#include <net/if_var.h>
42
43#include <netinet/in.h>
44#include <netinet/in_systm.h>
45#include <netinet/ip.h>
46
47#include <ctype.h>
48#include <netdb.h>
49#include <pcap.h>
50#include <signal.h>
51#include <stdio.h>
52
53#include <netinet/if_ether.h>
54#include "ethertype.h"
55
56#include <net/ppp_defs.h>
57#include "interface.h"
58#include "addrtoname.h"
59
60
61void q933_print();
62
63#define FR_EA_BIT(p) ((p)&0x1)
64#define FR_DLCI(b0,b1) ((((b0)&0xFC)<<2)+(((b1)&0xF0)>>4))
65
66struct fr_nlpids {
67 u_short id;
68 char *name;
69};
70
71/* find out how many bytes are there in a frame */
72int
73fr_addr_len(const u_char *p)
74{
75 int i=0;
76
77 while (!FR_EA_BIT(p[i]) && i++ && !FR_EA_BIT(p[i+1])) i++;
78 return (i+1);
79}
80
81/* the following is for framerelay */
82#define NLPID_LEN 1 /* NLPID is one byte long */
83#define NLPID_Q933 0x08
84#define NLPID_CLNP 0x81
85#define NLPID_ESIS 0x82
86#define NLPID_ISIS 0x83
87#define NLPID_CONS 0x84
88#define NLPID_IDRP 0x85
89#define NLPID_X25_ESIS 0x8a
90#define NLPID_IP 0xcc
91
92
93static struct fr_nlpids fr_nlpids[256];
94static fr_nlpid_flag =0;
95
96void init_fr_nlpids()
97{
98 int i;
99
100 if (!fr_nlpid_flag) {
101 for (i=0; i < 256; i++) {
102 fr_nlpids[i].id = 0;
103 fr_nlpids[i].name = "Not Specified";
104 }
105 fr_nlpids[NLPID_Q933].name = "Q.933";
106 fr_nlpids[NLPID_CLNP].name = "CLNP";
107 fr_nlpids[NLPID_ESIS].name = "ESIS";
108 fr_nlpids[NLPID_ISIS].name = "ISIS";
109 fr_nlpids[NLPID_CONS].name = "CONS";
110 fr_nlpids[NLPID_IDRP].name = "IDRP";
111 fr_nlpids[NLPID_X25_ESIS].name = "X25_ESIS";
112 fr_nlpids[NLPID_IP].name = "IP";
113 }
114 fr_nlpid_flag = 1;
115}
116
117/* Framerelay packet structure */
118
119/*
120 +---------------------------+
121 | flag (7E hexadecimal) |
122 +---------------------------+
123 | Q.922 Address* |
124 +-- --+
125 | |
126 +---------------------------+
127 | Control (UI = 0x03) |
128 +---------------------------+
129 | Optional Pad (0x00) |
130 +---------------------------+
131 | NLPID |
132 +---------------------------+
133 | . |
134 | . |
135 | . |
136 | Data |
137 | . |
138 | . |
139 +---------------------------+
140 | Frame Check Sequence |
141 +-- . --+
142 | (two octets) |
143 +---------------------------+
144 | flag (7E hexadecimal) |
145 +---------------------------+
146
147 * Q.922 addresses, as presently defined, are two octets and
148 contain a 10-bit DLCI. In some networks Q.922 addresses
149 may optionally be increased to three or four octets.
150
151*/
152
153#define FR_PROTOCOL(p) fr_protocol((p))
154
155int
156fr_hdrlen(const u_char *p)
157{
158 int hlen;
159 hlen = fr_addr_len(p)+1; /* addr_len + 0x03 + padding */
160 if( p[hlen] )
161 return hlen;
162 else
163 return hlen+1;
164}
165
166#define LAYER2_LEN(p) (fr_hdrlen((p))+NLPID_LEN)
167
168int
169fr_protocol(const u_char *p)
170{
171 int hlen;
172
173 hlen = fr_addr_len(p) + 1;
174 if (p[hlen]) /* check for padding */
175 return p[hlen];
176 else
177 return p[hlen+1];
178}
179
180void
181fr_hdlc_print(const u_char *p, int length)
182{
183 int proto;
184 int i;
185 int hlen;
186
187 proto = FR_PROTOCOL(p);
188
189 init_fr_nlpids();
190 /* this is kinda kludge since it assumed that DLCI is two bytes. */
191 printf("%4d %02x%02x=DLCI(%d) ", length, p[0], p[1], FR_DLCI(p[0],p[1]));
192 printf("%02x %6s: ", proto, fr_nlpids[proto].name);
193}
194
195
196
197void
198fr_if_print(u_char *user, const struct pcap_pkthdr *h,
199 register const u_char *p)
200{
201 register u_int length = h->len;
202 register u_int caplen = h->caplen;
203 int frame_relay = 0,
204 proto = FR_PROTOCOL(p);
205
206
207 ts_print(&h->ts);
208
209 if (caplen < fr_hdrlen(p)) {
210 printf("[|fr]");
211 goto out;
212 }
213
214 /*
215 * Some printers want to get back at the link level addresses,
216 * and/or check that they're not walking off the end of the packet.
217 * Rather than pass them all the way down, we set these globals.
218 */
219 packetp = p;
220 snapend = p + caplen;
221
222 if (eflag)
223 fr_hdlc_print(p, length);
224
225 length = length - (fr_hdrlen(p) + NLPID_LEN);
226
227
228 switch(FR_PROTOCOL(p)) {
229 case NLPID_IP:
230 case ETHERTYPE_IP:
231 ip_print((const u_char *)(p + LAYER2_LEN(p)), length);
232 break;
233 case NLPID_CLNP:
234 case NLPID_ESIS:
235 case NLPID_ISIS:
236 isoclns_print((const u_char *)(p + LAYER2_LEN(p)), length,
237 caplen, "000000", "000000");
238 break;
239 case NLPID_Q933:
240 q933_print((const u_char *)(p + LAYER2_LEN(p)), length);
241 break;
242 default:
243 if(!eflag)
244 fr_hdlc_print(p, length);
245 if(!xflag)
246 default_print((const u_char *)(p + LAYER2_LEN(p)),
247 caplen - LAYER2_LEN(p));
248 }
249
250 if (xflag)
251 default_print((const u_char *)(p + LAYER2_LEN(p)),
252 caplen - LAYER2_LEN(p));
253out:
254 putchar('\n');
255}
256#else
257#include <sys/types.h>
258#include <sys/time.h>
259
260#include <stdio.h>
261
262#include "interface.h"
263void
264fr_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
265{
266 error("not configured for ppp");
267 /* NOTREACHED */
268}
269#endif
270
271/*
272 * Q.933 decoding portion for framerelay specific.
273 */
274
275/* Q.933 packet format
276 Format of Other Protocols
277 using Q.933 NLPID
278 +-------------------------------+
279 | Q.922 Address |
280 +---------------+---------------+
281 |Control 0x03 | NLPID 0x08 |
282 +---------------+---------------+
283 | L2 Protocol ID |
284 | octet 1 | octet 2 |
285 +-------------------------------+
286 | L3 Protocol ID |
287 | octet 2 | octet 2 |
288 +-------------------------------+
289 | Protocol Data |
290 +-------------------------------+
291 | FCS |
292 +-------------------------------+
293 */
294
295/* L2 (Octet 1)- Call Reference Usually is 0x0 */
296
297/*
298 * L2 (Octet 2)- Message Types definition 1 byte long.
299 */
300/* Call Establish */
301#define MSG_TYPE_ESC_TO_NATIONAL 0x00
302#define MSG_TYPE_ALERT 0x01
303#define MSG_TYPE_CALL_PROCEEDING 0x02
304#define MSG_TYPE_CONNECT 0x07
305#define MSG_TYPE_CONNECT_ACK 0x0F
306#define MSG_TYPE_PROGRESS 0x03
307#define MSG_TYPE_SETUP 0x05
308/* Call Clear */
309#define MSG_TYPE_DISCONNECT 0x45
310#define MSG_TYPE_RELEASE 0x4D
311#define MSG_TYPE_RELEASE_COMPLETE 0x5A
312#define MSG_TYPE_RESTART 0x46
313#define MSG_TYPE_RESTART_ACK 0x4E
314/* Status */
315#define MSG_TYPE_STATUS 0x7D
316#define MSG_TYPE_STATUS_ENQ 0x75
317
318#define ONE_BYTE_IE_MASK 0xF0
319
320/* See L2 protocol ID picture above */
321struct q933_header {
322 u_char call_ref; /* usually is 0 for framerelay PVC */
323 u_char msg_type;
324};
325
326#define REPORT_TYPE_IE 0x01
327#define LINK_VERIFY_IE_91 0x19
328#define LINK_VERIFY_IE_94 0x03
329#define PVC_STATUS_IE 0x07
330
331#define MAX_IE_SIZE
332
333struct common_ie_header {
334 u_char ie_id;
335 u_char ie_len;
336};
337
338#define FULL_STATUS 0
339#define LINK_VERIFY 1
340#define ASYNC_PVC 2
341
342
343void
344q933_print(const u_char *p, int length)
345{
346 struct q933_header *header = (struct q933_header *)(p+1);
347 const u_char *ptemp = p;
348 int ie_type, ie_len;
349 char *decode_str, temp_str[255];
350 struct common_ie_header *ie_p;
351
352
353 /* printing out header part */
354 printf("Call Ref: %02x, MSG Type: %02x",
355 header->call_ref, header->msg_type);
356 switch(header->msg_type) {
357 case MSG_TYPE_STATUS:
358 decode_str = "STATUS REPLY";
359 break;
360 case MSG_TYPE_STATUS_ENQ:
361 decode_str = "STATUS ENQUIRY";
362 break;
363 default:
364 decode_str = "UNKNOWN MSG Type";
365 }
366 printf(" %s\n", decode_str);
367
368 length = length - 3;
369 ptemp = ptemp + 3;
370
371 /* Loop through the rest of IE */
372 while( length > 0 ) {
373 if( ptemp[0] & ONE_BYTE_IE_MASK ) {
374 ie_len = 1;
375 printf("\t\tOne byte IE: %02x, Content %02x\n",
376 (*ptemp & 0x70)>>4, (*ptemp & 0x0F));
377 length--;
378 ptemp++;
379 }
380 else { /* Multi-byte IE */
381 ie_p = (struct common_ie_header *)ptemp;
382 switch (ie_p->ie_id) {
383 case REPORT_TYPE_IE:
384 switch(ptemp[2]) {
385 case FULL_STATUS:
386 decode_str = "FULL STATUS";
387 break;
388 case LINK_VERIFY:
389 decode_str = "LINK VERIFY";
390 break;
391 case ASYNC_PVC:
392 decode_str = "Async PVC Status";
393 break;
394 default:
395 decode_str = "Reserved Value";
396 }
397 break;
398 case LINK_VERIFY_IE_91:
399 case LINK_VERIFY_IE_94:
400 snprintf(temp_str, sizeof(temp_str), "TX Seq: %3d, RX Seq: %3d",
401 ptemp[2], ptemp[3]);
402 decode_str = temp_str;
403 break;
404 case PVC_STATUS_IE:
405 snprintf(temp_str,sizeof(temp_str), "DLCI %d: status %s %s",
406 ((ptemp[2]&0x3f)<<4)+ ((ptemp[3]&0x78)>>3),
407 ptemp[4] & 0x8 ?"new,":" ",
408 ptemp[4] & 0x2 ?"Active":"Inactive");
409 break;
410 default:
411 decode_str = "Non-decoded Value";
412 }
413 printf("\t\tIE: %02X Len: %d, %s\n",
414 ie_p->ie_id, ie_p->ie_len, decode_str);
415 length = length - ie_p->ie_len - 2;
416 ptemp = ptemp + ie_p->ie_len + 2;
417 }
418 }
419
420}
421
422
423
424
425
426