1 /*
2 * Copyright (C) 2009-2016 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
17 */
18
19 #include <config.h>
20
21 #include "virsocketaddr.h"
22 #include "virerror.h"
23 #include "virstring.h"
24 #include "virbuffer.h"
25 #include "viralloc.h"
26
27 #define VIR_FROM_THIS VIR_FROM_NONE
28
29 /*
30 * Helpers to extract the IP arrays from the virSocketAddr *
31 * That part is the less portable of the module
32 */
33 typedef unsigned char virSocketAddrIPv4[4];
34 typedef unsigned short virSocketAddrIPv6[8];
35 typedef unsigned char virSocketAddrIPv6Nibbles[32];
36
37 static int
virSocketAddrGetIPv4Addr(const virSocketAddr * addr,virSocketAddrIPv4 * tab)38 virSocketAddrGetIPv4Addr(const virSocketAddr *addr,
39 virSocketAddrIPv4 *tab)
40 {
41 unsigned long val;
42 size_t i;
43
44 if (!addr || !tab || addr->data.stor.ss_family != AF_INET)
45 return -1;
46
47 val = ntohl(addr->data.inet4.sin_addr.s_addr);
48
49 for (i = 0; i < 4; i++) {
50 (*tab)[3 - i] = val & 0xFF;
51 val >>= 8;
52 }
53
54 return 0;
55 }
56
57 static int
virSocketAddrGetIPv6Addr(const virSocketAddr * addr,virSocketAddrIPv6 * tab)58 virSocketAddrGetIPv6Addr(const virSocketAddr *addr, virSocketAddrIPv6 *tab)
59 {
60 size_t i;
61
62 if (!addr || !tab || addr->data.stor.ss_family != AF_INET6)
63 return -1;
64
65 for (i = 0; i < 8; i++) {
66 (*tab)[i] = ((addr->data.inet6.sin6_addr.s6_addr[2 * i] << 8) |
67 addr->data.inet6.sin6_addr.s6_addr[2 * i + 1]);
68 }
69
70 return 0;
71 }
72
73 static int
virSocketAddrGetIPv6Nibbles(const virSocketAddr * addr,virSocketAddrIPv6Nibbles * tab)74 virSocketAddrGetIPv6Nibbles(const virSocketAddr *addr,
75 virSocketAddrIPv6Nibbles *tab)
76 {
77 size_t i;
78
79 if (!addr || !tab || addr->data.stor.ss_family != AF_INET6)
80 return -1;
81
82 for (i = 0; i < 16; i++) {
83 (*tab)[2 * i] = addr->data.inet6.sin6_addr.s6_addr[i] >> 4;
84 (*tab)[2 * i + 1] = addr->data.inet6.sin6_addr.s6_addr[i] & 0xF;
85 }
86
87 return 0;
88 }
89
90 static int
virSocketAddrParseInternal(struct addrinfo ** res,const char * val,int family,int ai_flags,bool reportError)91 virSocketAddrParseInternal(struct addrinfo **res,
92 const char *val,
93 int family,
94 int ai_flags,
95 bool reportError)
96 {
97 struct addrinfo hints;
98 int err;
99
100 if (val == NULL) {
101 if (reportError)
102 virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing address"));
103 return -1;
104 }
105
106 memset(&hints, 0, sizeof(hints));
107 hints.ai_family = family;
108 hints.ai_flags = ai_flags;
109 if ((err = getaddrinfo(val, NULL, &hints, res)) != 0) {
110 if (reportError)
111 virReportError(VIR_ERR_SYSTEM_ERROR,
112 _("Cannot parse socket address '%s': %s"),
113 val, gai_strerror(err));
114
115 return -1;
116 }
117
118 return 0;
119 }
120
121 /**
122 * virSocketAddrParse:
123 * @val: a numeric network address IPv4 or IPv6
124 * @addr: where to store the return value, optional.
125 * @family: address family to pass down to getaddrinfo
126 *
127 * Mostly a wrapper for getaddrinfo() extracting the address storage
128 * from the numeric string like 1.2.3.4 or 2001:db8:85a3:0:0:8a2e:370:7334
129 *
130 * Returns the length of the network address or -1 in case of error.
131 */
virSocketAddrParse(virSocketAddr * addr,const char * val,int family)132 int virSocketAddrParse(virSocketAddr *addr, const char *val, int family)
133 {
134 int len;
135 struct addrinfo *res;
136
137 if (virSocketAddrParseInternal(&res, val, family, AI_NUMERICHOST, true) < 0)
138 return -1;
139
140 if (res == NULL) {
141 virReportError(VIR_ERR_SYSTEM_ERROR,
142 _("No socket addresses found for '%s'"),
143 val);
144 return -1;
145 }
146
147 len = res->ai_addrlen;
148 if (addr != NULL) {
149 memcpy(&addr->data.stor, res->ai_addr, len);
150 addr->len = res->ai_addrlen;
151 }
152
153 freeaddrinfo(res);
154 return len;
155 }
156
157 /**
158 * virSocketAddrParseAny:
159 * @addr: where to store the return value, optional.
160 * @val: a network host name or a numeric network address IPv4 or IPv6
161 * @family: address family to pass down to getaddrinfo
162 * @reportError: boolean to control error reporting
163 *
164 * Mostly a wrapper for getaddrinfo() extracting the address storage
165 * from a host name like acme.example.com or a numeric string like 1.2.3.4
166 * or 2001:db8:85a3:0:0:8a2e:370:7334.
167 *
168 * When @val is a network host name, this function may be susceptible to a
169 * delay due to potentially lengthy network host address lookups.
170 *
171 * Returns the length of the network address or -1 in case of error.
172 */
virSocketAddrParseAny(virSocketAddr * addr,const char * val,int family,bool reportError)173 int virSocketAddrParseAny(virSocketAddr *addr,
174 const char *val,
175 int family,
176 bool reportError)
177 {
178 int len;
179 struct addrinfo *res;
180
181 if (virSocketAddrParseInternal(&res, val, family, 0, reportError) < 0)
182 return -1;
183
184 if (res == NULL) {
185 if (reportError) {
186 virReportError(VIR_ERR_SYSTEM_ERROR,
187 _("No socket addresses found for '%s'"),
188 val);
189 }
190 return -1;
191 }
192
193 len = res->ai_addrlen;
194 if (addr != NULL) {
195 memcpy(&addr->data.stor, res->ai_addr, len);
196 addr->len = res->ai_addrlen;
197 }
198
199 freeaddrinfo(res);
200 return len;
201 }
202
203 /*
204 * virSocketAddrParseIPv4:
205 * @val: an IPv4 numeric address
206 * @addr: the location to store the result
207 *
208 * Extract the address storage from an IPv4 numeric address
209 *
210 * Returns the length of the network address or -1 in case of error.
211 */
212 int
virSocketAddrParseIPv4(virSocketAddr * addr,const char * val)213 virSocketAddrParseIPv4(virSocketAddr *addr, const char *val)
214 {
215 return virSocketAddrParse(addr, val, AF_INET);
216 }
217
218 /*
219 * virSocketAddrParseIPv6:
220 * @val: an IPv6 numeric address
221 * @addr: the location to store the result
222 *
223 * Extract the address storage from an IPv6 numeric address
224 *
225 * Returns the length of the network address or -1 in case of error.
226 */
227 int
virSocketAddrParseIPv6(virSocketAddr * addr,const char * val)228 virSocketAddrParseIPv6(virSocketAddr *addr, const char *val)
229 {
230 return virSocketAddrParse(addr, val, AF_INET6);
231 }
232
233 /**
234 * virSocketAddrResolveService:
235 * @service: a service name or port number
236 *
237 * Resolve a service, which might be a plain port or service name,
238 * into a port number for IPv4/IPv6 usage
239 *
240 * Returns a numeric port number, or -1 on error
241 */
virSocketAddrResolveService(const char * service)242 int virSocketAddrResolveService(const char *service)
243 {
244 struct addrinfo *res, *tmp;
245 struct addrinfo hints;
246 int err;
247 int port = -1;
248
249 memset(&hints, 0, sizeof(hints));
250
251 if ((err = getaddrinfo(NULL, service, &hints, &res)) != 0) {
252 virReportError(VIR_ERR_SYSTEM_ERROR,
253 _("Cannot parse socket service '%s': %s"),
254 service, gai_strerror(err));
255 return -1;
256 }
257
258 tmp = res;
259 while (tmp) {
260 if (tmp->ai_family == AF_INET) {
261 struct sockaddr_in in;
262 memcpy(&in, tmp->ai_addr, sizeof(in));
263 port = ntohs(in.sin_port);
264 goto cleanup;
265 } else if (tmp->ai_family == AF_INET6) {
266 struct sockaddr_in6 in;
267 memcpy(&in, tmp->ai_addr, sizeof(in));
268 port = ntohs(in.sin6_port);
269 goto cleanup;
270 }
271 tmp = tmp->ai_next;
272 }
273
274 virReportError(VIR_ERR_SYSTEM_ERROR,
275 _("No matches for socket service '%s': %s"),
276 service, gai_strerror(err));
277
278 cleanup:
279 freeaddrinfo(res);
280
281 return port;
282 }
283
284 /*
285 * virSocketAddrSetIPv4AddrNetOrder:
286 * @addr: the location to store the result
287 * @val: the 32bit integer in network byte order representing the IPv4 address
288 *
289 * Set the IPv4 address given an integer in network order. This function does not
290 * touch any previously set port.
291 */
292 void
virSocketAddrSetIPv4AddrNetOrder(virSocketAddr * addr,uint32_t val)293 virSocketAddrSetIPv4AddrNetOrder(virSocketAddr *addr, uint32_t val)
294 {
295 addr->data.stor.ss_family = AF_INET;
296 addr->data.inet4.sin_addr.s_addr = val;
297 addr->len = sizeof(struct sockaddr_in);
298 }
299
300 /*
301 * virSocketAddrSetIPv4Addr:
302 * @addr: the location to store the result
303 * @val: the 32bit integer in host byte order representing the IPv4 address
304 *
305 * Set the IPv4 address given an integer in host order. This function does not
306 * touch any previously set port.
307 */
308 void
virSocketAddrSetIPv4Addr(virSocketAddr * addr,uint32_t val)309 virSocketAddrSetIPv4Addr(virSocketAddr *addr, uint32_t val)
310 {
311 virSocketAddrSetIPv4AddrNetOrder(addr, htonl(val));
312 }
313
314 /*
315 * virSocketAddrSetIPv6AddrNetOrder:
316 * @addr: the location to store the result
317 * @val: the 128bit integer in network byte order representing the IPv6 address
318 *
319 * Set the IPv6 address given an integer in network order. This function does not
320 * touch any previously set port.
321 */
virSocketAddrSetIPv6AddrNetOrder(virSocketAddr * addr,uint32_t val[4])322 void virSocketAddrSetIPv6AddrNetOrder(virSocketAddr *addr, uint32_t val[4])
323 {
324 addr->data.stor.ss_family = AF_INET6;
325 memcpy(addr->data.inet6.sin6_addr.s6_addr, val, 4 * sizeof(*val));
326 addr->len = sizeof(struct sockaddr_in6);
327 }
328
329 /*
330 * virSocketAddrSetIPv6Addr:
331 * @addr: the location to store the result
332 * @val: the 128bit integer in host byte order representing the IPv6 address
333 *
334 * Set the IPv6 address given an integer in host order. This function does not
335 * touch any previously set port.
336 */
virSocketAddrSetIPv6Addr(virSocketAddr * addr,uint32_t val[4])337 void virSocketAddrSetIPv6Addr(virSocketAddr *addr, uint32_t val[4])
338 {
339 size_t i = 0;
340 uint32_t host_val[4];
341
342 for (i = 0; i < 4; i++)
343 host_val[i] = htonl(val[i]);
344
345 virSocketAddrSetIPv6AddrNetOrder(addr, host_val);
346 }
347
348 /*
349 * virSocketAddrEqual:
350 * @s1: the location of the one IP address
351 * @s2: the location of the other IP address
352 *
353 * Compare two IP addresses for equality. Two addresses are equal
354 * if their IP addresses and ports are equal.
355 */
356 bool
virSocketAddrEqual(const virSocketAddr * s1,const virSocketAddr * s2)357 virSocketAddrEqual(const virSocketAddr *s1, const virSocketAddr *s2)
358 {
359 if (s1->data.stor.ss_family != s2->data.stor.ss_family)
360 return false;
361
362 switch (s1->data.stor.ss_family) {
363 case AF_INET:
364 return (memcmp(&s1->data.inet4.sin_addr.s_addr,
365 &s2->data.inet4.sin_addr.s_addr,
366 sizeof(s1->data.inet4.sin_addr.s_addr)) == 0 &&
367 s1->data.inet4.sin_port == s2->data.inet4.sin_port);
368 case AF_INET6:
369 return (memcmp(&s1->data.inet6.sin6_addr.s6_addr,
370 &s2->data.inet6.sin6_addr.s6_addr,
371 sizeof(s1->data.inet6.sin6_addr.s6_addr)) == 0 &&
372 s1->data.inet6.sin6_port == s2->data.inet6.sin6_port);
373 }
374 return false;
375 }
376
377 /*
378 * virSocketAddrIsPrivate:
379 * @s: the location of the IP address
380 *
381 * Return true if this address is in its family's defined
382 * "private/local" address space. For IPv4, private addresses are in
383 * the range of 192.168.0.0/16, 172.16.0.0/12, or 10.0.0.0/8. For
384 * IPv6, local addresses are in the range of FC00::/7 or FEC0::/10
385 * (that last one is deprecated, but still in use).
386 *
387 * See RFC1918, RFC3484, and RFC4193 for details.
388 */
389 bool
virSocketAddrIsPrivate(const virSocketAddr * addr)390 virSocketAddrIsPrivate(const virSocketAddr *addr)
391 {
392 unsigned long val;
393
394 switch (addr->data.stor.ss_family) {
395 case AF_INET:
396 val = ntohl(addr->data.inet4.sin_addr.s_addr);
397
398 return ((val & 0xFFFF0000) == ((192UL << 24) + (168 << 16)) ||
399 (val & 0xFFF00000) == ((172UL << 24) + (16 << 16)) ||
400 (val & 0xFF000000) == ((10UL << 24)));
401
402 case AF_INET6:
403 return ((addr->data.inet6.sin6_addr.s6_addr[0] & 0xFE) == 0xFC ||
404 ((addr->data.inet6.sin6_addr.s6_addr[0] & 0xFF) == 0xFE &&
405 (addr->data.inet6.sin6_addr.s6_addr[1] & 0xC0) == 0xC0));
406 }
407 return false;
408 }
409
410 /*
411 * virSocketAddrIsWildcard:
412 * @addr: address to check
413 *
414 * Check if passed address is a variant of ANYCAST address.
415 */
416 bool
virSocketAddrIsWildcard(const virSocketAddr * addr)417 virSocketAddrIsWildcard(const virSocketAddr *addr)
418 {
419 struct in_addr tmp = { .s_addr = INADDR_ANY };
420 switch (addr->data.stor.ss_family) {
421 case AF_INET:
422 return memcmp(&addr->data.inet4.sin_addr.s_addr, &tmp.s_addr,
423 sizeof(addr->data.inet4.sin_addr.s_addr)) == 0;
424 case AF_INET6:
425 return IN6_IS_ADDR_UNSPECIFIED(&addr->data.inet6.sin6_addr);
426 }
427 return false;
428 }
429
430 /*
431 * virSocketAddrFormat:
432 * @addr: an initialized virSocketAddr *
433 *
434 * Returns a string representation of the given address
435 * Returns NULL on any error
436 * Caller must free the returned string
437 */
438 char *
virSocketAddrFormat(const virSocketAddr * addr)439 virSocketAddrFormat(const virSocketAddr *addr)
440 {
441 return virSocketAddrFormatFull(addr, false, NULL);
442 }
443
444
445 /*
446 * virSocketAddrFormatFull:
447 * @addr: an initialized virSocketAddr *
448 * @withService: if true, then service info is appended
449 * @separator: separator between hostname & service.
450 *
451 * Returns a string representation of the given address. If a format conforming
452 * to URI specification is required, NULL should be passed to separator.
453 * Set @separator only if non-URI format is required, e.g. passing ';' for
454 * @separator if the address should be used with SASL.
455 * Caller must free the returned string.
456 */
457 char *
virSocketAddrFormatFull(const virSocketAddr * addr,bool withService,const char * separator)458 virSocketAddrFormatFull(const virSocketAddr *addr,
459 bool withService,
460 const char *separator)
461 {
462 char host[NI_MAXHOST], port[NI_MAXSERV];
463 char *addrstr;
464 int err;
465
466 if (addr == NULL) {
467 virReportError(VIR_ERR_INVALID_ARG, "%s", _("Missing address"));
468 return NULL;
469 }
470
471 /* Short-circuit since getnameinfo doesn't work
472 * nicely for UNIX sockets */
473 if (addr->data.sa.sa_family == AF_UNIX) {
474 if (withService) {
475 addrstr = g_strdup_printf(VIR_LOOPBACK_IPV4_ADDR "%s0",
476 separator ? separator : ":");
477 } else {
478 addrstr = g_strdup(VIR_LOOPBACK_IPV4_ADDR);
479 }
480 return addrstr;
481 }
482
483 if ((err = getnameinfo(&addr->data.sa,
484 addr->len,
485 host, sizeof(host),
486 port, sizeof(port),
487 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
488 virReportError(VIR_ERR_SYSTEM_ERROR,
489 _("Cannot convert socket address to string: %s"),
490 gai_strerror(err));
491 return NULL;
492 }
493
494 if (withService) {
495 g_autofree char *ipv6_host = NULL;
496 /* sasl_new_client demands the socket address to be in an odd format:
497 * a.b.c.d;port or e:f:g:h:i:j:k:l;port, so use square brackets for
498 * IPv6 only if no separator is passed to the function
499 */
500 if (!separator && VIR_SOCKET_ADDR_FAMILY(addr) == AF_INET6)
501 ipv6_host = g_strdup_printf("[%s]", host);
502
503 addrstr = g_strdup_printf("%s%s%s",
504 ipv6_host ? ipv6_host : host,
505 separator ? separator : ":", port);
506 } else {
507 addrstr = g_strdup(host);
508 }
509
510 return addrstr;
511 }
512
513
514 /*
515 * virSocketAddrSetPort:
516 * @addr: an initialized virSocketAddr *
517 * @port: the port number to set
518 *
519 * Set the transport layer port of the given virtSocketAddr
520 *
521 * Returns 0 on success, -1 on failure
522 */
523 int
virSocketAddrSetPort(virSocketAddr * addr,int port)524 virSocketAddrSetPort(virSocketAddr *addr, int port)
525 {
526 if (addr == NULL)
527 return -1;
528
529 port = htons(port);
530
531 if (addr->data.stor.ss_family == AF_INET) {
532 addr->data.inet4.sin_port = port;
533 } else if (addr->data.stor.ss_family == AF_INET6) {
534 addr->data.inet6.sin6_port = port;
535 } else {
536 return -1;
537 }
538
539 return 0;
540 }
541
542 /*
543 * virSocketGetPort:
544 * @addr: an initialized virSocketAddr *
545 *
546 * Returns the transport layer port of the given virtSocketAddr
547 * Returns -1 if @addr is invalid
548 */
549 int
virSocketAddrGetPort(virSocketAddr * addr)550 virSocketAddrGetPort(virSocketAddr *addr)
551 {
552 if (addr == NULL)
553 return -1;
554
555 if (addr->data.stor.ss_family == AF_INET) {
556 return ntohs(addr->data.inet4.sin_port);
557 } else if (addr->data.stor.ss_family == AF_INET6) {
558 return ntohs(addr->data.inet6.sin6_port);
559 }
560
561 return -1;
562 }
563
564
565 /*
566 * virSocketGetPath:
567 * @addr: an initialized virSocketAddr *
568 *
569 * Returns the UNIX socket path of the given virtSocketAddr
570 *
571 * Returns -1 if @addr is invalid or does not refer to an
572 * address of type AF_UNIX;
573 */
574 char *
virSocketAddrGetPath(virSocketAddr * addr G_GNUC_UNUSED)575 virSocketAddrGetPath(virSocketAddr *addr G_GNUC_UNUSED)
576 {
577 #ifndef WIN32
578 if (addr == NULL) {
579 virReportError(VIR_ERR_INVALID_ARG, "%s",
580 _("No socket address provided"));
581 return NULL;
582 }
583
584 if (addr->data.sa.sa_family != AF_UNIX) {
585 virReportError(VIR_ERR_INVALID_ARG, "%s",
586 _("UNIX socket address is required"));
587 return NULL;
588 }
589
590 return g_strndup(addr->data.un.sun_path, sizeof(addr->data.un.sun_path));
591 #else
592 virReportError(VIR_ERR_NO_SUPPORT, "%s",
593 _("UNIX sockets not supported on this platform"));
594 return NULL;
595 #endif
596 }
597
598
599 /**
600 * virSocketAddrIsNetmask:
601 * @netmask: the netmask address
602 *
603 * Check that @netmask is a proper network mask
604 *
605 * Returns 0 in case of success and -1 in case of error
606 */
virSocketAddrIsNetmask(virSocketAddr * netmask)607 int virSocketAddrIsNetmask(virSocketAddr *netmask)
608 {
609 int n = virSocketAddrGetNumNetmaskBits(netmask);
610 if (n < 0)
611 return -1;
612 return 0;
613 }
614
615 /**
616 * virSocketAddrMask:
617 * @addr: address that needs to be masked
618 * @netmask: the netmask address
619 * @network: where to store the result, can be same as @addr
620 *
621 * Mask off the host bits of @addr according to @netmask, turning it
622 * into a network address.
623 *
624 * Returns 0 in case of success, or -1 on error.
625 */
626 int
virSocketAddrMask(const virSocketAddr * addr,const virSocketAddr * netmask,virSocketAddr * network)627 virSocketAddrMask(const virSocketAddr *addr,
628 const virSocketAddr *netmask,
629 virSocketAddr *network)
630 {
631 memset(network, 0, sizeof(*network));
632 if (addr->data.stor.ss_family != netmask->data.stor.ss_family) {
633 network->data.stor.ss_family = AF_UNSPEC;
634 return -1;
635 }
636
637 if (addr->data.stor.ss_family == AF_INET) {
638 network->data.inet4.sin_addr.s_addr
639 = (addr->data.inet4.sin_addr.s_addr
640 & netmask->data.inet4.sin_addr.s_addr);
641 network->data.inet4.sin_port = 0;
642 network->data.stor.ss_family = AF_INET;
643 network->len = addr->len;
644 return 0;
645 }
646 if (addr->data.stor.ss_family == AF_INET6) {
647 size_t i;
648 for (i = 0; i < 16; i++) {
649 network->data.inet6.sin6_addr.s6_addr[i]
650 = (addr->data.inet6.sin6_addr.s6_addr[i]
651 & netmask->data.inet6.sin6_addr.s6_addr[i]);
652 }
653 network->data.inet6.sin6_port = 0;
654 network->data.stor.ss_family = AF_INET6;
655 network->len = addr->len;
656 return 0;
657 }
658 network->data.stor.ss_family = AF_UNSPEC;
659 return -1;
660 }
661
662 /**
663 * virSocketAddrMaskByPrefix:
664 * @addr: address that needs to be masked
665 * @prefix: prefix (# of 1 bits) of netmask to apply
666 * @network: where to store the result, can be same as @addr
667 *
668 * Mask off the host bits of @addr according to @prefix, turning it
669 * into a network address.
670 *
671 * Returns 0 in case of success, or -1 on error.
672 */
673 int
virSocketAddrMaskByPrefix(const virSocketAddr * addr,unsigned int prefix,virSocketAddr * network)674 virSocketAddrMaskByPrefix(const virSocketAddr *addr,
675 unsigned int prefix,
676 virSocketAddr *network)
677 {
678 virSocketAddr netmask;
679
680 if (virSocketAddrPrefixToNetmask(prefix, &netmask,
681 addr->data.stor.ss_family) < 0) {
682 network->data.stor.ss_family = AF_UNSPEC;
683 return -1;
684 }
685
686 return virSocketAddrMask(addr, &netmask, network);
687 }
688
689 /**
690 * virSocketAddrBroadcast:
691 * @addr: address that needs to be turned into broadcast address (IPv4 only)
692 * @netmask: the netmask address
693 * @broadcast: virSocketAddr to receive the broadcast address
694 *
695 * Mask ON the host bits of @addr according to @netmask, turning it
696 * into a broadcast address.
697 *
698 * Returns 0 in case of success, or -1 on error.
699 */
700 int
virSocketAddrBroadcast(const virSocketAddr * addr,const virSocketAddr * netmask,virSocketAddr * broadcast)701 virSocketAddrBroadcast(const virSocketAddr *addr,
702 const virSocketAddr *netmask,
703 virSocketAddr *broadcast)
704 {
705 memset(broadcast, 0, sizeof(*broadcast));
706
707 if ((addr->data.stor.ss_family != AF_INET) ||
708 (netmask->data.stor.ss_family != AF_INET)) {
709 broadcast->data.stor.ss_family = AF_UNSPEC;
710 return -1;
711 }
712
713 broadcast->data.stor.ss_family = AF_INET;
714 broadcast->len = addr->len;
715 broadcast->data.inet4.sin_addr.s_addr
716 = (addr->data.inet4.sin_addr.s_addr
717 | ~netmask->data.inet4.sin_addr.s_addr);
718 return 0;
719 }
720
721 /**
722 * virSocketAddrBroadcastByPrefix:
723 * @addr: address that needs to be turned into broadcast address (IPv4 only)
724 * @prefix: prefix (# of 1 bits) of netmask to apply
725 * @broadcast: virSocketAddr to receive the broadcast address
726 *
727 * Mask off the host bits of @addr according to @prefix, turning it
728 * into a network address.
729 *
730 * Returns 0 in case of success, or -1 on error.
731 */
732 int
virSocketAddrBroadcastByPrefix(const virSocketAddr * addr,unsigned int prefix,virSocketAddr * broadcast)733 virSocketAddrBroadcastByPrefix(const virSocketAddr *addr,
734 unsigned int prefix,
735 virSocketAddr *broadcast)
736 {
737 virSocketAddr netmask;
738
739 if (virSocketAddrPrefixToNetmask(prefix, &netmask,
740 addr->data.stor.ss_family) < 0)
741 return -1;
742
743 return virSocketAddrBroadcast(addr, &netmask, broadcast);
744 }
745
746 /**
747 * virSocketCheckNetmask:
748 * @addr1: a first network address
749 * @addr2: a second network address
750 * @netmask: the netmask address
751 *
752 * Check that @addr1 and @addr2 pertain to the same @netmask address
753 * range and returns the size of the range
754 *
755 * Returns 1 in case of success and 0 in case of failure and
756 * -1 in case of error
757 */
virSocketAddrCheckNetmask(virSocketAddr * addr1,virSocketAddr * addr2,virSocketAddr * netmask)758 int virSocketAddrCheckNetmask(virSocketAddr *addr1, virSocketAddr *addr2,
759 virSocketAddr *netmask)
760 {
761 size_t i;
762
763 if ((addr1 == NULL) || (addr2 == NULL) || (netmask == NULL))
764 return -1;
765 if ((addr1->data.stor.ss_family != addr2->data.stor.ss_family) ||
766 (addr1->data.stor.ss_family != netmask->data.stor.ss_family))
767 return -1;
768
769 if (virSocketAddrIsNetmask(netmask) != 0)
770 return -1;
771
772 if (addr1->data.stor.ss_family == AF_INET) {
773 virSocketAddrIPv4 t1, t2, tm;
774
775 if ((virSocketAddrGetIPv4Addr(addr1, &t1) < 0) ||
776 (virSocketAddrGetIPv4Addr(addr2, &t2) < 0) ||
777 (virSocketAddrGetIPv4Addr(netmask, &tm) < 0))
778 return -1;
779
780 for (i = 0; i < 4; i++) {
781 if ((t1[i] & tm[i]) != (t2[i] & tm[i]))
782 return 0;
783 }
784
785 } else if (addr1->data.stor.ss_family == AF_INET6) {
786 virSocketAddrIPv6 t1, t2, tm;
787
788 if ((virSocketAddrGetIPv6Addr(addr1, &t1) < 0) ||
789 (virSocketAddrGetIPv6Addr(addr2, &t2) < 0) ||
790 (virSocketAddrGetIPv6Addr(netmask, &tm) < 0))
791 return -1;
792
793 for (i = 0; i < 8; i++) {
794 if ((t1[i] & tm[i]) != (t2[i] & tm[i]))
795 return 0;
796 }
797
798 } else {
799 return -1;
800 }
801 return 1;
802 }
803
804 /**
805 * virSocketGetRange:
806 * @start: start of an IP range
807 * @end: end of an IP range
808 * @network: IP address of network that should completely contain this range
809 * @prefix: prefix of the network
810 *
811 * Check the order of the 2 addresses and compute the range, this will
812 * return 1 for identical addresses. Errors can come from incompatible
813 * addresses type, excessive range (>= 2^^16) where the two addresses
814 * are unrelated, inverted start and end, or a range that is not
815 * within network/prefix.
816 *
817 * Returns the size of the range or -1 in case of failure
818 */
819 int
virSocketAddrGetRange(virSocketAddr * start,virSocketAddr * end,virSocketAddr * network,int prefix)820 virSocketAddrGetRange(virSocketAddr *start, virSocketAddr *end,
821 virSocketAddr *network, int prefix)
822 {
823 int ret = 0;
824 size_t i;
825 virSocketAddr netmask;
826 g_autofree char *startStr = NULL;
827 g_autofree char *endStr = NULL;
828 g_autofree char *netStr = NULL;
829
830 if (start == NULL || end == NULL) {
831 virReportError(VIR_ERR_INTERNAL_ERROR,
832 _("NULL argument - %p %p"), start, end);
833 return -1;
834 }
835
836 startStr = virSocketAddrFormat(start);
837 endStr = virSocketAddrFormat(end);
838 if (!startStr || !endStr)
839 return -1; /*error already reported */
840
841 if (VIR_SOCKET_ADDR_FAMILY(start) != VIR_SOCKET_ADDR_FAMILY(end)) {
842 virReportError(VIR_ERR_INTERNAL_ERROR,
843 _("mismatch of address family in range %s - %s"),
844 startStr, endStr);
845 return -1;
846 }
847
848 if (network) {
849 /* some checks can only be done if we have details of the
850 * network the range should be within
851 */
852 if (!(netStr = virSocketAddrFormat(network)))
853 return -1;
854
855 if (VIR_SOCKET_ADDR_FAMILY(start) != VIR_SOCKET_ADDR_FAMILY(network)) {
856 virReportError(VIR_ERR_INTERNAL_ERROR,
857 _("mismatch of address family in "
858 "range %s - %s for network %s"),
859 startStr, endStr, netStr);
860 return -1;
861 }
862
863 if (prefix < 0 ||
864 virSocketAddrPrefixToNetmask(prefix, &netmask,
865 VIR_SOCKET_ADDR_FAMILY(network)) < 0) {
866 virReportError(VIR_ERR_INTERNAL_ERROR,
867 _("bad prefix %d for network %s when "
868 " checking range %s - %s"),
869 prefix, netStr, startStr, endStr);
870 return -1;
871 }
872
873 /* both start and end of range need to be within network */
874 if (virSocketAddrCheckNetmask(start, network, &netmask) <= 0 ||
875 virSocketAddrCheckNetmask(end, network, &netmask) <= 0) {
876 virReportError(VIR_ERR_INTERNAL_ERROR,
877 _("range %s - %s is not entirely within "
878 "network %s/%d"),
879 startStr, endStr, netStr, prefix);
880 return -1;
881 }
882
883 if (VIR_SOCKET_ADDR_IS_FAMILY(start, AF_INET)) {
884 virSocketAddr netaddr, broadcast;
885
886 if (virSocketAddrBroadcast(network, &netmask, &broadcast) < 0 ||
887 virSocketAddrMask(network, &netmask, &netaddr) < 0) {
888 virReportError(VIR_ERR_INTERNAL_ERROR,
889 _("failed to construct broadcast or network "
890 "address for network %s/%d"),
891 netStr, prefix);
892 return -1;
893 }
894
895 /* Don't allow the start of the range to be the network
896 * address (usually "...0") or the end of the range to be the
897 * broadcast address (usually "...255"). (the opposite also
898 * isn't allowed, but checking for that is implicit in all the
899 * other combined checks) (IPv6 doesn't have broadcast and
900 * network addresses, so this check is only done for IPv4)
901 */
902 if (virSocketAddrEqual(start, &netaddr)) {
903 virReportError(VIR_ERR_INTERNAL_ERROR,
904 _("start of range %s - %s in network %s/%d "
905 "is the network address"),
906 startStr, endStr, netStr, prefix);
907 return -1;
908 }
909
910 if (virSocketAddrEqual(end, &broadcast)) {
911 virReportError(VIR_ERR_INTERNAL_ERROR,
912 _("end of range %s - %s in network %s/%d "
913 "is the broadcast address"),
914 startStr, endStr, netStr, prefix);
915 return -1;
916 }
917 }
918 }
919
920 if (VIR_SOCKET_ADDR_IS_FAMILY(start, AF_INET)) {
921 virSocketAddrIPv4 t1, t2;
922
923 if (virSocketAddrGetIPv4Addr(start, &t1) < 0 ||
924 virSocketAddrGetIPv4Addr(end, &t2) < 0) {
925 virReportError(VIR_ERR_INTERNAL_ERROR,
926 _("failed to get IPv4 address "
927 "for start or end of range %s - %s"),
928 startStr, endStr);
929 return -1;
930 }
931
932 /* legacy check that everything except the last two bytes
933 * are the same
934 */
935 for (i = 0; i < 2; i++) {
936 if (t1[i] != t2[i]) {
937 virReportError(VIR_ERR_INTERNAL_ERROR,
938 _("range %s - %s is too large (> 65535)"),
939 startStr, endStr);
940 return -1;
941 }
942 }
943 ret = (t2[2] - t1[2]) * 256 + (t2[3] - t1[3]);
944 if (ret < 0) {
945 virReportError(VIR_ERR_INTERNAL_ERROR,
946 _("range %s - %s is reversed "),
947 startStr, endStr);
948 return -1;
949 }
950 ret++;
951 } else if (VIR_SOCKET_ADDR_IS_FAMILY(start, AF_INET6)) {
952 virSocketAddrIPv6 t1, t2;
953
954 if (virSocketAddrGetIPv6Addr(start, &t1) < 0 ||
955 virSocketAddrGetIPv6Addr(end, &t2) < 0) {
956 virReportError(VIR_ERR_INTERNAL_ERROR,
957 _("failed to get IPv6 address "
958 "for start or end of range %s - %s"),
959 startStr, endStr);
960 return -1;
961 }
962
963 /* legacy check that everything except the last two bytes are
964 * the same
965 */
966 for (i = 0; i < 7; i++) {
967 if (t1[i] != t2[i]) {
968 virReportError(VIR_ERR_INTERNAL_ERROR,
969 _("range %s - %s is too large (> 65535)"),
970 startStr, endStr);
971 return -1;
972 }
973 }
974 ret = t2[7] - t1[7];
975 if (ret < 0) {
976 virReportError(VIR_ERR_INTERNAL_ERROR,
977 _("range %s - %s start larger than end"),
978 startStr, endStr);
979 return -1;
980 }
981 ret++;
982 } else {
983 virReportError(VIR_ERR_INTERNAL_ERROR,
984 _("unsupported address family "
985 "for range %s - %s, must be ipv4 or ipv6"),
986 startStr, endStr);
987 return -1;
988 }
989
990 return ret;
991 }
992
993
994 /**
995 * virSocketAddrGetNumNetmaskBits
996 * @netmask: the presumed netmask
997 *
998 * Get the number of netmask bits in a netmask.
999 *
1000 * Returns the number of bits in the netmask or -1 if an error occurred
1001 * or the netmask is invalid.
1002 */
virSocketAddrGetNumNetmaskBits(const virSocketAddr * netmask)1003 int virSocketAddrGetNumNetmaskBits(const virSocketAddr *netmask)
1004 {
1005 size_t i, j;
1006 int c = 0;
1007
1008 if (netmask->data.stor.ss_family == AF_INET) {
1009 virSocketAddrIPv4 tm;
1010 uint8_t bit;
1011
1012 if (virSocketAddrGetIPv4Addr(netmask, &tm) < 0)
1013 return -1;
1014
1015 for (i = 0; i < 4; i++)
1016 if (tm[i] == 0xff)
1017 c += 8;
1018 else
1019 break;
1020
1021 if (c == 8 * 4)
1022 return c;
1023
1024 j = i << 3;
1025 while (j < (8 * 4)) {
1026 bit = 1 << (7 - (j & 7));
1027 if ((tm[j >> 3] & bit))
1028 c++;
1029 else
1030 break;
1031 j++;
1032 }
1033
1034 while (j < (8 * 4)) {
1035 bit = 1 << (7 - (j & 7));
1036 if ((tm[j >> 3] & bit))
1037 return -1;
1038 j++;
1039 }
1040
1041 return c;
1042 } else if (netmask->data.stor.ss_family == AF_INET6) {
1043 virSocketAddrIPv6 tm;
1044 uint16_t bit;
1045
1046 if (virSocketAddrGetIPv6Addr(netmask, &tm) < 0)
1047 return -1;
1048
1049 for (i = 0; i < 8; i++)
1050 if (tm[i] == 0xffff)
1051 c += 16;
1052 else
1053 break;
1054
1055 if (c == 16 * 8)
1056 return c;
1057
1058 j = i << 4;
1059 while (j < (16 * 8)) {
1060 bit = 1 << (15 - (j & 0xf));
1061 if ((tm[j >> 4] & bit))
1062 c++;
1063 else
1064 break;
1065 j++;
1066 }
1067
1068 while (j < (16 * 8)) {
1069 bit = 1 << (15 - (j & 0xf));
1070 if ((tm[j >> 4]) & bit)
1071 return -1;
1072 j++;
1073 }
1074
1075 return c;
1076 }
1077 return -1;
1078 }
1079
1080 /**
1081 * virSocketPrefixToNetmask:
1082 * @prefix: number of 1 bits to put in the netmask
1083 * @netmask: address to fill in with the desired netmask
1084 * @family: family of the address (AF_INET or AF_INET6 only)
1085 *
1086 * given @prefix and @family, fill in @netmask with a netmask
1087 * (eg 255.255.255.0).
1088 *
1089 * Returns 0 on success or -1 on error.
1090 */
1091
1092 int
virSocketAddrPrefixToNetmask(unsigned int prefix,virSocketAddr * netmask,int family)1093 virSocketAddrPrefixToNetmask(unsigned int prefix,
1094 virSocketAddr *netmask,
1095 int family)
1096 {
1097 memset(netmask, 0, sizeof(*netmask));
1098
1099 netmask->data.stor.ss_family = AF_UNSPEC; /* assume failure */
1100
1101 if (family == AF_INET) {
1102 int ip;
1103
1104 if (prefix > 32)
1105 return -1;
1106
1107 ip = prefix ? ~((1 << (32 - prefix)) - 1) : 0;
1108 netmask->data.inet4.sin_addr.s_addr = htonl(ip);
1109 netmask->data.stor.ss_family = AF_INET;
1110 netmask->len = sizeof(struct sockaddr_in);
1111
1112 } else if (family == AF_INET6) {
1113 size_t i = 0;
1114
1115 if (prefix > 128)
1116 return -1;
1117
1118 while (prefix >= 8) {
1119 /* do as much as possible an entire byte at a time */
1120 netmask->data.inet6.sin6_addr.s6_addr[i++] = 0xff;
1121 prefix -= 8;
1122 }
1123 if (prefix > 0) {
1124 /* final partial byte */
1125 netmask->data.inet6.sin6_addr.s6_addr[i++]
1126 = ~((1 << (8 - prefix)) -1);
1127 }
1128 while (i < 16) {
1129 /* zerofill remainder in case it wasn't initialized */
1130 netmask->data.inet6.sin6_addr.s6_addr[i++] = 0;
1131 }
1132 netmask->data.stor.ss_family = AF_INET6;
1133 netmask->len = sizeof(struct sockaddr_in6);
1134 }
1135
1136 return 0;
1137 }
1138
1139 /**
1140 * virSocketAddrGetIPPrefix:
1141 * @address: network address
1142 * @netmask: netmask for this network
1143 * @prefix: prefix if specified instead of netmask
1144 *
1145 * Returns prefix value on success or -1 on error.
1146 */
1147
1148 int
virSocketAddrGetIPPrefix(const virSocketAddr * address,const virSocketAddr * netmask,int prefix)1149 virSocketAddrGetIPPrefix(const virSocketAddr *address,
1150 const virSocketAddr *netmask,
1151 int prefix)
1152 {
1153 if (prefix > 0) {
1154 return prefix;
1155 } else if (netmask && VIR_SOCKET_ADDR_VALID(netmask)) {
1156 return virSocketAddrGetNumNetmaskBits(netmask);
1157 } else if (address && VIR_SOCKET_ADDR_IS_FAMILY(address, AF_INET)) {
1158 /* Return the natural prefix for the network's ip address.
1159 * On Linux we could use the IN_CLASSx() macros, but those
1160 * aren't guaranteed on all platforms, so we just deal with
1161 * the bits ourselves.
1162 */
1163 unsigned char octet
1164 = ntohl(address->data.inet4.sin_addr.s_addr) >> 24;
1165
1166 /* If address is 0.0.0.0, we surely want to have 0 prefix for
1167 * the default route. */
1168 if (address->data.inet4.sin_addr.s_addr == 0)
1169 return 0;
1170
1171 if ((octet & 0x80) == 0) {
1172 /* Class A network */
1173 return 8;
1174 } else if ((octet & 0xC0) == 0x80) {
1175 /* Class B network */
1176 return 16;
1177 } else if ((octet & 0xE0) == 0xC0) {
1178 /* Class C network */
1179 return 24;
1180 }
1181 return -1;
1182 } else if (address && VIR_SOCKET_ADDR_IS_FAMILY(address, AF_INET6)) {
1183 if (virSocketAddrIsWildcard(address))
1184 return 0;
1185 return 64;
1186 }
1187
1188 /* When none of the three (address/netmask/prefix) is given, 0 is
1189 * returned rather than error, because this is a valid
1190 * expectation, e.g. for the address/prefix used for a default
1191 * route (the destination of a default route is 0.0.0.0/0).
1192 */
1193 return 0;
1194 }
1195
1196 /**
1197 * virSocketAddrNumericFamily:
1198 * @address: address to check
1199 *
1200 * Check if passed address is an IP address in numeric format.
1201 *
1202 * Returns: AF_INET or AF_INET6 if @address is an numeric IP address,
1203 * -1 otherwise.
1204 */
1205 int
virSocketAddrNumericFamily(const char * address)1206 virSocketAddrNumericFamily(const char *address)
1207 {
1208 struct addrinfo *res;
1209 unsigned short family;
1210
1211 if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, AI_NUMERICHOST, false) < 0)
1212 return -1;
1213
1214 family = res->ai_addr->sa_family;
1215 freeaddrinfo(res);
1216 return family;
1217 }
1218
1219 /**
1220 * virSocketAddrIsNumericLocalhost:
1221 * @address: address to check
1222 *
1223 * Check if passed address is a numeric 'localhost' address.
1224 *
1225 * Returns: true if @address is a numeric 'localhost' address,
1226 * false otherwise
1227 */
1228 bool
virSocketAddrIsNumericLocalhost(const char * addr)1229 virSocketAddrIsNumericLocalhost(const char *addr)
1230 {
1231 virSocketAddr res;
1232 struct in_addr tmp = { .s_addr = htonl(INADDR_LOOPBACK) };
1233
1234 if (virSocketAddrParse(&res, addr, AF_UNSPEC) < 0)
1235 return false;
1236
1237 switch (res.data.stor.ss_family) {
1238 case AF_INET:
1239 return memcmp(&res.data.inet4.sin_addr.s_addr, &tmp.s_addr,
1240 sizeof(res.data.inet4.sin_addr.s_addr)) == 0;
1241 case AF_INET6:
1242 return IN6_IS_ADDR_LOOPBACK(&res.data.inet6.sin6_addr);
1243 }
1244
1245 return false;
1246 }
1247
1248
1249 /**
1250 * virSocketAddrPTRDomain:
1251 *
1252 * Create PTR domain which corresponds to @addr/@prefix. Both IPv4 and IPv6
1253 * addresses are supported, but @prefix must be divisible by 8 for IPv4 and
1254 * divisible by 4 for IPv6, otherwise -2 will be returned.
1255 *
1256 * Returns -2 if the PTR record cannot be automatically created,
1257 * -1 on error,
1258 * 0 on success.
1259 */
1260 int
virSocketAddrPTRDomain(const virSocketAddr * addr,unsigned int prefix,char ** ptr)1261 virSocketAddrPTRDomain(const virSocketAddr *addr,
1262 unsigned int prefix,
1263 char **ptr)
1264 {
1265 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
1266 size_t i;
1267
1268 if (VIR_SOCKET_ADDR_IS_FAMILY(addr, AF_INET)) {
1269 virSocketAddrIPv4 ip;
1270
1271 if (prefix == 0 || prefix >= 32 || prefix % 8 != 0)
1272 return -2;
1273
1274 if (virSocketAddrGetIPv4Addr(addr, &ip) < 0)
1275 return -1;
1276
1277 for (i = prefix / 8; i > 0; i--)
1278 virBufferAsprintf(&buf, "%u.", ip[i - 1]);
1279
1280 virBufferAddLit(&buf, VIR_SOCKET_ADDR_IPV4_ARPA);
1281 } else if (VIR_SOCKET_ADDR_IS_FAMILY(addr, AF_INET6)) {
1282 virSocketAddrIPv6Nibbles ip;
1283
1284 if (prefix == 0 || prefix >= 128 || prefix % 4 != 0)
1285 return -2;
1286
1287 if (virSocketAddrGetIPv6Nibbles(addr, &ip) < 0)
1288 return -1;
1289
1290 for (i = prefix / 4; i > 0; i--)
1291 virBufferAsprintf(&buf, "%x.", ip[i - 1]);
1292
1293 virBufferAddLit(&buf, VIR_SOCKET_ADDR_IPV6_ARPA);
1294 } else {
1295 return -2;
1296 }
1297
1298 if (!(*ptr = virBufferContentAndReset(&buf)))
1299 return -1;
1300
1301 return 0;
1302 }
1303
1304 void
virSocketAddrFree(virSocketAddr * addr)1305 virSocketAddrFree(virSocketAddr *addr)
1306 {
1307 g_free(addr);
1308 }
1309