58 #include <sys/types.h>
60 #include <sys/ioctl.h>
62 #include <sys/select.h>
70 #include <linux/if_tun.h>
74 #define CLONE_TUNTAP_NAME "/dev/net/tun"
77 static volatile int tuntap_fd = -1;
78 static int nonblocking = 0;
81 static int xemu_tuntap_set_nonblocking (
int fd,
int is_nonblocking )
84 if ((
flags = fcntl(fd, F_GETFL, 0)) == -1)
90 nonblocking = is_nonblocking;
91 return fcntl(fd, F_SETFL,
flags);
95 int xemu_tuntap_close (
void )
101 xemu_tuntap_set_nonblocking(fd, 0);
108 int xemu_tuntap_read (
void *buffer,
int min_size,
int max_size )
113 while (got < min_size) {
114 int r = read(tuntap_fd, buffer, max_size);
115 printf(
"ETH-LOW: read ret %d %s\n",
r,
r >= 0 ?
"NO-ERROR-CONDITION" : strerror(errno));
119 if (errno == EINTR) {
121 }
else if (errno == EAGAIN || errno == EWOULDBLOCK) {
123 return (got > 0) ? got : -2;
138 int xemu_tuntap_write (
void *buffer,
int size )
144 int w = write(tuntap_fd, buffer,
size);
148 if (errno == EINTR) {
150 }
else if (errno == EAGAIN || errno == EWOULDBLOCK) {
152 return (did > 0) ? did : -2;
167 int xemu_tuntap_select (
int flags,
int timeout_usecs )
172 struct timeval timeout, *timeout_p;
175 FD_SET(tuntap_fd, &fdsr);
176 FD_SET(tuntap_fd, &fdsw);
177 if (timeout_usecs >= 0) {
178 timeout.tv_sec = timeout_usecs / 1000000;
179 timeout.tv_usec = timeout_usecs % 1000000;
180 timeout_p = &timeout;
185 (
flags & XEMU_TUNTAP_SELECT_R) ? &fdsr : NULL,
186 (
flags & XEMU_TUNTAP_SELECT_W) ? &fdsw : NULL,
190 }
while (
r < 0 && errno == EINTR);
191 return (
r > 0) ? ((FD_ISSET(tuntap_fd, &fdsr) ? XEMU_TUNTAP_SELECT_R : 0) | (FD_ISSET(tuntap_fd, &fdsw) ? XEMU_TUNTAP_SELECT_W : 0)) :
r;
208 int xemu_tuntap_alloc (
const char *dev_in,
char *dev_out,
int dev_out_size,
unsigned int flags )
212 if (dev_in && strlen(dev_in) > IFNAMSIZ - 1)
217 memset(&ifr, 0,
sizeof(ifr));
219 switch (
flags & 0xFF) {
220 case XEMU_TUNTAP_IS_TAP:
221 ifr.ifr_flags = IFF_TAP;
223 case XEMU_TUNTAP_IS_TUN:
224 ifr.ifr_flags = IFF_TUN;
229 if (
flags & XEMU_TUNTAP_NO_PI)
230 ifr.ifr_flags |= IFF_NO_PI;
231 if ((fd = open(CLONE_TUNTAP_NAME, O_RDWR)) < 0)
233 if (dev_in && *dev_in)
234 strncpy(ifr.ifr_name, dev_in, IFNAMSIZ - 1);
237 if ((err = ioctl(fd, TUNSETIFF, (
void *) &ifr)) < 0) {
242 if (strlen(ifr.ifr_name) >= dev_out_size) {
246 strcpy(dev_out, ifr.ifr_name);
248 if (
flags & XEMU_TUNTAP_NONBLOCKING_IO) {
250 if (xemu_tuntap_set_nonblocking(fd, 1)) {