print-sctp.c 23 KB

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