diff --git a/vl.c b/vl.c --- a/vl.c +++ b/vl.c @@ -1652,7 +1652,7 @@ static void tun_add_read_packet(NetDrive static int net_tun_init(NetDriverState *nd) { int pid, status; - char *args[3]; + char *args[4]; char **parg; nd->fd = tun_open(nd->ifname, sizeof(nd->ifname)); @@ -1663,9 +1663,13 @@ static int net_tun_init(NetDriverState * pid = fork(); if (pid >= 0) { if (pid == 0) { + char MAC[24]; + memset(MAC,0,24); + sprintf(MAC, "%X.%X.%X.%X.%X.%X", nd->macaddr[0],nd->macaddr[1], nd->macaddr[2], nd->macaddr[3],nd->macaddr[4],nd->macaddr[5]); parg = args; *parg++ = network_script; *parg++ = nd->ifname; + *parg++ = MAC; *parg++ = NULL; execv(network_script, args); exit(1); @@ -2755,7 +2759,9 @@ void help(void) "\n" "Network options:\n" "-nics n simulate 'n' network cards [default=1]\n" - "-macaddr addr set the mac address of the first interface\n" + "-macaddr addr[,addr,addr ..] set the mac address(es) of the guest\n" + " if only one mac is specified it is used as \n" + " the mac address of the first interface \n" "-n script set tap/tun network init script [default=%s]\n" "-tun-fd fd use this fd as already opened tap/tun interface\n" #ifdef CONFIG_SLIRP @@ -3018,6 +3024,7 @@ int main(int argc, char **argv) int cyls, heads, secs, translation; int start_emulation = 1; uint8_t macaddr[6]; + uint8_t macaddrs[MAX_NICS][6]; int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; int optind; const char *r, *optarg; @@ -3075,7 +3082,7 @@ int main(int argc, char **argv) macaddr[3] = 0x12; macaddr[4] = 0x34; macaddr[5] = 0x56; - + optind = 1; for(;;) { if (optind >= argc) @@ -3217,33 +3224,80 @@ int main(int argc, char **argv) code_copy_enabled = 0; break; case QEMU_OPTION_nics: - nb_nics = atoi(optarg); - if (nb_nics < 0 || nb_nics > MAX_NICS) { - fprintf(stderr, "qemu: invalid number of network interfaces\n"); - exit(1); - } - break; + { + int i = 0, j = -1; + nb_nics = atoi(optarg); + if (nb_nics < 0 || nb_nics > MAX_NICS) { + fprintf(stderr, "qemu: invalid number of network interfaces\n"); + exit(1); + } + /* set the defaults */ + while (j++ < nb_nics-1) { + printf("setting default for NIC %d",j); + for(i = 0; i < 6; i++) { + if (i == 5) + macaddrs[j][i] = macaddr[i]+j; + else + macaddrs[j][i] = macaddr[i]; + } + } + } + break; case QEMU_OPTION_macaddr: { - const char *p; - int i; - p = optarg; - for(i = 0; i < 6; i++) { - macaddr[i] = strtol(p, (char **)&p, 16); - if (i == 5) { - if (*p != '\0') - goto macaddr_error; - } else { - if (*p != ':') { - macaddr_error: - fprintf(stderr, "qemu: invalid syntax for ethernet address\n"); - exit(1); - } - p++; - } - } - } - break; + char *macs[MAX_NICS]; + char *amac; + const char *p; + char *p2; + int i, j = 0, first_mac_seen = 0; + p = optarg; + + memset(macs,0,sizeof(macs)); + j=-1; + /* tokenize: unfortunately strtok is too smart for me */ + while(p!=NULL) { + j++; + macs[j] = (char *)p; + p2 = strstr(p, ","); + if (p2 == NULL) + break; + *p2 = 0; + p = p2+1; + } + + j = -1; + while (j++ < nb_nics-1) { + amac = macs[j]; + if (amac == NULL || !strlen(amac)) { + for(i = 0; i < 6; i++) { + if (i == 5) + macaddrs[j][i] = macaddr[i]+j; + else + macaddrs[j][i] = macaddr[i]; + } + + continue; + } + + for(i = 0; i < 6; i++) { + macaddrs[j][i] = strtol(amac, (char **)&amac, 16); + if (*amac != ':' && i != 5 ) { + fprintf(stderr, "qemu: invalid syntax for ethernet address\n"); + exit(1); + } + amac++; + } + + if(!first_mac_seen) { + for(i = 0; i < 6; i++) { + macaddr[i] = macaddrs[j][i]; + } + + first_mac_seen = 1; + } + } + } + break; #ifdef CONFIG_SLIRP case QEMU_OPTION_tftp: tftp_prefix = optarg; @@ -3443,13 +3497,12 @@ int main(int argc, char **argv) for(i = 0; i < nb_nics; i++) { NetDriverState *nd = &nd_table[i]; nd->index = i; - /* init virtual mac address */ - nd->macaddr[0] = macaddr[0]; - nd->macaddr[1] = macaddr[1]; - nd->macaddr[2] = macaddr[2]; - nd->macaddr[3] = macaddr[3]; - nd->macaddr[4] = macaddr[4]; - nd->macaddr[5] = macaddr[5] + i; + nd->macaddr[0] = macaddrs[i][0]; + nd->macaddr[1] = macaddrs[i][1]; + nd->macaddr[2] = macaddrs[i][2]; + nd->macaddr[3] = macaddrs[i][3]; + nd->macaddr[4] = macaddrs[i][4]; + nd->macaddr[5] = macaddrs[i][5]; switch(net_if_type) { #if defined(CONFIG_SLIRP) case NET_IF_USER: