GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/net/inet_net_ntop.c Lines: 0 49 0.0 %
Date: 2017-11-07 Branches: 0 47 0.0 %

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