1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* 2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * dhcpcd - DHCP client daemon 3e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Copyright (c) 2006-2009 Roy Marples <roy@marples.name> 4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * All rights reserved 5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Redistribution and use in source and binary forms, with or without 7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * modification, are permitted provided that the following conditions 8e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * are met: 9e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 1. Redistributions of source code must retain the above copyright 10e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer. 11e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 2. Redistributions in binary form must reproduce the above copyright 12e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer in the 13e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * documentation and/or other materials provided with the distribution. 14e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 15e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * SUCH DAMAGE. 26e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */ 27e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 28e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <linux/socket.h> 29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/stat.h> 30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/un.h> 31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <errno.h> 33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdio.h> 34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdlib.h> 35e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <string.h> 36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <time.h> 37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <unistd.h> 38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "config.h" 40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "common.h" 41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "dhcpcd.h" 42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "control.h" 43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "eloop.h" 44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int fd = -1; 46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic char buffer[1024]; 47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic char *argvp[255]; 48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstruct sockaddr_un sun; 50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstruct fd_list *fds = NULL; 51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void 53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtremove_control_data(void *arg) 54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct fd_list *l, *last = NULL; 56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (l = fds; l != NULL; l = l->next) { 58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (l == arg) { 59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt close(l->fd); 60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt delete_event(l->fd); 61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (last == NULL) 62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt fds = l->next; 63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt last->next = l->next; 65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(l); 66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt last = l; 69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void 73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidthandle_control_data(void *arg) 74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct fd_list *l = arg; 76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ssize_t bytes; 77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int argc; 78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *e, *p; 79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char **ap; 80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt bytes = read(l->fd, buffer, sizeof(buffer) - 1); 82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (bytes == -1 || bytes == 0) { 83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt remove_control_data(l); 84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt buffer[bytes] = '\0'; 87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = buffer; 88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt e = buffer + bytes; 89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt argc = 0; 90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ap = argvp; 91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (p < e && (size_t)argc < sizeof(argvp)) { 92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt argc++; 93e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *ap++ = p; 94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += strlen(p) + 1; 95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 96e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt handle_args(l, argc, argvp); 97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* ARGSUSED */ 100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void 101e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidthandle_control(_unused void *arg) 102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct sockaddr_un run; 104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt socklen_t len; 105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct fd_list *l; 106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int f; 107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 108e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt len = sizeof(run); 109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((f = accept(fd, (struct sockaddr *)&run, &len)) == -1) 110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l = xmalloc(sizeof(*l)); 112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l->fd = f; 113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l->listener = 0; 114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l->next = fds; 115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt fds = l; 116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_event(l->fd, handle_control_data, l); 117e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int 120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtmake_sock(void) 121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 122e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memset(&sun, 0, sizeof(sun)); 125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sun.sun_family = AF_UNIX; 126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt strlcpy(sun.sun_path, CONTROLSOCKET, sizeof(sun.sun_path)); 127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return sizeof(sun.sun_family) + strlen(sun.sun_path) + 1; 128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstart_control(void) 132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int len; 134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((len = make_sock()) == -1) 136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 137e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt unlink(CONTROLSOCKET); 138e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (bind(fd, (struct sockaddr *)&sun, len) == -1 || 139e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt chmod(CONTROLSOCKET, 140e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) == -1 || 141e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt set_cloexec(fd) == -1 || 142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt set_nonblock(fd) == -1 || 143e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt listen(fd, sizeof(fds)) == -1) 144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt close(fd); 146e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_event(fd, handle_control, NULL); 149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return fd; 150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 152e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstop_control(void) 154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 155e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int retval = 0; 156e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct fd_list *l, *ll; 157e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 158e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt delete_event(fd); 159e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (shutdown(fd, SHUT_RDWR) == -1) 160e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt retval = 1; 161e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt fd = -1; 162e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (unlink(CONTROLSOCKET) == -1) 163e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt retval = -1; 164e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 165e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l = fds; 166e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (l != NULL) { 167e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ll = l->next; 168e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt delete_event(l->fd); 169e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt shutdown(l->fd, SHUT_RDWR); 170e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt free(l); 171e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt l = ll; 172e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 173e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 174e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return retval; 175e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 176e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 177e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 178e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtopen_control(void) 179e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 180e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int len; 181e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 182e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((len = make_sock()) == -1) 183e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 184e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return connect(fd, (struct sockaddr *)&sun, len); 185e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 186e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 187e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtint 188e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsend_control(int argc, char * const *argv) 189e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 190e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *p = buffer; 191e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int i; 192e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt size_t len; 193e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 194e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (argc > 255) { 195e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = ENOBUFS; 196e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 197e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 198e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for (i = 0; i < argc; i++) { 199e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt len = strlen(argv[i]) + 1; 200e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((p - buffer) + len > sizeof(buffer)) { 201e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = ENOBUFS; 202e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return -1; 203e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 204e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(p, argv[i], len); 205e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += len; 206e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 207e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return write(fd, buffer, p - buffer); 208e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 209