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