]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-sctp.c
Address Michael's comments.
[tcpdump] / print-sctp.c
index dca312288031c5e4771d1e6e39fb7cfa9632c782..a8990a9ae005049cb57743e6ec95ad197ff6d979 100644 (file)
@@ -34,8 +34,8 @@
  */
 
 #ifndef lint
-static const char rcsid[] =
-"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.10 2002-08-01 08:53:27 risso Exp $ (NETLAB/PEL)";
+static const char rcsid[] _U_ =
+"@(#) $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 @@ static const char rcsid[] =
 #include "ip6.h"
 #endif
 
+#define CHAN_HP 6704
+#define CHAN_MP 6705
+#define CHAN_LP 6706
+
+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 */
@@ -68,12 +91,14 @@ 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;
+  int isforces = 0;
+
 
   sctpPktHdr = (const struct sctpHeader*) bp;
   endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;
@@ -87,12 +112,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))
     {
@@ -104,40 +124,40 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
   /*    sctpPacketLength -= sizeof(struct sctpHeader);  packet length  */
   /*                         is now only as long as the payload  */
 
-  sourcePort = ntohs(sctpPktHdr->source);
-  destPort = ntohs(sctpPktHdr->destination);
+  sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
+  destPort = EXTRACT_16BITS(&sctpPktHdr->destination);
 
 #ifdef INET6
   if (ip6) {
-    if (ip6->ip6_nxt == IPPROTO_SCTP) {
-      (void)printf("%s.%d > %s.%d: sctp",
-        ip6addr_string(&ip6->ip6_src),
-        sourcePort,
-        ip6addr_string(&ip6->ip6_dst),
-        destPort);
-    } else {
-      (void)printf("%d > %d: sctp",
-        sourcePort, destPort);
-    }
+    (void)printf("%s.%d > %s.%d: sctp",
+      ip6addr_string(&ip6->ip6_src),
+      sourcePort,
+      ip6addr_string(&ip6->ip6_dst),
+      destPort);
   } else
 #endif /*INET6*/
   {
-    if (ip->ip_p == IPPROTO_SCTP) {
-      (void)printf("%s.%d > %s.%d: sctp",
-        ipaddr_string(&ip->ip_src),
-        sourcePort,
-        ipaddr_string(&ip->ip_dst),
-        destPort);
-    } else {
-      (void)printf("%d > %d: sctp",
-        sourcePort, destPort);
-    }
+    (void)printf("%s.%d > %s.%d: sctp",
+      ipaddr_string(&ip->ip_src),
+      sourcePort,
+      ipaddr_string(&ip->ip_dst),
+      destPort);
   }
   fflush(stdout);
 
-  if (vflag < 2)
-       return;
+  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
+    sep = " (";
   /* cycle through all chunks, printing information on each one */
   for (chunkCount = 0,
         chunkDescPtr = (const struct sctpChunkDesc *)
@@ -149,18 +169,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 + ntohs(chunkDescPtr->chunkLength));
+      TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
+      chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);
 
-      align=ntohs(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 :
@@ -193,24 +222,47 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
 
            dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);
 
-           printf("[TSN: %u] ", (u_int32_t)ntohl(dataHdrPtr->TSN));
-           printf("[SID: %u] ", ntohs(dataHdrPtr->streamId));
-           printf("[SSEQ %u] ", ntohs(dataHdrPtr->sequence));
-           printf("[PPID 0x%x] ", (u_int32_t)ntohl(dataHdrPtr->payloadtype));
+           printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
+           printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
+           printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
+           printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
            fflush(stdout);
-
-           if (vflag)          /* if verbose output is specified */
-             {                    /* at the command line */
+           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;
+               }
+
+               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");
 
