Back to index

glibc  2.9
inet_net_ntop.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1996,1999 by Internet Software Consortium.
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
00009  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
00010  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
00011  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00012  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00013  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00014  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00015  * SOFTWARE.
00016  */
00017 
00018 #if defined(LIBC_SCCS) && !defined(lint)
00019 static const char rcsid[] = "$BINDId: inet_net_ntop.c,v 1.6 1999/01/08 19:23:42 vixie Exp $";
00020 #endif
00021 
00022 #include <sys/types.h>
00023 #include <sys/socket.h>
00024 #include <netinet/in.h>
00025 #include <arpa/inet.h>
00026 
00027 #include <errno.h>
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 
00032 #ifdef SPRINTF_CHAR
00033 # define SPRINTF(x) strlen(sprintfx)
00034 #else
00035 # define SPRINTF(x) ((size_t)sprintf x)
00036 #endif
00037 
00038 static char * inet_net_ntop_ipv4 (const u_char *src, int bits,
00039                                 char *dst, size_t size) __THROW;
00040 
00041 /*
00042  * char *
00043  * inet_net_ntop(af, src, bits, dst, size)
00044  *     convert network number from network to presentation format.
00045  *     generates CIDR style result always.
00046  * return:
00047  *     pointer to dst, or NULL if an error occurred (check errno).
00048  * author:
00049  *     Paul Vixie (ISC), July 1996
00050  */
00051 char *
00052 inet_net_ntop(af, src, bits, dst, size)
00053        int af;
00054        const void *src;
00055        int bits;
00056        char *dst;
00057        size_t size;
00058 {
00059        switch (af) {
00060        case AF_INET:
00061               return (inet_net_ntop_ipv4(src, bits, dst, size));
00062        default:
00063               __set_errno (EAFNOSUPPORT);
00064               return (NULL);
00065        }
00066 }
00067 
00068 /*
00069  * static char *
00070  * inet_net_ntop_ipv4(src, bits, dst, size)
00071  *     convert IPv4 network number from network to presentation format.
00072  *     generates CIDR style result always.
00073  * return:
00074  *     pointer to dst, or NULL if an error occurred (check errno).
00075  * note:
00076  *     network byte order assumed.  this means 192.5.5.240/28 has
00077  *     0b11110000 in its fourth octet.
00078  * author:
00079  *     Paul Vixie (ISC), July 1996
00080  */
00081 static char *
00082 inet_net_ntop_ipv4(src, bits, dst, size)
00083        const u_char *src;
00084        int bits;
00085        char *dst;
00086        size_t size;
00087 {
00088        char *odst = dst;
00089        char *t;
00090        u_int m;
00091        int b;
00092 
00093        if (bits < 0 || bits > 32) {
00094               __set_errno (EINVAL);
00095               return (NULL);
00096        }
00097        if (bits == 0) {
00098               if (size < sizeof "0")
00099                      goto emsgsize;
00100               *dst++ = '0';
00101               size--;
00102               *dst = '\0';
00103        }
00104 
00105        /* Format whole octets. */
00106        for (b = bits / 8; b > 0; b--) {
00107               if (size < sizeof "255.")
00108                      goto emsgsize;
00109               t = dst;
00110               dst += SPRINTF((dst, "%u", *src++));
00111               if (b > 1) {
00112                      *dst++ = '.';
00113                      *dst = '\0';
00114               }
00115               size -= (size_t)(dst - t);
00116        }
00117 
00118        /* Format partial octet. */
00119        b = bits % 8;
00120        if (b > 0) {
00121               if (size < sizeof ".255")
00122                      goto emsgsize;
00123               t = dst;
00124               if (dst != odst)
00125                      *dst++ = '.';
00126               m = ((1 << b) - 1) << (8 - b);
00127               dst += SPRINTF((dst, "%u", *src & m));
00128               size -= (size_t)(dst - t);
00129        }
00130 
00131        /* Format CIDR /width. */
00132        if (size < sizeof "/32")
00133               goto emsgsize;
00134        dst += SPRINTF((dst, "/%u", bits));
00135        return (odst);
00136 
00137  emsgsize:
00138        __set_errno (EMSGSIZE);
00139        return (NULL);
00140 }