xref: /dragonfly/contrib/tcpdump/print-sctp.c (revision 27bfbee1)
141c99275SPeter Avalos /* Copyright (c) 2001 NETLAB, Temple University
241c99275SPeter Avalos  * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware
341c99275SPeter Avalos  *
441c99275SPeter Avalos  * Jerry Heinz <gheinz@astro.temple.edu>
541c99275SPeter Avalos  * John Fiore <jfiore@joda.cis.temple.edu>
641c99275SPeter Avalos  * Armando L. Caro Jr. <acaro@cis.udel.edu>
741c99275SPeter Avalos  *
841c99275SPeter Avalos  * Redistribution and use in source and binary forms, with or without
941c99275SPeter Avalos  * modification, are permitted provided that the following conditions
1041c99275SPeter Avalos  * are met:
1141c99275SPeter Avalos  *
1241c99275SPeter Avalos  * 1. Redistributions of source code must retain the above copyright
1341c99275SPeter Avalos  *    notice, this list of conditions and the following disclaimer.
1441c99275SPeter Avalos  *
1541c99275SPeter Avalos  * 2. Redistributions in binary form must reproduce the above copyright
1641c99275SPeter Avalos  *    notice, this list of conditions and the following disclaimer in the
1741c99275SPeter Avalos  *    documentation and/or other materials provided with the distribution.
1841c99275SPeter Avalos  *
1941c99275SPeter Avalos  * 3. Neither the name of the University nor of the Laboratory may be used
2041c99275SPeter Avalos  *    to endorse or promote products derived from this software without
2141c99275SPeter Avalos  *    specific prior written permission.
2241c99275SPeter Avalos  *
2341c99275SPeter Avalos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2441c99275SPeter Avalos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2541c99275SPeter Avalos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2641c99275SPeter Avalos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2741c99275SPeter Avalos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2841c99275SPeter Avalos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2941c99275SPeter Avalos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3041c99275SPeter Avalos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3141c99275SPeter Avalos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3241c99275SPeter Avalos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3341c99275SPeter Avalos  * SUCH DAMAGE.
3441c99275SPeter Avalos  */
3541c99275SPeter Avalos 
3641c99275SPeter Avalos #ifndef lint
3741c99275SPeter Avalos static const char rcsid[] _U_ =
38ea7b4bf5SPeter Avalos "@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.21 2007-09-13 18:03:49 guy Exp $ (NETLAB/PEL)";
3941c99275SPeter Avalos #endif
4041c99275SPeter Avalos 
4141c99275SPeter Avalos #ifdef HAVE_CONFIG_H
4241c99275SPeter Avalos #include "config.h"
4341c99275SPeter Avalos #endif
4441c99275SPeter Avalos 
4541c99275SPeter Avalos #include <tcpdump-stdinc.h>
4641c99275SPeter Avalos 
4741c99275SPeter Avalos #include "sctpHeader.h"
4841c99275SPeter Avalos #include "sctpConstants.h"
4941c99275SPeter Avalos #include <assert.h>
5041c99275SPeter Avalos 
5141c99275SPeter Avalos #include <stdio.h>
5241c99275SPeter Avalos #include <string.h>
5341c99275SPeter Avalos 
5441c99275SPeter Avalos #include "interface.h"
5541c99275SPeter Avalos #include "addrtoname.h"
5641c99275SPeter Avalos #include "extract.h"			/* must come after interface.h */
5741c99275SPeter Avalos #include "ip.h"
5841c99275SPeter Avalos #ifdef INET6
5941c99275SPeter Avalos #include "ip6.h"
6041c99275SPeter Avalos #endif
6141c99275SPeter Avalos 
62*27bfbee1SPeter Avalos #define CHAN_HP 6704
63*27bfbee1SPeter Avalos #define CHAN_MP 6705
64*27bfbee1SPeter Avalos #define CHAN_LP 6706
65*27bfbee1SPeter Avalos 
66*27bfbee1SPeter Avalos struct tok ForCES_channels[] = {
67*27bfbee1SPeter Avalos 	{ CHAN_HP, "ForCES HP" },
68*27bfbee1SPeter Avalos 	{ CHAN_MP, "ForCES MP" },
69*27bfbee1SPeter Avalos 	{ CHAN_LP, "ForCES LP" },
70*27bfbee1SPeter Avalos 	{ 0, NULL }
71*27bfbee1SPeter Avalos };
72*27bfbee1SPeter Avalos 
73*27bfbee1SPeter Avalos static inline int isForCES_port(u_short Port)
74*27bfbee1SPeter Avalos {
75*27bfbee1SPeter Avalos 	if (Port == CHAN_HP)
76*27bfbee1SPeter Avalos 		return 1;
77*27bfbee1SPeter Avalos 	if (Port == CHAN_MP)
78*27bfbee1SPeter Avalos 		return 1;
79*27bfbee1SPeter Avalos 	if (Port == CHAN_LP)
80*27bfbee1SPeter Avalos 		return 1;
81*27bfbee1SPeter Avalos 
82*27bfbee1SPeter Avalos 	return 0;
83*27bfbee1SPeter Avalos }
84*27bfbee1SPeter Avalos 
8541c99275SPeter Avalos void sctp_print(const u_char *bp,        /* beginning of sctp packet */
8641c99275SPeter Avalos 		const u_char *bp2,       /* beginning of enclosing */
8741c99275SPeter Avalos 		u_int sctpPacketLength)  /* ip packet */
8841c99275SPeter Avalos {
8941c99275SPeter Avalos   const struct sctpHeader *sctpPktHdr;
9041c99275SPeter Avalos   const struct ip *ip;
9141c99275SPeter Avalos #ifdef INET6
9241c99275SPeter Avalos   const struct ip6_hdr *ip6;
9341c99275SPeter Avalos #endif
9441c99275SPeter Avalos   const void *endPacketPtr;
9541c99275SPeter Avalos   u_short sourcePort, destPort;
9641c99275SPeter Avalos   int chunkCount;
9741c99275SPeter Avalos   const struct sctpChunkDesc *chunkDescPtr;
9841c99275SPeter Avalos   const void *nextChunk;
9941c99275SPeter Avalos   const char *sep;
100*27bfbee1SPeter Avalos   int isforces = 0;
101*27bfbee1SPeter Avalos 
10241c99275SPeter Avalos 
10341c99275SPeter Avalos   sctpPktHdr = (const struct sctpHeader*) bp;
10441c99275SPeter Avalos   endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;
10541c99275SPeter Avalos 
10641c99275SPeter Avalos   if( (u_long) endPacketPtr > (u_long) snapend)
10741c99275SPeter Avalos     endPacketPtr = (const void *) snapend;
10841c99275SPeter Avalos   ip = (struct ip *)bp2;
10941c99275SPeter Avalos #ifdef INET6
11041c99275SPeter Avalos   if (IP_V(ip) == 6)
11141c99275SPeter Avalos     ip6 = (const struct ip6_hdr *)bp2;
11241c99275SPeter Avalos   else
11341c99275SPeter Avalos     ip6 = NULL;
11441c99275SPeter Avalos #endif /*INET6*/
11541c99275SPeter Avalos   TCHECK(*sctpPktHdr);
11641c99275SPeter Avalos 
11741c99275SPeter Avalos   if (sctpPacketLength < sizeof(struct sctpHeader))
11841c99275SPeter Avalos     {
11941c99275SPeter Avalos       (void)printf("truncated-sctp - %ld bytes missing!",
12041c99275SPeter Avalos 		   (long)sctpPacketLength-sizeof(struct sctpHeader));
12141c99275SPeter Avalos       return;
12241c99275SPeter Avalos     }
12341c99275SPeter Avalos 
12441c99275SPeter Avalos   /*    sctpPacketLength -= sizeof(struct sctpHeader);  packet length  */
12541c99275SPeter Avalos   /*  			      is now only as long as the payload  */
12641c99275SPeter Avalos 
12741c99275SPeter Avalos   sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
12841c99275SPeter Avalos   destPort = EXTRACT_16BITS(&sctpPktHdr->destination);
12941c99275SPeter Avalos 
13041c99275SPeter Avalos #ifdef INET6
13141c99275SPeter Avalos   if (ip6) {
13241c99275SPeter Avalos     (void)printf("%s.%d > %s.%d: sctp",
13341c99275SPeter Avalos       ip6addr_string(&ip6->ip6_src),
13441c99275SPeter Avalos       sourcePort,
13541c99275SPeter Avalos       ip6addr_string(&ip6->ip6_dst),
13641c99275SPeter Avalos       destPort);
13741c99275SPeter Avalos   } else
13841c99275SPeter Avalos #endif /*INET6*/
13941c99275SPeter Avalos   {
14041c99275SPeter Avalos     (void)printf("%s.%d > %s.%d: sctp",
14141c99275SPeter Avalos       ipaddr_string(&ip->ip_src),
14241c99275SPeter Avalos       sourcePort,
14341c99275SPeter Avalos       ipaddr_string(&ip->ip_dst),
14441c99275SPeter Avalos       destPort);
14541c99275SPeter Avalos   }
14641c99275SPeter Avalos   fflush(stdout);
14741c99275SPeter Avalos 
148*27bfbee1SPeter Avalos   if (isForCES_port(sourcePort)) {
149*27bfbee1SPeter Avalos          printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort));
150*27bfbee1SPeter Avalos          isforces = 1;
151*27bfbee1SPeter Avalos   }
152*27bfbee1SPeter Avalos   if (isForCES_port(destPort)) {
153*27bfbee1SPeter Avalos          printf("[%s]", tok2str(ForCES_channels, NULL, destPort));
154*27bfbee1SPeter Avalos          isforces = 1;
155*27bfbee1SPeter Avalos   }
156*27bfbee1SPeter Avalos 
15741c99275SPeter Avalos   if (vflag >= 2)
15841c99275SPeter Avalos     sep = "\n\t";
15941c99275SPeter Avalos   else
16041c99275SPeter Avalos     sep = " (";
16141c99275SPeter Avalos   /* cycle through all chunks, printing information on each one */
16241c99275SPeter Avalos   for (chunkCount = 0,
16341c99275SPeter Avalos 	 chunkDescPtr = (const struct sctpChunkDesc *)
16441c99275SPeter Avalos 	    ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader));
16541c99275SPeter Avalos        chunkDescPtr != NULL &&
16641c99275SPeter Avalos 	 ( (const void *)
16741c99275SPeter Avalos 	    ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc))
16841c99275SPeter Avalos 	   <= endPacketPtr);
16941c99275SPeter Avalos 
17041c99275SPeter Avalos        chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
17141c99275SPeter Avalos     {
17241c99275SPeter Avalos       u_int16_t chunkLength;
17341c99275SPeter Avalos       const u_char *chunkEnd;
17441c99275SPeter Avalos       u_int16_t align;
17541c99275SPeter Avalos 
17641c99275SPeter Avalos       TCHECK(*chunkDescPtr);
17741c99275SPeter Avalos       chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
17841c99275SPeter Avalos       if (chunkLength < sizeof(*chunkDescPtr)) {
17941c99275SPeter Avalos       	printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength);
18041c99275SPeter Avalos       	break;
18141c99275SPeter Avalos       }
18241c99275SPeter Avalos 
18341c99275SPeter Avalos       TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
18441c99275SPeter Avalos       chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);
18541c99275SPeter Avalos 
18641c99275SPeter Avalos       align=chunkLength % 4;
18741c99275SPeter Avalos       if (align != 0)
18841c99275SPeter Avalos 	align = 4 - align;
18941c99275SPeter Avalos 
19041c99275SPeter Avalos       nextChunk = (const void *) (chunkEnd + align);
19141c99275SPeter Avalos 
19241c99275SPeter Avalos       printf("%s%d) ", sep, chunkCount+1);
19341c99275SPeter Avalos       switch (chunkDescPtr->chunkID)
19441c99275SPeter Avalos 	{
19541c99275SPeter Avalos 	case SCTP_DATA :
19641c99275SPeter Avalos 	  {
19741c99275SPeter Avalos 	    const struct sctpDataPart *dataHdrPtr;
19841c99275SPeter Avalos 
19941c99275SPeter Avalos 	    printf("[DATA] ");
20041c99275SPeter Avalos 
20141c99275SPeter Avalos 	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
20241c99275SPeter Avalos 		== SCTP_DATA_UNORDERED)
20341c99275SPeter Avalos 	      printf("(U)");
20441c99275SPeter Avalos 
20541c99275SPeter Avalos 	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
20641c99275SPeter Avalos 		== SCTP_DATA_FIRST_FRAG)
20741c99275SPeter Avalos 	      printf("(B)");
20841c99275SPeter Avalos 
20941c99275SPeter Avalos 	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
21041c99275SPeter Avalos 		== SCTP_DATA_LAST_FRAG)
21141c99275SPeter Avalos 	      printf("(E)");
21241c99275SPeter Avalos 
21341c99275SPeter Avalos 	    if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
21441c99275SPeter Avalos 		 == SCTP_DATA_UNORDERED)
21541c99275SPeter Avalos 		||
21641c99275SPeter Avalos 		((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
21741c99275SPeter Avalos 		 == SCTP_DATA_FIRST_FRAG)
21841c99275SPeter Avalos 		||
21941c99275SPeter Avalos 		((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
22041c99275SPeter Avalos 		 == SCTP_DATA_LAST_FRAG) )
22141c99275SPeter Avalos 	      printf(" ");
22241c99275SPeter Avalos 
22341c99275SPeter Avalos 	    dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);
22441c99275SPeter Avalos 
22541c99275SPeter Avalos 	    printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
22641c99275SPeter Avalos 	    printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
22741c99275SPeter Avalos 	    printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
22841c99275SPeter Avalos 	    printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
22941c99275SPeter Avalos 	    fflush(stdout);
230*27bfbee1SPeter Avalos 	    if (isforces) {
231*27bfbee1SPeter Avalos 		const u_char *payloadPtr;
232*27bfbee1SPeter Avalos 		u_int chunksize = sizeof(struct sctpDataPart)+
233*27bfbee1SPeter Avalos 			          sizeof(struct sctpChunkDesc);
234*27bfbee1SPeter Avalos 		payloadPtr = (const u_char *) (dataHdrPtr + 1);
235*27bfbee1SPeter Avalos 		if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
236*27bfbee1SPeter Avalos 			sizeof(struct sctpDataPart)+
237*27bfbee1SPeter Avalos 			sizeof(struct sctpChunkDesc)+1) {
238*27bfbee1SPeter Avalos 		/* Less than 1 byte of chunk payload */
239*27bfbee1SPeter Avalos 			printf("bogus ForCES chunk length %u]",
240*27bfbee1SPeter Avalos 			    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
241*27bfbee1SPeter Avalos 			return;
242*27bfbee1SPeter Avalos 		}
24341c99275SPeter Avalos 
244*27bfbee1SPeter Avalos 		forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize);
245*27bfbee1SPeter Avalos 	   } else if (vflag >= 2) {	/* if verbose output is specified */
246*27bfbee1SPeter Avalos 					/* at the command line */
24741c99275SPeter Avalos 		const u_char *payloadPtr;
24841c99275SPeter Avalos 
24941c99275SPeter Avalos 		printf("[Payload");
25041c99275SPeter Avalos 
25141c99275SPeter Avalos 		if (!suppress_default_print) {
25241c99275SPeter Avalos 			payloadPtr = (const u_char *) (++dataHdrPtr);
25341c99275SPeter Avalos 			printf(":");
254*27bfbee1SPeter Avalos 			if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
25541c99275SPeter Avalos 			    sizeof(struct sctpDataPart)+
25641c99275SPeter Avalos 			    sizeof(struct sctpChunkDesc)+1) {
25741c99275SPeter Avalos 				/* Less than 1 byte of chunk payload */
25841c99275SPeter Avalos 				printf("bogus chunk length %u]",
259*27bfbee1SPeter Avalos 				    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
26041c99275SPeter Avalos 				return;
26141c99275SPeter Avalos 			}
26241c99275SPeter Avalos 			default_print(payloadPtr,
263*27bfbee1SPeter Avalos 			      EXTRACT_16BITS(&chunkDescPtr->chunkLength) -
26441c99275SPeter Avalos 			      (sizeof(struct sctpDataPart)+
26541c99275SPeter Avalos 			      sizeof(struct sctpChunkDesc)));
26641c99275SPeter Avalos 		} else
26741c99275SPeter Avalos 			printf("]");
26841c99275SPeter Avalos 	      }
26941c99275SPeter Avalos 	    break;
27041c99275SPeter Avalos 	  }
27141c99275SPeter Avalos 	case SCTP_INITIATION :
27241c99275SPeter Avalos 	  {
27341c99275SPeter Avalos 	    const struct sctpInitiation *init;
27441c99275SPeter Avalos 
27541c99275SPeter Avalos 	    printf("[INIT] ");
27641c99275SPeter Avalos 	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
27741c99275SPeter Avalos 	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
27841c99275SPeter Avalos 	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
27941c99275SPeter Avalos 	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
28041c99275SPeter Avalos 	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
28141c99275SPeter Avalos 	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
28241c99275SPeter Avalos 
28341c99275SPeter Avalos #if(0) /* ALC you can add code for optional params here */
28441c99275SPeter Avalos 	    if( (init+1) < chunkEnd )
28541c99275SPeter Avalos 	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
28641c99275SPeter Avalos 		     "Optional params present, but not printed.");
28741c99275SPeter Avalos #endif
28841c99275SPeter Avalos 	    break;
28941c99275SPeter Avalos 	  }
29041c99275SPeter Avalos 	case SCTP_INITIATION_ACK :
29141c99275SPeter Avalos 	  {
29241c99275SPeter Avalos 	    const struct sctpInitiation *init;
29341c99275SPeter Avalos 
29441c99275SPeter Avalos 	    printf("[INIT ACK] ");
29541c99275SPeter Avalos 	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
29641c99275SPeter Avalos 	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
29741c99275SPeter Avalos 	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
29841c99275SPeter Avalos 	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
29941c99275SPeter Avalos 	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
30041c99275SPeter Avalos 	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
30141c99275SPeter Avalos 
30241c99275SPeter Avalos #if(0) /* ALC you can add code for optional params here */
30341c99275SPeter Avalos 	    if( (init+1) < chunkEnd )
30441c99275SPeter Avalos 	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
30541c99275SPeter Avalos 		     "Optional params present, but not printed.");
30641c99275SPeter Avalos #endif
30741c99275SPeter Avalos 	    break;
30841c99275SPeter Avalos 	  }
30941c99275SPeter Avalos 	case SCTP_SELECTIVE_ACK:
31041c99275SPeter Avalos 	  {
31141c99275SPeter Avalos 	    const struct sctpSelectiveAck *sack;
31241c99275SPeter Avalos 	    const struct sctpSelectiveFrag *frag;
31341c99275SPeter Avalos 	    int fragNo, tsnNo;
31441c99275SPeter Avalos 	    const u_char *dupTSN;
31541c99275SPeter Avalos 
31641c99275SPeter Avalos 	    printf("[SACK] ");
31741c99275SPeter Avalos 	    sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
31841c99275SPeter Avalos 	    printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN));
31941c99275SPeter Avalos 	    printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd));
32041c99275SPeter Avalos 	    printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc));
32141c99275SPeter Avalos 	    printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns));
32241c99275SPeter Avalos 
32341c99275SPeter Avalos 
32441c99275SPeter Avalos 	    /* print gaps */
32541c99275SPeter Avalos 	    for (frag = ( (const struct sctpSelectiveFrag *)
32641c99275SPeter Avalos 			  ((const struct sctpSelectiveAck *) sack+1)),
32741c99275SPeter Avalos 		   fragNo=0;
32841c99275SPeter Avalos 		 (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
32941c99275SPeter Avalos 		 frag++, fragNo++)
33041c99275SPeter Avalos 	      printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
33141c99275SPeter Avalos 		     fragNo+1,
33241c99275SPeter Avalos 		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
33341c99275SPeter Avalos 		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd));
33441c99275SPeter Avalos 
33541c99275SPeter Avalos 
33641c99275SPeter Avalos 	    /* print duplicate TSNs */
33741c99275SPeter Avalos 	    for (dupTSN = (const u_char *)frag, tsnNo=0;
33841c99275SPeter Avalos 		 (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
33941c99275SPeter Avalos 		 dupTSN += 4, tsnNo++)
34041c99275SPeter Avalos 	      printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
34141c99275SPeter Avalos 	          EXTRACT_32BITS(dupTSN));
34241c99275SPeter Avalos 
34341c99275SPeter Avalos 	    break;
34441c99275SPeter Avalos 	  }
34541c99275SPeter Avalos 	case SCTP_HEARTBEAT_REQUEST :
34641c99275SPeter Avalos 	  {
34741c99275SPeter Avalos 	    const struct sctpHBsender *hb;
34841c99275SPeter Avalos 
34941c99275SPeter Avalos 	    hb=(const struct sctpHBsender*)chunkDescPtr;
35041c99275SPeter Avalos 
35141c99275SPeter Avalos 	    printf("[HB REQ] ");
35241c99275SPeter Avalos 
35341c99275SPeter Avalos 	    break;
35441c99275SPeter Avalos 	  }
35541c99275SPeter Avalos 	case SCTP_HEARTBEAT_ACK :
35641c99275SPeter Avalos 	  printf("[HB ACK] ");
35741c99275SPeter Avalos 	  break;
35841c99275SPeter Avalos 	case SCTP_ABORT_ASSOCIATION :
35941c99275SPeter Avalos 	  printf("[ABORT] ");
36041c99275SPeter Avalos 	  break;
36141c99275SPeter Avalos 	case SCTP_SHUTDOWN :
36241c99275SPeter Avalos 	  printf("[SHUTDOWN] ");
36341c99275SPeter Avalos 	  break;
36441c99275SPeter Avalos 	case SCTP_SHUTDOWN_ACK :
36541c99275SPeter Avalos 	  printf("[SHUTDOWN ACK] ");
36641c99275SPeter Avalos 	  break;
36741c99275SPeter Avalos 	case SCTP_OPERATION_ERR :
36841c99275SPeter Avalos 	  printf("[OP ERR] ");
36941c99275SPeter Avalos 	  break;
37041c99275SPeter Avalos 	case SCTP_COOKIE_ECHO :
37141c99275SPeter Avalos 	  printf("[COOKIE ECHO] ");
37241c99275SPeter Avalos 	  break;
37341c99275SPeter Avalos 	case SCTP_COOKIE_ACK :
37441c99275SPeter Avalos 	  printf("[COOKIE ACK] ");
37541c99275SPeter Avalos 	  break;
37641c99275SPeter Avalos 	case SCTP_ECN_ECHO :
37741c99275SPeter Avalos 	  printf("[ECN ECHO] ");
37841c99275SPeter Avalos 	  break;
37941c99275SPeter Avalos 	case SCTP_ECN_CWR :
38041c99275SPeter Avalos 	  printf("[ECN CWR] ");
38141c99275SPeter Avalos 	  break;
38241c99275SPeter Avalos 	case SCTP_SHUTDOWN_COMPLETE :
38341c99275SPeter Avalos 	  printf("[SHUTDOWN COMPLETE] ");
38441c99275SPeter Avalos 	  break;
38541c99275SPeter Avalos 	case SCTP_FORWARD_CUM_TSN :
38641c99275SPeter Avalos 	  printf("[FOR CUM TSN] ");
38741c99275SPeter Avalos 	  break;
38841c99275SPeter Avalos 	case SCTP_RELIABLE_CNTL :
38941c99275SPeter Avalos 	  printf("[REL CTRL] ");
39041c99275SPeter Avalos 	  break;
39141c99275SPeter Avalos 	case SCTP_RELIABLE_CNTL_ACK :
39241c99275SPeter Avalos 	  printf("[REL CTRL ACK] ");
39341c99275SPeter Avalos 	  break;
39441c99275SPeter Avalos 	default :
39541c99275SPeter Avalos 	  printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID);
39641c99275SPeter Avalos 	  return;
39741c99275SPeter Avalos 	}
39841c99275SPeter Avalos 
39941c99275SPeter Avalos 	if (vflag < 2)
40041c99275SPeter Avalos 	  sep = ", (";
40141c99275SPeter Avalos     }
40241c99275SPeter Avalos     return;
40341c99275SPeter Avalos 
40441c99275SPeter Avalos trunc:
40541c99275SPeter Avalos     printf("[|sctp]");
40641c99275SPeter Avalos     return;
40741c99275SPeter Avalos }
408