Hello all. Attached is an other patch (against the CVS) to allow for more flexible mac address parsing from the command line. Specifically it allows:
-using the '-' as separator (as Windows uses it) -using no separator at all (just 12 hexadecimal characters in a row) - again Windows uses this style in some configuration dialogs -using an offset from the default address (like +2 or -10). This is useful for quickly bringing up a virtual lan without having to remember the base macaddr, you just specify different offsets (an other option would be to use mac addresses like 12:34:56:78:9A:BC which are easy to remember, however I found that WinXP for example does not react well - duplicate packets, no conectivity at the IP level although the ARP level is fine, etc - if the OUI - the first 3 bytes of the mac address - is incorrect) Also, there was a suggestion on the list some time ago to use the crc of the path to the disk image as part of the macaddr to ensure uniqueness. If people feel that this would be useful, I'm happy to provide a patch. Best regards ___________________________________________________________ Yahoo! Mail is the world's favourite email. Don't settle for less, sign up for your free account today http://uk.rd.yahoo.com/evt=44106/*http://uk.docs.yahoo.com/mail/winter07.html
Index: vl.c =================================================================== RCS file: /sources/qemu/qemu/vl.c,v retrieving revision 1.317 diff -u -r1.317 vl.c --- vl.c 29 Jun 2007 23:26:08 -0000 1.317 +++ vl.c 1 Jul 2007 11:42:53 -0000 @@ -3020,21 +3020,66 @@ } } +static inline int is_hex_char(char c) +{ + return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9'); +} + static int parse_macaddr(uint8_t *macaddr, const char *p) { - int i; - for(i = 0; i < 6; i++) { - macaddr[i] = strtol(p, (char **)&p, 16); - if (i == 5) { - if (*p != '\0') - return -1; - } else { - if (*p != ':') - return -1; - p++; - } - } - return 0; + if (NULL == p) + return -1; + + if ('-' == *p || '+' == *p) + { + /* an offset relative to the default address */ + char *endptr; + int offset = strtol(p, (char**)&endptr, 0); + if ('\0' != *endptr) + return -1; + /* convert the macaddr to 64 bit num, add the offset and convert it back */ + uint64_t macaddr_l = ((uint64_t)macaddr[0] << 40UL) + ((uint64_t)macaddr[1] << 32UL) + + ((uint64_t)macaddr[2] << 24UL) + ((uint64_t)macaddr[3] << 16UL) + ((uint64_t)macaddr[4] << 8UL) + + ((uint64_t)macaddr[5]); + macaddr_l += offset; + macaddr[0] = (uint8_t)((macaddr_l >> 40UL) & 0xFF); + macaddr[1] = (uint8_t)((macaddr_l >> 32UL) & 0xFF); + macaddr[2] = (uint8_t)((macaddr_l >> 24UL) & 0xFF); + macaddr[3] = (uint8_t)((macaddr_l >> 16UL) & 0xFF); + macaddr[4] = (uint8_t)((macaddr_l >> 8UL) & 0xFF); + macaddr[5] = (uint8_t)((macaddr_l >> 0UL) & 0xFF); + } + else if (is_hex_char(*p)) + { + /* a full mac address - hopefully :) */ + int mac_i = 0; + while ('\0' != *p) + { + /* skip separator chars */ + while ( ('\0' != *p) && (':' == *p || '-' == *p) ) p++; + char hex_chars[3]; hex_chars[2] = '\0'; + /* get two hexdec chars and parse it */ + if ( is_hex_char(*p) && is_hex_char(*(p+1)) ) + { + hex_chars[0] = *p; hex_chars[1] = *(p+1); + macaddr[mac_i] = strtol(hex_chars, NULL, 16); + p += 2; mac_i++; + /* the string should contain only 6 pairs */ + if (mac_i >= 6 && *p != '\0') + return -1; + } + else + { + return -1; + } + } + } + else + { + /* error, unexpected character */ + return -1; + } + return 0; } static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)