qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] new tundev.c/tapdev.c plus two nics


From: Don Kitchen
Subject: [Qemu-devel] new tundev.c/tapdev.c plus two nics
Date: Wed, 18 Jan 2006 20:53:00 -0800 (PST)

With the new command-line syntax for 0.8.0 I've modified the program that
opens up tap devices (tundev.c) accordingly. The diffs are below for both
tundev.c and another version that opens up two nics, tundev2.c.

I am not providing the whole program because its license is not stated.
If Fabrice can give a clarification of the license since he is
distributing it himself, then great and anyone is welcome to distribute
the changed version instead without worry.

Oh and for tapdev2 sorry about suggesting perl. Sometimes you can't think
how to use anything but the big hammer.

--- tundev.c    2006-01-17 20:09:28.000000000 -0800
+++ tapdev.c    2006-01-12 22:52:37.000000000 -0800
@@ -13,7 +13,23 @@
 #include <linux/if_tun.h>
 
 /* Tiny code to open tap/tun device, and hand the fd to qemu.
-   Run as root, drops to given user. */
+   Run as root, drops to given user. 
+
+   Based on tundev.c freely distributed at in
+   http://fabrice.bellard.free.fr/qemu/tetrinet.tar.gz
+   Assuming that code is available under BSD or GPL license, these
+   modifications are under GPL.
+
+   Linux usage:
+
+DEV=`./tapdev root log /usr/bin/qemu ... &`
+/sbin/ifconfig $DEV 0.0.0.0 promisc up
+/sbin/ifconfig br0 >& /dev/null || (/usr/sbin/brctl addbr br0 && /sbin/ifconfig
+br0 up)
+/usr/sbin/brctl addif br0 $DEV
+echo br0 device $DEV
+
+*/
 int main(int argc, char *argv[])
 {
        struct ifreq ifr;
@@ -22,9 +38,12 @@
        char *newargs[argc];
        int fd;
 
-       if (argc < 4) {
+#define JUNKARGS 3
+#define TAPFDSTUFF 4 /* size of -net nic -net tap,fd=x */
+
+       if (argc < JUNKARGS+1) {
                fprintf(stderr,
-                       "Usage: switch user logfile qemu <qemu options>...\n");
+                       "Usage: tapdev switchuser logfile qemu <qemu 
options>...\n");
                exit(1);
        }
 
@@ -36,16 +55,16 @@
 
        memset(&ifr, 0, sizeof(ifr));
        ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-       strncpy(ifr.ifr_name, "tun%d", IFNAMSIZ);
+       strncpy(ifr.ifr_name, "tap%d", IFNAMSIZ);
        if (ioctl(fd, TUNSETIFF, (void *) &ifr) != 0) {
                perror("Could not get tun device");
                exit(1);
        }
 
        /* Set userid. */
-       p = getpwnam(argv[1]);
+       p = getpwnam(argv[JUNKARGS-2]);
        if (!p) {
-               fprintf(stderr, "No user '%s'\n", argv[1]);
+               fprintf(stderr, "No user '%s'\n", argv[JUNKARGS-2]);
                exit(1);
        }
        setgroups(0, NULL);
@@ -55,14 +74,22 @@
                exit(1);
        }
 
-       /* Insert -tun-fd, delete other args */
-       newargs[0] = argv[3];
-       asprintf(&newargs[1], "-tun-fd");
-       asprintf(&newargs[2], "%d", fd);
-       for (i = 4; i <= argc; i++)
-               newargs[i-1] = argv[i];
+/* arg# 0       1     2   3      4        5     6    7
+   old: tapdev  user  -   qemu   -hda     blah  ...
+
+   new: qemu    -net  nic -net   tap,fd=x -hda  blah ...
+*/
+
+       /* Insert -net nic -net tap,fd=x, delete other args */
+       newargs[0] = argv[0+JUNKARGS];
+       asprintf(&newargs[1], "-net");
+       asprintf(&newargs[2], "nic");
+       asprintf(&newargs[3], "-net");
+       asprintf(&newargs[4], "tap,fd=%d", fd);
+       for (i = JUNKARGS+1; i <= argc; i++)
+               newargs[i-JUNKARGS+TAPFDSTUFF] = argv[i];
                
-       if (strcmp(argv[2], "-") == 0) {
+       if (strcmp(argv[JUNKARGS-1], "-") == 0) {
                printf("%s\n", ifr.ifr_name);
                execvp(newargs[0], newargs);
                exit(1);
@@ -72,8 +99,8 @@
        case 0: {
                close(1);
                close(2);
-               open(argv[2], O_WRONLY|O_APPEND);
-               open(argv[2], O_WRONLY|O_APPEND);
+               open(argv[JUNKARGS-1], O_CREAT|O_WRONLY|O_APPEND);
+               open(argv[JUNKARGS-1], O_WRONLY|O_APPEND);
                close(0);
                execvp(newargs[0], newargs);
                exit(1);

-----SNIP------



--- tundev.c    2006-01-17 20:09:28.000000000 -0800
+++ tapdev2.c   2006-01-12 22:52:37.000000000 -0800
@@ -12,40 +12,75 @@
 #include <net/if.h>
 #include <linux/if_tun.h>
 
-/* Tiny code to open tap/tun device, and hand the fd to qemu.
-   Run as root, drops to given user. */
+/* Tiny code to open two tap devices, and hand the fds to qemu.
+   Run as root, drops to given user. 
+
+   Based on tundev.c freely distributed at in
+   http://fabrice.bellard.free.fr/qemu/tetrinet.tar.gz
+   Assuming that code is available under BSD or GPL license, these
+   modifications are under GPL.
+
+   Linux usage:
+
+DEVS=`./tapdev2 root log /usr/bin/qemu ... &`
+DEV1=`echo $DEVS | perl -pe 's/^([^ ]*) *([^ ]*)/$1/'`
+DEV2=`echo $DEVS | perl -pe 's/^([^ ]*) *([^ ]*)/$2/'`
+/sbin/ifconfig $DEV1 0.0.0.0 promisc up
+/sbin/ifconfig $DEV2 0.0.0.0 promisc up
+/sbin/ifconfig br0 >& /dev/null || (/usr/sbin/brctl addbr br0 && /sbin/ifconfig
+br0 up)
+/usr/sbin/brctl addif br0 $DEV1
+echo br0 device $DEV1   other device $DEV2
+
+*/
 int main(int argc, char *argv[])
 {
-       struct ifreq ifr;
+       struct ifreq ifr1;
+       struct ifreq ifr2;
        struct passwd *p;
        unsigned int i;
        char *newargs[argc];
-       int fd;
+       int fd1, fd2;
+
+#define JUNKARGS 3
+#define TAPFDSTUFF 4 /* size of -net nic -net tap,fd=x */
 
-       if (argc < 4) {
+       if (argc < JUNKARGS+1) {
                fprintf(stderr,
-                       "Usage: switch user logfile qemu <qemu options>...\n");
+                       "Usage: tapdev2 switchuser logfile qemu <qemu 
options>...\n");
                exit(1);
        }
 
-       fd = open("/dev/net/tun", O_RDWR);
-       if (fd < 0) {
-               perror("Could not open /dev/net/tun");
+       fd1 = open("/dev/net/tun", O_RDWR);
+       if (fd1 < 0) {
+               perror("1 Could not open /dev/net/tun");
+               exit(1);
+       }
+       fd2 = open("/dev/net/tun", O_RDWR);
+       if (fd2 < 0) {
+               perror("2 Could not open /dev/net/tun");
                exit(1);
        }
 
-       memset(&ifr, 0, sizeof(ifr));
-       ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-       strncpy(ifr.ifr_name, "tun%d", IFNAMSIZ);
-       if (ioctl(fd, TUNSETIFF, (void *) &ifr) != 0) {
-               perror("Could not get tun device");
+       memset(&ifr1, 0, sizeof(ifr1));
+       ifr1.ifr_flags = IFF_TAP | IFF_NO_PI;
+       strncpy(ifr1.ifr_name, "tap%d", IFNAMSIZ);
+       memset(&ifr2, 0, sizeof(ifr2));
+       ifr2.ifr_flags = IFF_TAP | IFF_NO_PI;
+       strncpy(ifr2.ifr_name, "tap%d", IFNAMSIZ);
+       if (ioctl(fd1, TUNSETIFF, (void *) &ifr1) != 0) {
+               perror("1 Could not get tun device");
+               exit(1);
+       }
+       if (ioctl(fd2, TUNSETIFF, (void *) &ifr2) != 0) {
+               perror("2 Could not get tun device");
                exit(1);
        }
 
        /* Set userid. */
-       p = getpwnam(argv[1]);
+       p = getpwnam(argv[JUNKARGS-2]);
        if (!p) {
-               fprintf(stderr, "No user '%s'\n", argv[1]);
+               fprintf(stderr, "No user '%s'\n", argv[JUNKARGS-2]);
                exit(1);
        }
        setgroups(0, NULL);
@@ -55,15 +90,28 @@
                exit(1);
        }
 
-       /* Insert -tun-fd, delete other args */
-       newargs[0] = argv[3];
-       asprintf(&newargs[1], "-tun-fd");
-       asprintf(&newargs[2], "%d", fd);
-       for (i = 4; i <= argc; i++)
-               newargs[i-1] = argv[i];
+/* arg# 0       1     2   3      4        5     6    7    8         9    10
+   old: tapdev2 user  -   qemu   -hda     blah  ...
+
+   new: qemu    -net  nic -net   tap,fd=x -net  nic  -net tap,fd=x  -hda blah 
...
+*/
+
+       /* Insert -net nic -net tap,fd=x, delete other args */
+       newargs[0] = argv[0+JUNKARGS];
+       asprintf(&newargs[1], "-net");
+       asprintf(&newargs[2], "nic");
+       asprintf(&newargs[3], "-net");
+       asprintf(&newargs[4], "tap,fd=%d", fd1);
+       asprintf(&newargs[TAPFDSTUFF+1], "-net");
+        asprintf(&newargs[TAPFDSTUFF+2], "nic");
+       asprintf(&newargs[TAPFDSTUFF+3], "-net");
+        asprintf(&newargs[TAPFDSTUFF+4], "tap,fd=%d", fd2);
+
+       for (i = JUNKARGS+1; i <= argc; i++)
+               newargs[i-JUNKARGS+TAPFDSTUFF+TAPFDSTUFF] = argv[i];
                
-       if (strcmp(argv[2], "-") == 0) {
-               printf("%s\n", ifr.ifr_name);
+       if (strcmp(argv[JUNKARGS-1], "-") == 0) {
+               printf("%s %s\n", ifr1.ifr_name, ifr2.ifr_name);
                execvp(newargs[0], newargs);
                exit(1);
        }
@@ -72,8 +120,8 @@
        case 0: {
                close(1);
                close(2);
-               open(argv[2], O_WRONLY|O_APPEND);
-               open(argv[2], O_WRONLY|O_APPEND);
+               open(argv[JUNKARGS-1], O_CREAT|O_WRONLY|O_APPEND);
+               open(argv[JUNKARGS-1], O_WRONLY|O_APPEND);
                close(0);
                execvp(newargs[0], newargs);
                exit(1);
@@ -82,6 +130,6 @@
                perror("fork failed");
                exit(1);
        }
-       printf("%s\n", ifr.ifr_name);
+       printf("%s %s\n", ifr1.ifr_name, ifr2.ifr_name);
        exit(0);
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]