From: Roy Marples Date: Sat, 29 Mar 2008 08:40:55 +0000 (+0000) Subject: Rework our error handling code a little to save ~5k on x86_64 X-Git-Tag: v4.0.2~524 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=453072ef8fa4589a255f797c7fdc64fccb775e5f;p=thirdparty%2Fdhcpcd.git Rework our error handling code a little to save ~5k on x86_64 --- diff --git a/arp.c b/arp.c index 399af0c7..3db15580 100644 --- a/arp.c +++ b/arp.c @@ -106,6 +106,8 @@ send_arp(const struct interface *iface, int op, struct in_addr sip, 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; } @@ -150,8 +152,10 @@ arp_claim(struct interface *iface, struct in_addr address) "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; diff --git a/bpf.c b/bpf.c index 92797dec..293f023c 100644 --- a/bpf.c +++ b/bpf.c @@ -48,16 +48,9 @@ #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) { @@ -76,26 +69,19 @@ 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; } @@ -103,7 +89,6 @@ open_socket(struct interface *iface, int protocol) flags = 1; if (ioctl(fd, BIOCIMMEDIATE, &flags) == -1) { - logger(LOG_ERR, "ioctl BIOCIMMEDIATE: %s", strerror(errno)); close(fd); return -1; } @@ -117,7 +102,6 @@ open_socket(struct interface *iface, int protocol) 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; } @@ -133,28 +117,18 @@ ssize_t 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. @@ -190,7 +164,6 @@ get_packet(const struct interface *iface, unsigned char *data, *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); diff --git a/client.c b/client.c index 85a65650..6636c316 100644 --- a/client.c +++ b/client.c @@ -401,6 +401,9 @@ client_setup(struct if_state *state, const struct options *options) 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) { @@ -451,8 +454,10 @@ do_socket(struct if_state *state, int mode) 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; } @@ -609,9 +614,7 @@ handle_signal (int sig, struct if_state *state, const struct options *options) 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); @@ -1081,8 +1084,10 @@ dhcp_run(const struct options *options, int *pidfd) 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)); diff --git a/configure.c b/configure.c index ccfd2e6a..ded0c237 100644 --- a/configure.c +++ b/configure.c @@ -644,8 +644,8 @@ configure (const struct options *options, struct interface *iface, { 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 diff --git a/dhcp.c b/dhcp.c index 7faf5c13..740691a6 100644 --- a/dhcp.c +++ b/dhcp.c @@ -455,6 +455,8 @@ send_message(const struct interface *iface, const struct dhcp *dhcp, 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; } diff --git a/dhcpcd.c b/dhcpcd.c index 6da8fc5d..25fc3914 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -259,7 +259,7 @@ main(int argc, char **argv) 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; @@ -605,8 +605,10 @@ main(int argc, char **argv) /* Seed random */ srandomdev(); +#ifdef __linux /* Massage our filters per platform */ setup_packet_filters(); +#endif if (dhcp_run(options, &pidfd) == 0) retval = EXIT_SUCCESS; diff --git a/duid.c b/duid.c index c2ad4a29..4a7051b7 100644 --- a/duid.c +++ b/duid.c @@ -38,7 +38,6 @@ #include "config.h" #include "common.h" #include "duid.h" -#include "logger.h" #ifdef ENABLE_DUID @@ -72,14 +71,14 @@ get_duid(unsigned char *duid, const struct interface *iface) 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; @@ -101,12 +100,8 @@ get_duid(unsigned char *duid, const struct interface *iface) 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) { diff --git a/if-bsd.c b/if-bsd.c index 0828c3f4..cbb90c9d 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -49,7 +49,6 @@ #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 @@ -64,16 +63,15 @@ if_address(const char *ifname, struct in_addr address, 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)); @@ -90,16 +88,9 @@ if_address(const char *ifname, struct in_addr address, 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 @@ -127,16 +118,14 @@ if_route(const char *ifname, struct in_addr destination, 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; @@ -187,14 +176,8 @@ if_route(const char *ifname, struct in_addr destination, #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; } diff --git a/if-linux.c b/if-linux.c index 0c3c1638..b579989e 100644 --- a/if-linux.c +++ b/if-linux.c @@ -51,7 +51,6 @@ #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. @@ -67,7 +66,7 @@ send_netlink(struct nlmsghdr *hdr) struct iovec iov; struct msghdr msg; static unsigned int seq; - char *buffer; + char *buffer = NULL; ssize_t bytes; union { @@ -77,18 +76,13 @@ send_netlink(struct nlmsghdr *hdr) 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; @@ -104,11 +98,8 @@ send_netlink(struct nlmsghdr *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; @@ -118,20 +109,18 @@ send_netlink(struct nlmsghdr *hdr) 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; } @@ -141,12 +130,7 @@ send_netlink(struct nlmsghdr *hdr) 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; } @@ -162,14 +146,11 @@ send_netlink(struct nlmsghdr *hdr) } /* 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; } @@ -180,9 +161,6 @@ send_netlink(struct nlmsghdr *hdr) } errno = -err->error; - /* Don't report on something already existing */ - if (errno != EEXIST) - logger(LOG_ERR, "netlink: %s", strerror(errno)); goto eexit; } } @@ -204,8 +182,7 @@ add_attr_l(struct nlmsghdr *n, unsigned int maxlen, int type, 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; } @@ -225,8 +202,7 @@ add_attr_32(struct nlmsghdr *n, unsigned int maxlen, int type, uint32_t data) 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; } @@ -259,7 +235,7 @@ if_address(const char *ifname, 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)); @@ -268,9 +244,8 @@ if_address(const char *ifname, 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; @@ -284,7 +259,8 @@ if_address(const char *ifname, 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; } @@ -296,13 +272,12 @@ if_route(const char *ifname, { 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; } @@ -341,7 +316,8 @@ if_route(const char *ifname, 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; } diff --git a/if.c b/if.c index a7671abf..5044c2ee 100644 --- a/if.c +++ b/if.c @@ -177,10 +177,8 @@ do_interface(const char *ifname, 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 */ @@ -190,8 +188,6 @@ do_interface(const char *ifname, 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; @@ -235,12 +231,8 @@ do_interface(const char *ifname, 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)); @@ -282,17 +274,13 @@ read_interface (const char *ifname, _unused int metric) 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: @@ -308,7 +296,7 @@ read_interface (const char *ifname, _unused int metric) logger (LOG_ERR, "interface is not Ethernet, FireWire, " \ "InfiniBand or Token Ring"); - goto exit; + goto eexit; } hwaddr = xmalloc(sizeof(unsigned char) * HWADDR_LEN); @@ -317,25 +305,19 @@ read_interface (const char *ifname, _unused int metric) #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", @@ -343,9 +325,7 @@ read_interface (const char *ifname, _unused int metric) 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; @@ -356,18 +336,13 @@ read_interface (const char *ifname, _unused int metric) 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)); @@ -391,7 +366,7 @@ read_interface (const char *ifname, _unused int metric) iface->listen_fd = -1; #endif -exit: +eexit: close(s); free(hwaddr); return iface; @@ -404,21 +379,16 @@ get_mtu(const char *ifname) 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; } @@ -429,10 +399,8 @@ set_mtu(const char *ifname, short int 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); @@ -440,10 +408,6 @@ set_mtu(const char *ifname, short int 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; } @@ -494,63 +458,86 @@ int 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; } diff --git a/if.h b/if.h index bb1ef15a..1bfe2b2b 100644 --- a/if.h +++ b/if.h @@ -138,8 +138,6 @@ int has_address(const char *, struct in_addr); 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); diff --git a/info.c b/info.c index 3901efa2..7224ede9 100644 --- a/info.c +++ b/info.c @@ -435,7 +435,7 @@ read_info(const struct interface *iface, struct dhcp *dhcp) } } 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")) diff --git a/signal.c b/signal.c index 050e1dc2..d6f29617 100644 --- a/signal.c +++ b/signal.c @@ -35,7 +35,6 @@ #include #include "common.h" -#include "logger.h" #include "signal.h" static int signal_pipe[2]; @@ -57,13 +56,10 @@ signal_handler(int sig) /* 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; @@ -128,10 +124,8 @@ signal_init(void) { 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]); @@ -142,10 +136,8 @@ signal_init(void) 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; @@ -162,10 +154,8 @@ signal_setup(void) 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; } @@ -181,10 +171,8 @@ signal_reset(void) 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; } diff --git a/socket.c b/socket.c index 4d345fbe..3bd765ac 100644 --- a/socket.c +++ b/socket.c @@ -53,7 +53,6 @@ #include "config.h" #include "dhcp.h" #include "if.h" -#include "logger.h" #include "socket.h" #include "bpf-filter.h" @@ -85,6 +84,42 @@ setup_packet_filters(void) 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) { @@ -96,60 +131,25 @@ 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 */ @@ -162,17 +162,10 @@ open_socket(struct interface *iface, int protocol) 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); @@ -181,6 +174,10 @@ open_socket(struct interface *iface, int protocol) iface->buffer_length = BUFFER_LENGTH; return fd; + +eexit: + close(fd); + return -1; } ssize_t @@ -192,15 +189,13 @@ send_packet(const struct interface *iface, int type, 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; } @@ -212,9 +207,7 @@ send_packet(const struct interface *iface, int type, 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. @@ -238,7 +231,6 @@ get_packet(const struct interface *iface, unsigned char *data, 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); @@ -254,13 +246,13 @@ get_packet(const struct interface *iface, unsigned char *data, 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; } diff --git a/socket.h b/socket.h index 37b01b0a..67366da8 100644 --- a/socket.h +++ b/socket.h @@ -33,7 +33,10 @@ #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);