print-fr.c revision 32145
1171164Smlaier/*
2171164Smlaier * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
3171164Smlaier *	The Regents of the University of California.  All rights reserved.
4171164Smlaier *
5171164Smlaier * Redistribution and use in source and binary forms, with or without
6171164Smlaier * modification, are permitted provided that: (1) source code distributions
7171164Smlaier * retain the above copyright notice and this paragraph in its entirety, (2)
8171164Smlaier * distributions including binary code include the above copyright notice and
9171164Smlaier * this paragraph in its entirety in the documentation or other materials
10171164Smlaier * provided with the distribution, and (3) all advertising materials mentioning
11171164Smlaier * features or use of this software display the following acknowledgement:
12171164Smlaier * ``This product includes software developed by the University of California,
13171164Smlaier * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14171164Smlaier * the University nor the names of its contributors may be used to endorse
15171164Smlaier * or promote products derived from this software without specific prior
16171164Smlaier * written permission.
17171164Smlaier * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18171164Smlaier * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19171164Smlaier * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20171164Smlaier */
21171164Smlaier
22171164Smlaier#ifndef lint
23171164Smlaierstatic  char rcsid[] =
24171164Smlaier	"@(#)$Header: /cvs/juniper/src/freebsd/contrib/tcpdump/print-fr.c,v 1.2 1997/07/18 20:24:15 boonmark Exp $ (LBL)";
25171164Smlaier#endif
26171164Smlaier
27171164Smlaier#ifdef PPP
28171164Smlaier#include <sys/param.h>
29171164Smlaier#include <sys/time.h>
30171164Smlaier#include <sys/socket.h>
31171164Smlaier#include <sys/file.h>
32171164Smlaier#include <sys/ioctl.h>
33171164Smlaier
34171164Smlaier#if __STDC__
35171164Smlaierstruct mbuf;
36171164Smlaierstruct rtentry;
37171164Smlaier#endif
38171164Smlaier#include <net/if.h>
39171164Smlaier
40171164Smlaier#include <netinet/in.h>
41171164Smlaier#include <netinet/in_systm.h>
42171164Smlaier#include <netinet/ip.h>
43171164Smlaier
44171164Smlaier#include <ctype.h>
45171164Smlaier#include <netdb.h>
46171164Smlaier#include <pcap.h>
47171164Smlaier#include <signal.h>
48171164Smlaier#include <stdio.h>
49171164Smlaier
50171164Smlaier#include <netinet/if_ether.h>
51171164Smlaier#include "ethertype.h"
52171164Smlaier
53171164Smlaier#include <net/ppp_defs.h>
54171164Smlaier#include "interface.h"
55171164Smlaier#include "addrtoname.h"
56171164Smlaier
57171164Smlaier
58171164Smlaiervoid q933_print();
59171164Smlaier
60171164Smlaier#define FR_EA_BIT(p) ((p)&0x1)
61171164Smlaier#define FR_DLCI(b0,b1) ((((b0)&0xFC)<<2)+(((b1)&0xF0)>>4))
62171164Smlaier
63171164Smlaierstruct fr_nlpids {
64171164Smlaier	u_short id;
65171164Smlaier	char *name;
66171164Smlaier};
67171164Smlaier
68171164Smlaier/* find out how many bytes are there in a frame */
69171164Smlaierint
70171164Smlaierfr_addr_len(const u_char *p)
71171164Smlaier{
72171164Smlaier	int i=0;
73171164Smlaier
74171164Smlaier	while (!FR_EA_BIT(p[i]) && i++ && !FR_EA_BIT(p[i+1])) i++;
75171164Smlaier	return (i+1);
76171164Smlaier}
77171164Smlaier
78171164Smlaier/* the following is for framerelay */
79171164Smlaier#define NLPID_LEN	1	/* NLPID is one byte long */
80171164Smlaier#define NLPID_Q933      0x08
81171164Smlaier#define NLPID_CLNP      0x81
82171164Smlaier#define NLPID_ESIS      0x82
83171164Smlaier#define NLPID_ISIS      0x83
84171164Smlaier#define NLPID_CONS      0x84
85171164Smlaier#define NLPID_IDRP      0x85
86171164Smlaier#define NLPID_X25_ESIS  0x8a
87171164Smlaier#define NLPID_IP        0xcc
88171164Smlaier
89171164Smlaier
90171164Smlaierstatic struct fr_nlpids fr_nlpids[256];
91171164Smlaierstatic fr_nlpid_flag =0;
92171164Smlaier
93171164Smlaiervoid init_fr_nlpids()
94171164Smlaier{
95171164Smlaier	int i;
96171164Smlaier
97171164Smlaier	if (!fr_nlpid_flag) {
98171164Smlaier		for (i=0; i < 256; i++) {
99171164Smlaier			fr_nlpids[i].id = 0;
100171164Smlaier			fr_nlpids[i].name = "Not Specified";
101171164Smlaier		}
102171164Smlaier		fr_nlpids[NLPID_Q933].name = "Q.933";
103171164Smlaier		fr_nlpids[NLPID_CLNP].name = "CLNP";
104171164Smlaier		fr_nlpids[NLPID_ESIS].name = "ESIS";
105171164Smlaier		fr_nlpids[NLPID_ISIS].name = "ISIS";
106171164Smlaier		fr_nlpids[NLPID_CONS].name = "CONS";
107171164Smlaier		fr_nlpids[NLPID_IDRP].name = "IDRP";
108171164Smlaier		fr_nlpids[NLPID_X25_ESIS].name = "X25_ESIS";
109171164Smlaier		fr_nlpids[NLPID_IP].name = "IP";
110171164Smlaier	}
111171164Smlaier	fr_nlpid_flag = 1;
112171164Smlaier}
113171164Smlaier
114171164Smlaier/* Framerelay packet structure */
115171164Smlaier
116171164Smlaier/*
117171164Smlaier                  +---------------------------+
118171164Smlaier                  |    flag (7E hexadecimal)  |
119171164Smlaier                  +---------------------------+
120171164Smlaier                  |       Q.922 Address*      |
121171164Smlaier                  +--                       --+
122171164Smlaier                  |                           |
123171164Smlaier                  +---------------------------+
124171164Smlaier                  | Control (UI = 0x03)       |
125171164Smlaier                  +---------------------------+
126171164Smlaier                  | Optional Pad      (0x00)  |
127171164Smlaier                  +---------------------------+
128171164Smlaier                  | NLPID                     |
129171164Smlaier                  +---------------------------+
130171164Smlaier                  |             .             |
131171164Smlaier                  |             .             |
132171164Smlaier                  |             .             |
133171164Smlaier                  |           Data            |
134171164Smlaier                  |             .             |
135171164Smlaier                  |             .             |
136171164Smlaier                  +---------------------------+
137171164Smlaier                  |   Frame Check Sequence    |
138171164Smlaier                  +--           .           --+
139171164Smlaier                  |       (two octets)        |
140171164Smlaier                  +---------------------------+
141171164Smlaier                  |   flag (7E hexadecimal)   |
142171164Smlaier                  +---------------------------+
143171164Smlaier
144171164Smlaier           * Q.922 addresses, as presently defined, are two octets and
145171164Smlaier             contain a 10-bit DLCI.  In some networks Q.922 addresses
146171164Smlaier             may optionally be increased to three or four octets.
147171164Smlaier
148171164Smlaier*/
149171164Smlaier
150171164Smlaier#define FR_PROTOCOL(p) fr_protocol((p))
151171164Smlaier
152171164Smlaierint
153171164Smlaierfr_hdrlen(const u_char *p)
154171164Smlaier{
155171164Smlaier	int hlen;
156171164Smlaier	hlen = fr_addr_len(p)+1;  /* addr_len + 0x03 + padding */
157171164Smlaier	if( p[hlen] )
158171164Smlaier		return hlen;
159171164Smlaier	else
160171164Smlaier		return hlen+1;
161171164Smlaier}
162171164Smlaier
163171164Smlaier#define LAYER2_LEN(p) (fr_hdrlen((p))+NLPID_LEN)
164171164Smlaier
165171164Smlaierint
166171164Smlaierfr_protocol(const u_char *p)
167171164Smlaier{
168171164Smlaier	int hlen;
169171164Smlaier
170171164Smlaier	hlen = fr_addr_len(p) + 1;
171171164Smlaier	if (p[hlen])  /* check for padding */
172171164Smlaier		return p[hlen];
173171164Smlaier	else
174171164Smlaier		return p[hlen+1];
175171164Smlaier}
176171164Smlaier
177171164Smlaiervoid
178171164Smlaierfr_hdlc_print(const u_char *p, int length)
179171164Smlaier{
180171164Smlaier	int proto;
181171164Smlaier	int i;
182171164Smlaier	int hlen;
183171164Smlaier
184171164Smlaier	proto = FR_PROTOCOL(p);
185171164Smlaier
186171164Smlaier	init_fr_nlpids();
187171164Smlaier	/* this is kinda kludge since it assumed that DLCI is two bytes. */
188171164Smlaier	printf("%4d %02x%02x=DLCI(%d) ", length, p[0], p[1], FR_DLCI(p[0],p[1]));
189171164Smlaier	printf("%02x %6s: ", proto, fr_nlpids[proto].name);
190171164Smlaier}
191171164Smlaier
192171164Smlaier
193171164Smlaier
194171164Smlaiervoid
195171164Smlaierfr_if_print(u_char *user, const struct pcap_pkthdr *h,
196171164Smlaier	     register const u_char *p)
197171164Smlaier{
198171164Smlaier	register u_int length = h->len;
199171164Smlaier	register u_int caplen = h->caplen;
200171164Smlaier	int frame_relay = 0,
201171164Smlaier	  proto = FR_PROTOCOL(p);
202171164Smlaier
203171164Smlaier
204171164Smlaier	ts_print(&h->ts);
205171164Smlaier
206171164Smlaier	if (caplen < fr_hdrlen(p)) {
207171164Smlaier		printf("[|fr]");
208171164Smlaier		goto out;
209171164Smlaier	}
210171164Smlaier
211171164Smlaier	/*
212171164Smlaier	 * Some printers want to get back at the link level addresses,
213171164Smlaier	 * and/or check that they're not walking off the end of the packet.
214171164Smlaier	 * Rather than pass them all the way down, we set these globals.
215171164Smlaier	 */
216171164Smlaier	packetp = p;
217171164Smlaier	snapend = p + caplen;
218171164Smlaier
219171164Smlaier	if (eflag)
220171164Smlaier		fr_hdlc_print(p, length);
221171164Smlaier
222171164Smlaier	length = length - (fr_hdrlen(p) + NLPID_LEN);
223171164Smlaier
224171164Smlaier
225171164Smlaier	switch(FR_PROTOCOL(p)) {
226171164Smlaier	case NLPID_IP:
227171164Smlaier	case ETHERTYPE_IP:
228171164Smlaier		ip_print((const u_char *)(p + LAYER2_LEN(p)), length);
229171164Smlaier		break;
230171164Smlaier	case NLPID_CLNP:
231171164Smlaier	case NLPID_ESIS:
232171164Smlaier	case NLPID_ISIS:
233171164Smlaier		isoclns_print((const u_char *)(p + LAYER2_LEN(p)), length,
234171164Smlaier			      caplen, "000000", "000000");
235171164Smlaier		break;
236171164Smlaier	case NLPID_Q933:
237171164Smlaier		q933_print((const u_char *)(p + LAYER2_LEN(p)), length);
238171164Smlaier		break;
239171164Smlaier	default:
240171164Smlaier		if(!eflag)
241171164Smlaier			fr_hdlc_print(p, length);
242171164Smlaier		if(!xflag)
243171164Smlaier			default_print((const u_char *)(p + LAYER2_LEN(p)),
244171164Smlaier					caplen - LAYER2_LEN(p));
245171164Smlaier	}
246171164Smlaier
247171164Smlaier	if (xflag)
248171164Smlaier		default_print((const u_char *)(p + LAYER2_LEN(p)),
249171164Smlaier				caplen - LAYER2_LEN(p));
250171164Smlaierout:
251171164Smlaier	putchar('\n');
252171164Smlaier}
253171164Smlaier#else
254171164Smlaier#include <sys/types.h>
255171164Smlaier#include <sys/time.h>
256171164Smlaier
257171164Smlaier#include <stdio.h>
258171164Smlaier
259171164Smlaier#include "interface.h"
260171164Smlaiervoid
261171164Smlaierfr_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
262171164Smlaier{
263171164Smlaier	error("not configured for ppp");
264171164Smlaier	/* NOTREACHED */
265171164Smlaier}
266171164Smlaier#endif
267171164Smlaier
268171164Smlaier/*
269171164Smlaier * Q.933 decoding portion for framerelay specific.
270171164Smlaier */
271171164Smlaier
272171164Smlaier/* Q.933 packet format
273171164Smlaier                      Format of Other Protocols
274171164Smlaier                          using Q.933 NLPID
275171164Smlaier                  +-------------------------------+
276171164Smlaier                  |        Q.922 Address          |
277171164Smlaier                  +---------------+---------------+
278171164Smlaier                  |Control  0x03  | NLPID   0x08  |
279171164Smlaier                  +---------------+---------------+
280171164Smlaier                  |          L2 Protocol ID       |
281171164Smlaier                  | octet 1       |  octet 2      |
282171164Smlaier                  +-------------------------------+
283171164Smlaier                  |          L3 Protocol ID       |
284171164Smlaier                  | octet 2       |  octet 2      |
285171164Smlaier                  +-------------------------------+
286171164Smlaier                  |         Protocol Data         |
287171164Smlaier                  +-------------------------------+
288171164Smlaier                  | FCS                           |
289171164Smlaier                  +-------------------------------+
290171164Smlaier */
291171164Smlaier
292171164Smlaier/* L2 (Octet 1)- Call Reference Usually is 0x0 */
293171164Smlaier
294171164Smlaier/*
295171164Smlaier * L2 (Octet 2)- Message Types definition 1 byte long.
296171164Smlaier */
297171164Smlaier/* Call Establish */
298171164Smlaier#define MSG_TYPE_ESC_TO_NATIONAL  0x00
299171164Smlaier#define MSG_TYPE_ALERT            0x01
300171164Smlaier#define MSG_TYPE_CALL_PROCEEDING  0x02
301171164Smlaier#define MSG_TYPE_CONNECT          0x07
302171164Smlaier#define MSG_TYPE_CONNECT_ACK      0x0F
303171164Smlaier#define MSG_TYPE_PROGRESS         0x03
304171164Smlaier#define MSG_TYPE_SETUP            0x05
305171164Smlaier/* Call Clear */
306171164Smlaier#define MSG_TYPE_DISCONNECT       0x45
307171164Smlaier#define MSG_TYPE_RELEASE          0x4D
308171164Smlaier#define MSG_TYPE_RELEASE_COMPLETE 0x5A
309171164Smlaier#define MSG_TYPE_RESTART          0x46
310171164Smlaier#define MSG_TYPE_RESTART_ACK      0x4E
311171164Smlaier/* Status */
312171164Smlaier#define MSG_TYPE_STATUS           0x7D
313171164Smlaier#define MSG_TYPE_STATUS_ENQ       0x75
314171164Smlaier
315171164Smlaier#define ONE_BYTE_IE_MASK 0xF0
316171164Smlaier
317171164Smlaier/* See L2 protocol ID picture above */
318171164Smlaierstruct q933_header {
319171164Smlaier    u_char call_ref;  /* usually is 0 for framerelay PVC */
320171164Smlaier    u_char msg_type;
321171164Smlaier};
322171164Smlaier
323171164Smlaier#define REPORT_TYPE_IE    0x01
324171164Smlaier#define LINK_VERIFY_IE_91 0x19
325171164Smlaier#define LINK_VERIFY_IE_94 0x03
326171164Smlaier#define PVC_STATUS_IE     0x07
327171164Smlaier
328171164Smlaier#define MAX_IE_SIZE
329171164Smlaier
330171164Smlaierstruct common_ie_header {
331171164Smlaier    u_char ie_id;
332171164Smlaier    u_char ie_len;
333171164Smlaier};
334171164Smlaier
335171164Smlaier#define FULL_STATUS 0
336171164Smlaier#define LINK_VERIFY 1
337171164Smlaier#define ASYNC_PVC   2
338171164Smlaier
339171164Smlaier
340171164Smlaiervoid
341171164Smlaierq933_print(const u_char *p, int length)
342171164Smlaier{
343171164Smlaier	struct q933_header *header = (struct q933_header *)(p+1);
344171164Smlaier	const u_char *ptemp = p;
345171164Smlaier	int ie_type, ie_len;
346171164Smlaier	char *decode_str, temp_str[255];
347171164Smlaier	struct common_ie_header *ie_p;
348171164Smlaier
349171164Smlaier
350171164Smlaier	/* printing out header part */
351171164Smlaier	printf("Call Ref: %02x, MSG Type: %02x",
352171164Smlaier	       header->call_ref, header->msg_type);
353171164Smlaier	switch(header->msg_type) {
354171164Smlaier	case MSG_TYPE_STATUS:
355171164Smlaier	    decode_str = "STATUS REPLY";
356171164Smlaier	    break;
357171164Smlaier	case MSG_TYPE_STATUS_ENQ:
358171164Smlaier	    decode_str = "STATUS ENQUIRY";
359171164Smlaier	    break;
360171164Smlaier	default:
361171164Smlaier	    decode_str = "UNKNOWN MSG Type";
362171164Smlaier	}
363171164Smlaier	printf(" %s\n", decode_str);
364171164Smlaier
365171164Smlaier	length = length - 3;
366171164Smlaier	ptemp = ptemp + 3;
367171164Smlaier
368171164Smlaier	/* Loop through the rest of IE */
369171164Smlaier	while( length > 0 ) {
370171164Smlaier	    if( ptemp[0] & ONE_BYTE_IE_MASK ) {
371171164Smlaier		ie_len = 1;
372171164Smlaier		printf("\t\tOne byte IE: %02x, Content %02x\n",
373171164Smlaier		       (*ptemp & 0x70)>>4, (*ptemp & 0x0F));
374171164Smlaier		length--;
375171164Smlaier		ptemp++;
376171164Smlaier	    }
377171164Smlaier	    else {  /* Multi-byte IE */
378171164Smlaier		ie_p = (struct common_ie_header *)ptemp;
379171164Smlaier		switch (ie_p->ie_id) {
380171164Smlaier		case REPORT_TYPE_IE:
381171164Smlaier		    switch(ptemp[2]) {
382171164Smlaier		    case FULL_STATUS:
383171164Smlaier			decode_str = "FULL STATUS";
384171164Smlaier			break;
385171164Smlaier		    case LINK_VERIFY:
386171164Smlaier			decode_str = "LINK VERIFY";
387171164Smlaier			break;
388171164Smlaier		    case ASYNC_PVC:
389171164Smlaier			decode_str = "Async PVC Status";
390171164Smlaier			break;
391171164Smlaier		    default:
392171164Smlaier			decode_str = "Reserved Value";
393171164Smlaier		    }
394171164Smlaier		    break;
395171164Smlaier		case LINK_VERIFY_IE_91:
396171164Smlaier		case LINK_VERIFY_IE_94:
397171164Smlaier		    sprintf(temp_str,"TX Seq: %3d, RX Seq: %3d",
398171164Smlaier			    ptemp[2], ptemp[3]);
399171164Smlaier		    decode_str = temp_str;
400171164Smlaier		    break;
401171164Smlaier		case PVC_STATUS_IE:
402171164Smlaier		    sprintf(temp_str,"DLCI %d: status %s %s",
403171164Smlaier			    ((ptemp[2]&0x3f)<<4)+ ((ptemp[3]&0x78)>>3),
404171164Smlaier			    ptemp[4] & 0x8 ?"new,":" ",
405171164Smlaier			    ptemp[4] & 0x2 ?"Active":"Inactive");
406171164Smlaier		    break;
407171164Smlaier		default:
408171164Smlaier		    decode_str = "Non-decoded Value";
409171164Smlaier		}
410171164Smlaier		printf("\t\tIE: %02X Len: %d, %s\n",
411171164Smlaier		       ie_p->ie_id, ie_p->ie_len, decode_str);
412171164Smlaier		length = length - ie_p->ie_len - 2;
413171164Smlaier		ptemp = ptemp + ie_p->ie_len + 2;
414171164Smlaier	    }
415171164Smlaier	}
416
417}
418
419
420
421
422
423
424