static int testMaskNetwork(const char *addrstr, int prefix, const char *networkstr) { virSocketAddr addr; virSocketAddr network; char *gotnet = NULL; /* Intentionally fill with garbage */ memset(&network, 1, sizeof(network)); if (virSocketAddrParse(&addr, addrstr, AF_UNSPEC) < 0) return -1; if (virSocketAddrMaskByPrefix(&addr, prefix, &network) < 0) return -1; if (!(gotnet = virSocketAddrFormat(&network))) return -1; if (STRNEQ(networkstr, gotnet)) { VIR_FREE(gotnet); fprintf(stderr, "Expected %s, got %s\n", networkstr, gotnet); return -1; } VIR_FREE(gotnet); return 0; }
static int testRange(const char *saddrstr, const char *eaddrstr, int size, bool pass) { virSocketAddr saddr; virSocketAddr eaddr; if (virSocketAddrParse(&saddr, saddrstr, AF_UNSPEC) < 0) return -1; if (virSocketAddrParse(&eaddr, eaddrstr, AF_UNSPEC) < 0) return -1; int gotsize = virSocketAddrGetRange(&saddr, &eaddr); VIR_DEBUG("Size want %d vs got %d", size, gotsize); if (gotsize < 0 || gotsize != size) { return pass ? -1 : 0; } else { return pass ? 0 : -1; } }
static int testParse(virSocketAddr *addr, const char *addrstr, int family, bool pass) { int rc; rc = virSocketAddrParse(addr, addrstr, family); if (rc < 0) return pass ? -1 : 0; else return pass ? 0 : -1; }
static int testWildcard(const char *addrstr, bool pass) { virSocketAddr addr; if (virSocketAddrParse(&addr, addrstr, AF_UNSPEC) < 0) return -1; if (virSocketAddrIsWildcard(&addr)) return pass ? 0 : -1; return pass ? -1 : 0; }
static int testNetmask(const char *addr1str, const char *addr2str, const char *netmaskstr, bool pass) { virSocketAddr addr1; virSocketAddr addr2; virSocketAddr netmask; if (virSocketAddrParse(&addr1, addr1str, AF_UNSPEC) < 0) return -1; if (virSocketAddrParse(&addr2, addr2str, AF_UNSPEC) < 0) return -1; if (virSocketAddrParse(&netmask, netmaskstr, AF_UNSPEC) < 0) return -1; int ret = virSocketAddrCheckNetmask(&addr1, &addr2, &netmask); if (ret <= 0) { return pass ? -1 : 0; } else { return pass ? 0 : -1; } }
static int vboxSocketParseAddrUtf16(vboxDriverPtr data, const PRUnichar *utf16, virSocketAddrPtr addr) { int result = -1; char *utf8 = NULL; VBOX_UTF16_TO_UTF8(utf16, &utf8); if (virSocketAddrParse(addr, utf8, AF_UNSPEC) < 0) goto cleanup; result = 0; cleanup: VBOX_UTF8_FREE(utf8); return result; }
static int lxcNetworkParseDataIPs(const char *name, virConfValuePtr value, lxcNetworkParseData *parseData) { int family = AF_INET; char **ipparts = NULL; virNetDevIPAddrPtr ip = NULL; if (VIR_ALLOC(ip) < 0) return -1; if (STREQ(name, "ipv6")) family = AF_INET6; ipparts = virStringSplit(value->str, "/", 2); if (virStringListLength((const char * const *)ipparts) != 2 || virSocketAddrParse(&ip->address, ipparts[0], family) < 0 || virStrToLong_ui(ipparts[1], NULL, 10, &ip->prefix) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid CIDR address: '%s'"), value->str); virStringListFree(ipparts); VIR_FREE(ip); return -1; } virStringListFree(ipparts); if (VIR_APPEND_ELEMENT(parseData->ips, parseData->nips, ip) < 0) { VIR_FREE(ip); return -1; } return 0; }
/* * virSocketAddrParseIPv6: * @val: an IPv6 numeric address * @addr: the location to store the result * * Extract the address storage from an IPv6 numeric address * * Returns the length of the network address or -1 in case of error. */ int virSocketAddrParseIPv6(virSocketAddrPtr addr, const char *val) { return virSocketAddrParse(addr, val, AF_INET6); }
static int lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) { lxcNetworkParseData *parseData = data; int status; if (STREQ(name, "lxc.network.type")) { /* Store the previous NIC */ status = lxcAddNetworkDefinition(parseData); if (status < 0) return -1; else if (status > 0) parseData->networks++; else if (parseData->type != NULL && STREQ(parseData->type, "none")) parseData->privnet = false; /* Start a new network interface config */ parseData->type = NULL; parseData->link = NULL; parseData->mac = NULL; parseData->flag = NULL; parseData->macvlanmode = NULL; parseData->vlanid = NULL; parseData->name = NULL; parseData->ips = NULL; parseData->nips = 0; /* Keep the new value */ parseData->type = value->str; } else if (STREQ(name, "lxc.network.link")) parseData->link = value->str; else if (STREQ(name, "lxc.network.hwaddr")) parseData->mac = value->str; else if (STREQ(name, "lxc.network.flags")) parseData->flag = value->str; else if (STREQ(name, "lxc.network.macvlan.mode")) parseData->macvlanmode = value->str; else if (STREQ(name, "lxc.network.vlan.id")) parseData->vlanid = value->str; else if (STREQ(name, "lxc.network.name")) parseData->name = value->str; else if (STREQ(name, "lxc.network.ipv4") || STREQ(name, "lxc.network.ipv6")) { int family = AF_INET; char **ipparts = NULL; virDomainNetIpDefPtr ip = NULL; if (VIR_ALLOC(ip) < 0) return -1; if (STREQ(name, "lxc.network.ipv6")) family = AF_INET6; ipparts = virStringSplit(value->str, "/", 2); if (virStringListLength((const char * const *)ipparts) != 2 || virSocketAddrParse(&ip->address, ipparts[0], family) < 0 || virStrToLong_ui(ipparts[1], NULL, 10, &ip->prefix) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid CIDR address: '%s'"), value->str); virStringFreeList(ipparts); VIR_FREE(ip); return -1; } virStringFreeList(ipparts); if (VIR_APPEND_ELEMENT(parseData->ips, parseData->nips, ip) < 0) { VIR_FREE(ip); return -1; } } else if (STREQ(name, "lxc.network.ipv4.gateway")) { parseData->gateway_ipv4 = value->str; } else if (STREQ(name, "lxc.network.ipv6.gateway")) { parseData->gateway_ipv6 = value->str; } else if (STRPREFIX(name, "lxc.network")) { VIR_WARN("Unhandled network property: %s = %s", name, value->str); } return 0; }
virNetDevIPRoutePtr virNetDevIPRouteCreate(const char *errorDetail, const char *family, const char *address, const char *netmask, const char *gateway, unsigned int prefix, bool hasPrefix, unsigned int metric, bool hasMetric) { virNetDevIPRoutePtr def = NULL; virSocketAddr testAddr; if (VIR_ALLOC(def) < 0) return NULL; if (VIR_STRDUP(def->family, family) < 0) goto error; def->prefix = prefix; def->has_prefix = hasPrefix; def->metric = metric; def->has_metric = hasMetric; /* Note: both network and gateway addresses must be specified */ if (!address) { virReportError(VIR_ERR_XML_ERROR, _("%s: Missing required address attribute " "in route definition"), errorDetail); goto error; } if (!gateway) { virReportError(VIR_ERR_XML_ERROR, _("%s: Missing required gateway attribute " "in route definition"), errorDetail); goto error; } if (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) { virReportError(VIR_ERR_XML_ERROR, _("%s: Bad network address '%s' " "in route definition"), errorDetail, address); goto error; } if (virSocketAddrParse(&def->gateway, gateway, AF_UNSPEC) < 0) { virReportError(VIR_ERR_XML_ERROR, _("%s: Bad gateway address '%s' " "in route definition"), errorDetail, gateway); goto error; } /* validate network address, etc. for each family */ if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) { if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) || VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) { virReportError(VIR_ERR_XML_ERROR, def->family == NULL ? _("%s: No family specified for non-IPv4 address '%s' " "in route definition") : _("%s: IPv4 family specified for non-IPv4 address '%s' " "in route definition"), errorDetail, address); goto error; } if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET)) { virReportError(VIR_ERR_XML_ERROR, def->family == NULL ? _("%s: No family specified for non-IPv4 gateway '%s' " "in route definition") : _("%s: IPv4 family specified for non-IPv4 gateway '%s' " "in route definition"), errorDetail, address); goto error; } if (netmask) { if (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0) { virReportError(VIR_ERR_XML_ERROR, _("%s: Bad netmask address '%s' " "in route definition"), errorDetail, netmask); goto error; } if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) { virReportError(VIR_ERR_XML_ERROR, _("%s: Invalid netmask '%s' " "for address '%s' (both must be IPv4)"), errorDetail, netmask, address); goto error; } if (def->has_prefix) { /* can't have both netmask and prefix at the same time */ virReportError(VIR_ERR_XML_ERROR, _("%s: Route definition cannot have both " "a prefix and a netmask"), errorDetail); goto error; } } if (def->prefix > 32) { virReportError(VIR_ERR_XML_ERROR, _("%s: Invalid prefix %u specified " "in route definition, " "must be 0 - 32"), errorDetail, def->prefix); goto error; } } else if (STREQ(def->family, "ipv6")) { if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) { virReportError(VIR_ERR_XML_ERROR, _("%s: ipv6 family specified for non-IPv6 address '%s' " "in route definition"), errorDetail, address); goto error; } if (netmask) { virReportError(VIR_ERR_XML_ERROR, _("%s: Specifying netmask invalid for IPv6 address '%s' " "in route definition"), errorDetail, address); goto error; } if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET6)) { virReportError(VIR_ERR_XML_ERROR, _("%s: ipv6 specified for non-IPv6 gateway address '%s' " "in route definition"), errorDetail, gateway); goto error; } if (def->prefix > 128) { virReportError(VIR_ERR_XML_ERROR, _("%s: Invalid prefix %u specified " "in route definition, " "must be 0 - 128"), errorDetail, def->prefix); goto error; } } else { virReportError(VIR_ERR_XML_ERROR, _("%s: Unrecognized family '%s' " "in route definition"), errorDetail, def->family); goto error; } /* make sure the address is a network address */ if (netmask) { if (virSocketAddrMask(&def->address, &def->netmask, &testAddr) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: Error converting address '%s' with netmask '%s' " "to network-address " "in route definition"), errorDetail, address, netmask); goto error; } } else { if (virSocketAddrMaskByPrefix(&def->address, def->prefix, &testAddr) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: Error converting address '%s' with prefix %u " "to network-address " "in route definition"), errorDetail, address, def->prefix); goto error; } } if (!virSocketAddrEqual(&def->address, &testAddr)) { virReportError(VIR_ERR_XML_ERROR, _("%s: Address '%s' in route definition " "is not a network address"), errorDetail, address); goto error; } return def; error: virNetDevIPRouteFree(def); return NULL; }