12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Copyright (c) 2001 NETLAB, Temple University
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Jerry Heinz <gheinz@astro.temple.edu>
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * John Fiore <jfiore@joda.cis.temple.edu>
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Armando L. Caro Jr. <acaro@cis.udel.edu>
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that the following conditions
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * are met:
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    documentation and/or other materials provided with the distribution.
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 3. Neither the name of the University nor of the Laboratory may be used
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    to endorse or promote products derived from this software without
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    specific prior written permission.
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * SUCH DAMAGE.
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef lint
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char rcsid[] _U_ =
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.16.2.5 2007/09/13 18:04:58 guy Exp $ (NETLAB/PEL)";
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "sctpHeader.h"
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "sctpConstants.h"
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <assert.h>
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrtoname.h"
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "extract.h"			/* must come after interface.h */
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ip.h"
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ip6.h"
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid sctp_print(const u_char *bp,        /* beginning of sctp packet */
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		const u_char *bp2,       /* beginning of enclosing */
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		u_int sctpPacketLength)  /* ip packet */
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  const struct sctpHeader *sctpPktHdr;
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  const struct ip *ip;
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  const struct ip6_hdr *ip6;
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  const void *endPacketPtr;
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  u_short sourcePort, destPort;
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  int chunkCount;
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  const struct sctpChunkDesc *chunkDescPtr;
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  const void *nextChunk;
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  const char *sep;
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  sctpPktHdr = (const struct sctpHeader*) bp;
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if( (u_long) endPacketPtr > (u_long) snapend)
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    endPacketPtr = (const void *) snapend;
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  ip = (struct ip *)bp2;
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (IP_V(ip) == 6)
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    ip6 = (const struct ip6_hdr *)bp2;
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  else
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    ip6 = NULL;
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /*INET6*/
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  TCHECK(*sctpPktHdr);
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (sctpPacketLength < sizeof(struct sctpHeader))
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    {
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      (void)printf("truncated-sctp - %ld bytes missing!",
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		   (long)sctpPacketLength-sizeof(struct sctpHeader));
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      return;
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  /*    sctpPacketLength -= sizeof(struct sctpHeader);  packet length  */
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  /*  			      is now only as long as the payload  */
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  destPort = EXTRACT_16BITS(&sctpPktHdr->destination);
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (ip6) {
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    (void)printf("%s.%d > %s.%d: sctp",
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      ip6addr_string(&ip6->ip6_src),
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      sourcePort,
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      ip6addr_string(&ip6->ip6_dst),
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      destPort);
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  } else
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /*INET6*/
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  {
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    (void)printf("%s.%d > %s.%d: sctp",
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      ipaddr_string(&ip->ip_src),
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      sourcePort,
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      ipaddr_string(&ip->ip_dst),
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      destPort);
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  }
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  fflush(stdout);
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (vflag >= 2)
1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    sep = "\n\t";
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  else
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    sep = " (";
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  /* cycle through all chunks, printing information on each one */
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  for (chunkCount = 0,
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 chunkDescPtr = (const struct sctpChunkDesc *)
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader));
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project       chunkDescPtr != NULL &&
1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 ( (const void *)
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc))
1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	   <= endPacketPtr);
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project       chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    {
1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      u_int16_t chunkLength;
1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      const u_char *chunkEnd;
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      u_int16_t align;
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      TCHECK(*chunkDescPtr);
1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      if (chunkLength < sizeof(*chunkDescPtr)) {
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      	printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength);
1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      	break;
1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      }
1482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);
1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      align=chunkLength % 4;
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      if (align != 0)
1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	align = 4 - align;
1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      nextChunk = (const void *) (chunkEnd + align);
1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      printf("%s%d) ", sep, chunkCount+1);
1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      switch (chunkDescPtr->chunkID)
1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	{
1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_DATA :
1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  {
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    const struct sctpDataPart *dataHdrPtr;
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[DATA] ");
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		== SCTP_DATA_UNORDERED)
1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      printf("(U)");
1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		== SCTP_DATA_FIRST_FRAG)
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      printf("(B)");
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		== SCTP_DATA_LAST_FRAG)
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      printf("(E)");
1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 == SCTP_DATA_UNORDERED)
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		||
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 == SCTP_DATA_FIRST_FRAG)
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		||
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 == SCTP_DATA_LAST_FRAG) )
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      printf(" ");
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);
1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    fflush(stdout);
1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (vflag >= 2)	   /* if verbose output is specified */
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      {		           /* at the command line */
1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		const u_char *payloadPtr;
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("[Payload");
2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (!suppress_default_print) {
2042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			payloadPtr = (const u_char *) (++dataHdrPtr);
2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(":");
2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (htons(chunkDescPtr->chunkLength) <
2072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    sizeof(struct sctpDataPart)+
2082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    sizeof(struct sctpChunkDesc)+1) {
2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				/* Less than 1 byte of chunk payload */
2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("bogus chunk length %u]",
2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    htons(chunkDescPtr->chunkLength));
2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return;
2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			default_print(payloadPtr,
2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			      htons(chunkDescPtr->chunkLength) -
2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			      (sizeof(struct sctpDataPart)+
2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			      sizeof(struct sctpChunkDesc)));
2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else
2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("]");
2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      }
2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    break;
2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  }
2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_INITIATION :
2242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  {
2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    const struct sctpInitiation *init;
2262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[INIT] ");
2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#if(0) /* ALC you can add code for optional params here */
2362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if( (init+1) < chunkEnd )
2372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
2382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		     "Optional params present, but not printed.");
2392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
2402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    break;
2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  }
2422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_INITIATION_ACK :
2432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  {
2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    const struct sctpInitiation *init;
2452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[INIT ACK] ");
2472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
2482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
2492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
2502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
2512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
2522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#if(0) /* ALC you can add code for optional params here */
2552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if( (init+1) < chunkEnd )
2562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
2572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		     "Optional params present, but not printed.");
2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
2592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    break;
2602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  }
2612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_SELECTIVE_ACK:
2622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  {
2632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    const struct sctpSelectiveAck *sack;
2642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    const struct sctpSelectiveFrag *frag;
2652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    int fragNo, tsnNo;
2662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    const u_char *dupTSN;
2672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[SACK] ");
2692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
2702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN));
2712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd));
2722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc));
2732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns));
2742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* print gaps */
2772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    for (frag = ( (const struct sctpSelectiveFrag *)
2782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			  ((const struct sctpSelectiveAck *) sack+1)),
2792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		   fragNo=0;
2802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
2812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 frag++, fragNo++)
2822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
2832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		     fragNo+1,
2842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
2852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd));
2862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    /* print duplicate TSNs */
2892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    for (dupTSN = (const u_char *)frag, tsnNo=0;
2902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
2912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 dupTSN += 4, tsnNo++)
2922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	      printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
2932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	          EXTRACT_32BITS(dupTSN));
2942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    break;
2962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  }
2972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_HEARTBEAT_REQUEST :
2982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  {
2992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    const struct sctpHBsender *hb;
3002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    hb=(const struct sctpHBsender*)chunkDescPtr;
3022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    printf("[HB REQ] ");
3042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    break;
3062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  }
3072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_HEARTBEAT_ACK :
3082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[HB ACK] ");
3092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_ABORT_ASSOCIATION :
3112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[ABORT] ");
3122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_SHUTDOWN :
3142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[SHUTDOWN] ");
3152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_SHUTDOWN_ACK :
3172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[SHUTDOWN ACK] ");
3182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_OPERATION_ERR :
3202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[OP ERR] ");
3212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_COOKIE_ECHO :
3232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[COOKIE ECHO] ");
3242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_COOKIE_ACK :
3262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[COOKIE ACK] ");
3272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_ECN_ECHO :
3292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[ECN ECHO] ");
3302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_ECN_CWR :
3322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[ECN CWR] ");
3332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_SHUTDOWN_COMPLETE :
3352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[SHUTDOWN COMPLETE] ");
3362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_FORWARD_CUM_TSN :
3382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[FOR CUM TSN] ");
3392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_RELIABLE_CNTL :
3412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[REL CTRL] ");
3422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case SCTP_RELIABLE_CNTL_ACK :
3442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[REL CTRL ACK] ");
3452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  break;
3462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default :
3472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID);
3482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  return;
3492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (vflag < 2)
3522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	  sep = ", (";
3532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
3542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
3552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
3572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    printf("[|sctp]");
3582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
3592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
360