* src/util/util.h src/util/util.c: two new functions virParseIPv4 and virParseIPv6 diff --git a/src/util/util.c b/src/util/util.c index e5135fc..bbd29dc 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1761,6 +1761,161 @@ void virGenerateMacAddr(const unsigned char *prefix, addr[5] = virRandom(256); } +static int virParseIPv4Byte(const char **addr) { + unsigned int v; + const char *cur = *addr; + + /* extend to accept hexa values ? */ + if (cur == NULL) + return(-1); + if ((*cur < '0') || (*cur > '9')) + return(-1); + v = *cur++ - '0'; + if ((*cur >= '0') && (*cur <= '9')) + v = 10 * v + *cur++ - '0'; + if ((*cur >= '0') && (*cur <= '9')) + v = 10 * v + *cur++ - '0'; + if (v > 255) + return(-1); + *addr = cur; + return(v); +} + +/* + * virParseIPv4: + * @addr: pointer to the address string in classic dotted format and zero + * terminated + * @res: optional pointer to the place to store the result + * + * Parse the IPv4 address in classic dot-decimal notation format like + * 192.0.2.235, and store the output if res is provided: + * for example res[0] = 192, res[1] = 0, res[2] = 2, res[3] = 235 + * + * Retuns 0 in case of success and -1 in case of error + */ +int virParseIPv4(const char *addr, virIPv4Val *res) { + int v; + const char *cur = addr; + + if (addr == NULL) + return(-1); + + if (res) + memset(res, 0, sizeof(*res)); + + v = virParseIPv4Byte(&cur); + if ((v < 0) || (*cur != '.')) + return(-1); + if (res) (*res)[0] = (unsigned char) v; + cur++; + + v = virParseIPv4Byte(&cur); + if ((v < 0) || (*cur != '.')) + return(-1); + if (res) (*res)[1] = (unsigned char) v; + cur++; + + v = virParseIPv4Byte(&cur); + if ((v < 0) || (*cur != '.')) + return(-1); + if (res) (*res)[2] = (unsigned char) v; + cur++; + + v = virParseIPv4Byte(&cur); + if ((v < 0) || (*cur != 0)) + return(-1); + if (res) (*res)[3] = (unsigned char) v; + + return(0); +} + +static int virParseIPv6Short(const char **addr) { + const char *cur = *addr; + char *end_ptr; + unsigned long result; + + if (cur == NULL) + return(-1); + errno = 0; + + /* This is solely to avoid accepting the leading + * space or "+" that strtoul would otherwise accept. + */ + if (!c_isxdigit(*cur)) + return(-1); + + result = strtoul(cur, &end_ptr, 16); + + if (((end_ptr - cur) < 1) || ((end_ptr - cur) > 4) || + (errno != 0) || (result > 0xFFFF)) + return(-1); + + *addr = end_ptr; + return((int) result); +} + +static int virCountColumn(const char *cur) { + int ret; + + for (ret = 0;*cur != 0;cur++) + if (*cur == ':') ret++; + return(ret); +} + +/* + * virParseIPv6: + * @addr: pointer to the address string in classic hex and column format + * and zero terminated + * @res: optional pointer to the place to store the result + * + * Parse the IPv6 address in classic dot-decimal notation format like + * 2001:db8:85a3:0:0:8a2e:370:7334, and store the output if res is provided: + * for example res[0] = 0x2001, res[1] = 0xdb8, etc. + * TODO: doesn't support the :: compression notation yet + * + * Retuns 0 in case of success and -1 in case of error + */ +int virParseIPv6(const char *addr, virIPv6Val *res) { + int v, i, left, compact; + const char *cur = addr; + + if (addr == NULL) + return(-1); + + if (res) + memset(res, 0, sizeof(*res)); + + compact = 0; + for (i = 0;i < 8;i++) { + if ((*cur == ':') && (compact == 0)) { + compact = 1; + cur++; + if (i == 0) { + /* if leading we expect :: */ + if (*cur != ':') + return(-1); + cur++; + if (*cur == 0) + return(0); + } + left = virCountColumn(cur); + if (7 - left <= i) + return(-1); + i = 7 - left; + } + v = virParseIPv6Short(&cur); + if (v < 0) + return(-1); + if (((i < 7) && (*cur != ':')) || + ((i == 7) && (*cur != 0))) + return(-1); + if (res) + (*res)[i] = (unsigned short) v; + cur++; + } + + return(0); +} int virEnumFromString(const char *const*types, unsigned int ntypes, diff --git a/src/util/util.h b/src/util/util.h index 8679636..b1be46f 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -185,6 +185,12 @@ void virFormatMacAddr(const unsigned char *addr, void virGenerateMacAddr(const unsigned char *prefix, unsigned char *addr); +typedef unsigned char virIPv4Val[4]; +typedef unsigned short virIPv6Val[8]; + +int virParseIPv4(const char *addr, virIPv4Val *res); +int virParseIPv6(const char *addr, virIPv6Val *res); + int virDiskNameToIndex(const char* str); -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list