[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] tap device and two nics
From: |
Don Kitchen |
Subject: |
[Qemu-devel] tap device and two nics |
Date: |
Tue, 4 Oct 2005 14:27:56 -0700 (PDT) |
Hi, it looks like I stirred up some change by asking about tun and tap.
(and definately it's important to know that "tun" is a tap device!)
In case anyone's interested, here is a tapdev2.c that I put together
to make use of two virtual nics as tap devices. Maybe also the script
setup will interest people for the regular tapdev.c. Apologies for the
clumsy way I use perl.
#define _GNU_SOURCE /* asprintf */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <net/if.h>
#include <linux/if_tun.h>
/* 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 ifr1;
struct ifreq ifr2;
struct passwd *p;
unsigned int i;
char *newargs[argc];
int fd1, fd2;
#define JUNKARGS 3
#define TWONICS 2
#define TAPFD 2
if (argc < 4) {
fprintf(stderr,
"Usage: tapdev2 switchuser logfile qemu <qemu
options>...\n");
exit(1);
}
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(&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[JUNKARGS-2]);
if (!p) {
fprintf(stderr, "No user '%s'\n", argv[JUNKARGS-2]);
exit(1);
}
setgroups(0, NULL);
setgid(p->pw_gid);
if (setuid(p->pw_uid) != 0) {
perror("setting uid");
exit(1);
}
/* arg# 0 1 2 3 4 5 6 7 8
old: tapdev2 user - qemu -hda blah ...
new: qemu -nics 2 -tun-fd x -tun-fd x -hda blah ...
*/
/* Insert -nics 2 -tun-fd, delete other args */
newargs[0] = argv[0+JUNKARGS];
asprintf(&newargs[1], "-nics");
asprintf(&newargs[2], "2");
asprintf(&newargs[TWONICS+1], "-tun-fd");
asprintf(&newargs[TWONICS+2], "%d", fd1);
asprintf(&newargs[TWONICS+TAPFD+1], "-tun-fd");
asprintf(&newargs[TWONICS+TAPFD+2], "%d", fd2);
for (i = JUNKARGS+1; i <= argc; i++)
newargs[i-JUNKARGS+TWONICS+TAPFD+TAPFD] = argv[i];
if (strcmp(argv[JUNKARGS-1], "-") == 0) {
printf("%s %s\n", ifr1.ifr_name, ifr2.ifr_name);
execvp(newargs[0], newargs);
exit(1);
}
switch (fork()) {
case 0: {
close(1);
close(2);
open(argv[JUNKARGS-1], O_WRONLY|O_APPEND);
open(argv[JUNKARGS-1], O_WRONLY|O_APPEND);
close(0);
execvp(newargs[0], newargs);
exit(1);
}
case -1:
perror("fork failed");
exit(1);
}
printf("%s %s\n", ifr1.ifr_name, ifr2.ifr_name);
exit(0);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] tap device and two nics,
Don Kitchen <=