]> The Tcpdump Group git mirrors - tcpdump/blobdiff - addrtostr.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / addrtostr.c
index 1ea792adc97451c55e6b1fe29291229faa59cf81..1fd2cf0908bfd5b95a6e31586fc7b229710d6be3 100644 (file)
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <config.h>
 
-#include <netdissect-stdinc.h>
+#include "netdissect-stdinc.h"
 #include "addrtostr.h"
 
 #include <stdio.h>
@@ -71,7 +69,7 @@ addrtostr (const void *src, char *dst, size_t size)
        return NULL;
     }
     for (i = 0; i < 4; ++i) {
-       int n = *srcaddr++;
+       int n = *srcaddr++;
        int non_zerop = 0;
 
        if (non_zerop || n / 100 > 0) {
@@ -106,37 +104,33 @@ addrtostr6 (const void *src, char *dst, size_t size)
    * to use pointer overlays.  All the world's not a VAX.
    */
   const u_char *srcaddr = (const u_char *)src;
-  char  tmp [INET6_ADDRSTRLEN+1];
-  char *tp;
+  char *dp;
+  size_t space_left, added_space;
+  int snprintfed;
   struct {
-    long base;
-    long len;
+    int base;
+    int len;
   } best, cur;
-  u_long words [IN6ADDRSZ / INT16SZ];
-  u_int  i;
+  uint16_t words [IN6ADDRSZ / INT16SZ];
+  int  i;
 
   /* Preprocess:
    *  Copy the input (bytewise) array into a wordwise array.
    *  Find the longest run of 0x00's in src[] for :: shorthanding.
    */
-  memset (words, 0, sizeof(words));
-  for (i = 0; i < IN6ADDRSZ; i++)
-      words[i/2] |= (srcaddr[i] << ((1 - (i % 2)) << 3));
+  for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+      words[i] = (srcaddr[2*i] << 8) | srcaddr[2*i + 1];
 
   best.len = 0;
   best.base = -1;
   cur.len = 0;
   cur.base  = -1;
-  for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
-  {
-    if (words[i] == 0)
-    {
+  for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+    if (words[i] == 0) {
       if (cur.base == -1)
            cur.base = i, cur.len = 1;
       else cur.len++;
-    }
-    else if (cur.base != -1)
-    {
+    } else if (cur.base != -1) {
       if (best.base == -1 || cur.len > best.len)
          best = cur;
       cur.base = -1;
@@ -149,51 +143,61 @@ addrtostr6 (const void *src, char *dst, size_t size)
 
   /* Format the result.
    */
-  tp = tmp;
-  for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
-  {
+  dp = dst;
+  space_left = size;
+#define APPEND_CHAR(c) \
+    { \
+        if (space_left == 0) { \
+            errno = ENOSPC; \
+            return (NULL); \
+        } \
+        *dp++ = c; \
+        space_left--; \
+    }
+  for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
     /* Are we inside the best run of 0x00's?
      */
-    if (best.base != -1 && i >= best.base && i < (best.base + best.len))
-    {
+    if (best.base != -1 && i >= best.base && i < (best.base + best.len)) {
       if (i == best.base)
-         *tp++ = ':';
+         APPEND_CHAR(':');
       continue;
     }
 
     /* Are we following an initial run of 0x00s or any real hex?
      */
     if (i != 0)
-       *tp++ = ':';
+       APPEND_CHAR(':');
 
     /* Is this address an encapsulated IPv4?
      */
     if (i == 6 && best.base == 0 &&
         (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
     {
-      if (!addrtostr(srcaddr+12, tp, sizeof(tmp) - (tp - tmp)))
-      {
+      if (!addrtostr(srcaddr+12, dp, space_left)) {
         errno = ENOSPC;
         return (NULL);
       }
-      tp += strlen(tp);
+      added_space = strlen(dp);
+      dp += added_space;
+      space_left -= added_space;
       break;
     }
-    tp += sprintf (tp, "%lx", words[i]);
+    snprintfed = snprintf (dp, space_left, "%x", words[i]);
+    if (snprintfed < 0)
+        return (NULL);
+    if ((size_t) snprintfed >= space_left) {
+        errno = ENOSPC;
+        return (NULL);
+    }
+    dp += snprintfed;
+    space_left -= snprintfed;
   }
 
   /* Was it a trailing run of 0x00's?
    */
   if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
-     *tp++ = ':';
-  *tp++ = '\0';
+     APPEND_CHAR(':');
+  APPEND_CHAR('\0');
 
-  /* Check for overflow, copy, and we're done.
-   */
-  if ((size_t)(tp - tmp) > size)
-  {
-    errno = ENOSPC;
-    return (NULL);
-  }
-  return strcpy (dst, tmp);
+  return (dst);
 }