1 /* Copyright (c) 2001 NETLAB, Temple University
2 * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware
4 * Jerry Heinz <gheinz@astro.temple.edu>
5 * John Fiore <jfiore@joda.cis.temple.edu>
6 * Armando L. Caro Jr. <acaro@cis.udel.edu>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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.
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.
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
36 /* \summary: Stream Control Transmission Protocol (SCTP) printer */
42 #include "netdissect-stdinc.h"
44 #define ND_LONGJMP_FROM_TCHECK
45 #include "netdissect.h"
46 #include "addrtoname.h"
53 * SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola
55 * Redistribution and use in source and binary forms, with or without
56 * modification, are permitted provided that the following conditions
59 * 1. Redistributions of source code must retain the above copyright
60 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
66 * 3. Neither the name of Cisco nor of Motorola may be used
67 * to endorse or promote products derived from this software without
68 * specific prior written permission.
70 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
71 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
74 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
76 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
77 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
78 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
79 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82 * This file is part of the SCTP reference Implementation
85 * Please send any bug reports or fixes you make to one of the following email
88 * rstewar1@email.mot.com
92 * Any bugs reported given to us we will try to fix... any fixes shared will
93 * be incorporated into the next SCTP release.
96 /* The valid defines for all message
97 * types know to SCTP. 0 is reserved
99 #define SCTP_DATA 0x00
100 #define SCTP_INITIATION 0x01
101 #define SCTP_INITIATION_ACK 0x02
102 #define SCTP_SELECTIVE_ACK 0x03
103 #define SCTP_HEARTBEAT_REQUEST 0x04
104 #define SCTP_HEARTBEAT_ACK 0x05
105 #define SCTP_ABORT_ASSOCIATION 0x06
106 #define SCTP_SHUTDOWN 0x07
107 #define SCTP_SHUTDOWN_ACK 0x08
108 #define SCTP_OPERATION_ERR 0x09
109 #define SCTP_COOKIE_ECHO 0x0a
110 #define SCTP_COOKIE_ACK 0x0b
111 #define SCTP_ECN_ECHO 0x0c
112 #define SCTP_ECN_CWR 0x0d
113 #define SCTP_SHUTDOWN_COMPLETE 0x0e
114 #define SCTP_FORWARD_CUM_TSN 0xc0
115 #define SCTP_RELIABLE_CNTL 0xc1
116 #define SCTP_RELIABLE_CNTL_ACK 0xc2
118 static const struct tok sctp_chunkid_str
[] = {
119 { SCTP_DATA
, "DATA" },
120 { SCTP_INITIATION
, "INIT" },
121 { SCTP_INITIATION_ACK
, "INIT ACK" },
122 { SCTP_SELECTIVE_ACK
, "SACK" },
123 { SCTP_HEARTBEAT_REQUEST
, "HB REQ" },
124 { SCTP_HEARTBEAT_ACK
, "HB ACK" },
125 { SCTP_ABORT_ASSOCIATION
, "ABORT" },
126 { SCTP_SHUTDOWN
, "SHUTDOWN" },
127 { SCTP_SHUTDOWN_ACK
, "SHUTDOWN ACK" },
128 { SCTP_OPERATION_ERR
, "OP ERR" },
129 { SCTP_COOKIE_ECHO
, "COOKIE ECHO" },
130 { SCTP_COOKIE_ACK
, "COOKIE ACK" },
131 { SCTP_ECN_ECHO
, "ECN ECHO" },
132 { SCTP_ECN_CWR
, "ECN CWR" },
133 { SCTP_SHUTDOWN_COMPLETE
, "SHUTDOWN COMPLETE" },
134 { SCTP_FORWARD_CUM_TSN
, "FOR CUM TSN" },
135 { SCTP_RELIABLE_CNTL
, "REL CTRL" },
136 { SCTP_RELIABLE_CNTL_ACK
, "REL CTRL ACK" },
140 /* Data Chuck Specific Flags */
141 #define SCTP_DATA_FRAG_MASK 0x03
142 #define SCTP_DATA_MIDDLE_FRAG 0x00
143 #define SCTP_DATA_LAST_FRAG 0x01
144 #define SCTP_DATA_FIRST_FRAG 0x02
145 #define SCTP_DATA_NOT_FRAG 0x03
146 #define SCTP_DATA_UNORDERED 0x04
148 #define SCTP_ADDRMAX 60
154 /* the sctp common header */
158 nd_uint16_t destination
;
159 nd_uint32_t verificationTag
;
163 /* various descriptor parsers */
165 struct sctpChunkDesc
{
168 nd_uint16_t chunkLength
;
171 struct sctpParamDesc
{
172 nd_uint16_t paramType
;
173 nd_uint16_t paramLength
;
177 struct sctpRelChunkDesc
{
178 struct sctpChunkDesc chk
;
179 nd_uint32_t serialNumber
;
182 struct sctpVendorSpecificParam
{
183 struct sctpParamDesc p
; /* type must be 0xfffe */
184 nd_uint32_t vendorId
; /* vendor ID from RFC 1700 */
185 nd_uint16_t vendorSpecificType
;
186 nd_uint16_t vendorSpecificLen
;
190 /* Structures for the control parts */
194 /* Sctp association init request/ack */
196 /* this is used for init ack, too */
197 struct sctpInitiation
{
198 nd_uint32_t initTag
; /* tag of mine */
199 nd_uint32_t rcvWindowCredit
; /* rwnd */
200 nd_uint16_t NumPreopenStreams
; /* OS */
201 nd_uint16_t MaxInboundStreams
; /* MIS */
202 nd_uint32_t initialTSN
;
203 /* optional param's follow in sctpParamDesc form */
206 struct sctpV4IpAddress
{
207 struct sctpParamDesc p
; /* type is set to SCTP_IPV4_PARAM_TYPE, len=10 */
212 struct sctpV6IpAddress
{
213 struct sctpParamDesc p
; /* type is set to SCTP_IPV6_PARAM_TYPE, len=22 */
218 struct sctpParamDesc param
;
223 struct sctpCookiePreserve
{
224 struct sctpParamDesc p
; /* type is set to SCTP_COOKIE_PRESERVE, len=8 */
225 nd_uint32_t extraTime
;
229 struct sctpTimeStamp
{
235 /* this guy is for use when
236 * I have a initiate message gloming the
240 struct sctpUnifiedInit
{
241 struct sctpChunkDesc uh
;
242 struct sctpInitiation initm
;
245 struct sctpSendableInit
{
246 struct sctpHeader mh
;
247 struct sctpUnifiedInit msg
;
251 /* Selective Acknowledgement
252 * has the following structure with
253 * a optional amount of trailing int's
254 * on the last part (based on the numberOfDesc
258 struct sctpSelectiveAck
{
259 nd_uint32_t highestConseqTSN
;
260 nd_uint32_t updatedRwnd
;
261 nd_uint16_t numberOfdesc
;
262 nd_uint16_t numDupTsns
;
265 struct sctpSelectiveFrag
{
266 nd_uint16_t fragmentStart
;
267 nd_uint16_t fragmentEnd
;
271 struct sctpUnifiedSack
{
272 struct sctpChunkDesc uh
;
273 struct sctpSelectiveAck sack
;
276 /* for the abort and shutdown ACK
277 * we must carry the init tag in the common header. Just the
278 * common header is all that is needed with a chunk descriptor.
280 struct sctpUnifiedAbort
{
281 struct sctpChunkDesc uh
;
284 struct sctpUnifiedAbortLight
{
285 struct sctpHeader mh
;
286 struct sctpChunkDesc uh
;
289 struct sctpUnifiedAbortHeavy
{
290 struct sctpHeader mh
;
291 struct sctpChunkDesc uh
;
292 nd_uint16_t causeCode
;
293 nd_uint16_t causeLen
;
296 /* For the graceful shutdown we must carry
297 * the tag (in common header) and the highest consequitive acking value
299 struct sctpShutdown
{
300 nd_uint32_t TSN_Seen
;
303 struct sctpUnifiedShutdown
{
304 struct sctpChunkDesc uh
;
305 struct sctpShutdown shut
;
308 /* in the unified message we add the trailing
309 * stream id since it is the only message
310 * that is defined as a operation error.
312 struct sctpOpErrorCause
{
314 nd_uint16_t causeLen
;
317 struct sctpUnifiedOpError
{
318 struct sctpChunkDesc uh
;
319 struct sctpOpErrorCause c
;
322 struct sctpUnifiedStreamError
{
323 struct sctpHeader mh
;
324 struct sctpChunkDesc uh
;
325 struct sctpOpErrorCause c
;
327 nd_uint16_t reserved
;
330 struct staleCookieMsg
{
331 struct sctpHeader mh
;
332 struct sctpChunkDesc uh
;
333 struct sctpOpErrorCause c
;
334 nd_uint32_t moretime
;
337 /* the following is used in all sends
338 * where nothing is needed except the
339 * chunk/type i.e. shutdownAck Abort */
341 struct sctpUnifiedSingleMsg
{
342 struct sctpHeader mh
;
343 struct sctpChunkDesc uh
;
348 nd_uint16_t streamId
;
349 nd_uint16_t sequence
;
350 nd_uint32_t payloadtype
;
353 struct sctpUnifiedDatagram
{
354 struct sctpChunkDesc uh
;
355 struct sctpDataPart dp
;
359 struct sctpChunkDesc uh
;
360 nd_uint32_t Lowest_TSN
;
365 struct sctpChunkDesc uh
;
366 nd_uint32_t TSN_reduced_at
;
369 static const struct tok ForCES_channels
[] = {
370 { CHAN_HP
, "ForCES HP" },
371 { CHAN_MP
, "ForCES MP" },
372 { CHAN_LP
, "ForCES LP" },
376 /* data chunk's payload protocol identifiers */
378 #define SCTP_PPID_IUA 1
379 #define SCTP_PPID_M2UA 2
380 #define SCTP_PPID_M3UA 3
381 #define SCTP_PPID_SUA 4
382 #define SCTP_PPID_M2PA 5
383 #define SCTP_PPID_V5UA 6
384 #define SCTP_PPID_H248 7
385 #define SCTP_PPID_BICC 8
386 #define SCTP_PPID_TALI 9
387 #define SCTP_PPID_DUA 10
388 #define SCTP_PPID_ASAP 11
389 #define SCTP_PPID_ENRP 12
390 #define SCTP_PPID_H323 13
391 #define SCTP_PPID_QIPC 14
392 #define SCTP_PPID_SIMCO 15
393 #define SCTP_PPID_DDPSC 16
394 #define SCTP_PPID_DDPSSC 17
395 #define SCTP_PPID_S1AP 18
396 #define SCTP_PPID_RUA 19
397 #define SCTP_PPID_HNBAP 20
398 #define SCTP_PPID_FORCES_HP 21
399 #define SCTP_PPID_FORCES_MP 22
400 #define SCTP_PPID_FORCES_LP 23
401 #define SCTP_PPID_SBC_AP 24
402 #define SCTP_PPID_NBAP 25
404 #define SCTP_PPID_X2AP 27
406 static const struct tok PayloadProto_idents
[] = {
407 { SCTP_PPID_IUA
, "ISDN Q.921" },
408 { SCTP_PPID_M2UA
, "M2UA" },
409 { SCTP_PPID_M3UA
, "M3UA" },
410 { SCTP_PPID_SUA
, "SUA" },
411 { SCTP_PPID_M2PA
, "M2PA" },
412 { SCTP_PPID_V5UA
, "V5.2" },
413 { SCTP_PPID_H248
, "H.248" },
414 { SCTP_PPID_BICC
, "BICC" },
415 { SCTP_PPID_TALI
, "TALI" },
416 { SCTP_PPID_DUA
, "DUA" },
417 { SCTP_PPID_ASAP
, "ASAP" },
418 { SCTP_PPID_ENRP
, "ENRP" },
419 { SCTP_PPID_H323
, "H.323" },
420 { SCTP_PPID_QIPC
, "Q.IPC" },
421 { SCTP_PPID_SIMCO
, "SIMCO" },
422 { SCTP_PPID_DDPSC
, "DDPSC" },
423 { SCTP_PPID_DDPSSC
, "DDPSSC" },
424 { SCTP_PPID_S1AP
, "S1AP" },
425 { SCTP_PPID_RUA
, "RUA" },
426 { SCTP_PPID_HNBAP
, "HNBAP" },
427 { SCTP_PPID_FORCES_HP
, "ForCES HP" },
428 { SCTP_PPID_FORCES_MP
, "ForCES MP" },
429 { SCTP_PPID_FORCES_LP
, "ForCES LP" },
430 { SCTP_PPID_SBC_AP
, "SBc-AP" },
431 { SCTP_PPID_NBAP
, "NBAP" },
433 { SCTP_PPID_X2AP
, "X2AP" },
439 isForCES_port(u_short Port
)
452 sctp_print(netdissect_options
*ndo
,
453 const u_char
*bp
, /* beginning of sctp packet */
454 const u_char
*bp2
, /* beginning of enclosing */
455 u_int sctpPacketLength
) /* sctp packet */
457 u_int sctpPacketLengthRemaining
;
458 const struct sctpHeader
*sctpPktHdr
;
460 const struct ip6_hdr
*ip6
;
462 u_short sourcePort
, destPort
;
464 const struct sctpChunkDesc
*chunkDescPtr
;
468 ndo
->ndo_protocol
= "sctp";
469 ND_ICHECKMSG_ZU("length", sctpPacketLength
, <, sizeof(struct sctpHeader
));
470 sctpPktHdr
= (const struct sctpHeader
*) bp
;
471 ND_TCHECK_SIZE(sctpPktHdr
);
472 sctpPacketLengthRemaining
= sctpPacketLength
;
474 sourcePort
= GET_BE_U_2(sctpPktHdr
->source
);
475 destPort
= GET_BE_U_2(sctpPktHdr
->destination
);
477 ip
= (const struct ip
*)bp2
;
479 ip6
= (const struct ip6_hdr
*)bp2
;
484 ND_PRINT("%s.%u > %s.%u: sctp",
485 GET_IP6ADDR_STRING(ip6
->ip6_src
),
487 GET_IP6ADDR_STRING(ip6
->ip6_dst
),
490 ND_PRINT("%s.%u > %s.%u: sctp",
491 GET_IPADDR_STRING(ip
->ip_src
),
493 GET_IPADDR_STRING(ip
->ip_dst
),
497 if (isForCES_port(sourcePort
)) {
498 ND_PRINT("[%s]", tok2str(ForCES_channels
, NULL
, sourcePort
));
501 if (isForCES_port(destPort
)) {
502 ND_PRINT("[%s]", tok2str(ForCES_channels
, NULL
, destPort
));
506 bp
+= sizeof(struct sctpHeader
);
507 sctpPacketLengthRemaining
-= sizeof(struct sctpHeader
);
509 if (ndo
->ndo_vflag
>= 2)
513 /* cycle through all chunks, printing information on each one */
514 for (chunkCount
= 0, chunkDescPtr
= (const struct sctpChunkDesc
*)bp
;
515 sctpPacketLengthRemaining
!= 0;
518 uint16_t chunkLength
, chunkLengthRemaining
;
521 chunkDescPtr
= (const struct sctpChunkDesc
*)bp
;
522 if (sctpPacketLengthRemaining
< sizeof(*chunkDescPtr
)) {
523 ND_PRINT("%s%u) [chunk descriptor cut off at end of packet]", sep
, chunkCount
+1);
526 ND_TCHECK_SIZE(chunkDescPtr
);
527 chunkLength
= GET_BE_U_2(chunkDescPtr
->chunkLength
);
528 if (chunkLength
< sizeof(*chunkDescPtr
)) {
529 ND_PRINT("%s%u) [Bad chunk length %u, < size of chunk descriptor]", sep
, chunkCount
+1, chunkLength
);
532 chunkLengthRemaining
= chunkLength
;
534 align
= chunkLength
% 4;
538 if (sctpPacketLengthRemaining
< align
) {
539 ND_PRINT("%s%u) [Bad chunk length %u, > remaining data in packet]", sep
, chunkCount
+1, chunkLength
);
543 ND_TCHECK_LEN(bp
, chunkLength
);
545 bp
+= sizeof(*chunkDescPtr
);
546 sctpPacketLengthRemaining
-= sizeof(*chunkDescPtr
);
547 chunkLengthRemaining
-= sizeof(*chunkDescPtr
);
549 ND_PRINT("%s%u) ", sep
, chunkCount
+1);
550 chunkID
= GET_U_1(chunkDescPtr
->chunkID
);
551 ND_PRINT("[%s] ", tok2str(sctp_chunkid_str
, "Unknown chunk type: 0x%x",
556 const struct sctpDataPart
*dataHdrPtr
;
559 uint16_t payload_size
;
561 chunkFlg
= GET_U_1(chunkDescPtr
->chunkFlg
);
562 if ((chunkFlg
& SCTP_DATA_UNORDERED
) == SCTP_DATA_UNORDERED
)
565 if ((chunkFlg
& SCTP_DATA_FIRST_FRAG
) == SCTP_DATA_FIRST_FRAG
)
568 if ((chunkFlg
& SCTP_DATA_LAST_FRAG
) == SCTP_DATA_LAST_FRAG
)
571 if( ((chunkFlg
& SCTP_DATA_UNORDERED
) == SCTP_DATA_UNORDERED
) ||
572 ((chunkFlg
& SCTP_DATA_FIRST_FRAG
) == SCTP_DATA_FIRST_FRAG
) ||
573 ((chunkFlg
& SCTP_DATA_LAST_FRAG
) == SCTP_DATA_LAST_FRAG
) )
576 ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining
, <,
577 sizeof(*dataHdrPtr
));
578 dataHdrPtr
=(const struct sctpDataPart
*)bp
;
580 ppid
= GET_BE_U_4(dataHdrPtr
->payloadtype
);
581 ND_PRINT("[TSN: %u] ", GET_BE_U_4(dataHdrPtr
->TSN
));
582 ND_PRINT("[SID: %u] ", GET_BE_U_2(dataHdrPtr
->streamId
));
583 ND_PRINT("[SSEQ %u] ", GET_BE_U_2(dataHdrPtr
->sequence
));
584 ND_PRINT("[PPID %s] ",
585 tok2str(PayloadProto_idents
, "0x%x", ppid
));
588 isforces
= (ppid
== SCTP_PPID_FORCES_HP
) ||
589 (ppid
== SCTP_PPID_FORCES_MP
) ||
590 (ppid
== SCTP_PPID_FORCES_LP
);
593 bp
+= sizeof(*dataHdrPtr
);
594 sctpPacketLengthRemaining
-= sizeof(*dataHdrPtr
);
595 chunkLengthRemaining
-= sizeof(*dataHdrPtr
);
596 ND_ICHECKMSG_U("chunk length", chunkLengthRemaining
, ==, 0);
597 payload_size
= chunkLengthRemaining
;
600 forces_print(ndo
, bp
, payload_size
);
601 /* ndo_protocol reassignment after forces_print() call */
602 ndo
->ndo_protocol
= "sctp";
603 } else if (ndo
->ndo_vflag
>= 2) { /* if verbose output is specified */
604 /* at the command line */
606 case SCTP_PPID_M3UA
:
607 m3ua_print(ndo
, bp
, payload_size
);
608 /* ndo_protocol reassignment after m3ua_print() call */
609 ndo
->ndo_protocol
= "sctp";
612 ND_PRINT("[Payload");
613 if (!ndo
->ndo_suppress_default_print
) {
615 ND_DEFAULTPRINT(bp
, payload_size
);
622 sctpPacketLengthRemaining
-= payload_size
;
623 chunkLengthRemaining
-= payload_size
;
626 case SCTP_INITIATION
:
628 const struct sctpInitiation
*init
;
630 ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining
, <,
632 init
=(const struct sctpInitiation
*)bp
;
633 ND_PRINT("[init tag: %u] ", GET_BE_U_4(init
->initTag
));
634 ND_PRINT("[rwnd: %u] ", GET_BE_U_4(init
->rcvWindowCredit
));
635 ND_PRINT("[OS: %u] ", GET_BE_U_2(init
->NumPreopenStreams
));
636 ND_PRINT("[MIS: %u] ", GET_BE_U_2(init
->MaxInboundStreams
));
637 ND_PRINT("[init TSN: %u] ", GET_BE_U_4(init
->initialTSN
));
639 sctpPacketLengthRemaining
-= sizeof(*init
);
640 chunkLengthRemaining
-= sizeof(*init
);
642 #if 0 /* ALC you can add code for optional params here */
643 if( chunkLengthRemaining
!= 0 )
644 ND_PRINT(" @@@@@ UNFINISHED @@@@@@%s\n",
645 "Optional params present, but not printed.");
647 bp
+= chunkLengthRemaining
;
648 sctpPacketLengthRemaining
-= chunkLengthRemaining
;
649 chunkLengthRemaining
= 0;
652 case SCTP_INITIATION_ACK
:
654 const struct sctpInitiation
*init
;
656 ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining
, <,
658 init
=(const struct sctpInitiation
*)bp
;
659 ND_PRINT("[init tag: %u] ", GET_BE_U_4(init
->initTag
));
660 ND_PRINT("[rwnd: %u] ", GET_BE_U_4(init
->rcvWindowCredit
));
661 ND_PRINT("[OS: %u] ", GET_BE_U_2(init
->NumPreopenStreams
));
662 ND_PRINT("[MIS: %u] ", GET_BE_U_2(init
->MaxInboundStreams
));
663 ND_PRINT("[init TSN: %u] ", GET_BE_U_4(init
->initialTSN
));
665 sctpPacketLengthRemaining
-= sizeof(*init
);
666 chunkLengthRemaining
-= sizeof(*init
);
668 #if 0 /* ALC you can add code for optional params here */
669 if( chunkLengthRemaining
!= 0 )
670 ND_PRINT(" @@@@@ UNFINISHED @@@@@@%s\n",
671 "Optional params present, but not printed.");
673 bp
+= chunkLengthRemaining
;
674 sctpPacketLengthRemaining
-= chunkLengthRemaining
;
675 chunkLengthRemaining
= 0;
678 case SCTP_SELECTIVE_ACK
:
680 const struct sctpSelectiveAck
*sack
;
681 const struct sctpSelectiveFrag
*frag
;
683 const u_char
*dupTSN
;
685 ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining
, <,
687 sack
=(const struct sctpSelectiveAck
*)bp
;
688 ND_PRINT("[cum ack %u] ", GET_BE_U_4(sack
->highestConseqTSN
));
689 ND_PRINT("[a_rwnd %u] ", GET_BE_U_4(sack
->updatedRwnd
));
690 ND_PRINT("[#gap acks %u] ", GET_BE_U_2(sack
->numberOfdesc
));
691 ND_PRINT("[#dup tsns %u] ", GET_BE_U_2(sack
->numDupTsns
));
693 sctpPacketLengthRemaining
-= sizeof(*sack
);
694 chunkLengthRemaining
-= sizeof(*sack
);
699 chunkLengthRemaining
!= 0 && fragNo
< GET_BE_U_2(sack
->numberOfdesc
);
700 bp
+= sizeof(*frag
), sctpPacketLengthRemaining
-= sizeof(*frag
), chunkLengthRemaining
-= sizeof(*frag
), fragNo
++) {
701 ND_ICHECKMSG_ZU("chunk length", chunkLengthRemaining
, <,
703 frag
= (const struct sctpSelectiveFrag
*)bp
;
704 ND_PRINT("\n\t\t[gap ack block #%u: start = %u, end = %u] ",
706 GET_BE_U_4(sack
->highestConseqTSN
) + GET_BE_U_2(frag
->fragmentStart
),
707 GET_BE_U_4(sack
->highestConseqTSN
) + GET_BE_U_2(frag
->fragmentEnd
));
710 /* print duplicate TSNs */
712 chunkLengthRemaining
!= 0 && tsnNo
<GET_BE_U_2(sack
->numDupTsns
);
713 bp
+= 4, sctpPacketLengthRemaining
-= 4, chunkLengthRemaining
-= 4, tsnNo
++) {
714 ND_ICHECKMSG_U("chunk length", chunkLengthRemaining
, <, 4);
715 dupTSN
= (const u_char
*)bp
;
716 ND_PRINT("\n\t\t[dup TSN #%u: %u] ", tsnNo
+1,
723 bp
+= chunkLengthRemaining
;
724 sctpPacketLengthRemaining
-= chunkLengthRemaining
;
725 chunkLengthRemaining
= 0;
731 * Any extra stuff at the end of the chunk?
734 bp
+= chunkLengthRemaining
;
735 sctpPacketLengthRemaining
-= chunkLengthRemaining
;
737 if (ndo
->ndo_vflag
< 2)
742 * Fail if the alignment padding isn't in the captured data.
743 * Otherwise, skip it.
745 ND_TCHECK_LEN(bp
, align
);
747 sctpPacketLengthRemaining
-= align
;
752 nd_print_invalid(ndo
);