2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 * Copyright (C) 2002 Jeff Dike
6 * Based on the "tunctl" utility 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>
24 #include <sys/ioctl.h>
25 #include <linux/if_tun.h>
31 typedef struct private_iface_t private_iface_t
;
33 struct private_iface_t
{
34 /** public interface */
36 /** device name in guest (eth0) */
38 /** device name at host (tap0) */
40 /** mconsole for guest */
45 * Implementation of iface_t.get_guestif.
47 static char* get_guestif(private_iface_t
*this)
53 * Implementation of iface_t.get_hostif.
55 static char* get_hostif(private_iface_t
*this)
61 * destroy the tap device
63 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->hostif
, sizeof(ifr
.ifr_name
) - 1);
72 tap
= open(TAP_DEVICE
, O_RDWR
);
75 DBG1("unable to open tap device %s: %m", TAP_DEVICE
);
78 if (ioctl(tap
, TUNSETIFF
, &ifr
) < 0 ||
79 ioctl(tap
, TUNSETPERSIST
, 0) < 0)
81 DBG1("removing %s failed: %m", this->hostif
);
90 * create the tap device
92 static char* create_tap(private_iface_t
*this, char *guest
)
97 memset(&ifr
, 0, sizeof(ifr
));
98 ifr
.ifr_flags
= IFF_TAP
| IFF_NO_PI
;
99 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s-%s", guest
, this->guestif
);
101 tap
= open(TAP_DEVICE
, O_RDWR
);
104 DBG1("unable to open tap device %s: %m", TAP_DEVICE
);
107 if (ioctl(tap
, TUNSETIFF
, &ifr
) < 0 ||
108 ioctl(tap
, TUNSETPERSIST
, 1) < 0 ||
109 ioctl(tap
, TUNSETOWNER
, 0))
111 DBG1("creating new tap device failed: %m");
116 return strdup(ifr
.ifr_name
);
120 * Implementation of iface_t.destroy.
122 static void destroy(private_iface_t
*this)
124 this->mconsole
->del_iface(this->mconsole
, this->guestif
);
132 * create the iface instance
134 iface_t
*iface_create(char *guest
, char *guestif
, mconsole_t
*mconsole
)
136 private_iface_t
*this = malloc_thing(private_iface_t
);
138 this->public.get_hostif
= (char*(*)(iface_t
*))get_hostif
;
139 this->public.get_guestif
= (char*(*)(iface_t
*))get_guestif
;
140 this->public.destroy
= (void*)destroy
;
142 this->mconsole
= mconsole
;
143 this->guestif
= strdup(guestif
);
144 this->hostif
= create_tap(this, guest
);
145 if (this->hostif
== NULL
)
152 if (!this->mconsole
->add_iface(this->mconsole
, this->guestif
, this->hostif
))
154 DBG1("creating interface '%s' in guest failed", this->guestif
);
161 return &this->public;