2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 * Copyright (C) 2002 Jeff Dike
6 * Based on the "tunctl" utlity from Jeff Dike.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 #include <sys/types.h>
23 #include <sys/ioctl.h>
24 #include <linux/if_tun.h>
30 typedef struct private_iface_t private_iface_t
;
32 struct private_iface_t
{
33 /** public interface */
35 /** device name in guest (eth0) */
37 /** device name at host (tap0) */
39 /** tap device handle to manage taps */
41 /** mconsole for guest */
46 * Implementation of iface_t.get_guest.
48 static char* get_guest(private_iface_t
*this)
54 * Implementation of iface_t.get_host.
56 static char* get_host(private_iface_t
*this)
62 * destroy the tap device
64 static bool destroy_tap(private_iface_t
*this)
68 memset(&ifr
, 0, sizeof(ifr
));
69 ifr
.ifr_flags
= IFF_TAP
| IFF_NO_PI
;
70 strncpy(ifr
.ifr_name
, this->host
, sizeof(ifr
.ifr_name
) - 1);
72 if (ioctl(this->tap
, TUNSETIFF
, &ifr
) < 0 ||
73 ioctl(this->tap
, TUNSETPERSIST
, 0) < 0)
75 DBG1("removing %s failed: %m", this->host
);
82 * create the tap device
84 static char* create_tap(private_iface_t
*this)
88 memset(&ifr
, 0, sizeof(ifr
));
89 ifr
.ifr_flags
= IFF_TAP
| IFF_NO_PI
;
91 if (ioctl(this->tap
, TUNSETIFF
, &ifr
) < 0 ||
92 ioctl(this->tap
, TUNSETPERSIST
, 1) < 0)
94 DBG1("creating new tap device failed: %m");
97 return strdup(ifr
.ifr_name
);
101 * Implementation of iface_t.destroy.
103 static void destroy(private_iface_t
*this)
105 this->mconsole
->del_iface(this->mconsole
, this->guest
);
114 * create the iface instance
116 iface_t
*iface_create(char *guest
, mconsole_t
*mconsole
)
118 private_iface_t
*this = malloc_thing(private_iface_t
);
120 this->public.get_host
= (char*(*)(iface_t
*))get_host
;
121 this->public.get_guest
= (char*(*)(iface_t
*))get_guest
;
122 this->public.destroy
= (void*)destroy
;
124 this->mconsole
= mconsole
;
125 this->tap
= open(TAP_DEVICE
, O_RDWR
);
128 DBG1("unable to open tap device %s: %m", TAP_DEVICE
);
132 this->guest
= strdup(guest
);
133 this->host
= create_tap(this);
134 if (this->host
== NULL
)
142 if (!this->mconsole
->add_iface(this->mconsole
, this->guest
, this->host
))
144 DBG1("creating interface '%s' in guest failed", this->guest
);
152 return &this->public;