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 if (length < 4) { 461 ND_PRINT((ndo, "Message too short (%u bytes)", length)); 462 return length; 463 } 464 465 if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) { 466 ND_PRINT((ndo, "FRF.16 Control, Flags [%s], %s, length %u", 467 bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)), 468 tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",p[2]), 469 length)); 470 tptr = p + 3; 471 tlen = length -3; 472 hdr_len = 3; 473 474 if (!ndo->ndo_vflag) 475 return hdr_len; 476 477 while (tlen>sizeof(struct ie_tlv_header_t)) { 478 ND_TCHECK2(*tptr, sizeof(struct ie_tlv_header_t)); 479 ie_type=tptr[0]; 480 ie_len=tptr[1]; 481 482 ND_PRINT((ndo, "\n\tIE %s (%u), length %u: ", 483 tok2str(mfr_ctrl_ie_values,"Unknown",ie_type), 484 ie_type, 485 ie_len)); 486 487 /* infinite loop check */ 488 if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t)) 489 return hdr_len; 490 491 ND_TCHECK2(*tptr, ie_len); 492 tptr+=sizeof(struct ie_tlv_header_t); 493 /* tlv len includes header */ 494 ie_len-=sizeof(struct ie_tlv_header_t); 495 tlen-=sizeof(struct ie_tlv_header_t); 496 497 switch (ie_type) { 498 499 case MFR_CTRL_IE_MAGIC_NUM: 500 /* FRF.16.1 Section 3.4.3 Magic Number Information Element */ 501 if (ie_len != 4) { 502 ND_PRINT((ndo, "(invalid length)")); 503 break; 504 } 505 ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(tptr))); 506 break; 507 508 case MFR_CTRL_IE_BUNDLE_ID: /* same message format */ 509 case MFR_CTRL_IE_LINK_ID: 510 for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) { 511 if (*(tptr+idx) != 0) /* don't print null termination */ 512 safeputchar(ndo, *(tptr + idx)); 513 else 514 break; 515 } 516 break; 517 518 case MFR_CTRL_IE_TIMESTAMP: 519 if (ie_len == sizeof(struct timeval)) { 520 ts_print(ndo, (const struct timeval *)tptr); 521 break; 522 } 523 /* fall through and hexdump if no unix timestamp */ 524 525 /* 526 * FIXME those are the defined IEs that lack a decoder 527 * you are welcome to contribute code ;-) 528 */ 529 530 case MFR_CTRL_IE_VENDOR_EXT: 531 case MFR_CTRL_IE_CAUSE: 532 533 default: 534 if (ndo->ndo_vflag <= 1) 535 print_unknown_data(ndo, tptr, "\n\t ", ie_len); 536 break; 537 } 538 539 /* do we want to see a hexdump of the IE ? */ 540 if (ndo->ndo_vflag > 1 ) 541 print_unknown_data(ndo, tptr, "\n\t ", ie_len); 542 543 tlen-=ie_len; 544 tptr+=ie_len; 545 } 546 return hdr_len; 547 } 548 /* 549 * FRF.16 Fragmentation Frame 550 * 551 * 7 6 5 4 3 2 1 0 552 * +----+----+----+----+----+----+----+----+ 553 * | B | E | C=0|seq. (high 4 bits) | EA | 554 * +----+----+----+----+----+----+----+----+ 555 * | sequence (low 8 bits) | 556 * +----+----+----+----+----+----+----+----+ 557 * | DLCI (6 bits) | CR | EA | 558 * +----+----+----+----+----+----+----+----+ 559 * | DLCI (4 bits) |FECN|BECN| DE | EA | 560 * +----+----+----+----+----+----+----+----+ 561 */ 562 563 sequence_num = (p[0]&0x1e)<<7 | p[1]; 564 /* whole packet or first fragment ? */ 565 if ((p[0] & MFR_BEC_MASK) == MFR_FRAG_FRAME || 566 (p[0] & MFR_BEC_MASK) == MFR_B_BIT) { 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 hdr_len = 2; 571 fr_print(ndo, p+hdr_len,length-hdr_len); 572 return hdr_len; 573 } 574 575 /* must be a middle or the last fragment */ 576 ND_PRINT((ndo, "FRF.16 Frag, seq %u, Flags [%s]", 577 sequence_num, 578 bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)))); 579 print_unknown_data(ndo, p, "\n\t", length); 580 581 return hdr_len; 582 583 trunc: 584 ND_PRINT((ndo, "[|mfr]")); 585 return length; 586 } 587 588 /* an NLPID of 0xb1 indicates a 2-byte 589 * FRF.15 header 590 * 591 * 7 6 5 4 3 2 1 0 592 * +----+----+----+----+----+----+----+----+ 593 * ~ Q.922 header ~ 594 * +----+----+----+----+----+----+----+----+ 595 * | NLPID (8 bits) | NLPID=0xb1 596 * +----+----+----+----+----+----+----+----+ 597 * | B | E | C |seq. (high 4 bits) | R | 598 * +----+----+----+----+----+----+----+----+ 599 * | sequence (low 8 bits) | 600 * +----+----+----+----+----+----+----+----+ 601 */ 602 603 #define FR_FRF15_FRAGTYPE 0x01 604 605 static void 606 frf15_print(netdissect_options *ndo, 607 const u_char *p, u_int length) 608 { 609 uint16_t sequence_num, flags; 610 611 if (length < 2) 612 goto trunc; 613 ND_TCHECK2(*p, 2); 614 615 flags = p[0]&MFR_BEC_MASK; 616 sequence_num = (p[0]&0x1e)<<7 | p[1]; 617 618 ND_PRINT((ndo, "FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u", 619 sequence_num, 620 bittok2str(frf_flag_values,"none",flags), 621 p[0]&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End", 622 length)); 623 624 /* TODO: 625 * depending on all permutations of the B, E and C bit 626 * dig as deep as we can - e.g. on the first (B) fragment 627 * there is enough payload to print the IP header 628 * on non (B) fragments it depends if the fragmentation 629 * model is end-to-end or interface based wether we want to print 630 * another Q.922 header 631 */ 632 return; 633 634 trunc: 635 ND_PRINT((ndo, "[|frf.15]")); 636 } 637 638 /* 639 * Q.933 decoding portion for framerelay specific. 640 */ 641 642 /* Q.933 packet format 643 Format of Other Protocols 644 using Q.933 NLPID 645 +-------------------------------+ 646 | Q.922 Address | 647 +---------------+---------------+ 648 |Control 0x03 | NLPID 0x08 | 649 +---------------+---------------+ 650 | L2 Protocol ID | 651 | octet 1 | octet 2 | 652 +-------------------------------+ 653 | L3 Protocol ID | 654 | octet 2 | octet 2 | 655 +-------------------------------+ 656 | Protocol Data | 657 +-------------------------------+ 658 | FCS | 659 +-------------------------------+ 660 */ 661 662 /* L2 (Octet 1)- Call Reference Usually is 0x0 */ 663 664 /* 665 * L2 (Octet 2)- Message Types definition 1 byte long. 666 */ 667 /* Call Establish */ 668 #define MSG_TYPE_ESC_TO_NATIONAL 0x00 669 #define MSG_TYPE_ALERT 0x01 670 #define MSG_TYPE_CALL_PROCEEDING 0x02 671 #define MSG_TYPE_CONNECT 0x07 672 #define MSG_TYPE_CONNECT_ACK 0x0F 673 #define MSG_TYPE_PROGRESS 0x03 674 #define MSG_TYPE_SETUP 0x05 675 /* Call Clear */ 676 #define MSG_TYPE_DISCONNECT 0x45 677 #define MSG_TYPE_RELEASE 0x4D 678 #define MSG_TYPE_RELEASE_COMPLETE 0x5A 679 #define MSG_TYPE_RESTART 0x46 680 #define MSG_TYPE_RESTART_ACK 0x4E 681 /* Status */ 682 #define MSG_TYPE_STATUS 0x7D 683 #define MSG_TYPE_STATUS_ENQ 0x75 684 685 static const struct tok fr_q933_msg_values[] = { 686 { MSG_TYPE_ESC_TO_NATIONAL, "ESC to National" }, 687 { MSG_TYPE_ALERT, "Alert" }, 688 { MSG_TYPE_CALL_PROCEEDING, "Call proceeding" }, 689 { MSG_TYPE_CONNECT, "Connect" }, 690 { MSG_TYPE_CONNECT_ACK, "Connect ACK" }, 691 { MSG_TYPE_PROGRESS, "Progress" }, 692 { MSG_TYPE_SETUP, "Setup" }, 693 { MSG_TYPE_DISCONNECT, "Disconnect" }, 694 { MSG_TYPE_RELEASE, "Release" }, 695 { MSG_TYPE_RELEASE_COMPLETE, "Release Complete" }, 696 { MSG_TYPE_RESTART, "Restart" }, 697 { MSG_TYPE_RESTART_ACK, "Restart ACK" }, 698 { MSG_TYPE_STATUS, "Status Reply" }, 699 { MSG_TYPE_STATUS_ENQ, "Status Enquiry" }, 700 { 0, NULL } 701 }; 702 703 #define IE_IS_SINGLE_OCTET(iecode) ((iecode) & 0x80) 704 #define IE_IS_SHIFT(iecode) (((iecode) & 0xF0) == 0x90) 705 #define IE_SHIFT_IS_NON_LOCKING(iecode) ((iecode) & 0x08) 706 #define IE_SHIFT_IS_LOCKING(iecode) (!(IE_SHIFT_IS_NON_LOCKING(iecode))) 707 #define IE_SHIFT_CODESET(iecode) ((iecode) & 0x07) 708 709 #define FR_LMI_ANSI_REPORT_TYPE_IE 0x01 710 #define FR_LMI_ANSI_LINK_VERIFY_IE_91 0x19 /* details? */ 711 #define FR_LMI_ANSI_LINK_VERIFY_IE 0x03 712 #define FR_LMI_ANSI_PVC_STATUS_IE 0x07 713 714 #define FR_LMI_CCITT_REPORT_TYPE_IE 0x51 715 #define FR_LMI_CCITT_LINK_VERIFY_IE 0x53 716 #define FR_LMI_CCITT_PVC_STATUS_IE 0x57 717 718 static const struct tok fr_q933_ie_values_codeset_0_5[] = { 719 { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" }, 720 { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" }, 721 { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" }, 722 { FR_LMI_ANSI_PVC_STATUS_IE, "ANSI PVC Status" }, 723 { FR_LMI_CCITT_REPORT_TYPE_IE, "CCITT Report Type" }, 724 { FR_LMI_CCITT_LINK_VERIFY_IE, "CCITT Link Verify" }, 725 { FR_LMI_CCITT_PVC_STATUS_IE, "CCITT PVC Status" }, 726 { 0, NULL } 727 }; 728 729 #define FR_LMI_REPORT_TYPE_IE_FULL_STATUS 0 730 #define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY 1 731 #define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC 2 732 733 static const struct tok fr_lmi_report_type_ie_values[] = { 734 { FR_LMI_REPORT_TYPE_IE_FULL_STATUS, "Full Status" }, 735 { FR_LMI_REPORT_TYPE_IE_LINK_VERIFY, "Link verify" }, 736 { FR_LMI_REPORT_TYPE_IE_ASYNC_PVC, "Async PVC Status" }, 737 { 0, NULL } 738 }; 739 740 /* array of 16 codesets - currently we only support codepage 0 and 5 */ 741 static const struct tok *fr_q933_ie_codesets[] = { 742 fr_q933_ie_values_codeset_0_5, 743 NULL, 744 NULL, 745 NULL, 746 NULL, 747 fr_q933_ie_values_codeset_0_5, 748 NULL, 749 NULL, 750 NULL, 751 NULL, 752 NULL, 753 NULL, 754 NULL, 755 NULL, 756 NULL, 757 NULL 758 }; 759 760 static int fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, 761 u_int ielength, const u_char *p); 762 763 typedef int (*codeset_pr_func_t)(netdissect_options *, u_int iecode, 764 u_int ielength, const u_char *p); 765 766 /* array of 16 codesets - currently we only support codepage 0 and 5 */ 767 static const codeset_pr_func_t fr_q933_print_ie_codeset[] = { 768 fr_q933_print_ie_codeset_0_5, 769 NULL, 770 NULL, 771 NULL, 772 NULL, 773 fr_q933_print_ie_codeset_0_5, 774 NULL, 775 NULL, 776 NULL, 777 NULL, 778 NULL, 779 NULL, 780 NULL, 781 NULL, 782 NULL, 783 NULL 784 }; 785 786 /* 787 * ITU-T Q.933. 788 * 789 * p points to octet 2, the octet containing the length of the 790 * call reference value, so p[n] is octet n+2 ("octet X" is as 791 * used in Q.931/Q.933). 792 * 793 * XXX - actually used both for Q.931 and Q.933. 794 */ 795 void 796 q933_print(netdissect_options *ndo, 797 const u_char *p, u_int length) 798 { 799 u_int olen; 800 u_int call_ref_length, i; 801 uint8_t call_ref[15]; /* maximum length - length field is 4 bits */ 802 u_int msgtype; 803 u_int iecode; 804 u_int ielength; 805 u_int codeset = 0; 806 u_int is_ansi = 0; 807 u_int ie_is_known; 808 u_int non_locking_shift; 809 u_int unshift_codeset; 810 811 ND_PRINT((ndo, "%s", ndo->ndo_eflag ? "" : "Q.933")); 812 813 if (length == 0 || !ND_TTEST(*p)) { 814 if (!ndo->ndo_eflag) 815 ND_PRINT((ndo, ", ")); 816 ND_PRINT((ndo, "length %u", length)); 817 goto trunc; 818 } 819 820 /* 821 * Get the length of the call reference value. 822 */ 823 olen = length; /* preserve the original length for display */ 824 call_ref_length = (*p) & 0x0f; 825 p++; 826 length--; 827 828 /* 829 * Get the call reference value. 830 */ 831 for (i = 0; i < call_ref_length; i++) { 832 if (length == 0 || !ND_TTEST(*p)) { 833 if (!ndo->ndo_eflag) 834 ND_PRINT((ndo, ", ")); 835 ND_PRINT((ndo, "length %u", olen)); 836 goto trunc; 837 } 838 call_ref[i] = *p; 839 p++; 840 length--; 841 } 842 843 /* 844 * Get the message type. 845 */ 846 if (length == 0 || !ND_TTEST(*p)) { 847 if (!ndo->ndo_eflag) 848 ND_PRINT((ndo, ", ")); 849 ND_PRINT((ndo, "length %u", olen)); 850 goto trunc; 851 } 852 msgtype = *p; 853 p++; 854 length--; 855 856 /* 857 * Peek ahead to see if we start with a shift. 858 */ 859 non_locking_shift = 0; 860 unshift_codeset = codeset; 861 if (length != 0) { 862 if (!ND_TTEST(*p)) { 863 if (!ndo->ndo_eflag) 864 ND_PRINT((ndo, ", ")); 865 ND_PRINT((ndo, "length %u", olen)); 866 goto trunc; 867 } 868 iecode = *p; 869 if (IE_IS_SHIFT(iecode)) { 870 /* 871 * It's a shift. Skip over it. 872 */ 873 p++; 874 length--; 875 876 /* 877 * Get the codeset. 878 */ 879 codeset = IE_SHIFT_CODESET(iecode); 880 881 /* 882 * If it's a locking shift to codeset 5, 883 * mark this as ANSI. (XXX - 5 is actually 884 * for national variants in general, not 885 * the US variant in particular, but maybe 886 * this is more American exceptionalism. :-)) 887 */ 888 if (IE_SHIFT_IS_LOCKING(iecode)) { 889 /* 890 * It's a locking shift. 891 */ 892 if (codeset == 5) { 893 /* 894 * It's a locking shift to 895 * codeset 5, so this is 896 * T1.617 Annex D. 897 */ 898 is_ansi = 1; 899 } 900 } else { 901 /* 902 * It's a non-locking shift. 903 * Remember the current codeset, so we 904 * can revert to it after the next IE. 905 */ 906 non_locking_shift = 1; 907 unshift_codeset = 0; 908 } 909 } 910 } 911 912 /* printing out header part */ 913 if (!ndo->ndo_eflag) 914 ND_PRINT((ndo, ", ")); 915 ND_PRINT((ndo, "%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset)); 916 917 if (call_ref_length != 0) { 918 ND_TCHECK(p[0]); 919 if (call_ref_length > 1 || p[0] != 0) { 920 /* 921 * Not a dummy call reference. 922 */ 923 ND_PRINT((ndo, ", Call Ref: 0x")); 924 for (i = 0; i < call_ref_length; i++) 925 ND_PRINT((ndo, "%02x", call_ref[i])); 926 } 927 } 928 if (ndo->ndo_vflag) { 929 ND_PRINT((ndo, ", %s (0x%02x), length %u", 930 tok2str(fr_q933_msg_values, 931 "unknown message", msgtype), 932 msgtype, 933 olen)); 934 } else { 935 ND_PRINT((ndo, ", %s", 936 tok2str(fr_q933_msg_values, 937 "unknown message 0x%02x", msgtype))); 938 } 939 940 /* Loop through the rest of the IEs */ 941 while (length != 0) { 942 /* 943 * What's the state of any non-locking shifts? 944 */ 945 if (non_locking_shift == 1) { 946 /* 947 * There's a non-locking shift in effect for 948 * this IE. Count it, so we reset the codeset 949 * before the next IE. 950 */ 951 non_locking_shift = 2; 952 } else if (non_locking_shift == 2) { 953 /* 954 * Unshift. 955 */ 956 codeset = unshift_codeset; 957 non_locking_shift = 0; 958 } 959 960 /* 961 * Get the first octet of the IE. 962 */ 963 if (!ND_TTEST(*p)) { 964 if (!ndo->ndo_vflag) { 965 ND_PRINT((ndo, ", length %u", olen)); 966 } 967 goto trunc; 968 } 969 iecode = *p; 970 p++; 971 length--; 972 973 /* Single-octet IE? */ 974 if (IE_IS_SINGLE_OCTET(iecode)) { 975 /* 976 * Yes. Is it a shift? 977 */ 978 if (IE_IS_SHIFT(iecode)) { 979 /* 980 * Yes. Is it locking? 981 */ 982 if (IE_SHIFT_IS_LOCKING(iecode)) { 983 /* 984 * Yes. 985 */ 986 non_locking_shift = 0; 987 } else { 988 /* 989 * No. Remember the current 990 * codeset, so we can revert 991 * to it after the next IE. 992 */ 993 non_locking_shift = 1; 994 unshift_codeset = codeset; 995 } 996 997 /* 998 * Get the codeset. 999 */ 1000 codeset = IE_SHIFT_CODESET(iecode); 1001 } 1002 } else { 1003 /* 1004 * No. Get the IE length. 1005 */ 1006 if (length == 0 || !ND_TTEST(*p)) { 1007 if (!ndo->ndo_vflag) { 1008 ND_PRINT((ndo, ", length %u", olen)); 1009 } 1010 goto trunc; 1011 } 1012 ielength = *p; 1013 p++; 1014 length--; 1015 1016 /* lets do the full IE parsing only in verbose mode 1017 * however some IEs (DLCI Status, Link Verify) 1018 * are also interesting in non-verbose mode */ 1019 if (ndo->ndo_vflag) { 1020 ND_PRINT((ndo, "\n\t%s IE (0x%02x), length %u: ", 1021 tok2str(fr_q933_ie_codesets[codeset], 1022 "unknown", iecode), 1023 iecode, 1024 ielength)); 1025 } 1026 1027 /* sanity checks */ 1028 if (iecode == 0 || ielength == 0) { 1029 return; 1030 } 1031 if (length < ielength || !ND_TTEST2(*p, ielength)) { 1032 if (!ndo->ndo_vflag) { 1033 ND_PRINT((ndo, ", length %u", olen)); 1034 } 1035 goto trunc; 1036 } 1037 1038 ie_is_known = 0; 1039 if (fr_q933_print_ie_codeset[codeset] != NULL) { 1040 ie_is_known = fr_q933_print_ie_codeset[codeset](ndo, iecode, ielength, p); 1041 } 1042 1043 if (ie_is_known) { 1044 /* 1045 * Known IE; do we want to see a hexdump 1046 * of it? 1047 */ 1048 if (ndo->ndo_vflag > 1) { 1049 /* Yes. */ 1050 print_unknown_data(ndo, p, "\n\t ", ielength); 1051 } 1052 } else { 1053 /* 1054 * Unknown IE; if we're printing verbosely, 1055 * print its content in hex. 1056 */ 1057 if (ndo->ndo_vflag >= 1) { 1058 print_unknown_data(ndo, p, "\n\t", ielength); 1059 } 1060 } 1061 1062 length -= ielength; 1063 p += ielength; 1064 } 1065 } 1066 if (!ndo->ndo_vflag) { 1067 ND_PRINT((ndo, ", length %u", olen)); 1068 } 1069 return; 1070 1071 trunc: 1072 ND_PRINT((ndo, "[|q.933]")); 1073 } 1074 1075 static int 1076 fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, 1077 u_int ielength, const u_char *p) 1078 { 1079 u_int dlci; 1080 1081 switch (iecode) { 1082 1083 case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */ 1084 case FR_LMI_CCITT_REPORT_TYPE_IE: 1085 if (ielength < 1) { 1086 if (!ndo->ndo_vflag) { 1087 ND_PRINT((ndo, ", ")); 1088 } 1089 ND_PRINT((ndo, "Invalid REPORT TYPE IE")); 1090 return 1; 1091 } 1092 if (ndo->ndo_vflag) { 1093 ND_PRINT((ndo, "%s (%u)", 1094 tok2str(fr_lmi_report_type_ie_values,"unknown",p[0]), 1095 p[0])); 1096 } 1097 return 1; 1098 1099 case FR_LMI_ANSI_LINK_VERIFY_IE: /* fall through */ 1100 case FR_LMI_CCITT_LINK_VERIFY_IE: 1101 case FR_LMI_ANSI_LINK_VERIFY_IE_91: 1102 if (!ndo->ndo_vflag) { 1103 ND_PRINT((ndo, ", ")); 1104 } 1105 if (ielength < 2) { 1106 ND_PRINT((ndo, "Invalid LINK VERIFY IE")); 1107 return 1; 1108 } 1109 ND_PRINT((ndo, "TX Seq: %3d, RX Seq: %3d", p[0], p[1])); 1110 return 1; 1111 1112 case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */ 1113 case FR_LMI_CCITT_PVC_STATUS_IE: 1114 if (!ndo->ndo_vflag) { 1115 ND_PRINT((ndo, ", ")); 1116 } 1117 /* now parse the DLCI information element. */ 1118 if ((ielength < 3) || 1119 (p[0] & 0x80) || 1120 ((ielength == 3) && !(p[1] & 0x80)) || 1121 ((ielength == 4) && ((p[1] & 0x80) || !(p[2] & 0x80))) || 1122 ((ielength == 5) && ((p[1] & 0x80) || (p[2] & 0x80) || 1123 !(p[3] & 0x80))) || 1124 (ielength > 5) || 1125 !(p[ielength - 1] & 0x80)) { 1126 ND_PRINT((ndo, "Invalid DLCI in PVC STATUS IE")); 1127 return 1; 1128 } 1129 1130 dlci = ((p[0] & 0x3F) << 4) | ((p[1] & 0x78) >> 3); 1131 if (ielength == 4) { 1132 dlci = (dlci << 6) | ((p[2] & 0x7E) >> 1); 1133 } 1134 else if (ielength == 5) { 1135 dlci = (dlci << 13) | (p[2] & 0x7F) | ((p[3] & 0x7E) >> 1); 1136 } 1137 1138 ND_PRINT((ndo, "DLCI %u: status %s%s", dlci, 1139 p[ielength - 1] & 0x8 ? "New, " : "", 1140 p[ielength - 1] & 0x2 ? "Active" : "Inactive")); 1141 return 1; 1142 } 1143 1144 return 0; 1145 } 1146 /* 1147 * Local Variables: 1148 * c-style: whitesmith 1149 * c-basic-offset: 8 1150 * End: 1151 */ 1152