From 4a0ba80d62c0d8aeb5c9857749659fdf716c380a Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20Graber?= Date: Fri, 9 Aug 2013 11:32:55 +0200 Subject: [PATCH] Replace mktemp() by a new mkifname() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Using mktemp() leads to build time warnings and isn't actually appropriate for what we want to do as it's checking for the existence of a file and not a network interface. Replace those calls by an equivalent mkifname() function which uses the same template as mktemp but instead checks for existing network interfaces. Signed-off-by: Stéphane Graber Acked-by: Serge Hallyn --- src/lxc/conf.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 53c05e667..1bd8c1454 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #if HAVE_PTY_H #include @@ -272,6 +274,64 @@ static struct caps_opt caps_opt[] = { static struct caps_opt caps_opt[] = {}; #endif +static char padchar[] = +"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +static char *mkifname(char *template) +{ + char *name = NULL; + int i = 0; + FILE *urandom; + unsigned int seed; + char randstate[2048]; + struct ifaddrs *ifaddr, *ifa; + int ifexists = 0; + + /* Get all the network interfaces */ + getifaddrs(&ifaddr); + + /* Initialize the random number generator */ + urandom = fopen ("/dev/urandom", "r"); + if (urandom != NULL) { + if (fread (&seed, sizeof(seed), 1, urandom) <= 0) + seed = time(0); + fclose(urandom); + } + else + seed = time(0); + initstate(seed, randstate, 256); + + /* Generate random names until we find one that doesn't exist */ + while(1) { + ifexists = 0; + name = strdup(template); + + if (name == NULL) + return NULL; + + for (i = 0; i < strlen(name); i++) { + if (name[i] == 'X') { + name[i] = padchar[random() % (strlen(padchar) - 1)]; + } + } + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (strcmp(ifa->ifa_name, name) == 0) { + ifexists = 1; + break; + } + } + + if (ifexists == 0) + break; + + free(name); + } + + freeifaddrs(ifaddr); + return name; +} + static int run_buffer(char *buffer) { FILE *f; @@ -2174,13 +2234,13 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd ERROR("veth1 name too long"); return -1; } - veth1 = mktemp(veth1buf); + veth1 = mkifname(veth1buf); /* store away for deconf */ memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ); } snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX"); - veth2 = mktemp(veth2buf); + veth2 = mkifname(veth2buf); if (!strlen(veth1) || !strlen(veth2)) { ERROR("failed to allocate a temporary name"); @@ -2286,7 +2346,7 @@ static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n if (err >= sizeof(peerbuf)) return -1; - peer = mktemp(peerbuf); + peer = mkifname(peerbuf); if (!strlen(peer)) { ERROR("failed to make a temporary name"); return -1; -- 2.47.2