retval = send_packet(iface, ETHERTYPE_ARP,
(unsigned char *) arp, arphdr_len(arp));
+ if (retval == -1)
+ logger(LOG_ERR,"send_packet: %s", strerror(errno));
free(arp);
return retval;
}
"checking %s is available on attached networks",
inet_ntoa(address));
- if (!open_socket(iface, ETHERTYPE_ARP))
+ if (!open_socket(iface, ETHERTYPE_ARP)) {
+ logger (LOG_ERR, "open_socket: %s", strerror(errno));
return -1;
+ }
fds[0].fd = signal_fd();
fds[1].fd = iface->fd;
#include "config.h"
#include "dhcp.h"
#include "if.h"
-#include "logger.h"
#include "socket.h"
#include "bpf-filter.h"
-void
-setup_packet_filters(void)
-{
- /* Empty function */
-}
-
int
open_socket(struct interface *iface, int protocol)
{
} while (fd == -1 && errno == EBUSY);
free(device);
- if (fd == -1) {
- logger(LOG_ERR, "unable to open a BPF device");
+ if (fd == -1)
return -1;
- }
close_on_exec(fd);
-
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
if (ioctl(fd, BIOCSETIF, &ifr) == -1) {
- logger(LOG_ERR,
- "cannot attach interface `%s' to bpf device `%s': %s",
- iface->name, device, strerror(errno));
close(fd);
return -1;
}
/* Get the required BPF buffer length from the kernel. */
if (ioctl(fd, BIOCGBLEN, &buf) == -1) {
- logger (LOG_ERR, "ioctl BIOCGBLEN: %s", strerror(errno));
close(fd);
return -1;
}
flags = 1;
if (ioctl(fd, BIOCIMMEDIATE, &flags) == -1) {
- logger(LOG_ERR, "ioctl BIOCIMMEDIATE: %s", strerror(errno));
close(fd);
return -1;
}
pf.bf_len = sizeof(dhcp_bpf_filter)/sizeof(dhcp_bpf_filter[0]);
}
if (ioctl(fd, BIOCSETF, &pf) == -1) {
- logger(LOG_ERR, "ioctl BIOCSETF: %s", strerror(errno));
close(fd);
return -1;
}
send_packet(const struct interface *iface, int type,
const unsigned char *data, size_t len)
{
- ssize_t retval = -1;
struct iovec iov[2];
struct ether_header hw;
- if (iface->family == ARPHRD_ETHER) {
- memset(&hw, 0, sizeof(hw));
- memset(&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
- hw.ether_type = htons(type);
-
- iov[0].iov_base = &hw;
- iov[0].iov_len = sizeof(hw);
- } else {
- logger(LOG_ERR, "unsupported interace type %d", iface->family);
- return -1;
- }
+ memset(&hw, 0, sizeof(hw));
+ memset(&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
+ hw.ether_type = htons(type);
+ iov[0].iov_base = &hw;
+ iov[0].iov_len = sizeof(hw);
iov[1].iov_base = (unsigned char *)data;
iov[1].iov_len = len;
- if ((retval = writev(iface->fd, iov, 2)) == -1)
- logger(LOG_ERR, "writev: %s", strerror(errno));
-
- return retval;
+ return writev(iface->fd, iov, 2);
}
/* BPF requires that we read the entire buffer.
*buffer_len = read(iface->fd, bpf.buffer, iface->buffer_length);
*buffer_pos = 0;
if (*buffer_len < 1) {
- logger(LOG_ERR, "read: %s", strerror(errno));
ts.tv_sec = 3;
ts.tv_nsec = 0;
nanosleep(&ts, NULL);
if (options->doduid) {
duid = xmalloc(DUID_LEN);
duid_len = get_duid(duid, iface);
+ if (duid_len == 0)
+ logger(LOG_ERR, "get_duid: %s",
+ strerror(errno));
}
if (duid_len > 0) {
state->interface->fd = -1;
if (mode == SOCKET_OPEN)
- if (open_socket(state->interface, ETHERTYPE_IP) == -1)
+ if (open_socket(state->interface, ETHERTYPE_IP) == -1) {
+ logger(LOG_ERR, "open_socket: %s", strerror(errno));
return false;
+ }
state->socket = mode;
return true;
}
if (!IN_LINKLOCAL(ntohl(state->dhcp->address.s_addr))) {
do_socket(state, SOCKET_OPEN);
state->xid = (uint32_t)random();
- if ((open_socket(state->interface, false)) >= 0)
- _send_message(state, DHCP_RELEASE,
- options);
+ _send_message(state, DHCP_RELEASE, options);
do_socket(state, SOCKET_CLOSED);
}
unlink(state->interface->infofile);
int sig;
iface = read_interface(options->interface, options->metric);
- if (!iface)
+ if (!iface) {
+ logger(LOG_ERR, "read_interface: %s", strerror(errno));
goto eexit;
+ }
state = xzalloc(sizeof(*state));
state->dhcp = xzalloc(sizeof(*state->dhcp));
{
dest.s_addr = dhcp->address.s_addr & dhcp->netmask.s_addr;
gate.s_addr = 0;
- add_route (iface->name, dest, dhcp->netmask, gate, options->metric);
- del_route (iface->name, dest, dhcp->netmask, gate, 0);
+ add_route(iface->name, dest, dhcp->netmask, gate, options->metric);
+ del_route(iface->name, dest, dhcp->netmask, gate, 0);
}
#endif
retval = send_packet(iface, ETHERTYPE_IP, (unsigned char *)packet,
message_length +
sizeof(packet->ip) + sizeof(packet->udp));
+ if (retval == -1)
+ logger(LOG_ERR, "send_packet: %s", strerror(errno));
free(packet);
return retval;
}
goto abort;
}
errno = 0;
- options->leasetime = (uint32_t)strtol (optarg, NULL, 0);
+ options->leasetime = (uint32_t)strtol(optarg, NULL, 0);
if (errno == EINVAL || errno == ERANGE) {
logger(LOG_ERR, "`%s' out of range", optarg);
goto abort;
/* Seed random */
srandomdev();
+#ifdef __linux
/* Massage our filters per platform */
setup_packet_filters();
+#endif
if (dhcp_run(options, &pidfd) == 0)
retval = EXIT_SUCCESS;
#include "config.h"
#include "common.h"
#include "duid.h"
-#include "logger.h"
#ifdef ENABLE_DUID
if (len)
return len;
} else {
- if (errno != ENOENT) {
- logger(LOG_ERR, "fopen `%s': %s",
- DUIDFILE, strerror(errno));
+ if (errno != ENOENT)
return 0;
- }
}
/* No file? OK, lets make one based on our interface */
+ if (!(f = fopen(DUIDFILE, "w")))
+ return 0;
+
type = htons(1); /* DUI-D-LLT */
memcpy(p, &type, 2);
p += 2;
len = p - duid;
- if (!(f = fopen(DUIDFILE, "w")))
- logger(LOG_ERR, "fopen `%s': %s", DUIDFILE, strerror(errno));
- else {
- x = fprintf(f, "%s\n", hwaddr_ntoa(duid, len));
- fclose(f);
- }
+ x = fprintf(f, "%s\n", hwaddr_ntoa(duid, len));
+ fclose(f);
/* Failed to write the duid? scrub it, we cannot use it */
if (x < 1) {
#include "common.h"
#include "dhcp.h"
#include "if.h"
-#include "logger.h"
/* Darwin doesn't define this for some very odd reason */
#ifndef SA_SIZE
struct in_addr netmask, struct in_addr broadcast, int del)
{
int s;
+ int retval;
struct ifaliasreq ifa;
union {
struct sockaddr *sa;
struct sockaddr_in *sin;
} _s;
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
return -1;
- }
memset(&ifa, 0, sizeof(ifa));
strlcpy(ifa.ifra_name, ifname, sizeof(ifa.ifra_name));
ADDADDR(ifa.ifra_broadaddr, broadcast);
#undef ADDADDR
- if (ioctl(s, del ? SIOCDIFADDR : SIOCAIFADDR, &ifa) == -1) {
- logger(LOG_ERR, "ioctl %s: %s",
- del ? "SIOCDIFADDR" : "SIOCAIFADDR",
- strerror(errno));
- close(s);
- return -1;
- }
-
+ retval = ioctl(s, del ? SIOCDIFADDR : SIOCAIFADDR, &ifa);
close(s);
- return 0;
+ return retval;
}
int
size_t l;
unsigned char *hwaddr;
size_t hwlen = 0;
+ int retval = 0;
log_route(destination, netmask, gateway, metric, change, del);
- if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
+ if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
return -1;
- }
memset(&rtm, 0, sizeof(rtm));
-
rtm.hdr.rtm_version = RTM_VERSION;
rtm.hdr.rtm_seq = ++seq;
rtm.hdr.rtm_type = change ? RTM_CHANGE : del ? RTM_DELETE : RTM_ADD;
#undef ADDADDR
rtm.hdr.rtm_msglen = l = bp - (char *)&rtm;
- if (write(s, &rtm, l) == -1) {
- /* Don't report error about routes already existing */
- if (errno != EEXIST)
- logger(LOG_ERR, "write: %s", strerror(errno));
- close(s);
- return -1;
- }
-
+ if (write(s, &rtm, l) == -1)
+ retval = -1;
close(s);
- return 0;
+ return retval;
}
#include "common.h"
#include "dhcp.h"
#include "if.h"
-#include "logger.h"
/* This netlink stuff is overly compex IMO.
* The BSD implementation is much cleaner and a lot less code.
struct iovec iov;
struct msghdr msg;
static unsigned int seq;
- char *buffer;
+ char *buffer = NULL;
ssize_t bytes;
union
{
int len, l;
struct nlmsgerr *err;
- if ((s = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
+ if ((s = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1)
return -1;
- }
memset(&nl, 0, sizeof(nl));
nl.nl_family = AF_NETLINK;
- if (bind(s, (struct sockaddr *)&nl, sizeof(nl)) == -1) {
- logger(LOG_ERR, "bind: %s", strerror(errno));
- close(s);
- return -1;
- }
+ if (bind(s, (struct sockaddr *)&nl, sizeof(nl)) == -1)
+ goto eexit;
memset(&iov, 0, sizeof(iov));
iov.iov_base = hdr;
hdr->nlmsg_flags |= NLM_F_ACK;
hdr->nlmsg_seq = ++seq;
- if (sendmsg(s, &msg, 0) == -1) {
- logger(LOG_ERR, "write: %s", strerror(errno));
- close(s);
- return -1;
- }
+ if (sendmsg(s, &msg, 0) == -1)
+ goto eexit;
buffer = xzalloc(sizeof(char) * BUFFERLEN);
iov.iov_base = buffer;
bytes = recvmsg(s, &msg, 0);
if (bytes == -1) {
- if (errno != EINTR)
- logger (LOG_ERR, "recvmsg: %s",
- strerror(errno));
- continue;
+ if (errno == EINTR)
+ continue;
+ goto eexit;
}
if (bytes == 0) {
- logger(LOG_ERR, "netlink: EOF");
+ errno = ENODATA;
goto eexit;
}
if (msg.msg_namelen != sizeof(nl)) {
- logger(LOG_ERR,
- "netlink: sender address length mismatch");
+ errno = EBADMSG;
goto eexit;
}
err = (struct nlmsgerr *)NLMSG_DATA(h.nlm);
if (l < 0 || len > bytes) {
- if (msg.msg_flags & MSG_TRUNC)
- logger(LOG_ERR,
- "netlink: truncated message");
- else
- logger(LOG_ERR,
- "netlink: malformed message");
+ errno = EBADMSG;
goto eexit;
}
}
/* We get an NLMSG_ERROR back with a code of zero for success */
- if (h.nlm->nlmsg_type != NLMSG_ERROR) {
- logger(LOG_ERR, "netlink: unexpected reply %d",
- h.nlm->nlmsg_type);
- goto eexit;
- }
+ if (h.nlm->nlmsg_type != NLMSG_ERROR)
+ continue;
if ((unsigned)l < sizeof(*err)) {
- logger(LOG_ERR, "netlink: error truncated");
+ errno = EBADMSG;
goto eexit;
}
}
errno = -err->error;
- /* Don't report on something already existing */
- if (errno != EEXIST)
- logger(LOG_ERR, "netlink: %s", strerror(errno));
goto eexit;
}
}
struct rtattr *rta;
if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
- logger(LOG_ERR, "add_attr_l: message exceeded bound of %d\n",
- maxlen);
+ errno = ENOBUFS;
return -1;
}
struct rtattr *rta;
if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
- logger(LOG_ERR, "add_attr32: message exceeded bound of %d\n",
- maxlen);
+ errno = ENOBUFS;
return -1;
}
struct in_addr broadcast, int del)
{
struct nlma *nlm;
- int retval;
+ int retval = 0;
nlm = xzalloc(sizeof(*nlm));
nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
nlm->hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
if (!(nlm->ifa.ifa_index = if_nametoindex(ifname))) {
- logger(LOG_ERR, "if_nametoindex: no index for interface `%s'",
- ifname);
free(nlm);
+ errno = ENODEV;
return -1;
}
nlm->ifa.ifa_family = AF_INET;
add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_BROADCAST,
&broadcast.s_addr, sizeof(broadcast.s_addr));
- retval = send_netlink(&nlm->hdr);
+ if (send_netlink(&nlm->hdr) == -1)
+ retval = -1;
free(nlm);
return retval;
}
{
struct nlmr *nlm;
unsigned int ifindex;
- int retval;
+ int retval = 0;
log_route(destination, netmask, gateway, metric, change, del);
if (!(ifindex = if_nametoindex(ifname))) {
- logger(LOG_ERR, "if_nametoindex: no index for interface `%s'",
- ifname);
+ errno = ENODEV;
return -1;
}
add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, ifindex);
add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, metric);
- retval = send_netlink(&nlm->hdr);
+ if (send_netlink(&nlm->hdr) == -1)
+ retval = -1;
free(nlm);
return retval;
}
struct sockaddr_dl sdl;
#endif
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
return -1;
- }
/* Not all implementations return the needed buffer size for
* SIOGIFCONF so we loop like so for all until it works */
ifc.ifc_buf = xmalloc((size_t)len);
if (ioctl(s, SIOCGIFCONF, &ifc) == -1) {
if (errno != EINVAL || lastlen != 0) {
- logger(LOG_ERR, "ioctl SIOCGIFCONF: %s",
- strerror(errno));
close(s);
free(ifc.ifc_buf);
return -1;
if (ifr->ifr_addr.sa_family == AF_INET) {
memcpy(&address, &ifr->ifr_addr, sizeof(address));
if (flush) {
- if (ioctl(s, SIOCGIFNETMASK, ifr) == -1) {
- logger(LOG_ERR,
- "ioctl SIOCGIFNETMASK: %s",
- strerror(errno));
+ if (ioctl(s, SIOCGIFNETMASK, ifr) == -1)
continue;
- }
memcpy(&netmask, &ifr->ifr_addr,
sizeof(netmask));
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
return NULL;
- }
#ifdef __linux__
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
- if (ioctl(s, SIOCGIFHWADDR, &ifr) == -1) {
- logger(LOG_ERR, "ioctl SIOCGIFHWADDR: %s", strerror(errno));
- goto exit;
- }
+ if (ioctl(s, SIOCGIFHWADDR, &ifr) == -1)
+ goto eexit;
switch (ifr.ifr_hwaddr.sa_family) {
case ARPHRD_ETHER:
logger (LOG_ERR,
"interface is not Ethernet, FireWire, " \
"InfiniBand or Token Ring");
- goto exit;
+ goto eexit;
}
hwaddr = xmalloc(sizeof(unsigned char) * HWADDR_LEN);
#else
ifr.ifr_metric = metric;
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
- if (ioctl(s, SIOCSIFMETRIC, &ifr) == -1) {
- logger(LOG_ERR, "ioctl SIOCSIFMETRIC: %s", strerror(errno));
- goto exit;
- }
+ if (ioctl(s, SIOCSIFMETRIC, &ifr) == -1)
+ goto eexit;
hwaddr = xmalloc(sizeof(unsigned char) * HWADDR_LEN);
- if (do_interface(ifname, hwaddr, &hwlen, NULL, false, false) != 1) {
- logger(LOG_ERR, "could not find interface %s", ifname);
- goto exit;
- }
+ if (do_interface(ifname, hwaddr, &hwlen, NULL, false, false) != 1)
+ goto eexit;
family = ARPHRD_ETHER;
#endif
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
- if (ioctl(s, SIOCGIFMTU, &ifr) == -1) {
- logger(LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror(errno));
- goto exit;
- }
+ if (ioctl(s, SIOCGIFMTU, &ifr) == -1)
+ goto eexit;
if (ifr.ifr_mtu < MTU_MIN) {
logger(LOG_DEBUG, "MTU of %d is too low, setting to %d",
ifr.ifr_mtu = MTU_MIN;
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCSIFMTU, &ifr) == -1) {
- logger(LOG_ERR, "ioctl SIOCSIFMTU,: %s",
- strerror(errno));
- goto exit;
+ goto eexit;
}
}
mtu = ifr.ifr_mtu;
if ((p = strchr(ifr.ifr_name, ':')))
*p = '\0';
#endif
- if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
- logger(LOG_ERR, "ioctl SIOCGIFFLAGS: %s", strerror(errno));
- goto exit;
- }
+ if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1)
+ goto eexit;
if (!(ifr.ifr_flags & IFF_UP) || !(ifr.ifr_flags & IFF_RUNNING)) {
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
- if (ioctl(s, SIOCSIFFLAGS, &ifr) != 0) {
- logger(LOG_ERR, "ioctl SIOCSIFFLAGS: %s",
- strerror(errno));
- goto exit;
- }
+ if (ioctl(s, SIOCSIFFLAGS, &ifr) != 0)
+ goto eexit;
}
iface = xzalloc(sizeof(*iface));
iface->listen_fd = -1;
#endif
-exit:
+eexit:
close(s);
free(hwaddr);
return iface;
int r;
int s;
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
return -1;
- }
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
r = ioctl(s, SIOCGIFMTU, &ifr);
close(s);
- if (r == -1) {
- logger(LOG_ERR, "ioctl SIOCGIFMTU: %s", strerror(errno));
+ if (r == -1)
return -1;
- }
-
return ifr.ifr_mtu;
}
int r;
int s;
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
return -1;
- }
memset(&ifr, 0, sizeof(ifr));
logger(LOG_DEBUG, "setting MTU to %d", mtu);
ifr.ifr_mtu = mtu;
r = ioctl(s, SIOCSIFMTU, &ifr);
close(s);
-
- if (r == -1)
- logger(LOG_ERR, "ioctl SIOCSIFMTU: %s", strerror(errno));
-
return r == 0 ? 0 : -1;
}
add_address(const char *ifname, struct in_addr address,
struct in_addr netmask, struct in_addr broadcast)
{
+ int retval;
+
logger(LOG_INFO, "adding IP address %s/%d",
inet_ntoa(address), inet_ntocidr(netmask));
-
- return if_address(ifname, address, netmask, broadcast, 0);
+ retval = if_address(ifname, address, netmask, broadcast, 0);
+ if (retval == -1)
+ logger(LOG_ERR, "if_address: %s", strerror(errno));
+ return retval;
}
int
del_address(const char *ifname, struct in_addr address, struct in_addr netmask)
{
struct in_addr t;
+ int retval;
logger(LOG_INFO, "removing IP address %s/%d",
inet_ntoa(address), inet_ntocidr(netmask));
-
t.s_addr = 0;
- return if_address(ifname, address, netmask, t, 1);
+ retval = if_address(ifname, address, netmask, t, 1);
+ if (retval == -1)
+ logger(LOG_ERR, "if_address: %s", strerror(errno));
+ return retval;
}
int
add_route(const char *ifname, struct in_addr destination,
struct in_addr netmask, struct in_addr gateway, int metric)
{
- return if_route(ifname, destination, netmask, gateway, metric, 0, 0);
-}
+ int retval;
-int
-change_route(const char *ifname, struct in_addr destination,
- struct in_addr netmask, struct in_addr gateway, int metric)
-{
- return if_route(ifname, destination, netmask, gateway, metric, 1, 0);
+ retval = if_route(ifname, destination, netmask, gateway, metric, 0, 0);
+ if (retval == -1)
+ logger(LOG_ERR, "if_route: %s", strerror(errno));
+ return retval;
}
int
del_route(const char *ifname, struct in_addr destination,
struct in_addr netmask, struct in_addr gateway, int metric)
{
- return if_route(ifname, destination, netmask, gateway, metric, 0, 1);
+ int retval;
+
+ retval = if_route(ifname, destination, netmask, gateway, metric, 0, 1);
+ if (retval == -1)
+ logger(LOG_ERR, "if_route: %s", strerror(errno));
+ return retval;
}
int
flush_addresses(const char *ifname)
{
- return do_interface(ifname, NULL, NULL, NULL, true, false);
+ int retval;
+ retval = do_interface(ifname, NULL, NULL, NULL, true, false);
+ if (retval == -1)
+ logger(LOG_ERR, "do_interface: %s", strerror(errno));
+ return retval;
}
in_addr_t
get_address(const char *ifname)
{
struct in_addr address;
+ int retval;
- if (do_interface(ifname, NULL, NULL, &address, false, true) > 0)
+ retval = do_interface(ifname, NULL, NULL, &address, false, true);
+ if (retval > 0)
return address.s_addr;
- return 0;
+ if (retval == -1)
+ logger(LOG_ERR, "do_interface: %s", strerror(errno));
+ return retval;
}
int
has_address(const char *ifname, struct in_addr address)
{
- return do_interface(ifname, NULL, NULL, &address, false, false);
+ int retval;
+
+ retval = do_interface(ifname, NULL, NULL, &address, false, false);
+ if (retval == -1)
+ logger(LOG_ERR, "do_interface: %s", strerror(errno));
+ return retval;
}
int add_route(const char *, struct in_addr, struct in_addr, struct in_addr,
int);
-int change_route(const char *, struct in_addr, struct in_addr, struct in_addr,
- int);
int del_route(const char *, struct in_addr, struct in_addr, struct in_addr,
int);
void log_route(struct in_addr, struct in_addr, struct in_addr, int, int, int);
}
} else if (strcmp(var, "GATEWAYS") == 0) {
p = value;
- while ((value = strsep (&p, " "))) {
+ while ((value = strsep(&p, " "))) {
route = xzalloc(sizeof(*route));
if (parse_address(&route->gateway, value,
"GATEWAYS"))
#include <unistd.h>
#include "common.h"
-#include "logger.h"
#include "signal.h"
static int signal_pipe[2];
/* Add a signal to our stack */
while (signals[i])
i++;
- if (i > sizeof(signals) / sizeof(signals[0]))
- logger(LOG_ERR, "signal buffer overrun");
- else
+ if (i <= sizeof(signals) / sizeof(signals[0]))
signals[i] = sig;
- if (write(signal_pipe[1], &sig, sizeof(sig)) == -1)
- logger(LOG_ERR, "Could not send signal: %s", strerror(errno));
+ write(signal_pipe[1], &sig, sizeof(sig));
/* Restore errno */
errno = serrno;
{
struct sigaction sa;
- if (pipe(signal_pipe) == -1) {
- logger(LOG_ERR, "pipe: %s", strerror(errno));
+ if (pipe(signal_pipe) == -1)
return -1;
- }
/* Stop any scripts from inheriting us */
close_on_exec(signal_pipe[0]);
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT;
- if (sigaction(SIGCHLD, &sa, NULL) == -1) {
- logger(LOG_ERR, "sigaction: %s", strerror(errno));
+ if (sigaction(SIGCHLD, &sa, NULL) == -1)
return -1;
- }
memset(signals, 0, sizeof(signals));
return 0;
sigemptyset(&sa.sa_mask);
for (i = 0; i < sizeof(handle_sigs) / sizeof(handle_sigs[0]); i++)
- if (sigaction(handle_sigs[i], &sa, NULL) == -1) {
- logger(LOG_ERR, "sigaction: %s", strerror(errno));
+ if (sigaction(handle_sigs[i], &sa, NULL) == -1)
return -1;
- }
return 0;
}
sigemptyset(&sa.sa_mask);
for (i = 0; i < sizeof(handle_sigs) / sizeof(handle_sigs[0]); i++)
- if (sigaction(handle_sigs[i], &sa, NULL) == -1) {
- logger(LOG_ERR, "sigaction: %s", strerror(errno));
+ if (sigaction(handle_sigs[i], &sa, NULL) == -1)
return -1;
- }
-
+
return 0;
}
#include "config.h"
#include "dhcp.h"
#include "if.h"
-#include "logger.h"
#include "socket.h"
#include "bpf-filter.h"
arp_bpf_filter[2].k -= ETH_HLEN;
}
+static int open_listen_socket(struct interface *iface)
+{
+ int fd;
+ union sockunion {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ } su;
+ struct ifreq ifr;
+ int n = 1;
+
+ if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+ return -1;
+
+ memset(&su, 0, sizeof(su));
+ su.sin.sin_family = AF_INET;
+ su.sin.sin_port = htons(DHCP_CLIENT_PORT);
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
+ goto eexit;
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1)
+ goto eexit;
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
+ goto eexit;
+ if (bind(fd, &su.sa, sizeof(su)) == -1)
+ goto eexit;
+
+ iface->listen_fd = fd;
+ close_on_exec(fd);
+ return 0;
+
+eexit:
+ close(fd);
+ return -1;
+}
+
int
open_socket(struct interface *iface, int protocol)
{
struct sockaddr_storage ss;
} su;
struct sock_fprog pf;
- struct ifreq ifr;
- int n = 1;
/* We need to bind to a port, otherwise Linux generate ICMP messages
* that cannot contect the port when we have an address.
* We don't actually use this fd at all, instead using our packet
* filter socket. */
- if (iface->listen_fd == -1 && protocol == ETHERTYPE_IP) {
- if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
- } else {
- memset(&su, 0, sizeof(su));
- su.sin.sin_family = AF_INET;
- su.sin.sin_port = htons(DHCP_CLIENT_PORT);
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- &n, sizeof(n)) == -1)
- logger(LOG_ERR, "SO_REUSEADDR: %s",
- strerror(errno));
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
- &n, sizeof(n)) == -1)
- logger(LOG_ERR, "SO_RCVBUF: %s",
- strerror(errno));
- memset (&ifr, 0, sizeof(ifr));
- strncpy (ifr.ifr_name, iface->name,
- sizeof(ifr.ifr_name));
- if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
- &ifr, sizeof(ifr)) == -1)
- logger(LOG_ERR, "SO_SOBINDTODEVICE: %s",
- strerror(errno));
- if (bind(fd, &su.sa, sizeof(su)) == -1) {
- logger(LOG_ERR, "bind: %s", strerror(errno));
- close(fd);
- } else {
- iface->listen_fd = fd;
- close_on_exec(fd);
- }
- }
- }
+ if (iface->listen_fd == -1 && protocol == ETHERTYPE_IP)
+ if (open_listen_socket(iface) == -1)
+ return -1;
- if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(protocol))) == -1) {
- logger(LOG_ERR, "socket: %s", strerror(errno));
+ if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(protocol))) == -1)
return -1;
- }
+
close_on_exec(fd);
-
memset(&su, 0, sizeof(su));
su.sll.sll_family = PF_PACKET;
su.sll.sll_protocol = htons(protocol);
if (!(su.sll.sll_ifindex = if_nametoindex(iface->name))) {
- logger(LOG_ERR,
- "if_nametoindex: no index for interface `%s'",
- iface->name);
- close(fd);
- return -1;
+ errno = ENOENT;
+ goto eexit;
}
/* Install the DHCP filter */
pf.len = sizeof(dhcp_bpf_filter) / sizeof(dhcp_bpf_filter[0]);
}
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &pf, sizeof(pf)) != 0)
- {
- logger(LOG_ERR, "SO_ATTACH_FILTER: %s", strerror(errno));
- close(fd);
- return -1;
- }
+ goto eexit;
- if (bind(fd, &su.sa, sizeof(su)) == -1) {
- logger(LOG_ERR, "bind: %s", strerror(errno));
- close(fd);
- return -1;
- }
+ if (bind(fd, &su.sa, sizeof(su)) == -1)
+ goto eexit;
if (iface->fd > -1)
close(iface->fd);
iface->buffer_length = BUFFER_LENGTH;
return fd;
+
+eexit:
+ close(fd);
+ return -1;
}
ssize_t
struct sockaddr_ll sll;
struct sockaddr_storage ss;
} su;
- ssize_t retval;
memset(&su, 0, sizeof(su));
su.sll.sll_family = AF_PACKET;
su.sll.sll_protocol = htons(type);
if (!(su.sll.sll_ifindex = if_nametoindex(iface->name))) {
- logger(LOG_ERR, "if_nametoindex: no index for interface `%s'",
- iface->name);
+ errno = ENOENT;
return -1;
}
else
memset(&su.sll.sll_addr, 0xff, iface->hwlen);
- if ((retval = sendto(iface->fd, data, len,0,&su.sa,sizeof(su))) == -1)
- logger(LOG_ERR, "sendto: %s", strerror(errno));
- return retval;
+ return sendto(iface->fd, data, len,0,&su.sa,sizeof(su));
}
/* Linux has no need for the buffer as we can read as much as we want.
bytes = read(iface->fd, buffer, iface->buffer_length);
if (bytes == -1) {
- logger(LOG_ERR, "read: %s", strerror(errno));
ts.tv_sec = 3;
ts.tv_nsec = 0;
nanosleep(&ts, NULL);
if ((unsigned)bytes < (sizeof(pay.packet->ip) +sizeof(pay.packet->udp)))
{
- logger(LOG_DEBUG, "message too short, ignoring");
+ errno = EBADMSG;
return -1;
}
pay.buffer = buffer;
if (bytes < ntohs(pay.packet->ip.ip_len)) {
- logger(LOG_DEBUG, "truncated packet, ignoring");
+ errno = EBADMSG;
return -1;
}
#include "dhcp.h"
#include "if.h"
+#ifdef __linux__
void setup_packet_filters(void);
+#endif
+
int open_socket(struct interface *, int);
ssize_t send_packet(const struct interface *, int,
const unsigned char *, size_t);