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