1 /* 2 * Copyright (c) 1996 by Internet Software Consortium. 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 9 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 10 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 11 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 14 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 15 * SOFTWARE. 16 */ 17 18 #if defined(LIBC_SCCS) && !defined(lint) 19 static const char orig_rcsid[] = "From Id: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp"; 20 static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.1.1.1 2003/11/19 01:51:29 kyu3 Exp $"; 21 #endif 22 23 #include <sys/types.h> 24 #include <sys/socket.h> 25 #include <netinet/in.h> 26 #include <arpa/inet.h> 27 28 #include <errno.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <stdlib.h> 32 33 #ifdef SPRINTF_CHAR 34 # define SPRINTF(x) strlen(sprintf/**/x) 35 #else 36 # define SPRINTF(x) ((size_t)sprintf x) 37 #endif 38 39 static char * inet_net_ntop_ipv4 (const u_char *src, int bits, 40 char *dst, size_t size); 41 42 /* 43 * char * 44 * inet_net_ntop(af, src, bits, dst, size) 45 * convert network number from network to presentation format. 46 * generates CIDR style result always. 47 * return: 48 * pointer to dst, or NULL if an error occurred (check errno). 49 * author: 50 * Paul Vixie (ISC), July 1996 51 */ 52 char * 53 inet_net_ntop( 54 int af, 55 const void *src, 56 int bits, 57 char *dst, 58 size_t size 59 ) 60 { 61 switch (af) { 62 case AF_INET: 63 return (inet_net_ntop_ipv4(src, bits, dst, size)); 64 default: 65 errno = EAFNOSUPPORT; 66 return (NULL); 67 } 68 } 69 70 /* 71 * static char * 72 * inet_net_ntop_ipv4(src, bits, dst, size) 73 * convert IPv4 network number from network to presentation format. 74 * generates CIDR style result always. 75 * return: 76 * pointer to dst, or NULL if an error occurred (check errno). 77 * note: 78 * network byte order assumed. this means 192.5.5.240/28 has 79 * 0x11110000 in its fourth octet. 80 * author: 81 * Paul Vixie (ISC), July 1996 82 */ 83 static char * 84 inet_net_ntop_ipv4( 85 const u_char *src, 86 int bits, 87 char *dst, 88 size_t size 89 ) 90 { 91 char *odst = dst; 92 char *t; 93 u_int m; 94 int b; 95 96 if (bits < 0 || bits > 32) { 97 errno = EINVAL; 98 return (NULL); 99 } 100 if (bits == 0) { 101 if (size < sizeof "0") 102 goto emsgsize; 103 *dst++ = '0'; 104 *dst = '\0'; 105 } 106 107 /* Format whole octets. */ 108 for (b = bits / 8; b > 0; b--) { 109 if (size < sizeof "255.") 110 goto emsgsize; 111 t = dst; 112 dst += SPRINTF((dst, "%u", *src++)); 113 if (b > 1) { 114 *dst++ = '.'; 115 *dst = '\0'; 116 } 117 size -= (size_t)(dst - t); 118 } 119 120 /* Format partial octet. */ 121 b = bits % 8; 122 if (b > 0) { 123 if (size < sizeof ".255") 124 goto emsgsize; 125 t = dst; 126 if (dst != odst) 127 *dst++ = '.'; 128 m = ((1 << b) - 1) << (8 - b); 129 dst += SPRINTF((dst, "%u", ((unsigned int)(*src & m)))); 130 size -= (size_t)(dst - t); 131 } 132 133 /* Format CIDR /width. */ 134 if (size < sizeof "/32") 135 goto emsgsize; 136 dst += SPRINTF((dst, "/%u", bits)); 137 return (odst); 138 139 emsgsize: 140 errno = EMSGSIZE; 141 return (NULL); 142 } 143