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