Ok, here goes as per discussion...

Please apply.
This patch is intended for allowing automated clever scripting
for networking (tuntap only).

It does the following:
1) extends syntax for specifying the macaddr

Examples:

a) "-nics 2"
Which will give you the
    0x52:0x54:0x00:0x12:0x34:0x56 for the first nic
and 0x52:0x54:0x00:0x12:0x34:0x57 for the second nic

b) "-nics 3 -macaddr 00:11:a:0:1:39"

Which will give first NIC 00:11:a:0:1:39, the second 00:11:a:0:1:3A
and the third 00:11:a:0:1:3B.

c) "-nics 2 -macaddr 00:11:a:0:2:19,00:11:a:0:1:19"
Which will give first NIC 00:11:a:0:2:19, the second 00:11:a:0:1:19

d) "-nics 3 -macaddr 00:11:a:0:1:39,00:11:a:0:3:19"

which will give the first NIC a MAC of 00:11:a:0:1:39 the second
00:11:a:0:3:19 and the last 00:11:a:0:1:3B

2) In addition to receiving the tun device name as $1, the
net setup script now receives $2 as the guest MAC address.
One could encode a byte or two in this MAC address for example as a
message to the host script so that it can do something like prepare a
route etc

cheers,
jamal
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:
_______________________________________________
Qemu-devel mailing list
[EMAIL PROTECTED]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to