Add safe_read() to ncmlib and use it in ndhc.
This commit is contained in:
parent
a43e69c7ae
commit
693c9256e4
26
ncmlib/io.c
26
ncmlib/io.c
@ -1,5 +1,5 @@
|
|||||||
/* io.c - light wrappers for POSIX i/o functions
|
/* 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 <njkain at gmail dot com>
|
* (c) 2010 Nicholas J. Kain <njkain at gmail dot com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -30,11 +30,29 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
// 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 safe_write(int fd, const char *buf, int len)
|
||||||
{
|
{
|
||||||
int r;
|
int r, s = 0;
|
||||||
int s = 0;
|
|
||||||
while (s < len) {
|
while (s < len) {
|
||||||
r = write(fd, buf + s, len - s);
|
r = write(fd, buf + s, len - s);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* io.h - light wrappers for POSIX i/o functions
|
/* 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 <njkain at gmail dot com>
|
* (c) 2010 Nicholas J. Kain <njkain at gmail dot com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#ifndef NCM_IO_H_
|
#ifndef NCM_IO_H_
|
||||||
#define 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);
|
int safe_write(int fd, const char *buf, int len);
|
||||||
|
|
||||||
#endif /* NCM_IO_H_ */
|
#endif /* NCM_IO_H_ */
|
||||||
|
@ -41,26 +41,31 @@
|
|||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "dhcpc.h"
|
#include "dhcpc.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
/* Create a random xid */
|
/* Create a random xid */
|
||||||
uint32_t random_xid(void)
|
uint32_t random_xid(void)
|
||||||
{
|
{
|
||||||
static int initialized;
|
static int initialized;
|
||||||
if (!initialized) {
|
if (initialized)
|
||||||
int fd;
|
return rand();
|
||||||
uint32_t seed;
|
|
||||||
|
|
||||||
fd = open("/dev/urandom", O_RDONLY);
|
uint32_t seed;
|
||||||
if (fd == -1 || read(fd, &seed, sizeof seed) < 0) {
|
int fd = open("/dev/urandom", O_RDONLY);
|
||||||
log_warning("Could not load seed from /dev/urandom: %s",
|
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);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_warning("Could not open /dev/urandom: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
seed = time(0);
|
seed = time(0);
|
||||||
}
|
}
|
||||||
if (fd != -1)
|
|
||||||
close(fd);
|
|
||||||
srand(seed);
|
srand(seed);
|
||||||
initialized++;
|
initialized = 1;
|
||||||
}
|
|
||||||
return rand();
|
return rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,25 +183,16 @@ int get_raw_packet(struct dhcpMessage *payload, int fd)
|
|||||||
struct udp_dhcp_packet packet;
|
struct udp_dhcp_packet packet;
|
||||||
uint32_t source, dest;
|
uint32_t source, dest;
|
||||||
uint16_t check;
|
uint16_t check;
|
||||||
|
const int header_size = sizeof(struct iphdr) + sizeof(struct udphdr);
|
||||||
ssize_t len = 0;
|
const int packet_size = sizeof(struct udp_dhcp_packet);
|
||||||
const ssize_t header_size = sizeof(struct iphdr) + sizeof(struct udphdr);
|
|
||||||
const ssize_t packet_size = sizeof(struct udp_dhcp_packet);
|
|
||||||
|
|
||||||
memset(&packet, 0, packet_size);
|
memset(&packet, 0, packet_size);
|
||||||
while (len < packet_size) {
|
int len = safe_read(fd, (char *)&packet, packet_size);
|
||||||
ssize_t r = read(fd, ((char *)&packet) + len, packet_size - len);
|
if (len == -1) {
|
||||||
if (r == 0)
|
|
||||||
break;
|
|
||||||
if (r == -1) {
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
log_line("get_raw_packet: read error %s", strerror(errno));
|
log_line("get_raw_packet: read error %s", strerror(errno));
|
||||||
usleep(500000); /* possible down interface, looping condition */
|
usleep(500000); /* possible down interface, looping condition */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
len += r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len < header_size) {
|
if (len < header_size) {
|
||||||
log_line("Message too short to contain IP + UDP headers, ignoring");
|
log_line("Message too short to contain IP + UDP headers, ignoring");
|
||||||
|
@ -48,9 +48,9 @@ int get_packet(struct dhcpMessage *packet, int fd)
|
|||||||
unsigned char *vendor;
|
unsigned char *vendor;
|
||||||
|
|
||||||
memset(packet, 0, sizeof(struct dhcpMessage));
|
memset(packet, 0, sizeof(struct dhcpMessage));
|
||||||
bytes = read(fd, packet, sizeof(struct dhcpMessage));
|
bytes = safe_read(fd, (char *)packet, sizeof(struct dhcpMessage));
|
||||||
if (bytes < 0) {
|
if (bytes == -1) {
|
||||||
log_line("couldn't read on listening socket, ignoring");
|
log_line("read on listen socket failed: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user