Merge remote-tracking branch 'goog/tcpdump'

* goog/tcpdump: (3066 commits)
  Remove old version. Getting ready for new tcpdump 4.5
  Support -Q for setting the capture direction.
  Clean up the TLV processing loop.
  With -A and -AA, don't send CRs to the standard output.
  Use the new libpcap <pcap/nflog.h> for NFLOG definitions and declarations.
  Do our own isascii(), isprint(), isgraph(), and toascii().
  Fix a compiler warning.
  Don't use the __attribute__((packed)) on most platforms.
  The interval in an AODV HELLO extension is not aligned on a 4-byte boundary.
  As with memcpy, so with memcmp.
  More UNALIGNED_MEM{CPY,CMP} on IP addresses.
  Another case where UNALIGNED_MEMCPY() is probably necessary.
  No need for casting back and forth.
  Only do the unaligned_mem{cpy,cmp} hack if necessary.
  No need to declare unaligned_mem{cpy,cmp} in netdissect.h *and* interface.h.
  More possibly-unaligned memcpy()s and assignments - use unaligned_memcpy().
  Check for compiling for IPv6; don't check whether we can create an IPv6 socket.
  Use unaligned_memcmp() to compare with IPv{4,6} addresses in a packet.
  Use EXTRACT_nBITS even when just testing against zero.
  Fix some more unaligned accesses.
  ...

Change-Id: I9e98707d30c989b9e32dcd5af798bd0746ab4434
diff --git a/print-sctp.c b/print-sctp.c
index 7a18978..5a4b1e9 100644
--- a/print-sctp.c
+++ b/print-sctp.c
@@ -35,7 +35,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.16.2.5 2007/09/13 18:04:58 guy Exp $ (NETLAB/PEL)";
+"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.21 2007-09-13 18:03:49 guy Exp $ (NETLAB/PEL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -59,6 +59,29 @@
 #include "ip6.h"
 #endif
 
+#define CHAN_HP 6704
+#define CHAN_MP 6705
+#define CHAN_LP 6706
+
+static const struct tok ForCES_channels[] = {
+	{ CHAN_HP, "ForCES HP" },
+	{ CHAN_MP, "ForCES MP" },
+	{ CHAN_LP, "ForCES LP" },
+	{ 0, NULL }
+};
+
+static inline int isForCES_port(u_short Port)
+{
+	if (Port == CHAN_HP)
+		return 1;
+	if (Port == CHAN_MP)
+		return 1;
+	if (Port == CHAN_LP)
+		return 1;
+
+	return 0;
+}
+
 void sctp_print(const u_char *bp,        /* beginning of sctp packet */
 		const u_char *bp2,       /* beginning of enclosing */
 		u_int sctpPacketLength)  /* ip packet */
@@ -74,6 +97,8 @@
   const struct sctpChunkDesc *chunkDescPtr;
   const void *nextChunk;
   const char *sep;
+  int isforces = 0;
+
 
   sctpPktHdr = (const struct sctpHeader*) bp;
   endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;
@@ -120,6 +145,15 @@
   }
   fflush(stdout);
 
+  if (isForCES_port(sourcePort)) {
+         printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort));
+         isforces = 1;
+  }
+  if (isForCES_port(destPort)) {
+         printf("[%s]", tok2str(ForCES_channels, NULL, destPort));
+         isforces = 1;
+  }
+
   if (vflag >= 2)
     sep = "\n\t";
   else
@@ -193,9 +227,23 @@
 	    printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
 	    printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
 	    fflush(stdout);
+	    if (isforces) {
+		const u_char *payloadPtr;
+		u_int chunksize = sizeof(struct sctpDataPart)+
+			          sizeof(struct sctpChunkDesc);
+		payloadPtr = (const u_char *) (dataHdrPtr + 1);
+		if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
+			sizeof(struct sctpDataPart)+
+			sizeof(struct sctpChunkDesc)+1) {
+		/* Less than 1 byte of chunk payload */
+			printf("bogus ForCES chunk length %u]",
+			    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
+			return;
+		}
 
-	    if (vflag >= 2)	   /* if verbose output is specified */
-	      {		           /* at the command line */
+		forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize);
+	   } else if (vflag >= 2) {	/* if verbose output is specified */
+					/* at the command line */
 		const u_char *payloadPtr;
 
 		printf("[Payload");
@@ -203,16 +251,16 @@
 		if (!suppress_default_print) {
 			payloadPtr = (const u_char *) (++dataHdrPtr);
 			printf(":");
-			if (htons(chunkDescPtr->chunkLength) <
+			if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
 			    sizeof(struct sctpDataPart)+
 			    sizeof(struct sctpChunkDesc)+1) {
 				/* Less than 1 byte of chunk payload */
 				printf("bogus chunk length %u]",
-				    htons(chunkDescPtr->chunkLength));
+				    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
 				return;
 			}
 			default_print(payloadPtr,
-			      htons(chunkDescPtr->chunkLength) -
+			      EXTRACT_16BITS(&chunkDescPtr->chunkLength) -
 			      (sizeof(struct sctpDataPart)+
 			      sizeof(struct sctpChunkDesc)));
 		} else
@@ -295,15 +343,8 @@
 	    break;
 	  }
 	case SCTP_HEARTBEAT_REQUEST :
-	  {
-	    const struct sctpHBsender *hb;
-
-	    hb=(const struct sctpHBsender*)chunkDescPtr;
-
-	    printf("[HB REQ] ");
-
-	    break;
-	  }
+	  printf("[HB REQ] ");
+	  break;
 	case SCTP_HEARTBEAT_ACK :
 	  printf("[HB ACK] ");
 	  break;