1 /* Copyright (c) 2001 NETLAB, Temple University 2 * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware 3 * 4 * Jerry Heinz <gheinz@astro.temple.edu> 5 * John Fiore <jfiore@joda.cis.temple.edu> 6 * Armando L. Caro Jr. <acaro@cis.udel.edu> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the University nor of the Laboratory may be used 20 * to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 /* \summary: Stream Control Transmission Protocol (SCTP) printer */ 37 38 #ifdef HAVE_CONFIG_H 39 #include "config.h" 40 #endif 41 42 #include <netdissect-stdinc.h> 43 44 #include "netdissect.h" 45 #include "addrtoname.h" 46 #include "extract.h" 47 #include "ip.h" 48 #include "ip6.h" 49 50 /* Definitions from: 51 * 52 * SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola 53 * 54 * Redistribution and use in source and binary forms, with or without 55 * modification, are permitted provided that the following conditions 56 * are met: 57 * 58 * 1. Redistributions of source code must retain the above copyright 59 * notice, this list of conditions and the following disclaimer. 60 * 61 * 2. Redistributions in binary form must reproduce the above copyright 62 * notice, this list of conditions and the following disclaimer in the 63 * documentation and/or other materials provided with the distribution. 64 * 65 * 3. Neither the name of Cisco nor of Motorola may be used 66 * to endorse or promote products derived from this software without 67 * specific prior written permission. 68 * 69 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 70 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 71 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 72 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 73 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 74 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 75 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 76 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 77 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 78 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 79 * SUCH DAMAGE. 80 * 81 * This file is part of the SCTP reference Implementation 82 * 83 * 84 * Please send any bug reports or fixes you make to one of the following email 85 * addresses: 86 * 87 * rstewar1@email.mot.com 88 * kmorneau@cisco.com 89 * qxie1@email.mot.com 90 * 91 * Any bugs reported given to us we will try to fix... any fixes shared will 92 * be incorperated into the next SCTP release. 93 */ 94 95 /* The valid defines for all message 96 * types know to SCTP. 0 is reserved 97 */ 98 #define SCTP_DATA 0x00 99 #define SCTP_INITIATION 0x01 100 #define SCTP_INITIATION_ACK 0x02 101 #define SCTP_SELECTIVE_ACK 0x03 102 #define SCTP_HEARTBEAT_REQUEST 0x04 103 #define SCTP_HEARTBEAT_ACK 0x05 104 #define SCTP_ABORT_ASSOCIATION 0x06 105 #define SCTP_SHUTDOWN 0x07 106 #define SCTP_SHUTDOWN_ACK 0x08 107 #define SCTP_OPERATION_ERR 0x09 108 #define SCTP_COOKIE_ECHO 0x0a 109 #define SCTP_COOKIE_ACK 0x0b 110 #define SCTP_ECN_ECHO 0x0c 111 #define SCTP_ECN_CWR 0x0d 112 #define SCTP_SHUTDOWN_COMPLETE 0x0e 113 #define SCTP_FORWARD_CUM_TSN 0xc0 114 #define SCTP_RELIABLE_CNTL 0xc1 115 #define SCTP_RELIABLE_CNTL_ACK 0xc2 116 117 static const struct tok sctp_chunkid_str[] = { 118 { SCTP_DATA, "DATA" }, 119 { SCTP_INITIATION, "INIT" }, 120 { SCTP_INITIATION_ACK, "INIT ACK" }, 121 { SCTP_SELECTIVE_ACK, "SACK" }, 122 { SCTP_HEARTBEAT_REQUEST, "HB REQ" }, 123 { SCTP_HEARTBEAT_ACK, "HB ACK" }, 124 { SCTP_ABORT_ASSOCIATION, "ABORT" }, 125 { SCTP_SHUTDOWN, "SHUTDOWN" }, 126 { SCTP_SHUTDOWN_ACK, "SHUTDOWN ACK" }, 127 { SCTP_OPERATION_ERR, "OP ERR" }, 128 { SCTP_COOKIE_ECHO, "COOKIE ECHO" }, 129 { SCTP_COOKIE_ACK, "COOKIE ACK" }, 130 { SCTP_ECN_ECHO, "ECN ECHO" }, 131 { SCTP_ECN_CWR, "ECN CWR" }, 132 { SCTP_SHUTDOWN_COMPLETE, "SHUTDOWN COMPLETE" }, 133 { SCTP_FORWARD_CUM_TSN, "FOR CUM TSN" }, 134 { SCTP_RELIABLE_CNTL, "REL CTRL" }, 135 { SCTP_RELIABLE_CNTL_ACK, "REL CTRL ACK" }, 136 { 0, NULL } 137 }; 138 139 /* Data Chuck Specific Flags */ 140 #define SCTP_DATA_FRAG_MASK 0x03 141 #define SCTP_DATA_MIDDLE_FRAG 0x00 142 #define SCTP_DATA_LAST_FRAG 0x01 143 #define SCTP_DATA_FIRST_FRAG 0x02 144 #define SCTP_DATA_NOT_FRAG 0x03 145 #define SCTP_DATA_UNORDERED 0x04 146 147 #define SCTP_ADDRMAX 60 148 149 #define CHAN_HP 6704 150 #define CHAN_MP 6705 151 #define CHAN_LP 6706 152 153 /* the sctp common header */ 154 155 struct sctpHeader{ 156 uint16_t source; 157 uint16_t destination; 158 uint32_t verificationTag; 159 uint32_t adler32; 160 }; 161 162 /* various descriptor parsers */ 163 164 struct sctpChunkDesc{ 165 uint8_t chunkID; 166 uint8_t chunkFlg; 167 uint16_t chunkLength; 168 }; 169 170 struct sctpParamDesc{ 171 uint16_t paramType; 172 uint16_t paramLength; 173 }; 174 175 176 struct sctpRelChunkDesc{ 177 struct sctpChunkDesc chk; 178 uint32_t serialNumber; 179 }; 180 181 struct sctpVendorSpecificParam { 182 struct sctpParamDesc p; /* type must be 0xfffe */ 183 uint32_t vendorId; /* vendor ID from RFC 1700 */ 184 uint16_t vendorSpecificType; 185 uint16_t vendorSpecificLen; 186 }; 187 188 189 /* Structures for the control parts */ 190 191 192 193 /* Sctp association init request/ack */ 194 195 /* this is used for init ack, too */ 196 struct sctpInitiation{ 197 uint32_t initTag; /* tag of mine */ 198 uint32_t rcvWindowCredit; /* rwnd */ 199 uint16_t NumPreopenStreams; /* OS */ 200 uint16_t MaxInboundStreams; /* MIS */ 201 uint32_t initialTSN; 202 /* optional param's follow in sctpParamDesc form */ 203 }; 204 205 struct sctpV4IpAddress{ 206 struct sctpParamDesc p; /* type is set to SCTP_IPV4_PARAM_TYPE, len=10 */ 207 uint32_t ipAddress; 208 }; 209 210 211 struct sctpV6IpAddress{ 212 struct sctpParamDesc p; /* type is set to SCTP_IPV6_PARAM_TYPE, len=22 */ 213 uint8_t ipAddress[16]; 214 }; 215 216 struct sctpDNSName{ 217 struct sctpParamDesc param; 218 uint8_t name[1]; 219 }; 220 221 222 struct sctpCookiePreserve{ 223 struct sctpParamDesc p; /* type is set to SCTP_COOKIE_PRESERVE, len=8 */ 224 uint32_t extraTime; 225 }; 226 227 228 struct sctpTimeStamp{ 229 uint32_t ts_sec; 230 uint32_t ts_usec; 231 }; 232 233 /* wire structure of my cookie */ 234 struct cookieMessage{ 235 uint32_t TieTag_curTag; /* copied from assoc if present */ 236 uint32_t TieTag_hisTag; /* copied from assoc if present */ 237 int32_t cookieLife; /* life I will award this cookie */ 238 struct sctpTimeStamp timeEnteringState; /* the time I built cookie */ 239 struct sctpInitiation initAckISent; /* the INIT-ACK that I sent to my peer */ 240 uint32_t addressWhereISent[4]; /* I make this 4 ints so I get 128bits for future */ 241 int32_t addrtype; /* address type */ 242 uint16_t locScope; /* V6 local scope flag */ 243 uint16_t siteScope; /* V6 site scope flag */ 244 /* at the end is tacked on the INIT chunk sent in 245 * its entirety and of course our 246 * signature. 247 */ 248 }; 249 250 251 /* this guy is for use when 252 * I have a initiate message gloming the 253 * things together. 254 255 */ 256 struct sctpUnifiedInit{ 257 struct sctpChunkDesc uh; 258 struct sctpInitiation initm; 259 }; 260 261 struct sctpSendableInit{ 262 struct sctpHeader mh; 263 struct sctpUnifiedInit msg; 264 }; 265 266 267 /* Selective Acknowledgement 268 * has the following structure with 269 * a optional ammount of trailing int's 270 * on the last part (based on the numberOfDesc 271 * field). 272 */ 273 274 struct sctpSelectiveAck{ 275 uint32_t highestConseqTSN; 276 uint32_t updatedRwnd; 277 uint16_t numberOfdesc; 278 uint16_t numDupTsns; 279 }; 280 281 struct sctpSelectiveFrag{ 282 uint16_t fragmentStart; 283 uint16_t fragmentEnd; 284 }; 285 286 287 struct sctpUnifiedSack{ 288 struct sctpChunkDesc uh; 289 struct sctpSelectiveAck sack; 290 }; 291 292 /* for both RTT request/response the 293 * following is sent 294 */ 295 296 struct sctpHBrequest { 297 uint32_t time_value_1; 298 uint32_t time_value_2; 299 }; 300 301 /* here is what I read and respond with to. */ 302 struct sctpHBunified{ 303 struct sctpChunkDesc hdr; 304 struct sctpParamDesc hb; 305 }; 306 307 308 /* here is what I send */ 309 struct sctpHBsender{ 310 struct sctpChunkDesc hdr; 311 struct sctpParamDesc hb; 312 struct sctpHBrequest rtt; 313 int8_t addrFmt[SCTP_ADDRMAX]; 314 uint16_t userreq; 315 }; 316 317 318 319 /* for the abort and shutdown ACK 320 * we must carry the init tag in the common header. Just the 321 * common header is all that is needed with a chunk descriptor. 322 */ 323 struct sctpUnifiedAbort{ 324 struct sctpChunkDesc uh; 325 }; 326 327 struct sctpUnifiedAbortLight{ 328 struct sctpHeader mh; 329 struct sctpChunkDesc uh; 330 }; 331 332 struct sctpUnifiedAbortHeavy{ 333 struct sctpHeader mh; 334 struct sctpChunkDesc uh; 335 uint16_t causeCode; 336 uint16_t causeLen; 337 }; 338 339 /* For the graceful shutdown we must carry 340 * the tag (in common header) and the highest consequitive acking value 341 */ 342 struct sctpShutdown { 343 uint32_t TSN_Seen; 344 }; 345 346 struct sctpUnifiedShutdown{ 347 struct sctpChunkDesc uh; 348 struct sctpShutdown shut; 349 }; 350 351 /* in the unified message we add the trailing 352 * stream id since it is the only message 353 * that is defined as a operation error. 354 */ 355 struct sctpOpErrorCause{ 356 uint16_t cause; 357 uint16_t causeLen; 358 }; 359 360 struct sctpUnifiedOpError{ 361 struct sctpChunkDesc uh; 362 struct sctpOpErrorCause c; 363 }; 364 365 struct sctpUnifiedStreamError{ 366 struct sctpHeader mh; 367 struct sctpChunkDesc uh; 368 struct sctpOpErrorCause c; 369 uint16_t strmNum; 370 uint16_t reserved; 371 }; 372 373 struct staleCookieMsg{ 374 struct sctpHeader mh; 375 struct sctpChunkDesc uh; 376 struct sctpOpErrorCause c; 377 uint32_t moretime; 378 }; 379 380 /* the following is used in all sends 381 * where nothing is needed except the 382 * chunk/type i.e. shutdownAck Abort */ 383 384 struct sctpUnifiedSingleMsg{ 385 struct sctpHeader mh; 386 struct sctpChunkDesc uh; 387 }; 388 389 struct sctpDataPart{ 390 uint32_t TSN; 391 uint16_t streamId; 392 uint16_t sequence; 393 uint32_t payloadtype; 394 }; 395 396 struct sctpUnifiedDatagram{ 397 struct sctpChunkDesc uh; 398 struct sctpDataPart dp; 399 }; 400 401 struct sctpECN_echo{ 402 struct sctpChunkDesc uh; 403 uint32_t Lowest_TSN; 404 }; 405 406 407 struct sctpCWR{ 408 struct sctpChunkDesc uh; 409 uint32_t TSN_reduced_at; 410 }; 411 412 static const struct tok ForCES_channels[] = { 413 { CHAN_HP, "ForCES HP" }, 414 { CHAN_MP, "ForCES MP" }, 415 { CHAN_LP, "ForCES LP" }, 416 { 0, NULL } 417 }; 418 419 /* data chunk's payload protocol identifiers */ 420 421 #define SCTP_PPID_IUA 1 422 #define SCTP_PPID_M2UA 2 423 #define SCTP_PPID_M3UA 3 424 #define SCTP_PPID_SUA 4 425 #define SCTP_PPID_M2PA 5 426 #define SCTP_PPID_V5UA 6 427 #define SCTP_PPID_H248 7 428 #define SCTP_PPID_BICC 8 429 #define SCTP_PPID_TALI 9 430 #define SCTP_PPID_DUA 10 431 #define SCTP_PPID_ASAP 11 432 #define SCTP_PPID_ENRP 12 433 #define SCTP_PPID_H323 13 434 #define SCTP_PPID_QIPC 14 435 #define SCTP_PPID_SIMCO 15 436 #define SCTP_PPID_DDPSC 16 437 #define SCTP_PPID_DDPSSC 17 438 #define SCTP_PPID_S1AP 18 439 #define SCTP_PPID_RUA 19 440 #define SCTP_PPID_HNBAP 20 441 #define SCTP_PPID_FORCES_HP 21 442 #define SCTP_PPID_FORCES_MP 22 443 #define SCTP_PPID_FORCES_LP 23 444 #define SCTP_PPID_SBC_AP 24 445 #define SCTP_PPID_NBAP 25 446 /* 26 */ 447 #define SCTP_PPID_X2AP 27 448 449 static const struct tok PayloadProto_idents[] = { 450 { SCTP_PPID_IUA, "ISDN Q.921" }, 451 { SCTP_PPID_M2UA, "M2UA" }, 452 { SCTP_PPID_M3UA, "M3UA" }, 453 { SCTP_PPID_SUA, "SUA" }, 454 { SCTP_PPID_M2PA, "M2PA" }, 455 { SCTP_PPID_V5UA, "V5.2" }, 456 { SCTP_PPID_H248, "H.248" }, 457 { SCTP_PPID_BICC, "BICC" }, 458 { SCTP_PPID_TALI, "TALI" }, 459 { SCTP_PPID_DUA, "DUA" }, 460 { SCTP_PPID_ASAP, "ASAP" }, 461 { SCTP_PPID_ENRP, "ENRP" }, 462 { SCTP_PPID_H323, "H.323" }, 463 { SCTP_PPID_QIPC, "Q.IPC" }, 464 { SCTP_PPID_SIMCO, "SIMCO" }, 465 { SCTP_PPID_DDPSC, "DDPSC" }, 466 { SCTP_PPID_DDPSSC, "DDPSSC" }, 467 { SCTP_PPID_S1AP, "S1AP" }, 468 { SCTP_PPID_RUA, "RUA" }, 469 { SCTP_PPID_HNBAP, "HNBAP" }, 470 { SCTP_PPID_FORCES_HP, "ForCES HP" }, 471 { SCTP_PPID_FORCES_MP, "ForCES MP" }, 472 { SCTP_PPID_FORCES_LP, "ForCES LP" }, 473 { SCTP_PPID_SBC_AP, "SBc-AP" }, 474 { SCTP_PPID_NBAP, "NBAP" }, 475 /* 26 */ 476 { SCTP_PPID_X2AP, "X2AP" }, 477 { 0, NULL } 478 }; 479 480 481 static inline int isForCES_port(u_short Port) 482 { 483 if (Port == CHAN_HP) 484 return 1; 485 if (Port == CHAN_MP) 486 return 1; 487 if (Port == CHAN_LP) 488 return 1; 489 490 return 0; 491 } 492 493 void sctp_print(netdissect_options *ndo, 494 const u_char *bp, /* beginning of sctp packet */ 495 const u_char *bp2, /* beginning of enclosing */ 496 u_int sctpPacketLength) /* ip packet */ 497 { 498 u_int sctpPacketLengthRemaining; 499 const struct sctpHeader *sctpPktHdr; 500 const struct ip *ip; 501 const struct ip6_hdr *ip6; 502 u_short sourcePort, destPort; 503 int chunkCount; 504 const struct sctpChunkDesc *chunkDescPtr; 505 const char *sep; 506 int isforces = 0; 507 508 if (sctpPacketLength < sizeof(struct sctpHeader)) 509 { 510 ND_PRINT((ndo, "truncated-sctp - %ld bytes missing!", 511 (long)(sizeof(struct sctpHeader) - sctpPacketLength))); 512 return; 513 } 514 sctpPktHdr = (const struct sctpHeader*) bp; 515 ND_TCHECK(*sctpPktHdr); 516 sctpPacketLengthRemaining = sctpPacketLength; 517 518 sourcePort = EXTRACT_16BITS(&sctpPktHdr->source); 519 destPort = EXTRACT_16BITS(&sctpPktHdr->destination); 520 521 ip = (const struct ip *)bp2; 522 if (IP_V(ip) == 6) 523 ip6 = (const struct ip6_hdr *)bp2; 524 else 525 ip6 = NULL; 526 527 if (ip6) { 528 ND_PRINT((ndo, "%s.%d > %s.%d: sctp", 529 ip6addr_string(ndo, &ip6->ip6_src), 530 sourcePort, 531 ip6addr_string(ndo, &ip6->ip6_dst), 532 destPort)); 533 } else 534 { 535 ND_PRINT((ndo, "%s.%d > %s.%d: sctp", 536 ipaddr_string(ndo, &ip->ip_src), 537 sourcePort, 538 ipaddr_string(ndo, &ip->ip_dst), 539 destPort)); 540 } 541 542 if (isForCES_port(sourcePort)) { 543 ND_PRINT((ndo, "[%s]", tok2str(ForCES_channels, NULL, sourcePort))); 544 isforces = 1; 545 } 546 if (isForCES_port(destPort)) { 547 ND_PRINT((ndo, "[%s]", tok2str(ForCES_channels, NULL, destPort))); 548 isforces = 1; 549 } 550 551 bp += sizeof(struct sctpHeader); 552 sctpPacketLengthRemaining -= sizeof(struct sctpHeader); 553 554 if (ndo->ndo_vflag >= 2) 555 sep = "\n\t"; 556 else 557 sep = " ("; 558 /* cycle through all chunks, printing information on each one */ 559 for (chunkCount = 0, chunkDescPtr = (const struct sctpChunkDesc *)bp; 560 sctpPacketLengthRemaining != 0; 561 chunkCount++) 562 { 563 uint16_t chunkLength, chunkLengthRemaining; 564 uint16_t align; 565 566 chunkDescPtr = (const struct sctpChunkDesc *)bp; 567 if (sctpPacketLengthRemaining < sizeof(*chunkDescPtr)) { 568 ND_PRINT((ndo, "%s%d) [chunk descriptor cut off at end of packet]", sep, chunkCount+1)); 569 break; 570 } 571 ND_TCHECK(*chunkDescPtr); 572 chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength); 573 if (chunkLength < sizeof(*chunkDescPtr)) { 574 ND_PRINT((ndo, "%s%d) [Bad chunk length %u, < size of chunk descriptor]", sep, chunkCount+1, chunkLength)); 575 break; 576 } 577 chunkLengthRemaining = chunkLength; 578 579 align = chunkLength % 4; 580 if (align != 0) 581 align = 4 - align; 582 583 if (sctpPacketLengthRemaining < align) { 584 ND_PRINT((ndo, "%s%d) [Bad chunk length %u, > remaining data in packet]", sep, chunkCount+1, chunkLength)); 585 break; 586 } 587 588 ND_TCHECK2(*bp, chunkLength); 589 590 bp += sizeof(*chunkDescPtr); 591 sctpPacketLengthRemaining -= sizeof(*chunkDescPtr); 592 chunkLengthRemaining -= sizeof(*chunkDescPtr); 593 594 ND_PRINT((ndo, "%s%d) ", sep, chunkCount+1)); 595 ND_PRINT((ndo, "[%s] ", tok2str(sctp_chunkid_str, "Unknown chunk type: 0x%x", 596 chunkDescPtr->chunkID))); 597 switch (chunkDescPtr->chunkID) 598 { 599 case SCTP_DATA : 600 { 601 const struct sctpDataPart *dataHdrPtr; 602 uint32_t ppid; 603 u_int payload_size; 604 605 if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) 606 == SCTP_DATA_UNORDERED) 607 ND_PRINT((ndo, "(U)")); 608 609 if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) 610 == SCTP_DATA_FIRST_FRAG) 611 ND_PRINT((ndo, "(B)")); 612 613 if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) 614 == SCTP_DATA_LAST_FRAG) 615 ND_PRINT((ndo, "(E)")); 616 617 if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) 618 == SCTP_DATA_UNORDERED) 619 || 620 ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) 621 == SCTP_DATA_FIRST_FRAG) 622 || 623 ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) 624 == SCTP_DATA_LAST_FRAG) ) 625 ND_PRINT((ndo, " ")); 626 627 if (chunkLengthRemaining < sizeof(*dataHdrPtr)) { 628 ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); 629 return; 630 } 631 dataHdrPtr=(const struct sctpDataPart*)bp; 632 633 ppid = EXTRACT_32BITS(&dataHdrPtr->payloadtype); 634 ND_PRINT((ndo, "[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN))); 635 ND_PRINT((ndo, "[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId))); 636 ND_PRINT((ndo, "[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence))); 637 ND_PRINT((ndo, "[PPID %s] ", 638 tok2str(PayloadProto_idents, "0x%x", ppid))); 639 640 if (!isforces) { 641 isforces = (ppid == SCTP_PPID_FORCES_HP) || 642 (ppid == SCTP_PPID_FORCES_MP) || 643 (ppid == SCTP_PPID_FORCES_LP); 644 } 645 646 bp += sizeof(*dataHdrPtr); 647 sctpPacketLengthRemaining -= sizeof(*dataHdrPtr); 648 chunkLengthRemaining -= sizeof(*dataHdrPtr); 649 payload_size = chunkLengthRemaining; 650 if (payload_size == 0) { 651 ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); 652 return; 653 } 654 655 if (isforces) { 656 forces_print(ndo, bp, payload_size); 657 } else if (ndo->ndo_vflag >= 2) { /* if verbose output is specified */ 658 /* at the command line */ 659 switch (ppid) { 660 case SCTP_PPID_M3UA : 661 m3ua_print(ndo, bp, payload_size); 662 break; 663 default: 664 ND_PRINT((ndo, "[Payload")); 665 if (!ndo->ndo_suppress_default_print) { 666 ND_PRINT((ndo, ":")); 667 ND_DEFAULTPRINT(bp, payload_size); 668 } 669 ND_PRINT((ndo, "]")); 670 break; 671 } 672 } 673 bp += payload_size; 674 sctpPacketLengthRemaining -= payload_size; 675 chunkLengthRemaining -= payload_size; 676 break; 677 } 678 case SCTP_INITIATION : 679 { 680 const struct sctpInitiation *init; 681 682 if (chunkLengthRemaining < sizeof(*init)) { 683 ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); 684 return; 685 } 686 init=(const struct sctpInitiation*)bp; 687 ND_PRINT((ndo, "[init tag: %u] ", EXTRACT_32BITS(&init->initTag))); 688 ND_PRINT((ndo, "[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit))); 689 ND_PRINT((ndo, "[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams))); 690 ND_PRINT((ndo, "[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams))); 691 ND_PRINT((ndo, "[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN))); 692 bp += sizeof(*init); 693 sctpPacketLengthRemaining -= sizeof(*init); 694 chunkLengthRemaining -= sizeof(*init); 695 696 #if 0 /* ALC you can add code for optional params here */ 697 if( chunkLengthRemaining != 0 ) 698 ND_PRINT((ndo, " @@@@@ UNFINISHED @@@@@@%s\n", 699 "Optional params present, but not printed.")); 700 #endif 701 bp += chunkLengthRemaining; 702 sctpPacketLengthRemaining -= chunkLengthRemaining; 703 chunkLengthRemaining = 0; 704 break; 705 } 706 case SCTP_INITIATION_ACK : 707 { 708 const struct sctpInitiation *init; 709 710 if (chunkLengthRemaining < sizeof(*init)) { 711 ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); 712 return; 713 } 714 init=(const struct sctpInitiation*)bp; 715 ND_PRINT((ndo, "[init tag: %u] ", EXTRACT_32BITS(&init->initTag))); 716 ND_PRINT((ndo, "[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit))); 717 ND_PRINT((ndo, "[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams))); 718 ND_PRINT((ndo, "[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams))); 719 ND_PRINT((ndo, "[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN))); 720 bp += sizeof(*init); 721 sctpPacketLengthRemaining -= sizeof(*init); 722 chunkLengthRemaining -= sizeof(*init); 723 724 #if 0 /* ALC you can add code for optional params here */ 725 if( chunkLengthRemaining != 0 ) 726 ND_PRINT((ndo, " @@@@@ UNFINISHED @@@@@@%s\n", 727 "Optional params present, but not printed.")); 728 #endif 729 bp += chunkLengthRemaining; 730 sctpPacketLengthRemaining -= chunkLengthRemaining; 731 chunkLengthRemaining = 0; 732 break; 733 } 734 case SCTP_SELECTIVE_ACK: 735 { 736 const struct sctpSelectiveAck *sack; 737 const struct sctpSelectiveFrag *frag; 738 int fragNo, tsnNo; 739 const u_char *dupTSN; 740 741 if (chunkLengthRemaining < sizeof(*sack)) { 742 ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); 743 return; 744 } 745 sack=(const struct sctpSelectiveAck*)bp; 746 ND_PRINT((ndo, "[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN))); 747 ND_PRINT((ndo, "[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd))); 748 ND_PRINT((ndo, "[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc))); 749 ND_PRINT((ndo, "[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns))); 750 bp += sizeof(*sack); 751 sctpPacketLengthRemaining -= sizeof(*sack); 752 chunkLengthRemaining -= sizeof(*sack); 753 754 755 /* print gaps */ 756 for (fragNo=0; 757 chunkLengthRemaining != 0 && fragNo < EXTRACT_16BITS(&sack->numberOfdesc); 758 bp += sizeof(*frag), sctpPacketLengthRemaining -= sizeof(*frag), chunkLengthRemaining -= sizeof(*frag), fragNo++) { 759 if (chunkLengthRemaining < sizeof(*frag)) { 760 ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); 761 return; 762 } 763 frag = (const struct sctpSelectiveFrag *)bp; 764 ND_PRINT((ndo, "\n\t\t[gap ack block #%d: start = %u, end = %u] ", 765 fragNo+1, 766 EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart), 767 EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd))); 768 } 769 770 /* print duplicate TSNs */ 771 for (tsnNo=0; 772 chunkLengthRemaining != 0 && tsnNo<EXTRACT_16BITS(&sack->numDupTsns); 773 bp += 4, sctpPacketLengthRemaining -= 4, chunkLengthRemaining -= 4, tsnNo++) { 774 if (chunkLengthRemaining < 4) { 775 ND_PRINT((ndo, "bogus chunk length %u]", chunkLength)); 776 return; 777 } 778 dupTSN = (const u_char *)bp; 779 ND_PRINT((ndo, "\n\t\t[dup TSN #%u: %u] ", tsnNo+1, 780 EXTRACT_32BITS(dupTSN))); 781 } 782 break; 783 } 784 default : 785 { 786 bp += chunkLengthRemaining; 787 sctpPacketLengthRemaining -= chunkLengthRemaining; 788 chunkLengthRemaining = 0; 789 break; 790 } 791 } 792 793 /* 794 * Any extra stuff at the end of the chunk? 795 * XXX - report this? 796 */ 797 bp += chunkLengthRemaining; 798 sctpPacketLengthRemaining -= chunkLengthRemaining; 799 800 if (ndo->ndo_vflag < 2) 801 sep = ", ("; 802 803 if (align != 0) { 804 /* 805 * Fail if the alignment padding isn't in the captured data. 806 * Otherwise, skip it. 807 */ 808 ND_TCHECK2(*bp, align); 809 bp += align; 810 sctpPacketLengthRemaining -= align; 811 } 812 } 813 return; 814 815 trunc: 816 ND_PRINT((ndo, "[|sctp]")); 817 } 818