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