xref: /freebsd/contrib/tcpdump/print-sctp.c (revision cac3dcd5)
1a90e161bSBill Fenner /* Copyright (c) 2001 NETLAB, Temple University
2a90e161bSBill Fenner  * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware
3a90e161bSBill Fenner  *
4a90e161bSBill Fenner  * Jerry Heinz <gheinz@astro.temple.edu>
5a90e161bSBill Fenner  * John Fiore <jfiore@joda.cis.temple.edu>
6a90e161bSBill Fenner  * Armando L. Caro Jr. <acaro@cis.udel.edu>
7a90e161bSBill Fenner  *
8a90e161bSBill Fenner  * Redistribution and use in source and binary forms, with or without
9a90e161bSBill Fenner  * modification, are permitted provided that the following conditions
10a90e161bSBill Fenner  * are met:
11a90e161bSBill Fenner  *
12a90e161bSBill Fenner  * 1. Redistributions of source code must retain the above copyright
13a90e161bSBill Fenner  *    notice, this list of conditions and the following disclaimer.
14a90e161bSBill Fenner  *
15a90e161bSBill Fenner  * 2. Redistributions in binary form must reproduce the above copyright
16a90e161bSBill Fenner  *    notice, this list of conditions and the following disclaimer in the
17a90e161bSBill Fenner  *    documentation and/or other materials provided with the distribution.
18a90e161bSBill Fenner  *
19a90e161bSBill Fenner  * 3. Neither the name of the University nor of the Laboratory may be used
20a90e161bSBill Fenner  *    to endorse or promote products derived from this software without
21a90e161bSBill Fenner  *    specific prior written permission.
22a90e161bSBill Fenner  *
23a90e161bSBill Fenner  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24a90e161bSBill Fenner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25a90e161bSBill Fenner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26a90e161bSBill Fenner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27a90e161bSBill Fenner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28a90e161bSBill Fenner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29a90e161bSBill Fenner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30a90e161bSBill Fenner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31a90e161bSBill Fenner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32a90e161bSBill Fenner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33a90e161bSBill Fenner  * SUCH DAMAGE.
34a90e161bSBill Fenner  */
35a90e161bSBill Fenner 
36a90e161bSBill Fenner #ifndef lint
375b0fe478SBruce M Simpson static const char rcsid[] _U_ =
38a5779b6eSRui Paulo "@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.21 2007-09-13 18:03:49 guy Exp $ (NETLAB/PEL)";
39a90e161bSBill Fenner #endif
40a90e161bSBill Fenner 
41a90e161bSBill Fenner #ifdef HAVE_CONFIG_H
42a90e161bSBill Fenner #include "config.h"
43a90e161bSBill Fenner #endif
44a90e161bSBill Fenner 
455b0fe478SBruce M Simpson #include <tcpdump-stdinc.h>
46a90e161bSBill Fenner 
47a90e161bSBill Fenner #include "sctpHeader.h"
48a90e161bSBill Fenner #include "sctpConstants.h"
49a90e161bSBill Fenner #include <assert.h>
50a90e161bSBill Fenner 
51a90e161bSBill Fenner #include <stdio.h>
52a90e161bSBill Fenner #include <string.h>
53a90e161bSBill Fenner 
54a90e161bSBill Fenner #include "interface.h"
55a90e161bSBill Fenner #include "addrtoname.h"
56a90e161bSBill Fenner #include "extract.h"			/* must come after interface.h */
57a90e161bSBill Fenner #include "ip.h"
58a90e161bSBill Fenner #ifdef INET6
59a90e161bSBill Fenner #include "ip6.h"
60a90e161bSBill Fenner #endif
61a90e161bSBill Fenner 
62cac3dcd5SXin LI #define CHAN_HP 6704
63cac3dcd5SXin LI #define CHAN_MP 6705
64cac3dcd5SXin LI #define CHAN_LP 6706
6527df3f5dSRui Paulo 
6627df3f5dSRui Paulo struct tok ForCES_channels[] = {
6727df3f5dSRui Paulo 	{ CHAN_HP, "ForCES HP" },
6827df3f5dSRui Paulo 	{ CHAN_MP, "ForCES MP" },
6927df3f5dSRui Paulo 	{ CHAN_LP, "ForCES LP" },
7027df3f5dSRui Paulo 	{ 0, NULL }
7127df3f5dSRui Paulo };
7227df3f5dSRui Paulo 
7327df3f5dSRui Paulo static inline int isForCES_port(u_short Port)
7427df3f5dSRui Paulo {
7527df3f5dSRui Paulo 	if (Port == CHAN_HP)
7627df3f5dSRui Paulo 		return 1;
7727df3f5dSRui Paulo 	if (Port == CHAN_MP)
7827df3f5dSRui Paulo 		return 1;
7927df3f5dSRui Paulo 	if (Port == CHAN_LP)
8027df3f5dSRui Paulo 		return 1;
8127df3f5dSRui Paulo 
8227df3f5dSRui Paulo 	return 0;
8327df3f5dSRui Paulo }
8427df3f5dSRui Paulo 
85a90e161bSBill Fenner void sctp_print(const u_char *bp,        /* beginning of sctp packet */
86a90e161bSBill Fenner 		const u_char *bp2,       /* beginning of enclosing */
87a90e161bSBill Fenner 		u_int sctpPacketLength)  /* ip packet */
88a90e161bSBill Fenner {
89a90e161bSBill Fenner   const struct sctpHeader *sctpPktHdr;
90a90e161bSBill Fenner   const struct ip *ip;
91a90e161bSBill Fenner #ifdef INET6
92a90e161bSBill Fenner   const struct ip6_hdr *ip6;
93a90e161bSBill Fenner #endif
949afd0c29SBill Fenner   const void *endPacketPtr;
95a90e161bSBill Fenner   u_short sourcePort, destPort;
96a90e161bSBill Fenner   int chunkCount;
979afd0c29SBill Fenner   const struct sctpChunkDesc *chunkDescPtr;
989afd0c29SBill Fenner   const void *nextChunk;
991de50e9fSSam Leffler   const char *sep;
10027df3f5dSRui Paulo   int isforces = 0;
10127df3f5dSRui Paulo 
102a90e161bSBill Fenner 
1039afd0c29SBill Fenner   sctpPktHdr = (const struct sctpHeader*) bp;
1049afd0c29SBill Fenner   endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;
105a90e161bSBill Fenner 
106a90e161bSBill Fenner   if( (u_long) endPacketPtr > (u_long) snapend)
1079afd0c29SBill Fenner     endPacketPtr = (const void *) snapend;
108a90e161bSBill Fenner   ip = (struct ip *)bp2;
109a90e161bSBill Fenner #ifdef INET6
110a90e161bSBill Fenner   if (IP_V(ip) == 6)
1119afd0c29SBill Fenner     ip6 = (const struct ip6_hdr *)bp2;
112a90e161bSBill Fenner   else
113a90e161bSBill Fenner     ip6 = NULL;
114a90e161bSBill Fenner #endif /*INET6*/
115f4d0c64aSSam Leffler   TCHECK(*sctpPktHdr);
116a90e161bSBill Fenner 
117a90e161bSBill Fenner   if (sctpPacketLength < sizeof(struct sctpHeader))
118a90e161bSBill Fenner     {
119a90e161bSBill Fenner       (void)printf("truncated-sctp - %ld bytes missing!",
120a90e161bSBill Fenner 		   (long)sctpPacketLength-sizeof(struct sctpHeader));
121a90e161bSBill Fenner       return;
122a90e161bSBill Fenner     }
123a90e161bSBill Fenner 
124a90e161bSBill Fenner   /*    sctpPacketLength -= sizeof(struct sctpHeader);  packet length  */
125a90e161bSBill Fenner   /*  			      is now only as long as the payload  */
126a90e161bSBill Fenner 
1275b0fe478SBruce M Simpson   sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
1285b0fe478SBruce M Simpson   destPort = EXTRACT_16BITS(&sctpPktHdr->destination);
129a90e161bSBill Fenner 
130a90e161bSBill Fenner #ifdef INET6
131a90e161bSBill Fenner   if (ip6) {
132a90e161bSBill Fenner     (void)printf("%s.%d > %s.%d: sctp",
133a90e161bSBill Fenner       ip6addr_string(&ip6->ip6_src),
134a90e161bSBill Fenner       sourcePort,
135a90e161bSBill Fenner       ip6addr_string(&ip6->ip6_dst),
136a90e161bSBill Fenner       destPort);
137a90e161bSBill Fenner   } else
138a90e161bSBill Fenner #endif /*INET6*/
139a90e161bSBill Fenner   {
140a90e161bSBill Fenner     (void)printf("%s.%d > %s.%d: sctp",
141a90e161bSBill Fenner       ipaddr_string(&ip->ip_src),
142a90e161bSBill Fenner       sourcePort,
143a90e161bSBill Fenner       ipaddr_string(&ip->ip_dst),
144a90e161bSBill Fenner       destPort);
145a90e161bSBill Fenner   }
146a90e161bSBill Fenner   fflush(stdout);
147a90e161bSBill Fenner 
14827df3f5dSRui Paulo   if (isForCES_port(sourcePort)) {
14927df3f5dSRui Paulo          printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort));
15027df3f5dSRui Paulo          isforces = 1;
15127df3f5dSRui Paulo   }
15227df3f5dSRui Paulo   if (isForCES_port(destPort)) {
15327df3f5dSRui Paulo          printf("[%s]", tok2str(ForCES_channels, NULL, destPort));
15427df3f5dSRui Paulo          isforces = 1;
15527df3f5dSRui Paulo   }
15627df3f5dSRui Paulo 
1571de50e9fSSam Leffler   if (vflag >= 2)
1581de50e9fSSam Leffler     sep = "\n\t";
1591de50e9fSSam Leffler   else
1601de50e9fSSam Leffler     sep = " (";
161a90e161bSBill Fenner   /* cycle through all chunks, printing information on each one */
162a90e161bSBill Fenner   for (chunkCount = 0,
1639afd0c29SBill Fenner 	 chunkDescPtr = (const struct sctpChunkDesc *)
1649afd0c29SBill Fenner 	    ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader));
165a90e161bSBill Fenner        chunkDescPtr != NULL &&
1669afd0c29SBill Fenner 	 ( (const void *)
1679afd0c29SBill Fenner 	    ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc))
168a90e161bSBill Fenner 	   <= endPacketPtr);
169a90e161bSBill Fenner 
1709afd0c29SBill Fenner        chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
171a90e161bSBill Fenner     {
172f4d0c64aSSam Leffler       u_int16_t chunkLength;
1739afd0c29SBill Fenner       const u_char *chunkEnd;
174f4d0c64aSSam Leffler       u_int16_t align;
175a90e161bSBill Fenner 
176f4d0c64aSSam Leffler       TCHECK(*chunkDescPtr);
177f4d0c64aSSam Leffler       chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
178f4d0c64aSSam Leffler       if (chunkLength < sizeof(*chunkDescPtr)) {
179f4d0c64aSSam Leffler       	printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength);
180f4d0c64aSSam Leffler       	break;
181f4d0c64aSSam Leffler       }
182a90e161bSBill Fenner 
183f4d0c64aSSam Leffler       TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
184f4d0c64aSSam Leffler       chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);
185f4d0c64aSSam Leffler 
186f4d0c64aSSam Leffler       align=chunkLength % 4;
187a90e161bSBill Fenner       if (align != 0)
188a90e161bSBill Fenner 	align = 4 - align;
189a90e161bSBill Fenner 
1909afd0c29SBill Fenner       nextChunk = (const void *) (chunkEnd + align);
191a90e161bSBill Fenner 
1921de50e9fSSam Leffler       printf("%s%d) ", sep, chunkCount+1);
193a90e161bSBill Fenner       switch (chunkDescPtr->chunkID)
194a90e161bSBill Fenner 	{
195a90e161bSBill Fenner 	case SCTP_DATA :
196a90e161bSBill Fenner 	  {
1979afd0c29SBill Fenner 	    const struct sctpDataPart *dataHdrPtr;
198a90e161bSBill Fenner 
199a90e161bSBill Fenner 	    printf("[DATA] ");
200a90e161bSBill Fenner 
201a90e161bSBill Fenner 	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
202a90e161bSBill Fenner 		== SCTP_DATA_UNORDERED)
203a90e161bSBill Fenner 	      printf("(U)");
204a90e161bSBill Fenner 
205a90e161bSBill Fenner 	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
206a90e161bSBill Fenner 		== SCTP_DATA_FIRST_FRAG)
207a90e161bSBill Fenner 	      printf("(B)");
208a90e161bSBill Fenner 
209a90e161bSBill Fenner 	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
210a90e161bSBill Fenner 		== SCTP_DATA_LAST_FRAG)
211a90e161bSBill Fenner 	      printf("(E)");
212a90e161bSBill Fenner 
213a90e161bSBill Fenner 	    if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
214a90e161bSBill Fenner 		 == SCTP_DATA_UNORDERED)
215a90e161bSBill Fenner 		||
216a90e161bSBill Fenner 		((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
217a90e161bSBill Fenner 		 == SCTP_DATA_FIRST_FRAG)
218a90e161bSBill Fenner 		||
219a90e161bSBill Fenner 		((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
220a90e161bSBill Fenner 		 == SCTP_DATA_LAST_FRAG) )
221a90e161bSBill Fenner 	      printf(" ");
222a90e161bSBill Fenner 
2239afd0c29SBill Fenner 	    dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);
224a90e161bSBill Fenner 
2255b0fe478SBruce M Simpson 	    printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
2265b0fe478SBruce M Simpson 	    printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
2275b0fe478SBruce M Simpson 	    printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
2285b0fe478SBruce M Simpson 	    printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
229a90e161bSBill Fenner 	    fflush(stdout);
23027df3f5dSRui Paulo 	    if (isforces) {
23127df3f5dSRui Paulo 		const u_char *payloadPtr;
23227df3f5dSRui Paulo 		u_int chunksize = sizeof(struct sctpDataPart)+
23327df3f5dSRui Paulo 			          sizeof(struct sctpChunkDesc);
23427df3f5dSRui Paulo 		payloadPtr = (const u_char *) (dataHdrPtr + 1);
23527df3f5dSRui Paulo 		if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
23627df3f5dSRui Paulo 			sizeof(struct sctpDataPart)+
23727df3f5dSRui Paulo 			sizeof(struct sctpChunkDesc)+1) {
23827df3f5dSRui Paulo 		/* Less than 1 byte of chunk payload */
23927df3f5dSRui Paulo 			printf("bogus ForCES chunk length %u]",
24027df3f5dSRui Paulo 			    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
24127df3f5dSRui Paulo 			return;
24227df3f5dSRui Paulo 		}
243a90e161bSBill Fenner 
24427df3f5dSRui Paulo 		forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize);
24527df3f5dSRui Paulo 	   } else if (vflag >= 2) {	/* if verbose output is specified */
24627df3f5dSRui Paulo 					/* at the command line */
2479afd0c29SBill Fenner 		const u_char *payloadPtr;
248a90e161bSBill Fenner 
249a90e161bSBill Fenner 		printf("[Payload");
250a90e161bSBill Fenner 
2512ebc47dbSSam Leffler 		if (!suppress_default_print) {
2529afd0c29SBill Fenner 			payloadPtr = (const u_char *) (++dataHdrPtr);
253a90e161bSBill Fenner 			printf(":");
25427df3f5dSRui Paulo 			if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
2555b0fe478SBruce M Simpson 			    sizeof(struct sctpDataPart)+
2565b0fe478SBruce M Simpson 			    sizeof(struct sctpChunkDesc)+1) {
257b5bfcb5dSMax Laier 				/* Less than 1 byte of chunk payload */
2585b0fe478SBruce M Simpson 				printf("bogus chunk length %u]",
25927df3f5dSRui Paulo 				    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
2605b0fe478SBruce M Simpson 				return;
2615b0fe478SBruce M Simpson 			}
262a90e161bSBill Fenner 			default_print(payloadPtr,
26327df3f5dSRui Paulo 			      EXTRACT_16BITS(&chunkDescPtr->chunkLength) -
2645b0fe478SBruce M Simpson 			      (sizeof(struct sctpDataPart)+
265b5bfcb5dSMax Laier 			      sizeof(struct sctpChunkDesc)));
266a90e161bSBill Fenner 		} else
267a90e161bSBill Fenner 			printf("]");
268a90e161bSBill Fenner 	      }
269a90e161bSBill Fenner 	    break;
270a90e161bSBill Fenner 	  }
271a90e161bSBill Fenner 	case SCTP_INITIATION :
272a90e161bSBill Fenner 	  {
2739afd0c29SBill Fenner 	    const struct sctpInitiation *init;
274a90e161bSBill Fenner 
275a90e161bSBill Fenner 	    printf("[INIT] ");
2769afd0c29SBill Fenner 	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
2775b0fe478SBruce M Simpson 	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
2785b0fe478SBruce M Simpson 	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
2795b0fe478SBruce M Simpson 	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
2805b0fe478SBruce M Simpson 	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
2815b0fe478SBruce M Simpson 	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
282a90e161bSBill Fenner 
283a90e161bSBill Fenner #if(0) /* ALC you can add code for optional params here */
284a90e161bSBill Fenner 	    if( (init+1) < chunkEnd )
285a90e161bSBill Fenner 	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
286a90e161bSBill Fenner 		     "Optional params present, but not printed.");
287a90e161bSBill Fenner #endif
288a90e161bSBill Fenner 	    break;
289a90e161bSBill Fenner 	  }
290a90e161bSBill Fenner 	case SCTP_INITIATION_ACK :
291a90e161bSBill Fenner 	  {
2929afd0c29SBill Fenner 	    const struct sctpInitiation *init;
293a90e161bSBill Fenner 
294a90e161bSBill Fenner 	    printf("[INIT ACK] ");
2959afd0c29SBill Fenner 	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
2965b0fe478SBruce M Simpson 	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
2975b0fe478SBruce M Simpson 	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
2985b0fe478SBruce M Simpson 	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
2995b0fe478SBruce M Simpson 	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
3005b0fe478SBruce M Simpson 	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
301a90e161bSBill Fenner 
302a90e161bSBill Fenner #if(0) /* ALC you can add code for optional params here */
303a90e161bSBill Fenner 	    if( (init+1) < chunkEnd )
304a90e161bSBill Fenner 	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
305a90e161bSBill Fenner 		     "Optional params present, but not printed.");
306a90e161bSBill Fenner #endif
307a90e161bSBill Fenner 	    break;
308a90e161bSBill Fenner 	  }
309a90e161bSBill Fenner 	case SCTP_SELECTIVE_ACK:
310a90e161bSBill Fenner 	  {
3119afd0c29SBill Fenner 	    const struct sctpSelectiveAck *sack;
3129afd0c29SBill Fenner 	    const struct sctpSelectiveFrag *frag;
313a90e161bSBill Fenner 	    int fragNo, tsnNo;
314f4d0c64aSSam Leffler 	    const u_char *dupTSN;
315a90e161bSBill Fenner 
316a90e161bSBill Fenner 	    printf("[SACK] ");
3179afd0c29SBill Fenner 	    sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
3185b0fe478SBruce M Simpson 	    printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN));
3195b0fe478SBruce M Simpson 	    printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd));
3205b0fe478SBruce M Simpson 	    printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc));
3215b0fe478SBruce M Simpson 	    printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns));
322a90e161bSBill Fenner 
323a90e161bSBill Fenner 
324a90e161bSBill Fenner 	    /* print gaps */
3259afd0c29SBill Fenner 	    for (frag = ( (const struct sctpSelectiveFrag *)
3269afd0c29SBill Fenner 			  ((const struct sctpSelectiveAck *) sack+1)),
327a90e161bSBill Fenner 		   fragNo=0;
3285b0fe478SBruce M Simpson 		 (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
329a90e161bSBill Fenner 		 frag++, fragNo++)
330a90e161bSBill Fenner 	      printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
331a90e161bSBill Fenner 		     fragNo+1,
3325b0fe478SBruce M Simpson 		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
3335b0fe478SBruce M Simpson 		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd));
334a90e161bSBill Fenner 
335a90e161bSBill Fenner 
336a90e161bSBill Fenner 	    /* print duplicate TSNs */
337f4d0c64aSSam Leffler 	    for (dupTSN = (const u_char *)frag, tsnNo=0;
3385b0fe478SBruce M Simpson 		 (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
339f4d0c64aSSam Leffler 		 dupTSN += 4, tsnNo++)
340a90e161bSBill Fenner 	      printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
3415b0fe478SBruce M Simpson 	          EXTRACT_32BITS(dupTSN));
342a90e161bSBill Fenner 
343a90e161bSBill Fenner 	    break;
344a90e161bSBill Fenner 	  }
345a90e161bSBill Fenner 	case SCTP_HEARTBEAT_REQUEST :
346a90e161bSBill Fenner 	  {
3479afd0c29SBill Fenner 	    const struct sctpHBsender *hb;
348a90e161bSBill Fenner 
3499afd0c29SBill Fenner 	    hb=(const struct sctpHBsender*)chunkDescPtr;
350a90e161bSBill Fenner 
351a90e161bSBill Fenner 	    printf("[HB REQ] ");
352a90e161bSBill Fenner 
353a90e161bSBill Fenner 	    break;
354a90e161bSBill Fenner 	  }
355a90e161bSBill Fenner 	case SCTP_HEARTBEAT_ACK :
356a90e161bSBill Fenner 	  printf("[HB ACK] ");
357a90e161bSBill Fenner 	  break;
358a90e161bSBill Fenner 	case SCTP_ABORT_ASSOCIATION :
359a90e161bSBill Fenner 	  printf("[ABORT] ");
360a90e161bSBill Fenner 	  break;
361a90e161bSBill Fenner 	case SCTP_SHUTDOWN :
362a90e161bSBill Fenner 	  printf("[SHUTDOWN] ");
363a90e161bSBill Fenner 	  break;
364a90e161bSBill Fenner 	case SCTP_SHUTDOWN_ACK :
365a90e161bSBill Fenner 	  printf("[SHUTDOWN ACK] ");
366a90e161bSBill Fenner 	  break;
367a90e161bSBill Fenner 	case SCTP_OPERATION_ERR :
368a90e161bSBill Fenner 	  printf("[OP ERR] ");
369a90e161bSBill Fenner 	  break;
370a90e161bSBill Fenner 	case SCTP_COOKIE_ECHO :
371a90e161bSBill Fenner 	  printf("[COOKIE ECHO] ");
372a90e161bSBill Fenner 	  break;
373a90e161bSBill Fenner 	case SCTP_COOKIE_ACK :
374a90e161bSBill Fenner 	  printf("[COOKIE ACK] ");
375a90e161bSBill Fenner 	  break;
376a90e161bSBill Fenner 	case SCTP_ECN_ECHO :
377a90e161bSBill Fenner 	  printf("[ECN ECHO] ");
378a90e161bSBill Fenner 	  break;
379a90e161bSBill Fenner 	case SCTP_ECN_CWR :
380a90e161bSBill Fenner 	  printf("[ECN CWR] ");
381a90e161bSBill Fenner 	  break;
382a90e161bSBill Fenner 	case SCTP_SHUTDOWN_COMPLETE :
383a90e161bSBill Fenner 	  printf("[SHUTDOWN COMPLETE] ");
384a90e161bSBill Fenner 	  break;
385a90e161bSBill Fenner 	case SCTP_FORWARD_CUM_TSN :
386a90e161bSBill Fenner 	  printf("[FOR CUM TSN] ");
387a90e161bSBill Fenner 	  break;
388a90e161bSBill Fenner 	case SCTP_RELIABLE_CNTL :
389a90e161bSBill Fenner 	  printf("[REL CTRL] ");
390a90e161bSBill Fenner 	  break;
391a90e161bSBill Fenner 	case SCTP_RELIABLE_CNTL_ACK :
392a90e161bSBill Fenner 	  printf("[REL CTRL ACK] ");
393a90e161bSBill Fenner 	  break;
394a90e161bSBill Fenner 	default :
395a90e161bSBill Fenner 	  printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID);
396a90e161bSBill Fenner 	  return;
397a90e161bSBill Fenner 	}
3981de50e9fSSam Leffler 
3991de50e9fSSam Leffler 	if (vflag < 2)
4001de50e9fSSam Leffler 	  sep = ", (";
401a90e161bSBill Fenner     }
402f4d0c64aSSam Leffler     return;
403f4d0c64aSSam Leffler 
404f4d0c64aSSam Leffler trunc:
405f4d0c64aSSam Leffler     printf("[|sctp]");
406f4d0c64aSSam Leffler     return;
407a90e161bSBill Fenner }
408