diff --git a/ChangeLog b/ChangeLog index dd19a6cb54..f0ee76755b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Thu Mar 20 12:23:03 CET 2008 Daniel Veillard + + * src/util.c src/util.h src/xml.c: applied patch from Hiroyuki Kaguchi + fixing Ethernet MAC addresses parsingand separating as an util + function, with added comments from Jim Meyering + Wed Mar 19 15:31:34 CET 2008 Daniel Veillard * src/qemu_conf.c src/qemu_conf.h src/qemu_driver.c: applied patch diff --git a/src/util.c b/src/util.c index edaa5aaf34..69e899fa41 100644 --- a/src/util.c +++ b/src/util.c @@ -688,6 +688,51 @@ __virMacAddrCompare (const char *p, const char *q) return (c > d ? 1 : c < d ? -1 : 0); } +/** + * virParseMacAddr: + * @str: string representation of MAC address, e.g., "0:1E:FC:E:3a:CB" + * @addr: 6-byte MAC address + * + * Parse a MAC address + * + * Return 0 upon success, or -1 in case of error. + */ +int +virParseMacAddr(const char* str, unsigned char *addr) +{ + int i; + + errno = 0; + for (i = 0; i < 6; i++) { + char *end_ptr; + unsigned long result; + + /* This is solely to avoid accepting the leading + * space or "+" that strtoul would otherwise accept. + */ + if (!isxdigit(*str)) + break; + + result = strtoul(str, &end_ptr, 16); + + if ((end_ptr - str) < 1 || 2 < (end_ptr - str) || + (errno != 0) || + (0xFF < result)) + break; + + addr[i] = (unsigned char) result; + + if ((i == 5) && (*end_ptr == '\0')) + return 0; + if (*end_ptr != ':') + break; + + str = end_ptr + 1; + } + + return -1; +} + /* * Local variables: * indent-tabs-mode: nil diff --git a/src/util.h b/src/util.h index 25a3ab8319..62cef51218 100644 --- a/src/util.h +++ b/src/util.h @@ -85,4 +85,6 @@ int __virMacAddrCompare (const char *mac1, const char *mac2); void virSkipSpaces(const char **str); int virParseNumber(const char **str); +int virParseMacAddr(const char* str, unsigned char *addr); + #endif /* __VIR_UTIL_H__ */ diff --git a/src/xml.c b/src/xml.c index 475772c73e..16dddf555b 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1233,22 +1233,8 @@ virDomainParseXMLIfDesc(virConnectPtr conn ATTRIBUTE_UNUSED, virBufferAddLit(buf, "(vif "); if (mac != NULL) { - unsigned int addr[12]; - int tmp = sscanf((const char *) mac, - "%01x%01x:%01x%01x:%01x%01x:%01x%01x:%01x%01x:%01x%01x", - (unsigned int *) &addr[0], - (unsigned int *) &addr[1], - (unsigned int *) &addr[2], - (unsigned int *) &addr[3], - (unsigned int *) &addr[4], - (unsigned int *) &addr[5], - (unsigned int *) &addr[6], - (unsigned int *) &addr[7], - (unsigned int *) &addr[8], - (unsigned int *) &addr[9], - (unsigned int *) &addr[10], - (unsigned int *) &addr[11]); - if (tmp != 12 || strlen((const char *) mac) != 17) { + unsigned char addr[6]; + if (virParseMacAddr((const char*) mac, addr) == -1) { virXMLError(conn, VIR_ERR_INVALID_MAC, (const char *) mac, 0); goto error; }