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 /* \summary: Frame Relay printer */ 23 24 #ifdef HAVE_CONFIG_H 25 #include "config.h" 26 #endif 27 28 #include <netdissect-stdinc.h> 29 30 #include <stdio.h> 31 #include <string.h> 32 33 #include "netdissect.h" 34 #include "addrtoname.h" 35 #include "ethertype.h" 36 #include "llc.h" 37 #include "nlpid.h" 38 #include "extract.h" 39 #include "oui.h" 40 41 static void frf15_print(netdissect_options *ndo, const u_char *, u_int); 42 43 /* 44 * the frame relay header has a variable length 45 * 46 * the EA bit determines if there is another byte 47 * in the header 48 * 49 * minimum header length is 2 bytes 50 * maximum header length is 4 bytes 51 * 52 * 7 6 5 4 3 2 1 0 53 * +----+----+----+----+----+----+----+----+ 54 * | DLCI (6 bits) | CR | EA | 55 * +----+----+----+----+----+----+----+----+ 56 * | DLCI (4 bits) |FECN|BECN| DE | EA | 57 * +----+----+----+----+----+----+----+----+ 58 * | DLCI (7 bits) | EA | 59 * +----+----+----+----+----+----+----+----+ 60 * | DLCI (6 bits) |SDLC| EA | 61 * +----+----+----+----+----+----+----+----+ 62 */ 63 64 #define FR_EA_BIT 0x01 65 66 #define FR_CR_BIT 0x02000000 67 #define FR_DE_BIT 0x00020000 68 #define FR_BECN_BIT 0x00040000 69 #define FR_FECN_BIT 0x00080000 70 #define FR_SDLC_BIT 0x00000002 71 72 73 static const struct tok fr_header_flag_values[] = { 74 { FR_CR_BIT, "C!" }, 75 { FR_DE_BIT, "DE" }, 76 { FR_BECN_BIT, "BECN" }, 77 { FR_FECN_BIT, "FECN" }, 78 { FR_SDLC_BIT, "sdlcore" }, 79 { 0, NULL } 80 }; 81 82 /* FRF.15 / FRF.16 */ 83 #define MFR_B_BIT 0x80 84 #define MFR_E_BIT 0x40 85 #define MFR_C_BIT 0x20 86 #define MFR_BEC_MASK (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT) 87 #define MFR_CTRL_FRAME (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT) 88 #define MFR_FRAG_FRAME (MFR_B_BIT | MFR_E_BIT ) 89 90 static const struct tok frf_flag_values[] = { 91 { MFR_B_BIT, "Begin" }, 92 { MFR_E_BIT, "End" }, 93 { MFR_C_BIT, "Control" }, 94 { 0, NULL } 95 }; 96 97 /* Finds out Q.922 address length, DLCI and flags. Returns 1 on success, 98 * 0 on invalid address, -1 on truncated packet 99 * save the flags dep. on address length 100 */ 101 static int parse_q922_addr(netdissect_options *ndo, 102 const u_char *p, u_int *dlci, 103 u_int *addr_len, uint8_t *flags, u_int length) 104 { 105 if (!ND_TTEST(p[0]) || length < 1) 106 return -1; 107 if ((p[0] & FR_EA_BIT)) 108 return 0; 109 110 if (!ND_TTEST(p[1]) || length < 2) 111 return -1; 112 *addr_len = 2; 113 *dlci = ((p[0] & 0xFC) << 2) | ((p[1] & 0xF0) >> 4); 114 115 flags[0] = p[0] & 0x02; /* populate the first flag fields */ 116 flags[1] = p[1] & 0x0c; 117 flags[2] = 0; /* clear the rest of the flags */ 118 flags[3] = 0; 119 120 if (p[1] & FR_EA_BIT) 121 return 1; /* 2-byte Q.922 address */ 122 123 p += 2; 124 length -= 2; 125 if (!ND_TTEST(p[0]) || length < 1) 126 return -1; 127 (*addr_len)++; /* 3- or 4-byte Q.922 address */ 128 if ((p[0] & FR_EA_BIT) == 0) { 129 *dlci = (*dlci << 7) | (p[0] >> 1); 130 (*addr_len)++; /* 4-byte Q.922 address */ 131 p++; 132 length--; 133 } 134 135 if (!ND_TTEST(p[0]) || length < 1) 136 return -1; 137 if ((p[0] & FR_EA_BIT) == 0) 138 return 0; /* more than 4 bytes of Q.922 address? */ 139 140 flags[3] = p[0] & 0x02; 141 142 *dlci = (*dlci << 6) | (p[0] >> 2); 143 144 return 1; 145 } 146 147 char * 148 q922_string(netdissect_options *ndo, const u_char *p, u_int length) 149 { 150 151 static u_int dlci, addr_len; 152 static uint8_t flags[4]; 153 static char buffer[sizeof("DLCI xxxxxxxxxx")]; 154 memset(buffer, 0, sizeof(buffer)); 155 156 if (parse_q922_addr(ndo, p, &dlci, &addr_len, flags, length) == 1){ 157 snprintf(buffer, sizeof(buffer), "DLCI %u", dlci); 158 } 159 160 return buffer; 161 } 162 163 164 /* Frame Relay packet structure, with flags and CRC removed 165 166 +---------------------------+ 167 | Q.922 Address* | 168 +-- --+ 169 | | 170 +---------------------------+ 171 | Control (UI = 0x03) | 172 +---------------------------+ 173 | Optional Pad (0x00) | 174 +---------------------------+ 175 | NLPID | 176 +---------------------------+ 177 | . | 178 | . | 179 | . | 180 | Data | 181 | . | 182 | . | 183 +---------------------------+ 184 185 * Q.922 addresses, as presently defined, are two octets and 186 contain a 10-bit DLCI. In some networks Q.922 addresses 187 may optionally be increased to three or four octets. 188 */ 189 190 static void 191 fr_hdr_print(netdissect_options *ndo, 192 int length, u_int addr_len, u_int dlci, uint8_t *flags, uint16_t nlpid) 193 { 194 if (ndo->ndo_qflag) { 195 ND_PRINT((ndo, "Q.922, DLCI %u, length %u: ", 196 dlci, 197 length)); 198 } else { 199 if (nlpid <= 0xff) /* if its smaller than 256 then its a NLPID */ 200 ND_PRINT((ndo, "Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ", 201 addr_len, 202 dlci, 203 bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), 204 tok2str(nlpid_values,"unknown", nlpid), 205 nlpid, 206 length)); 207 else /* must be an ethertype */ 208 ND_PRINT((ndo, "Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ", 209 addr_len, 210 dlci, 211 bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), 212 tok2str(ethertype_values, "unknown", nlpid), 213 nlpid, 214 length)); 215 } 216 } 217 218 u_int 219 fr_if_print(netdissect_options *ndo, 220 const struct pcap_pkthdr *h, register const u_char *p) 221 { 222 register u_int length = h->len; 223 register u_int caplen = h->caplen; 224 225 ND_TCHECK2(*p, 4); /* minimum frame header length */ 226 227 if ((length = fr_print(ndo, p, length)) == 0) 228 return (0); 229 else 230 return length; 231 trunc: 232 ND_PRINT((ndo, "[|fr]")); 233 return caplen; 234 } 235 236 u_int 237 fr_print(netdissect_options *ndo, 238 register const u_char *p, u_int length) 239 { 240 int ret; 241 uint16_t extracted_ethertype; 242 u_int dlci; 243 u_int addr_len; 244 uint16_t nlpid; 245 u_int hdr_len; 246 uint8_t flags[4]; 247 248 ret = parse_q922_addr(ndo, p, &dlci, &addr_len, flags, length); 249 if (ret == -1) 250 goto trunc; 251 if (ret == 0) { 252 ND_PRINT((ndo, "Q.922, invalid address")); 253 return 0; 254 } 255 256 ND_TCHECK(p[addr_len]); 257 if (length < addr_len + 1) 258 goto trunc; 259 260 if (p[addr_len] != LLC_UI && dlci != 0) { 261 /* 262 * Let's figure out if we have Cisco-style encapsulation, 263 * with an Ethernet type (Cisco HDLC type?) following the 264 * address. 265 */ 266 if (!ND_TTEST2(p[addr_len], 2) || length < addr_len + 2) { 267 /* no Ethertype */ 268 ND_PRINT((ndo, "UI %02x! ", p[addr_len])); 269 } else { 270 extracted_ethertype = EXTRACT_16BITS(p+addr_len); 271 272 if (ndo->ndo_eflag) 273 fr_hdr_print(ndo, length, addr_len, dlci, 274 flags, extracted_ethertype); 275 276 if (ethertype_print(ndo, extracted_ethertype, 277 p+addr_len+ETHERTYPE_LEN, 278 length-addr_len-ETHERTYPE_LEN, 279 ndo->ndo_snapend-p-addr_len-ETHERTYPE_LEN, 280 NULL, NULL) == 0) 281 /* ether_type not known, probably it wasn't one */ 282 ND_PRINT((ndo, "UI %02x! ", p[addr_len])); 283 else 284 return addr_len + 2; 285 } 286 } 287 288 ND_TCHECK(p[addr_len+1]); 289 if (length < addr_len + 2) 290 goto trunc; 291 292 if (p[addr_len + 1] == 0) { 293 /* 294 * Assume a pad byte after the control (UI) byte. 295 * A pad byte should only be used with 3-byte Q.922. 296 */ 297 if (addr_len != 3) 298 ND_PRINT((ndo, "Pad! ")); 299 hdr_len = addr_len + 1 /* UI */ + 1 /* pad */ + 1 /* NLPID */; 300 } else { 301 /* 302 * Not a pad byte. 303 * A pad byte should be used with 3-byte Q.922. 304 */ 305 if (addr_len == 3) 306 ND_PRINT((ndo, "No pad! ")); 307 hdr_len = addr_len + 1 /* UI */ + 1 /* NLPID */; 308 } 309 310 ND_TCHECK(p[hdr_len - 1]); 311 if (length < hdr_len) 312 goto trunc; 313 nlpid = p[hdr_len - 1]; 314 315 if (ndo->ndo_eflag) 316 fr_hdr_print(ndo, length, addr_len, dlci, flags, nlpid); 317 p += hdr_len; 318 length -= hdr_len; 319 320 switch (nlpid) { 321 case NLPID_IP: 322 ip_print(ndo, p, length); 323 break; 324 325 case NLPID_IP6: 326 ip6_print(ndo, p, length); 327 break; 328 329 case NLPID_CLNP: 330 case NLPID_ESIS: 331 case NLPID_ISIS: 332 isoclns_print(ndo, p - 1, length + 1); /* OSI printers need the NLPID field */ 333 break; 334 335 case NLPID_SNAP: 336 if (snap_print(ndo, p, length, ndo->ndo_snapend - p, NULL, NULL, 0) == 0) { 337 /* ether_type not known, print raw packet */ 338 if (!ndo->ndo_eflag) 339 fr_hdr_print(ndo, length + hdr_len, hdr_len, 340 dlci, flags, nlpid); 341 if (!ndo->ndo_suppress_default_print) 342 ND_DEFAULTPRINT(p - hdr_len, length + hdr_len); 343 } 344 break; 345 346 case NLPID_Q933: 347 q933_print(ndo, p, length); 348 break; 349 350 case NLPID_MFR: 351 frf15_print(ndo, p, length); 352 break; 353 354 case NLPID_PPP: 355 ppp_print(ndo, p, length); 356 break; 357 358 default: 359 if (!ndo->ndo_eflag) 360 fr_hdr_print(ndo, length + hdr_len, addr_len, 361 dlci, flags, nlpid); 362 if (!ndo->ndo_xflag) 363 ND_DEFAULTPRINT(p, length); 364 } 365 366 return hdr_len; 367 368 trunc: 369 ND_PRINT((ndo, "[|fr]")); 370 return 0; 371 372 } 373 374 u_int 375 mfr_if_print(netdissect_options *ndo, 376 const struct pcap_pkthdr *h, register const u_char *p) 377 { 378 register u_int length = h->len; 379 register u_int caplen = h->caplen; 380 381 ND_TCHECK2(*p, 2); /* minimum frame header length */ 382 383 if ((length = mfr_print(ndo, p, length)) == 0) 384 return (0); 385 else 386 return length; 387 trunc: 388 ND_PRINT((ndo, "[|mfr]")); 389 return caplen; 390 } 391 392 393 #define MFR_CTRL_MSG_ADD_LINK 1 394 #define MFR_CTRL_MSG_ADD_LINK_ACK 2 395 #define MFR_CTRL_MSG_ADD_LINK_REJ 3 396 #define MFR_CTRL_MSG_HELLO 4 397 #define MFR_CTRL_MSG_HELLO_ACK 5 398 #define MFR_CTRL_MSG_REMOVE_LINK 6 399 #define MFR_CTRL_MSG_REMOVE_LINK_ACK 7 400 401 static const struct tok mfr_ctrl_msg_values[] = { 402 { MFR_CTRL_MSG_ADD_LINK, "Add Link" }, 403 { MFR_CTRL_MSG_ADD_LINK_ACK, "Add Link ACK" }, 404 { MFR_CTRL_MSG_ADD_LINK_REJ, "Add Link Reject" }, 405 { MFR_CTRL_MSG_HELLO, "Hello" }, 406 { MFR_CTRL_MSG_HELLO_ACK, "Hello ACK" }, 407 { MFR_CTRL_MSG_REMOVE_LINK, "Remove Link" }, 408 { MFR_CTRL_MSG_REMOVE_LINK_ACK, "Remove Link ACK" }, 409 { 0, NULL } 410 }; 411 412 #define MFR_CTRL_IE_BUNDLE_ID 1 413 #define MFR_CTRL_IE_LINK_ID 2 414 #define MFR_CTRL_IE_MAGIC_NUM 3 415 #define MFR_CTRL_IE_TIMESTAMP 5 416 #define MFR_CTRL_IE_VENDOR_EXT 6 417 #define MFR_CTRL_IE_CAUSE 7 418 419 static const struct tok mfr_ctrl_ie_values[] = { 420 { MFR_CTRL_IE_BUNDLE_ID, "Bundle ID"}, 421 { MFR_CTRL_IE_LINK_ID, "Link ID"}, 422 { MFR_CTRL_IE_MAGIC_NUM, "Magic Number"}, 423 { MFR_CTRL_IE_TIMESTAMP, "Timestamp"}, 424 { MFR_CTRL_IE_VENDOR_EXT, "Vendor Extension"}, 425 { MFR_CTRL_IE_CAUSE, "Cause"}, 426 { 0, NULL } 427 }; 428 429 #define MFR_ID_STRING_MAXLEN 50 430 431 struct ie_tlv_header_t { 432 uint8_t ie_type; 433 uint8_t ie_len; 434 }; 435 436 u_int 437 mfr_print(netdissect_options *ndo, 438 register const u_char *p, u_int length) 439 { 440 u_int tlen,idx,hdr_len = 0; 441 uint16_t sequence_num; 442 uint8_t ie_type,ie_len; 443 const uint8_t *tptr; 444 445 446 /* 447 * FRF.16 Link Integrity Control Frame 448 * 449 * 7 6 5 4 3 2 1 0 450 * +----+----+----+----+----+----+----+----+ 451 * | B | E | C=1| 0 0 0 0 | EA | 452 * +----+----+----+----+----+----+----+----+ 453 * | 0 0 0 0 0 0 0 0 | 454 * +----+----+----+----+----+----+----+----+ 455 * | message type | 456 * +----+----+----+----+----+----+----+----+ 457 */ 458 459 ND_TCHECK2(*p, 4); /* minimum frame header length */ 460 461 if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) { 462 ND_PRINT((ndo, "FRF.16 Control, Flags [%s], %s, length %u", 463 bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)), 464 tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",p[2]), 465 length)); 466 tptr = p + 3; 467 tlen = length -3; 468 hdr_len = 3; 469 470 if (!ndo->ndo_vflag) 471 return hdr_len; 472 473 while (tlen>sizeof(struct ie_tlv_header_t)) { 474 ND_TCHECK2(*tptr, sizeof(struct ie_tlv_header_t)); 475 ie_type=tptr[0]; 476 ie_len=tptr[1]; 477 478 ND_PRINT((ndo, "\n\tIE %s (%u), length %u: ", 479 tok2str(mfr_ctrl_ie_values,"Unknown",ie_type), 480 ie_type, 481 ie_len)); 482 483 /* infinite loop check */ 484 if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t)) 485 return hdr_len; 486 487 ND_TCHECK2(*tptr, ie_len); 488 tptr+=sizeof(struct ie_tlv_header_t); 489 /* tlv len includes header */ 490 ie_len-=sizeof(struct ie_tlv_header_t); 491 tlen-=sizeof(struct ie_tlv_header_t); 492 493 switch (ie_type) { 494 495 case MFR_CTRL_IE_MAGIC_NUM: 496 ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(tptr))); 497 break; 498 499 case MFR_CTRL_IE_BUNDLE_ID: /* same message format */ 500 case MFR_CTRL_IE_LINK_ID: 501 for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) { 502 if (*(tptr+idx) != 0) /* don't print null termination */ 503 safeputchar(ndo, *(tptr + idx)); 504 else 505 break; 506 } 507 break; 508 509 case MFR_CTRL_IE_TIMESTAMP: 510 if (ie_len == sizeof(struct timeval)) { 511 ts_print(ndo, (const struct timeval *)tptr); 512 break; 513 } 514 /* fall through and hexdump if no unix timestamp */ 515 516 /* 517 * FIXME those are the defined IEs that lack a decoder 518 * you are welcome to contribute code ;-) 519 */ 520 521 case MFR_CTRL_IE_VENDOR_EXT: 522 case MFR_CTRL_IE_CAUSE: 523 524 default: 525 if (ndo->ndo_vflag <= 1) 526 print_unknown_data(ndo, tptr, "\n\t ", ie_len); 527 break; 528 } 529 530 /* do we want to see a hexdump of the IE ? */ 531 if (ndo->ndo_vflag > 1 ) 532 print_unknown_data(ndo, tptr, "\n\t ", ie_len); 533 534 tlen-=ie_len; 535 tptr+=ie_len; 536 } 537 return hdr_len; 538 } 539 /* 540 * FRF.16 Fragmentation Frame 541 * 542 * 7 6 5 4 3 2 1 0 543 * +----+----+----+----+----+----+----+----+ 544 * | B | E | C=0|seq. (high 4 bits) | EA | 545 * +----+----+----+----+----+----+----+----+ 546 * | sequence (low 8 bits) | 547 * +----+----+----+----+----+----+----+----+ 548 * | DLCI (6 bits) | CR | EA | 549 * +----+----+----+----+----+----+----+----+ 550 * | DLCI (4 bits) |FECN|BECN| DE | EA | 551 * +----+----+----+----+----+----+----+----+ 552 */ 553 554 sequence_num = (p[0]&0x1e)<<7 | p[1]; 555 /* whole packet or first fragment ? */ 556 if ((p[0] & MFR_BEC_MASK) == MFR_FRAG_FRAME || 557 (p[0] & MFR_BEC_MASK) == MFR_B_BIT) { 558 ND_PRINT((ndo, "FRF.16 Frag, seq %u, Flags [%s], ", 559 sequence_num, 560 bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)))); 561 hdr_len = 2; 562 fr_print(ndo, p+hdr_len,length-hdr_len); 563 return hdr_len; 564 } 565 566 /* must be a middle or the last fragment */ 567 ND_PRINT((ndo, "FRF.16 Frag, seq %u, Flags [%s]", 568 sequence_num, 569 bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)))); 570 print_unknown_data(ndo, p, "\n\t", length); 571 572 return hdr_len; 573 574 trunc: 575 ND_PRINT((ndo, "[|mfr]")); 576 return length; 577 } 578 579 /* an NLPID of 0xb1 indicates a 2-byte 580 * FRF.15 header 581 * 582 * 7 6 5 4 3 2 1 0 583 * +----+----+----+----+----+----+----+----+ 584 * ~ Q.922 header ~ 585 * +----+----+----+----+----+----+----+----+ 586 * | NLPID (8 bits) | NLPID=0xb1 587 * +----+----+----+----+----+----+----+----+ 588 * | B | E | C |seq. (high 4 bits) | R | 589 * +----+----+----+----+----+----+----+----+ 590 * | sequence (low 8 bits) | 591 * +----+----+----+----+----+----+----+----+ 592 */ 593 594 #define FR_FRF15_FRAGTYPE 0x01 595 596 static void 597 frf15_print(netdissect_options *ndo, 598 const u_char *p, u_int length) 599 { 600 uint16_t sequence_num, flags; 601 602 if (length < 2) 603 goto trunc; 604 ND_TCHECK2(*p, 2); 605 606 flags = p[0]&MFR_BEC_MASK; 607 sequence_num = (p[0]&0x1e)<<7 | p[1]; 608 609 ND_PRINT((ndo, "FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u", 610 sequence_num, 611 bittok2str(frf_flag_values,"none",flags), 612 p[0]&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End", 613 length)); 614 615 /* TODO: 616 * depending on all permutations of the B, E and C bit 617 * dig as deep as we can - e.g. on the first (B) fragment 618 * there is enough payload to print the IP header 619 * on non (B) fragments it depends if the fragmentation 620 * model is end-to-end or interface based wether we want to print 621 * another Q.922 header 622 */ 623 return; 624 625 trunc: 626 ND_PRINT((ndo, "[|frf.15]")); 627 } 628 629 /* 630 * Q.933 decoding portion for framerelay specific. 631 */ 632 633 /* Q.933 packet format 634 Format of Other Protocols 635 using Q.933 NLPID 636 +-------------------------------+ 637 | Q.922 Address | 638 +---------------+---------------+ 639 |Control 0x03 | NLPID 0x08 | 640 +---------------+---------------+ 641 | L2 Protocol ID | 642 | octet 1 | octet 2 | 643 +-------------------------------+ 644 | L3 Protocol ID | 645 | octet 2 | octet 2 | 646 +-------------------------------+ 647 | Protocol Data | 648 +-------------------------------+ 649 | FCS | 650 +-------------------------------+ 651 */ 652 653 /* L2 (Octet 1)- Call Reference Usually is 0x0 */ 654 655 /* 656 * L2 (Octet 2)- Message Types definition 1 byte long. 657 */ 658 /* Call Establish */ 659 #define MSG_TYPE_ESC_TO_NATIONAL 0x00 660 #define MSG_TYPE_ALERT 0x01 661 #define MSG_TYPE_CALL_PROCEEDING 0x02 662 #define MSG_TYPE_CONNECT 0x07 663 #define MSG_TYPE_CONNECT_ACK 0x0F 664 #define MSG_TYPE_PROGRESS 0x03 665 #define MSG_TYPE_SETUP 0x05 666 /* Call Clear */ 667 #define MSG_TYPE_DISCONNECT 0x45 668 #define MSG_TYPE_RELEASE 0x4D 669 #define MSG_TYPE_RELEASE_COMPLETE 0x5A 670 #define MSG_TYPE_RESTART 0x46 671 #define MSG_TYPE_RESTART_ACK 0x4E 672 /* Status */ 673 #define MSG_TYPE_STATUS 0x7D 674 #define MSG_TYPE_STATUS_ENQ 0x75 675 676 static const struct tok fr_q933_msg_values[] = { 677 { MSG_TYPE_ESC_TO_NATIONAL, "ESC to National" }, 678 { MSG_TYPE_ALERT, "Alert" }, 679 { MSG_TYPE_CALL_PROCEEDING, "Call proceeding" }, 680 { MSG_TYPE_CONNECT, "Connect" }, 681 { MSG_TYPE_CONNECT_ACK, "Connect ACK" }, 682 { MSG_TYPE_PROGRESS, "Progress" }, 683 { MSG_TYPE_SETUP, "Setup" }, 684 { MSG_TYPE_DISCONNECT, "Disconnect" }, 685 { MSG_TYPE_RELEASE, "Release" }, 686 { MSG_TYPE_RELEASE_COMPLETE, "Release Complete" }, 687 { MSG_TYPE_RESTART, "Restart" }, 688 { MSG_TYPE_RESTART_ACK, "Restart ACK" }, 689 { MSG_TYPE_STATUS, "Status Reply" }, 690 { MSG_TYPE_STATUS_ENQ, "Status Enquiry" }, 691 { 0, NULL } 692 }; 693 694 #define IE_IS_SINGLE_OCTET(iecode) ((iecode) & 0x80) 695 #define IE_IS_SHIFT(iecode) (((iecode) & 0xF0) == 0x90) 696 #define IE_SHIFT_IS_NON_LOCKING(iecode) ((iecode) & 0x08) 697 #define IE_SHIFT_IS_LOCKING(iecode) (!(IE_SHIFT_IS_NON_LOCKING(iecode))) 698 #define IE_SHIFT_CODESET(iecode) ((iecode) & 0x07) 699 700 #define FR_LMI_ANSI_REPORT_TYPE_IE 0x01 701 #define FR_LMI_ANSI_LINK_VERIFY_IE_91 0x19 /* details? */ 702 #define FR_LMI_ANSI_LINK_VERIFY_IE 0x03 703 #define FR_LMI_ANSI_PVC_STATUS_IE 0x07 704 705 #define FR_LMI_CCITT_REPORT_TYPE_IE 0x51 706 #define FR_LMI_CCITT_LINK_VERIFY_IE 0x53 707 #define FR_LMI_CCITT_PVC_STATUS_IE 0x57 708 709 static const struct tok fr_q933_ie_values_codeset_0_5[] = { 710 { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" }, 711 { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" }, 712 { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" }, 713 { FR_LMI_ANSI_PVC_STATUS_IE, "ANSI PVC Status" }, 714 { FR_LMI_CCITT_REPORT_TYPE_IE, "CCITT Report Type" }, 715 { FR_LMI_CCITT_LINK_VERIFY_IE, "CCITT Link Verify" }, 716 { FR_LMI_CCITT_PVC_STATUS_IE, "CCITT PVC Status" }, 717 { 0, NULL } 718 }; 719 720 #define FR_LMI_REPORT_TYPE_IE_FULL_STATUS 0 721 #define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY 1 722 #define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC 2 723 724 static const struct tok fr_lmi_report_type_ie_values[] = { 725 { FR_LMI_REPORT_TYPE_IE_FULL_STATUS, "Full Status" }, 726 { FR_LMI_REPORT_TYPE_IE_LINK_VERIFY, "Link verify" }, 727 { FR_LMI_REPORT_TYPE_IE_ASYNC_PVC, "Async PVC Status" }, 728 { 0, NULL } 729 }; 730 731 /* array of 16 codesets - currently we only support codepage 0 and 5 */ 732 static const struct tok *fr_q933_ie_codesets[] = { 733 fr_q933_ie_values_codeset_0_5, 734 NULL, 735 NULL, 736 NULL, 737 NULL, 738 fr_q933_ie_values_codeset_0_5, 739 NULL, 740 NULL, 741 NULL, 742 NULL, 743 NULL, 744 NULL, 745 NULL, 746 NULL, 747 NULL, 748 NULL 749 }; 750 751 static int fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, 752 u_int ielength, const u_char *p); 753 754 typedef int (*codeset_pr_func_t)(netdissect_options *, u_int iecode, 755 u_int ielength, const u_char *p); 756 757 /* array of 16 codesets - currently we only support codepage 0 and 5 */ 758 static const codeset_pr_func_t fr_q933_print_ie_codeset[] = { 759 fr_q933_print_ie_codeset_0_5, 760 NULL, 761 NULL, 762 NULL, 763 NULL, 764 fr_q933_print_ie_codeset_0_5, 765 NULL, 766 NULL, 767 NULL, 768 NULL, 769 NULL, 770 NULL, 771 NULL, 772 NULL, 773 NULL, 774 NULL 775 }; 776 777 /* 778 * ITU-T Q.933. 779 * 780 * p points to octet 2, the octet containing the length of the 781 * call reference value, so p[n] is octet n+2 ("octet X" is as 782 * used in Q.931/Q.933). 783 * 784 * XXX - actually used both for Q.931 and Q.933. 785 */ 786 void 787 q933_print(netdissect_options *ndo, 788 const u_char *p, u_int length) 789 { 790 u_int olen; 791 u_int call_ref_length, i; 792 uint8_t call_ref[15]; /* maximum length - length field is 4 bits */ 793 u_int msgtype; 794 u_int iecode; 795 u_int ielength; 796 u_int codeset = 0; 797 u_int is_ansi = 0; 798 u_int ie_is_known; 799 u_int non_locking_shift; 800 u_int unshift_codeset; 801 802 ND_PRINT((ndo, "%s", ndo->ndo_eflag ? "" : "Q.933")); 803 804 if (length == 0 || !ND_TTEST(*p)) { 805 if (!ndo->ndo_eflag) 806 ND_PRINT((ndo, ", ")); 807 ND_PRINT((ndo, "length %u", length)); 808 goto trunc; 809 } 810 811 /* 812 * Get the length of the call reference value. 813 */ 814 olen = length; /* preserve the original length for display */ 815 call_ref_length = (*p) & 0x0f; 816 p++; 817 length--; 818 819 /* 820 * Get the call reference value. 821 */ 822 for (i = 0; i < call_ref_length; i++) { 823 if (length == 0 || !ND_TTEST(*p)) { 824 if (!ndo->ndo_eflag) 825 ND_PRINT((ndo, ", ")); 826 ND_PRINT((ndo, "length %u", olen)); 827 goto trunc; 828 } 829 call_ref[i] = *p; 830 p++; 831 length--; 832 } 833 834 /* 835 * Get the message type. 836 */ 837 if (length == 0 || !ND_TTEST(*p)) { 838 if (!ndo->ndo_eflag) 839 ND_PRINT((ndo, ", ")); 840 ND_PRINT((ndo, "length %u", olen)); 841 goto trunc; 842 } 843 msgtype = *p; 844 p++; 845 length--; 846 847 /* 848 * Peek ahead to see if we start with a shift. 849 */ 850 non_locking_shift = 0; 851 unshift_codeset = codeset; 852 if (length != 0) { 853 if (!ND_TTEST(*p)) { 854 if (!ndo->ndo_eflag) 855 ND_PRINT((ndo, ", ")); 856 ND_PRINT((ndo, "length %u", olen)); 857 goto trunc; 858 } 859 iecode = *p; 860 if (IE_IS_SHIFT(iecode)) { 861 /* 862 * It's a shift. Skip over it. 863 */ 864 p++; 865 length--; 866 867 /* 868 * Get the codeset. 869 */ 870 codeset = IE_SHIFT_CODESET(iecode); 871 872 /* 873 * If it's a locking shift to codeset 5, 874 * mark this as ANSI. (XXX - 5 is actually 875 * for national variants in general, not 876 * the US variant in particular, but maybe 877 * this is more American exceptionalism. :-)) 878 */ 879 if (IE_SHIFT_IS_LOCKING(iecode)) { 880 /* 881 * It's a locking shift. 882 */ 883 if (codeset == 5) { 884 /* 885 * It's a locking shift to 886 * codeset 5, so this is 887 * T1.617 Annex D. 888 */ 889 is_ansi = 1; 890 } 891 } else { 892 /* 893 * It's a non-locking shift. 894 * Remember the current codeset, so we 895 * can revert to it after the next IE. 896 */ 897 non_locking_shift = 1; 898 unshift_codeset = 0; 899 } 900 } 901 } 902 903 /* printing out header part */ 904 if (!ndo->ndo_eflag) 905 ND_PRINT((ndo, ", ")); 906 ND_PRINT((ndo, "%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset)); 907 908 if (call_ref_length != 0) { 909 ND_TCHECK(p[0]); 910 if (call_ref_length > 1 || p[0] != 0) { 911 /* 912 * Not a dummy call reference. 913 */ 914 ND_PRINT((ndo, ", Call Ref: 0x")); 915 for (i = 0; i < call_ref_length; i++) 916 ND_PRINT((ndo, "%02x", call_ref[i])); 917 } 918 } 919 if (ndo->ndo_vflag) { 920 ND_PRINT((ndo, ", %s (0x%02x), length %u", 921 tok2str(fr_q933_msg_values, 922 "unknown message", msgtype), 923 msgtype, 924 olen)); 925 } else { 926 ND_PRINT((ndo, ", %s", 927 tok2str(fr_q933_msg_values, 928 "unknown message 0x%02x", msgtype))); 929 } 930 931 /* Loop through the rest of the IEs */ 932 while (length != 0) { 933 /* 934 * What's the state of any non-locking shifts? 935 */ 936 if (non_locking_shift == 1) { 937 /* 938 * There's a non-locking shift in effect for 939 * this IE. Count it, so we reset the codeset 940 * before the next IE. 941 */ 942 non_locking_shift = 2; 943 } else if (non_locking_shift == 2) { 944 /* 945 * Unshift. 946 */ 947 codeset = unshift_codeset; 948 non_locking_shift = 0; 949 } 950 951 /* 952 * Get the first octet of the IE. 953 */ 954 if (!ND_TTEST(*p)) { 955 if (!ndo->ndo_vflag) { 956 ND_PRINT((ndo, ", length %u", olen)); 957 } 958 goto trunc; 959 } 960 iecode = *p; 961 p++; 962 length--; 963 964 /* Single-octet IE? */ 965 if (IE_IS_SINGLE_OCTET(iecode)) { 966 /* 967 * Yes. Is it a shift? 968 */ 969 if (IE_IS_SHIFT(iecode)) { 970 /* 971 * Yes. Is it locking? 972 */ 973 if (IE_SHIFT_IS_LOCKING(iecode)) { 974 /* 975 * Yes. 976 */ 977 non_locking_shift = 0; 978 } else { 979 /* 980 * No. Remember the current 981 * codeset, so we can revert 982 * to it after the next IE. 983 */ 984 non_locking_shift = 1; 985 unshift_codeset = codeset; 986 } 987 988 /* 989 * Get the codeset. 990 */ 991 codeset = IE_SHIFT_CODESET(iecode); 992 } 993 } else { 994 /* 995 * No. Get the IE length. 996 */ 997 if (length == 0 || !ND_TTEST(*p)) { 998 if (!ndo->ndo_vflag) { 999 ND_PRINT((ndo, ", length %u", olen)); 1000 } 1001 goto trunc; 1002 } 1003 ielength = *p; 1004 p++; 1005 length--; 1006 1007 /* lets do the full IE parsing only in verbose mode 1008 * however some IEs (DLCI Status, Link Verify) 1009 * are also interesting in non-verbose mode */ 1010 if (ndo->ndo_vflag) { 1011 ND_PRINT((ndo, "\n\t%s IE (0x%02x), length %u: ", 1012 tok2str(fr_q933_ie_codesets[codeset], 1013 "unknown", iecode), 1014 iecode, 1015 ielength)); 1016 } 1017 1018 /* sanity checks */ 1019 if (iecode == 0 || ielength == 0) { 1020 return; 1021 } 1022 if (length < ielength || !ND_TTEST2(*p, ielength)) { 1023 if (!ndo->ndo_vflag) { 1024 ND_PRINT((ndo, ", length %u", olen)); 1025 } 1026 goto trunc; 1027 } 1028 1029 ie_is_known = 0; 1030 if (fr_q933_print_ie_codeset[codeset] != NULL) { 1031 ie_is_known = fr_q933_print_ie_codeset[codeset](ndo, iecode, ielength, p); 1032 } 1033 1034 if (ie_is_known) { 1035 /* 1036 * Known IE; do we want to see a hexdump 1037 * of it? 1038 */ 1039 if (ndo->ndo_vflag > 1) { 1040 /* Yes. */ 1041 print_unknown_data(ndo, p, "\n\t ", ielength); 1042 } 1043 } else { 1044 /* 1045 * Unknown IE; if we're printing verbosely, 1046 * print its content in hex. 1047 */ 1048 if (ndo->ndo_vflag >= 1) { 1049 print_unknown_data(ndo, p, "\n\t", ielength); 1050 } 1051 } 1052 1053 length -= ielength; 1054 p += ielength; 1055 } 1056 } 1057 if (!ndo->ndo_vflag) { 1058 ND_PRINT((ndo, ", length %u", olen)); 1059 } 1060 return; 1061 1062 trunc: 1063 ND_PRINT((ndo, "[|q.933]")); 1064 } 1065 1066 static int 1067 fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, 1068 u_int ielength, const u_char *p) 1069 { 1070 u_int dlci; 1071 1072 switch (iecode) { 1073 1074 case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */ 1075 case FR_LMI_CCITT_REPORT_TYPE_IE: 1076 if (ielength < 1) { 1077 if (!ndo->ndo_vflag) { 1078 ND_PRINT((ndo, ", ")); 1079 } 1080 ND_PRINT((ndo, "Invalid REPORT TYPE IE")); 1081 return 1; 1082 } 1083 if (ndo->ndo_vflag) { 1084 ND_PRINT((ndo, "%s (%u)", 1085 tok2str(fr_lmi_report_type_ie_values,"unknown",p[0]), 1086 p[0])); 1087 } 1088 return 1; 1089 1090 case FR_LMI_ANSI_LINK_VERIFY_IE: /* fall through */ 1091 case FR_LMI_CCITT_LINK_VERIFY_IE: 1092 case FR_LMI_ANSI_LINK_VERIFY_IE_91: 1093 if (!ndo->ndo_vflag) { 1094 ND_PRINT((ndo, ", ")); 1095 } 1096 if (ielength < 2) { 1097 ND_PRINT((ndo, "Invalid LINK VERIFY IE")); 1098 return 1; 1099 } 1100 ND_PRINT((ndo, "TX Seq: %3d, RX Seq: %3d", p[0], p[1])); 1101 return 1; 1102 1103 case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */ 1104 case FR_LMI_CCITT_PVC_STATUS_IE: 1105 if (!ndo->ndo_vflag) { 1106 ND_PRINT((ndo, ", ")); 1107 } 1108 /* now parse the DLCI information element. */ 1109 if ((ielength < 3) || 1110 (p[0] & 0x80) || 1111 ((ielength == 3) && !(p[1] & 0x80)) || 1112 ((ielength == 4) && ((p[1] & 0x80) || !(p[2] & 0x80))) || 1113 ((ielength == 5) && ((p[1] & 0x80) || (p[2] & 0x80) || 1114 !(p[3] & 0x80))) || 1115 (ielength > 5) || 1116 !(p[ielength - 1] & 0x80)) { 1117 ND_PRINT((ndo, "Invalid DLCI in PVC STATUS IE")); 1118 return 1; 1119 } 1120 1121 dlci = ((p[0] & 0x3F) << 4) | ((p[1] & 0x78) >> 3); 1122 if (ielength == 4) { 1123 dlci = (dlci << 6) | ((p[2] & 0x7E) >> 1); 1124 } 1125 else if (ielength == 5) { 1126 dlci = (dlci << 13) | (p[2] & 0x7F) | ((p[3] & 0x7E) >> 1); 1127 } 1128 1129 ND_PRINT((ndo, "DLCI %u: status %s%s", dlci, 1130 p[ielength - 1] & 0x8 ? "New, " : "", 1131 p[ielength - 1] & 0x2 ? "Active" : "Inactive")); 1132 return 1; 1133 } 1134 1135 return 0; 1136 } 1137 /* 1138 * Local Variables: 1139 * c-style: whitesmith 1140 * c-basic-offset: 8 1141 * End: 1142 */ 1143