-               if (!xflag && !qflag) {
+               if (!suppress_default_print) {
                        payloadPtr = (const u_char *) (++dataHdrPtr);
                        printf(":");
+                       if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
+                           sizeof(struct sctpDataPart)+
+                           sizeof(struct sctpChunkDesc)+1) {
+                               /* Less than 1 byte of chunk payload */
+                               printf("bogus chunk length %u]",
+                                   EXTRACT_16BITS(&chunkDescPtr->chunkLength));
+                               return;
+                       }
                        default_print(payloadPtr,
-                             htons(chunkDescPtr->chunkLength)-1 -
-                             sizeof(struct sctpDataPart)-sizeof(struct sctpChunkDesc));
+                             EXTRACT_16BITS(&chunkDescPtr->chunkLength) -
+                             (sizeof(struct sctpDataPart)+
+                             sizeof(struct sctpChunkDesc)));
                } else
                        printf("]");
              }
@@ -222,11 +274,11 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
 
            printf("[INIT] ");
            init=(const struct sctpInitiation*)(chunkDescPtr+1);
-           printf("[init tag: %u] ", (u_int32_t)ntohl(init->initTag));
-           printf("[rwnd: %u] ", (u_int32_t)ntohl(init->rcvWindowCredit));
-           printf("[OS: %u] ", ntohs(init->NumPreopenStreams));
-           printf("[MIS: %u] ", ntohs(init->MaxInboundStreams));
-           printf("[init TSN: %u] ", (u_int32_t)ntohl(init->initialTSN));
+           printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
+           printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
+           printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
+           printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
+           printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
 
 #if(0) /* ALC you can add code for optional params here */
            if( (init+1) < chunkEnd )
@@ -241,11 +293,11 @@ void sctp_print(const u_char *bp,        /* beginning of sctp packet */
 
            printf("[INIT ACK] ");
            init=(const struct sctpInitiation*)(chunkDescPtr+1);
-           printf("[init tag: %u] ", (u_int32_t)ntohl(init->initTag));
-           printf("[rwnd: %u] ", (u_int32_t)ntohl(init->rcvWindowCredit));
-           printf("[OS: %u] ", ntohs(init->NumPreopenStreams));
-           printf("[MIS: %u] ", ntohs(init->MaxInboundStreams));
-           printf("[init TSN: %u] ", (u_int32_t)ntohl(init->initialTSN));
+           printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
+           printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
+           printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
+           printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
+           printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
 
 #if(0) /* ALC you can add code for optional params here */
            if( (init+1) < chunkEnd )
@@ -259,34 +311,34 @@ 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);
-           printf("[cum ack %u] ", (u_int32_t)ntohl(sack->highestConseqTSN));
-           printf("[a_rwnd %u] ", (u_int32_t)ntohl(sack->updatedRwnd));
-           printf("[#gap acks %u] ", ntohs(sack->numberOfdesc));
-           printf("[#dup tsns %u] ", ntohs(sack->numDupTsns));
+           printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN));
+           printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd));
+           printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc));
+           printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns));
 
 
            /* print gaps */
            for (frag = ( (const struct sctpSelectiveFrag *)
                          ((const struct sctpSelectiveAck *) sack+1)),
                   fragNo=0;
-                (const void *)frag < nextChunk && fragNo < ntohs(sack->numberOfdesc);
+                (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
                 frag++, fragNo++)
              printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
                     fragNo+1,
-                    (u_int32_t)(ntohl(sack->highestConseqTSN) + ntohs(frag->fragmentStart)),
-                    (u_int32_t)(ntohl(sack->highestConseqTSN) + ntohs(frag->fragmentEnd)));
+                    EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
+                    EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd));
 
 
            /* print duplicate TSNs */
-           for (dupTSN = (const u_long*)frag, tsnNo=0;
-                (const void *) dupTSN < nextChunk && tsnNo<ntohs(sack->numDupTsns);
-                dupTSN++, tsnNo++)
+           for (dupTSN = (const u_char *)frag, tsnNo=0;
+                (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
+                dupTSN += 4, tsnNo++)
              printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
-                 (u_int32_t)ntohl(*dupTSN));
+                 EXTRACT_32BITS(dupTSN));
 
            break;
          }
@@ -343,5 +395,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;
 }