Index: src/util.c =================================================================== RCS file: /data/cvs/libvirt/src/util.c,v retrieving revision 1.25 diff -u -r1.25 util.c --- src/util.c 3 Mar 2008 20:39:52 -0000 1.25 +++ src/util.c 19 Mar 2008 06:29:15 -0000 @@ -688,6 +688,53 @@ return (c > d ? 1 : c < d ? -1 : 0); } +/** + * virParseMacAddr: + * @str: pointer to the char used + * @addr: MAC address + * + * Parse a MAC address + * + * Returns 0 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 (*end_ptr != ':') { + if (i == 5 && *end_ptr == '\0') + return 0; + + break; + } + + str = end_ptr + 1; + } + + return -1; +} + /* * Local variables: * indent-tabs-mode: nil Index: src/util.h =================================================================== RCS file: /data/cvs/libvirt/src/util.h,v retrieving revision 1.13 diff -u -r1.13 util.h --- src/util.h 27 Feb 2008 16:14:44 -0000 1.13 +++ src/util.h 19 Mar 2008 06:29:15 -0000 @@ -85,4 +85,6 @@ void virSkipSpaces(const char **str); int virParseNumber(const char **str); +int virParseMacAddr(const char* str, unsigned char *addr); + #endif /* __VIR_UTIL_H__ */ Index: src/xml.c =================================================================== RCS file: /data/cvs/libvirt/src/xml.c,v retrieving revision 1.113 diff -u -r1.113 xml.c --- src/xml.c 27 Feb 2008 04:35:08 -0000 1.113 +++ src/xml.c 19 Mar 2008 06:29:16 -0000 @@ -1233,22 +1233,8 @@ 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; }