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