/* * CORE * Copyright (c)2010-2012 the Boeing Company. * See the LICENSE file included in this distribution. * * author: Tom Goff * * vnode_chnl.c * * Functions for setting up a local UNIX socket to use as a control channel * for interacting with a network namespace. * */ #include #include #include #include #include #include #include "vnode_msg.h" #include "vnode_tlv.h" #include "vnode_chnl.h" #include "vnode_io.h" extern int verbose; int vnode_connect(const char *name) { int fd; struct sockaddr_un addr; #ifdef DEBUG WARNX("opening '%s'", name); #endif if (strlen(name) > sizeof(addr.sun_path) - 1) { WARNX("name too long: '%s'", name); return -1; } if ((fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0) { WARN("socket() failed"); return -1; } addr.sun_family = AF_UNIX; strcpy(addr.sun_path, name); if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { WARN("connect() failed for '%s'", name); close(fd); return -1; } if (set_cloexec(fd)) WARN("set_cloexec() failed for fd %d", fd); if (set_nonblock(fd)) WARN("set_nonblock() failed for fd %d", fd); return fd; } int vnode_listen(const char *name) { int fd; struct sockaddr_un addr; #ifdef DEBUG WARNX("opening '%s'", name); #endif if (strlen(name) > sizeof(addr.sun_path) - 1) { WARNX("name too long: '%s'", name); return -1; } if ((fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0) { WARN("socket() failed"); return -1; } unlink(name); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, name); if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { WARN("bind() failed for '%s'", name); close(fd); return -1; } /* to override umask */ if (chmod(name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) WARN("fchmod() failed for '%s'", name); if (listen(fd, 5) < 0) { WARN("listen() failed"); close(fd); return -1; } if (set_nonblock(fd)) WARN("set_nonblock() failed for fd %d", fd); return fd; }