"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/lwres/lwinetntop.c" (7 Sep 2020, 4768 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lwinetntop.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 /*! \file lwinetntop.c
   13  */
   14 #if defined(LIBC_SCCS) && !defined(lint)
   15 static char rcsid[] =
   16     "$Id: lwinetntop.c,v 1.18 2007/06/19 23:47:22 tbox Exp $";
   17 #endif /* LIBC_SCCS and not lint */
   18 
   19 #include <config.h>
   20 
   21 #include <errno.h>
   22 #include <stdio.h>
   23 #include <string.h>
   24 
   25 #include <lwres/net.h>
   26 #include "print_p.h"
   27 
   28 #define NS_INT16SZ   2
   29 #define NS_IN6ADDRSZ    16
   30 
   31 /*
   32  * WARNING: Don't even consider trying to compile this on a system where
   33  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
   34  */
   35 
   36 static const char *inet_ntop4(const unsigned char *src, char *dst,
   37                   size_t size);
   38 
   39 #ifdef AF_INET6
   40 static const char *inet_ntop6(const unsigned char *src, char *dst,
   41                   size_t size);
   42 #endif
   43 
   44 /*! char *
   45  * lwres_net_ntop(af, src, dst, size)
   46  *  convert a network format address to presentation format.
   47  * return:
   48  *  pointer to presentation format address (`dst'), or NULL (see errno).
   49  * author:
   50  *  Paul Vixie, 1996.
   51  */
   52 const char *
   53 lwres_net_ntop(int af, const void *src, char *dst, size_t size) {
   54     switch (af) {
   55     case AF_INET:
   56         return (inet_ntop4(src, dst, size));
   57 #ifdef AF_INET6
   58     case AF_INET6:
   59         return (inet_ntop6(src, dst, size));
   60 #endif
   61     default:
   62         errno = EAFNOSUPPORT;
   63         return (NULL);
   64     }
   65     /* NOTREACHED */
   66 }
   67 
   68 /*! const char *
   69  * inet_ntop4(src, dst, size)
   70  *  format an IPv4 address
   71  * return:
   72  *  `dst' (as a const)
   73  * notes:
   74  *  (1) uses no statics
   75  *  (2) takes a unsigned char* not an in_addr as input
   76  * author:
   77  *  Paul Vixie, 1996.
   78  */
   79 static const char *
   80 inet_ntop4(const unsigned char *src, char *dst, size_t size) {
   81     static const char fmt[] = "%u.%u.%u.%u";
   82     char tmp[sizeof("255.255.255.255")];
   83     size_t len;
   84 
   85     len = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
   86     if (len >= size) {
   87         errno = ENOSPC;
   88         return (NULL);
   89     }
   90     strcpy(dst, tmp);
   91 
   92     return (dst);
   93 }
   94 
   95 /*! const char *
   96  * inet_ntop6(src, dst, size)
   97  *  convert IPv6 binary address into presentation (printable) format
   98  * author:
   99  *  Paul Vixie, 1996.
  100  */
  101 #ifdef AF_INET6
  102 static const char *
  103 inet_ntop6(const unsigned char *src, char *dst, size_t size) {
  104     /*!
  105      * Note that int32_t and int16_t need only be "at least" large enough
  106      * to contain a value of the specified size.  On some systems, like
  107      * Crays, there is no such thing as an integer variable with 16 bits.
  108      * Keep this in mind if you think this function should have been coded
  109      * to use pointer overlays.  All the world's not a VAX.
  110      */
  111     char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp;
  112     struct { int base, len; } best, cur;
  113     unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
  114     int i;
  115 
  116     /*
  117      * Preprocess:
  118      *  Copy the input (bytewise) array into a wordwise array.
  119      *  Find the longest run of 0x00's in src[] for :: shorthanding.
  120      */
  121     memset(words, '\0', sizeof(words));
  122     for (i = 0; i < NS_IN6ADDRSZ; i++)
  123         words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
  124     best.base = -1;
  125     best.len = 0;
  126     cur.base = -1;
  127     cur.len = 0;
  128     for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
  129         if (words[i] == 0) {
  130             if (cur.base == -1)
  131                 cur.base = i, cur.len = 1;
  132             else
  133                 cur.len++;
  134         } else {
  135             if (cur.base != -1) {
  136                 if (best.base == -1 || cur.len > best.len)
  137                     best = cur;
  138                 cur.base = -1;
  139             }
  140         }
  141     }
  142     if (cur.base != -1) {
  143         if (best.base == -1 || cur.len > best.len)
  144             best = cur;
  145     }
  146     if (best.base != -1 && best.len < 2)
  147         best.base = -1;
  148 
  149     /*
  150      * Format the result.
  151      */
  152     tp = tmp;
  153     for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
  154         /* Are we inside the best run of 0x00's? */
  155         if (best.base != -1 && i >= best.base &&
  156             i < (best.base + best.len)) {
  157             if (i == best.base)
  158                 *tp++ = ':';
  159             continue;
  160         }
  161         /* Are we following an initial run of 0x00s or any real hex? */
  162         if (i != 0)
  163             *tp++ = ':';
  164         /* Is this address an encapsulated IPv4? */
  165         if (i == 6 && best.base == 0 &&
  166             (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
  167             if (!inet_ntop4(src+12, tp,
  168                     sizeof(tmp) - (tp - tmp)))
  169                 return (NULL);
  170             tp += strlen(tp);
  171             break;
  172         }
  173         tp += sprintf(tp, "%x", words[i]); /* XXX */
  174     }
  175     /* Was it a trailing run of 0x00's? */
  176     if (best.base != -1 && (best.base + best.len) ==
  177         (NS_IN6ADDRSZ / NS_INT16SZ))
  178         *tp++ = ':';
  179     *tp++ = '\0';
  180 
  181     /*
  182      * Check for overflow, copy, and we're done.
  183      */
  184     if ((size_t)(tp - tmp) > size) {
  185         errno = ENOSPC;
  186         return (NULL);
  187     }
  188     strcpy(dst, tmp);
  189     return (dst);
  190 }
  191 #endif /* AF_INET6 */