From 6e9d856a9d1de4fb8229f54bff7635a59aeb6823 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" <nicholas@kain.us> Date: Fri, 20 Jul 2012 14:56:17 -0400 Subject: [PATCH] Code cleanup. Create struct ifchd_client and pull all of the global static arrays that are indexed by the socket slot index into an array of struct ifchd_clients. --- ifchd/ifchd-defines.h | 27 ++++- ifchd/ifchd.c | 249 +++++++++++++++++++++--------------------- ifchd/linux.c | 74 +++++-------- 3 files changed, 177 insertions(+), 173 deletions(-) diff --git a/ifchd/ifchd-defines.h b/ifchd/ifchd-defines.h index a62e43d..3377ec6 100644 --- a/ifchd/ifchd-defines.h +++ b/ifchd/ifchd-defines.h @@ -4,10 +4,35 @@ #include "defines.h" #define PID_FILE_DEFAULT "/var/run/ifchd.pid" -#define IFCHD_VERSION "0.8" +#define IFCHD_VERSION "0.9" #define MAX_BUF 1024 #define SOCK_QUEUE 2 #define CONN_TIMEOUT 60 +#include <net/if.h> +#include "strlist.h" +struct ifchd_client { + /* Socket fd, current state, and idle time for connection. */ + int fd; + int state; + int idle_time; + /* + * Per-connection pointers into the command lists. Respectively, the + * topmost item on the list, the current item, and the last item on the + * list. + */ + strlist_t *head, *curl, *last; + /* Lists of nameservers and search domains. Unfortunately they must be + * per-connection, since otherwise seperate clients could race against + * one another to write out unpredictable data. + */ + strlist_t *namesvrs, *domains; + + /* Symbolic name of the interface associated with a connection. */ + char ifnam[IFNAMSIZ]; + /* Per-connection buffer. */ + char ibuf[MAX_BUF]; +}; + #endif /* IFCHD_DEFINES_H_ */ diff --git a/ifchd/ifchd.c b/ifchd/ifchd.c index ee707d4..9be2953 100644 --- a/ifchd/ifchd.c +++ b/ifchd/ifchd.c @@ -80,22 +80,12 @@ enum states { STATE_WINS }; +struct ifchd_client clients[SOCK_QUEUE]; + static int epollfd, signalFd; /* Extra two event slots are for signalFd and the listen socket. */ static struct epoll_event events[SOCK_QUEUE+2]; -/* Socket fd, current state, and idle time for connections. */ -static int sks[SOCK_QUEUE], state[SOCK_QUEUE], idle_time[SOCK_QUEUE]; - -/* Per-connection buffers. */ -static char ibuf[SOCK_QUEUE][MAX_BUF]; - -/* - * Per-connection pointers into the command lists. Respectively, the - * topmost item on the list, the current item, and the last item on the list. - */ -static strlist_t *head[SOCK_QUEUE], *curl[SOCK_QUEUE], *last[SOCK_QUEUE]; - int resolv_conf_fd = -1; /* int ntp_conf_fd = -1; */ @@ -108,13 +98,6 @@ static pid_t peer_pid; static int gflags_verbose = 0; -/* Lists of nameservers and search domains. Unfortunately they must be - * per-connection, since otherwise seperate clients could race against - * one another to write out unpredictable data. - */ -static strlist_t *namesvrs[SOCK_QUEUE]; -static strlist_t *domains[SOCK_QUEUE]; - static void die_nulstr(strlist_t *p) { if (!p) @@ -229,8 +212,8 @@ static void write_resolve_conf(int idx) if (lseek(resolv_conf_fd, 0, SEEK_SET) == -1) return; - write_resolve_list("nameserver ", namesvrs[idx]); - write_resolve_list("search ", domains[idx]); + write_resolve_list("nameserver ", clients[idx].namesvrs); + write_resolve_list("search ", clients[idx].domains); off = lseek(resolv_conf_fd, 0, SEEK_CUR); if (off == -1) { log_line("write_resolve_conf: lseek returned error: %s\n", @@ -294,7 +277,7 @@ static void perform_dns(int idx, char *str) { if (!str || resolv_conf_fd == -1) return; - parse_list(idx, str, &(namesvrs[idx]), &write_resolve_conf); + parse_list(idx, str, &clients[idx].namesvrs, &write_resolve_conf); } /* Updates for print daemons are too non-standard to be useful. */ @@ -315,7 +298,7 @@ static void perform_domain(int idx, char *str) { if (!str || resolv_conf_fd == -1) return; - parse_list(idx, str, &(domains[idx]), &write_resolve_conf); + parse_list(idx, str, &clients[idx].domains, &write_resolve_conf); } /* I don't think this can be done without a netfilter extension @@ -331,22 +314,38 @@ static void perform_ntpsrv(int idx, char *str) static void perform_wins(int idx, char *str) {} -/* Wipes all state associated with a given connection. */ -static void new_sk(int idx, int val) +static void ifchd_client_init(struct ifchd_client *p) { - sks[idx] = val; - memset(ibuf[idx], '\0', sizeof(ibuf[idx])); - free_strlist(head[idx]); - free_strlist(namesvrs[idx]); - free_strlist(domains[idx]); - head[idx] = NULL; - curl[idx] = NULL; - last[idx] = NULL; - namesvrs[idx] = NULL; - domains[idx] = NULL; - idle_time[idx] = time(NULL); - state[idx] = STATE_NOTHING; - clear_if_data(idx); + p->fd = -1; + p->idle_time = time(NULL); + p->state = STATE_NOTHING; + + memset(p->ibuf, 0, sizeof p->ibuf); + memset(p->ifnam, 0, sizeof p->ifnam); + p->head = NULL; + p->curl = NULL; + p->last = NULL; + p->namesvrs = NULL; + p->domains = NULL; +} + +static void ifchd_client_wipe(struct ifchd_client *p) +{ + if (p->fd >= 0) { + epoll_del(p->fd); + close(p->fd); + } + free_strlist(p->head); + free_strlist(p->namesvrs); + free_strlist(p->domains); + ifchd_client_init(p); +} + +static void ifchd_client_new(struct ifchd_client *p, int fd) +{ + ifchd_client_wipe(p); + p->fd = fd; + epoll_add(fd); } /* Conditionally accepts a new connection and initializes data structures. */ @@ -355,12 +354,13 @@ static void add_sk(int sk) int i; if (authorized_peer(sk, peer_pid, peer_uid, peer_gid)) { - for (i = 0; i < SOCK_QUEUE; i++) - if (sks[i] == -1) { - new_sk(i, sk); - epoll_add(sk); + for (i = 0; i < SOCK_QUEUE; i++) { + struct ifchd_client *p = &clients[i]; + if (p->fd == -1) { + ifchd_client_new(p, sk); return; } + } } close(sk); } @@ -371,13 +371,11 @@ static void close_idle_sk(void) int i; for (i=0; i<SOCK_QUEUE; i++) { - if (sks[i] == -1) + struct ifchd_client *p = &clients[i]; + if (p->fd == -1) continue; - if (time(NULL) - idle_time[i] > CONN_TIMEOUT) { - epoll_del(sks[i]); - close(sks[i]); - new_sk(i, -1); - } + if (time(NULL) - p->idle_time > CONN_TIMEOUT) + ifchd_client_wipe(p); } } @@ -385,29 +383,30 @@ static void close_idle_sk(void) static int stream_onto_list(int i) { int e, s; + struct ifchd_client *cl = &clients[i]; - for (e = 0, s = 0; ibuf[i][e] != '\0'; e++) { - if (ibuf[i][e] == ':') { + for (e = 0, s = 0; cl->ibuf[e] != '\0'; e++) { + if (cl->ibuf[e] == ':') { /* Zero-length command: skip. */ if (s == e) { s = e + 1; continue; } - curl[i] = xmalloc(sizeof(strlist_t)); + cl->curl = xmalloc(sizeof(strlist_t)); - if (head[i] == NULL) { - head[i] = curl[i]; - last[i] = NULL; + if (cl->head == NULL) { + cl->head = cl->curl; + cl->last = NULL; } - curl[i]->next = NULL; - if (last[i] != NULL) - last[i]->next = curl[i]; + cl->curl->next = NULL; + if (cl->last != NULL) + cl->last->next = cl->curl; - curl[i]->str = xmalloc(e - s + 1); + cl->curl->str = xmalloc(e - s + 1); - strlcpy(curl[i]->str, ibuf[i] + s, e - s + 1); - last[i] = curl[i]; + strlcpy(cl->curl->str, cl->ibuf + s, e - s + 1); + cl->last = cl->curl; s = e + 1; } } @@ -419,132 +418,133 @@ static int stream_onto_list(int i) static void execute_list(int i) { char *p; + struct ifchd_client *cl = &clients[i]; for (;;) { - if (!curl[i]) + if (!cl->curl) break; - die_nulstr(curl[i]); + die_nulstr(cl->curl); - p = curl[i]->str; + p = cl->curl->str; if (gflags_verbose) log_line("execute_list - p = '%s'", p); - switch (state[i]) { + switch (cl->state) { case STATE_NOTHING: if (strncmp(p, CMD_INTERFACE, sizeof(CMD_INTERFACE)) == 0) - state[i] = STATE_INTERFACE; + cl->state = STATE_INTERFACE; if (strncmp(p, CMD_IP, sizeof(CMD_IP)) == 0) - state[i] = STATE_IP; + cl->state = STATE_IP; if (strncmp(p, CMD_SUBNET, sizeof(CMD_SUBNET)) == 0) - state[i] = STATE_SUBNET; + cl->state = STATE_SUBNET; if (strncmp(p, CMD_TIMEZONE, sizeof(CMD_TIMEZONE)) == 0) - state[i] = STATE_TIMEZONE; + cl->state = STATE_TIMEZONE; if (strncmp(p, CMD_ROUTER, sizeof(CMD_ROUTER)) == 0) - state[i] = STATE_ROUTER; + cl->state = STATE_ROUTER; if (strncmp(p, CMD_DNS, sizeof(CMD_DNS)) == 0) - state[i] = STATE_DNS; + cl->state = STATE_DNS; if (strncmp(p, CMD_LPRSVR, sizeof(CMD_LPRSVR)) == 0) - state[i] = STATE_LPRSVR; + cl->state = STATE_LPRSVR; if (strncmp(p, CMD_HOSTNAME, sizeof(CMD_HOSTNAME)) == 0) - state[i] = STATE_HOSTNAME; + cl->state = STATE_HOSTNAME; if (strncmp(p, CMD_DOMAIN, sizeof(CMD_DOMAIN)) == 0) - state[i] = STATE_DOMAIN; + cl->state = STATE_DOMAIN; if (strncmp(p, CMD_IPTTL, sizeof(CMD_IPTTL)) == 0) - state[i] = STATE_IPTTL; + cl->state = STATE_IPTTL; if (strncmp(p, CMD_MTU, sizeof(CMD_MTU)) == 0) - state[i] = STATE_MTU; + cl->state = STATE_MTU; if (strncmp(p, CMD_BROADCAST, sizeof(CMD_BROADCAST)) == 0) - state[i] = STATE_BROADCAST; + cl->state = STATE_BROADCAST; if (strncmp(p, CMD_NTPSVR, sizeof(CMD_NTPSVR)) == 0) - state[i] = STATE_NTPSVR; + cl->state = STATE_NTPSVR; if (strncmp(p, CMD_WINS, sizeof(CMD_WINS)) == 0) - state[i] = STATE_WINS; - free_stritem(&(curl[i])); + cl->state = STATE_WINS; + free_stritem(&cl->curl); break; case STATE_INTERFACE: perform_interface(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_IP: perform_ip(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_SUBNET: perform_subnet(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_TIMEZONE: perform_timezone(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_ROUTER: perform_router(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_DNS: perform_dns(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_LPRSVR: perform_lprsvr(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_HOSTNAME: perform_hostname(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_DOMAIN: perform_domain(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_IPTTL: perform_ipttl(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_MTU: perform_mtu(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_BROADCAST: perform_broadcast(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_NTPSVR: perform_ntpsrv(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; case STATE_WINS: perform_wins(i, p); - free_stritem(&(curl[i])); - state[i] = STATE_NOTHING; + free_stritem(&cl->curl); + cl->state = STATE_NOTHING; break; default: @@ -552,7 +552,7 @@ static void execute_list(int i) break; } } - head[i] = curl[i]; + cl->head = cl->curl; } /* Opens a non-blocking listening socket with the appropriate properties. */ @@ -690,18 +690,19 @@ static void process_client_fd(int fd) char buf[MAX_BUF]; int r, index, sqidx = -1; for (int j = 0; j < SOCK_QUEUE; ++j) { - if (sks[j] == fd) { + if (clients[j].fd == fd) { sqidx = j; break; } } if (sqidx == -1) suicide("epoll returned pending read for untracked fd"); + struct ifchd_client *cl = &clients[sqidx]; - idle_time[sqidx] = time(NULL); + cl->idle_time = time(NULL); memset(buf, '\0', sizeof buf); - r = safe_read(sks[sqidx], buf, sizeof buf / 2 - 1); + r = safe_read(cl->fd, buf, sizeof buf / 2 - 1); if (r == 0) goto fail; else if (r < 0) { @@ -713,31 +714,29 @@ static void process_client_fd(int fd) /* Discard everything and close connection if we risk overflow. * This approach is maximally conservative... worst case is that * some client requests will get dropped. */ - index = strlen(ibuf[sqidx]); + index = strlen(cl->ibuf); if (index + strlen(buf) > sizeof buf - 2) goto fail; /* Append new stream input avoiding overflow. */ - strlcpy(ibuf[sqidx] + index, buf, sizeof ibuf[sqidx] - index); + strlcpy(cl->ibuf + index, buf, sizeof cl->ibuf - index); /* Decompose ibuf contents onto strlist. */ index = stream_onto_list(sqidx); /* Remove everything that we've parsed into the list. */ - strlcpy(buf, ibuf[sqidx] + index, sizeof buf); - strlcpy(ibuf[sqidx], buf, sizeof ibuf[sqidx]); + strlcpy(buf, cl->ibuf + index, sizeof buf); + strlcpy(cl->ibuf, buf, sizeof cl->ibuf); /* Now we have a strlist of commands and arguments. * Decompose and execute it. */ - if (!head[sqidx]) + if (!cl->head) return; - curl[sqidx] = head[sqidx]; + cl->curl = cl->head; execute_list(sqidx); return; fail: - epoll_del(sks[sqidx]); - close(sks[sqidx]); - new_sk(sqidx, -1); + ifchd_client_wipe(cl); } /* Core function that handles connections, gathers input, and calls @@ -748,8 +747,7 @@ static void dispatch_work(void) /* Initialize all structures to blank state. */ for (int i = 0; i < SOCK_QUEUE; i++) - sks[i] = -1; - initialize_if_data(); + ifchd_client_init(&clients[i]); lsock = get_listen(); @@ -1002,11 +1000,8 @@ int main(int argc, char** argv) { dispatch_work(); /* Explicitly freed so memory debugger output has less static. */ - for (c=0; c<SOCK_QUEUE; ++c) { - free_strlist(head[c]); - free_strlist(namesvrs[c]); - free_strlist(domains[c]); - } + for (size_t i = 0; i < SOCK_QUEUE; ++i) + ifchd_client_wipe(&clients[i]); exit(EXIT_SUCCESS); } diff --git a/ifchd/linux.c b/ifchd/linux.c index a5aeb83..62900e2 100644 --- a/ifchd/linux.c +++ b/ifchd/linux.c @@ -51,25 +51,9 @@ #include "ifch_proto.h" #include "strl.h" -/* Symbolic name of the interface associated with a connection. */ -static char ifnam[SOCK_QUEUE][IFNAMSIZ]; +extern struct ifchd_client clients[SOCK_QUEUE]; static strlist_t *okif; -/* Clear a specified ifnam structure. */ -void clear_if_data(int idx) -{ - memset(ifnam[idx], '\0', IFNAMSIZ); -} - -/* Clear all ifnam structures. */ -void initialize_if_data(void) -{ - int i; - for (i = 0; i < SOCK_QUEUE; i++) { - clear_if_data(i); - } -} - /* Adds to the list of interface names ifchd clients are allowed to change. */ void add_permitted_if(char *s) { @@ -128,8 +112,8 @@ void perform_interface(int idx, char *str) return; /* Update interface name. */ - memset(ifnam[idx], '\0', IFNAMSIZ); - strlcpy(ifnam[idx], str, IFNAMSIZ); + memset(clients[idx].ifnam, '\0', IFNAMSIZ); + strlcpy(clients[idx].ifnam, str, IFNAMSIZ); } static int set_if_flag(int idx, short flag) @@ -137,27 +121,27 @@ static int set_if_flag(int idx, short flag) int fd, ret = -1; struct ifreq ifrt; - if (!is_permitted(ifnam[idx])) + if (!is_permitted(clients[idx].ifnam)) goto out0; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { log_line("%s: (set_if_flag) failed to open interface socket: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); goto out0; } - strlcpy(ifrt.ifr_name, ifnam[idx], IFNAMSIZ); + strlcpy(ifrt.ifr_name, clients[idx].ifnam, IFNAMSIZ); if (ioctl(fd, SIOCGIFFLAGS, &ifrt) < 0) { - log_line("%s: unknown interface: %s\n", ifnam[idx], strerror(errno)); + log_line("%s: unknown interface: %s\n", clients[idx].ifnam, strerror(errno)); goto out1; } if (((ifrt.ifr_flags & flag ) ^ flag) & flag) { - strlcpy(ifrt.ifr_name, ifnam[idx], IFNAMSIZ); + strlcpy(ifrt.ifr_name, clients[idx].ifnam, IFNAMSIZ); ifrt.ifr_flags |= flag; if (ioctl(fd, SIOCSIFFLAGS, &ifrt) < 0) { log_line("%s: failed to set interface flags: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); goto out1; } } else @@ -179,14 +163,14 @@ void perform_ip(int idx, char *str) if (!str) return; - if (!is_permitted(ifnam[idx])) + if (!is_permitted(clients[idx].ifnam)) return; if (!inet_pton(AF_INET, str, &ipaddr)) return; if (set_if_flag(idx, (IFF_UP | IFF_RUNNING))) return; - strlcpy(ifrt.ifr_name, ifnam[idx], IFNAMSIZ); + strlcpy(ifrt.ifr_name, clients[idx].ifnam, IFNAMSIZ); memset(&sin, 0, sizeof(struct sockaddr)); sin.sin_family = AF_INET; sin.sin_addr = ipaddr; @@ -195,12 +179,12 @@ void perform_ip(int idx, char *str) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { log_line("%s: (perform_ip) failed to open interface socket: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); return; } if (ioctl(fd, SIOCSIFADDR, &ifrt) < 0) log_line("%s: failed to configure IP: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); close(fd); } @@ -214,12 +198,12 @@ void perform_subnet(int idx, char *str) if (!str) return; - if (!is_permitted(ifnam[idx])) + if (!is_permitted(clients[idx].ifnam)) return; if (!inet_pton(AF_INET, str, &subnet)) return; - strlcpy(ifrt.ifr_name, ifnam[idx], IFNAMSIZ); + strlcpy(ifrt.ifr_name, clients[idx].ifnam, IFNAMSIZ); memset(&sin, 0, sizeof(struct sockaddr)); sin.sin_family = AF_INET; sin.sin_addr = subnet; @@ -228,14 +212,14 @@ void perform_subnet(int idx, char *str) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { log_line("%s: (perform_ip) failed to open interface socket: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); return; } if (ioctl(fd, SIOCSIFNETMASK, &ifrt) < 0) { sin.sin_addr.s_addr = 0xffffffff; if (ioctl(fd, SIOCSIFNETMASK, &ifrt) < 0) log_line("%s: failed to configure subnet: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); } close(fd); } @@ -251,7 +235,7 @@ void perform_router(int idx, char *str) if (!str) return; - if (!is_permitted(ifnam[idx])) + if (!is_permitted(clients[idx].ifnam)) return; if (!inet_pton(AF_INET, str, &router)) return; @@ -269,19 +253,19 @@ void perform_router(int idx, char *str) rt.rt_flags = RTF_UP | RTF_GATEWAY; if (mask->sin_addr.s_addr == 0xffffffff) rt.rt_flags |= RTF_HOST; - rt.rt_dev = ifnam[idx]; + rt.rt_dev = clients[idx].ifnam; rt.rt_metric = 1; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { log_line("%s: (perform_router) failed to open interface socket: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); return; } if (ioctl(fd, SIOCADDRT, &rt)) { if (errno != EEXIST) log_line("%s: failed to set route: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); } close(fd); } @@ -294,21 +278,21 @@ void perform_mtu(int idx, char *str) if (!str) return; - if (!is_permitted(ifnam[idx])) + if (!is_permitted(clients[idx].ifnam)) return; mtu = strtol(str, NULL, 10); ifrt.ifr_mtu = mtu; - strlcpy(ifrt.ifr_name, ifnam[idx], IFNAMSIZ); + strlcpy(ifrt.ifr_name, clients[idx].ifnam, IFNAMSIZ); fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { log_line("%s: (perform_mtu) failed to open interface socket: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); return; } if (ioctl(fd, SIOCSIFMTU, &ifrt) < 0) - log_line("%s: failed to set MTU (%d): %s\n", ifnam[idx], mtu, + log_line("%s: failed to set MTU (%d): %s\n", clients[idx].ifnam, mtu, strerror(errno)); close(fd); } @@ -322,12 +306,12 @@ void perform_broadcast(int idx, char *str) if (!str) return; - if (!is_permitted(ifnam[idx])) + if (!is_permitted(clients[idx].ifnam)) return; if (!inet_pton(AF_INET, str, &broadcast)) return; - strlcpy(ifrt.ifr_name, ifnam[idx], IFNAMSIZ); + strlcpy(ifrt.ifr_name, clients[idx].ifnam, IFNAMSIZ); memset(&sin, 0, sizeof(struct sockaddr)); sin.sin_family = AF_INET; sin.sin_addr = broadcast; @@ -335,11 +319,11 @@ void perform_broadcast(int idx, char *str) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { - log_line("%s: (perform_broadcast) failed to open interface socket: %s\n", ifnam[idx], strerror(errno)); + log_line("%s: (perform_broadcast) failed to open interface socket: %s\n", clients[idx].ifnam, strerror(errno)); return; } if (ioctl(fd, SIOCSIFBRDADDR, &ifrt) < 0) log_line("%s: failed to set broadcast: %s\n", - ifnam[idx], strerror(errno)); + clients[idx].ifnam, strerror(errno)); close(fd); }