From 693c9256e416fb320622aeaf3ac2f7a854d556f1 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Sat, 13 Nov 2010 08:37:33 -0500 Subject: [PATCH] Add safe_read() to ncmlib and use it in ndhc. --- ncmlib/io.c | 26 +++++++++++++++++++---- ncmlib/io.h | 3 ++- ndhc/clientpacket.c | 52 +++++++++++++++++++++------------------------ ndhc/packet.c | 6 +++--- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/ncmlib/io.c b/ncmlib/io.c index 97cf8a7..3bda0dc 100644 --- a/ncmlib/io.c +++ b/ncmlib/io.c @@ -1,5 +1,5 @@ /* io.c - light wrappers for POSIX i/o functions - * Time-stamp: <2010-11-13 08:08:39 njk> + * Time-stamp: <2010-11-13 08:22:53 njk> * * (c) 2010 Nicholas J. Kain * All rights reserved. @@ -30,11 +30,29 @@ #include #include -// returns -1 on error, >= 0 on success +/* returns -1 on error, >= 0 and equal to # chars read on success */ +int safe_read(int fd, char *buf, int len) +{ + int r, s = 0; + while (s < len) { + r = read(fd, buf + s, len - s); + if (r == 0) + break; + if (r == -1) { + if (errno == EINTR) + continue; + else + return -1; + } + s += r; + } + return s; +} + +/* returns -1 on error, >= 0 and equal to # chars written on success */ int safe_write(int fd, const char *buf, int len) { - int r; - int s = 0; + int r, s = 0; while (s < len) { r = write(fd, buf + s, len - s); if (r == -1) { diff --git a/ncmlib/io.h b/ncmlib/io.h index 719dce9..9e24419 100644 --- a/ncmlib/io.h +++ b/ncmlib/io.h @@ -1,5 +1,5 @@ /* io.h - light wrappers for POSIX i/o functions - * Time-stamp: <2010-11-13 08:07:43 njk> + * Time-stamp: <2010-11-13 08:22:48 njk> * * (c) 2010 Nicholas J. Kain * All rights reserved. @@ -30,6 +30,7 @@ #ifndef NCM_IO_H_ #define NCM_IO_H_ +int safe_read(int fd, char *buf, int len); int safe_write(int fd, const char *buf, int len); #endif /* NCM_IO_H_ */ diff --git a/ndhc/clientpacket.c b/ndhc/clientpacket.c index a4eb325..d52b9a3 100644 --- a/ndhc/clientpacket.c +++ b/ndhc/clientpacket.c @@ -41,26 +41,31 @@ #include "options.h" #include "dhcpc.h" #include "log.h" +#include "io.h" /* Create a random xid */ uint32_t random_xid(void) { static int initialized; - if (!initialized) { - int fd; - uint32_t seed; + if (initialized) + return rand(); - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1 || read(fd, &seed, sizeof seed) < 0) { - log_warning("Could not load seed from /dev/urandom: %s", - strerror(errno)); - seed = time(0); + uint32_t seed; + int fd = open("/dev/urandom", O_RDONLY); + if (fd != -1) { + int r = safe_read(fd, (char *)&seed, sizeof seed); + if (r == -1) { + log_warning("Could not read /dev/urandom: %s", strerror(errno)); + close(fd); + seed = time(0); } - if (fd != -1) - close(fd); - srand(seed); - initialized++; + } else { + log_warning("Could not open /dev/urandom: %s", + strerror(errno)); + seed = time(0); } + srand(seed); + initialized = 1; return rand(); } @@ -178,24 +183,15 @@ int get_raw_packet(struct dhcpMessage *payload, int fd) struct udp_dhcp_packet packet; uint32_t source, dest; uint16_t check; - - ssize_t len = 0; - const ssize_t header_size = sizeof(struct iphdr) + sizeof(struct udphdr); - const ssize_t packet_size = sizeof(struct udp_dhcp_packet); + const int header_size = sizeof(struct iphdr) + sizeof(struct udphdr); + const int packet_size = sizeof(struct udp_dhcp_packet); memset(&packet, 0, packet_size); - while (len < packet_size) { - ssize_t r = read(fd, ((char *)&packet) + len, packet_size - len); - if (r == 0) - break; - if (r == -1) { - if (errno == EINTR) - continue; - log_line("get_raw_packet: read error %s", strerror(errno)); - usleep(500000); /* possible down interface, looping condition */ - return -1; - } - len += r; + int len = safe_read(fd, (char *)&packet, packet_size); + if (len == -1) { + log_line("get_raw_packet: read error %s", strerror(errno)); + usleep(500000); /* possible down interface, looping condition */ + return -1; } if (len < header_size) { diff --git a/ndhc/packet.c b/ndhc/packet.c index 1fc5763..a03c4c9 100644 --- a/ndhc/packet.c +++ b/ndhc/packet.c @@ -48,9 +48,9 @@ int get_packet(struct dhcpMessage *packet, int fd) unsigned char *vendor; memset(packet, 0, sizeof(struct dhcpMessage)); - bytes = read(fd, packet, sizeof(struct dhcpMessage)); - if (bytes < 0) { - log_line("couldn't read on listening socket, ignoring"); + bytes = safe_read(fd, (char *)packet, sizeof(struct dhcpMessage)); + if (bytes == -1) { + log_line("read on listen socket failed: %s", strerror(errno)); return -1; }