1 /* $NetBSD: util.c,v 1.8 2008/07/02 07:44:15 dyoung Exp $ */
4 * Copyright (c) 2008 David Young. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: util.c,v 1.8 2008/07/02 07:44:15 dyoung Exp $");
43 #include <sys/socket.h>
44 #include <sys/ioctl.h>
46 #include <netinet/in.h> /* XXX */
54 static int oaf
= -1, s
;
56 if (oaf
== naf
|| (oaf
!= -1 && naf
== AF_UNSPEC
))
65 s
= socket(naf
, SOCK_DGRAM
, 0);
74 get_string(const char *val
, const char *sep
, u_int8_t
*buf
, int *lenp
)
82 hexstr
= (val
[0] == '0' && tolower((u_char
)val
[1]) == 'x');
88 if (sep
!= NULL
&& strchr(sep
, *val
) != NULL
) {
93 if (!isxdigit((u_char
)val
[0]) ||
94 !isxdigit((u_char
)val
[1])) {
95 warnx("bad hexadecimal digits");
101 warnx("hexadecimal digits too long");
103 warnx("strings too long");
107 #define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
108 *p
++ = (tohex((u_char
)val
[0]) << 4) |
109 tohex((u_char
)val
[1]);
117 memset(p
, 0, *lenp
- len
);
123 print_string(const u_int8_t
*buf
, int len
)
130 if (len
< 2 || buf
[0] != '0' || tolower(buf
[1]) != 'x') {
131 for (; i
< len
; i
++) {
132 if (!isprint(buf
[i
]))
139 if (hasspc
|| len
== 0)
140 printf("\"%.*s\"", len
, buf
);
142 printf("%.*s", len
, buf
);
145 for (i
= 0; i
< len
; i
++)
146 printf("%02x", buf
[i
]);
150 struct paddr_prefix
*
151 prefixlen_to_mask(int af
, int plen
)
155 struct sockaddr_in sin
;
156 struct sockaddr_in6 sin6
;
158 struct paddr_prefix
*pfx
;
163 memset(&u
, 0, sizeof(u
));
167 addrlen
= sizeof(u
.sin
.sin_addr
);
168 addr
= (uint8_t *)&u
.sin
.sin_addr
;
169 u
.sa
.sa_len
= sizeof(u
.sin
);
172 addrlen
= sizeof(u
.sin6
.sin6_addr
);
173 addr
= (uint8_t *)&u
.sin6
.sin6_addr
;
174 u
.sa
.sa_len
= sizeof(u
.sin6
);
182 if (plen
< 0 || (size_t)plen
> addrlen
* NBBY
) {
188 plen
= addrlen
* NBBY
;
190 memset(addr
, 0xff, (plen
+ NBBY
- 1) / NBBY
);
194 addr
[plen
/ NBBY
] &= ~((uint8_t)0xff >> nbit
);
195 pfx
= malloc(offsetof(struct paddr_prefix
, pfx_addr
) + u
.sa
.sa_len
);
199 memcpy(&pfx
->pfx_addr
, &u
.sa
, u
.sa
.sa_len
);
205 direct_ioctl(prop_dictionary_t env
, unsigned long cmd
, void *data
)
210 if ((s
= getsock(AF_UNSPEC
)) == -1)
211 err(EXIT_FAILURE
, "getsock");
213 if ((ifname
= getifname(env
)) == NULL
)
214 err(EXIT_FAILURE
, "getifname");
216 estrlcpy(data
, ifname
, IFNAMSIZ
);
218 return ioctl(s
, cmd
, data
);
222 indirect_ioctl(prop_dictionary_t env
, unsigned long cmd
, void *data
)
226 memset(&ifr
, 0, sizeof(ifr
));
230 return direct_ioctl(env
, cmd
, &ifr
);
234 /* KAME idiosyncrasy */
236 in6_fillscopeid(struct sockaddr_in6
*sin6
)
238 if (IN6_IS_ADDR_LINKLOCAL(&sin6
->sin6_addr
)) {
239 sin6
->sin6_scope_id
=
240 ntohs(*(u_int16_t
*)&sin6
->sin6_addr
.s6_addr
[2]);
241 sin6
->sin6_addr
.s6_addr
[2] = sin6
->sin6_addr
.s6_addr
[3] = 0;