]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-sctp.c
Pointers into packet data should usually be pointers to unsigned 1-byte
[tcpdump] / print-sctp.c
index 937f5e5c74165852041854553dc9834c209c757f..d38cfde2d6755ddcb276b621346ddbbb2a0c4bc4 100644 (file)
@@ -34,8 +34,8 @@
  */
 
 #ifndef lint
-static const char rcsid[] =
-"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.13 2003-08-06 05:02:13 guy Exp $ (NETLAB/PEL)";
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.20 2005-07-07 01:22:20 guy Exp $ (NETLAB/PEL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -68,12 +68,12 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
 #ifdef INET6
   const struct ip6_hdr *ip6;
 #endif
-  const u_char *cp;
   const void *endPacketPtr;
   u_short sourcePort, destPort;
   int chunkCount;
   const struct sctpChunkDesc *chunkDescPtr;
   const void *nextChunk;
+  const char *sep;
 
   sctpPktHdr = (const struct sctpHeader*) bp;
   endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;
@@ -87,12 +87,7 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
   else
     ip6 = NULL;
 #endif /*INET6*/
-  cp = (const u_char *)(sctpPktHdr + 1);
-  if (cp > snapend)
-    {
-      printf("[|sctp]");
-      return;
-    }
+  TCHECK(*sctpPktHdr);
 
   if (sctpPacketLength < sizeof(struct sctpHeader))
     {
@@ -125,9 +120,10 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
   }
   fflush(stdout);
 
-  if (vflag < 2)
-       return;
-
+  if (vflag >= 2)
+    sep = "\n\t";
+  else
+    sep = " (";
   /* cycle through all chunks, printing information on each one */
   for (chunkCount = 0,
         chunkDescPtr = (const struct sctpChunkDesc *)
@@ -139,18 +135,27 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
 
        chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
     {
-      u_short align;
+      u_int16_t chunkLength;
       const u_char *chunkEnd;
+      u_int16_t align;
+
+      TCHECK(*chunkDescPtr);
+      chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
+      if (chunkLength < sizeof(*chunkDescPtr)) {
+       printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength);
+       break;
+      }
 
-      chunkEnd = ((const u_char*)chunkDescPtr + EXTRACT_16BITS(&chunkDescPtr->chunkLength));
+      TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
+      chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);
 
-      align=EXTRACT_16BITS(&chunkDescPtr->chunkLength) % 4;
+      align=chunkLength % 4;
       if (align != 0)
        align = 4 - align;
 
       nextChunk = (const void *) (chunkEnd + align);
 
-      printf("\n\t%d) ", chunkCount+1);
+      printf("%s%d) ", sep, chunkCount+1);
       switch (chunkDescPtr->chunkID)
        {
        case SCTP_DATA :
@@ -189,13 +194,13 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
            printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
            fflush(stdout);
 
-           if (vflag)          /* if verbose output is specified */
+           if (vflag >= 2)        /* if verbose output is specified */
              {                    /* at the command line */
                const u_char *payloadPtr;
 
                printf("[Payload");
 
-               if (!xflag && !qflag) {
+               if (!suppress_default_print) {
                        payloadPtr = (const u_char *) (++dataHdrPtr);
                        printf(":");
                        if (htons(chunkDescPtr->chunkLength) <
@@ -257,7 +262,7 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
            const struct sctpSelectiveAck *sack;
            const struct sctpSelectiveFrag *frag;
            int fragNo, tsnNo;
-           const u_long *dupTSN;
+           const u_char *dupTSN;
 
            printf("[SACK] ");
            sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
@@ -280,9 +285,9 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
 
 
            /* print duplicate TSNs */
-           for (dupTSN = (const u_long*)frag, tsnNo=0;
+           for (dupTSN = (const u_char *)frag, tsnNo=0;
                 (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
-                dupTSN++, tsnNo++)
+                dupTSN += 4, tsnNo++)
              printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
                  EXTRACT_32BITS(dupTSN));
 
@@ -341,5 +346,13 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
          printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID);
          return;
        }
+
+       if (vflag < 2)
+         sep = ", (";
     }
+    return;
+
+trunc:
+    printf("[|sctp]");
+    return;
 }