core-extra/netns/vnode_chnl.c

117 lines
2.1 KiB
C

/*
* CORE
* Copyright (c)2010-2012 the Boeing Company.
* See the LICENSE file included in this distribution.
*
* author: Tom Goff <thomas.goff@boeing.com>
*
* vnode_chnl.c
*
* Functions for setting up a local UNIX socket to use as a control channel
* for interacting with a network namespace.
*
*/
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/socket.h>
#include <sys/un.h>
#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;
}