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