From 5f55dbc3ff60309b7322dd2d0261182a0c2e0e64 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Fri, 12 Nov 2010 19:43:16 -0500 Subject: [PATCH] Fix previous commit -- handle filling empty options properly. Clean up pidfile defaults and help message. Clean up the write/sendto fixes to be a bit more readable. --- ndhc/ndhc.c | 11 ++++++----- ndhc/packet.c | 10 ++++------ ndhc/script.c | 28 +++++++++++++++++----------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/ndhc/ndhc.c b/ndhc/ndhc.c index 54786ac..c40b7e4 100644 --- a/ndhc/ndhc.c +++ b/ndhc/ndhc.c @@ -1,6 +1,6 @@ -/* dhcpc.c +/* ndhc.c * - * ndhc DHCP client + * ndhc DHCP client, originally based on udhcpc * * Nicholas J. Kain 2004-2010 * Russ Dill July 2001 @@ -93,6 +93,7 @@ static void show_usage(void) " -f, --foreground Do not fork after getting lease\n" " -b, --background Fork to background if lease cannot be\n" " immediately negotiated.\n" +" -p, --pidfile File to which the pid will be written\n" " -i, --interface=INTERFACE Interface to use (default: eth0)\n" " -n, --now Exit with failure if lease cannot be\n" " immediately negotiated.\n" @@ -458,8 +459,8 @@ static int do_work(void) int main(int argc, char **argv) { - char pidfile[MAX_PATH_LENGTH] = ""; - char chroot_dir[MAX_PATH_LENGTH] = PID_FILE_DEFAULT; + char pidfile[MAX_PATH_LENGTH] = PID_FILE_DEFAULT; + char chroot_dir[MAX_PATH_LENGTH] = ""; int c, len; struct passwd *pwd; uid_t uid = 0; @@ -507,7 +508,7 @@ int main(int argc, char **argv) client_config.background_if_no_lease = 1; break; case 'p': - strlcpy(pidfile, optarg, MAX_PATH_LENGTH); + strlcpy(pidfile, optarg, sizeof pidfile); break; case 'h': case 'H': diff --git a/ndhc/packet.c b/ndhc/packet.c index 486cdcb..da5d5a6 100644 --- a/ndhc/packet.c +++ b/ndhc/packet.c @@ -152,7 +152,7 @@ int raw_packet(struct dhcpMessage *payload, uint32_t source_ip, int remain = sizeof(struct udp_dhcp_packet); int sent = 0; while (1) { - result = sendto(fd, &packet + sent, remain, 0, + result = sendto(fd, &packet + sent, remain - sent, 0, (struct sockaddr *)&dest, sizeof dest); if (result == -1) { if (errno == EINTR) @@ -160,9 +160,8 @@ int raw_packet(struct dhcpMessage *payload, uint32_t source_ip, log_error("raw_packet: sendto failed: %s", strerror(errno)); break; } - remain =- result; sent += result; - if (remain == 0) + if (remain == sent) break; } out_fd: @@ -203,16 +202,15 @@ int kernel_packet(struct dhcpMessage *payload, uint32_t source_ip, int remain = sizeof(struct dhcpMessage); int sent = 0; while (1) { - result = write(fd, payload + sent, remain); + result = write(fd, payload + sent, remain - sent); if (result == -1) { if (errno == EINTR) continue; log_error("kernel_packet: write failed: %s", strerror(errno)); break; } - remain =- result; sent += result; - if (remain == 0) + if (remain == sent) break; } out_fd: diff --git a/ndhc/script.c b/ndhc/script.c index d372f0f..15e4ad1 100644 --- a/ndhc/script.c +++ b/ndhc/script.c @@ -54,7 +54,8 @@ static int sprintip(char *dest, size_t size, char *pre, unsigned char *ip) } /* Fill dest with the text of option 'option'. */ -static void fill_options(char *dest, unsigned char *option, +/* Returns 0 if successful, -1 if nothing was filled in. */ +static int fill_options(char *dest, unsigned char *option, struct dhcp_option *type_p, unsigned int maxlen) { int type, optlen; @@ -62,9 +63,12 @@ static void fill_options(char *dest, unsigned char *option, int16_t val_s16; uint32_t val_u32; int32_t val_s32; - int len = option[OPT_LEN - 2]; char *odest; + if (!option) + return -1; + int len = option[OPT_LEN - 2]; + odest = dest; dest += snprintf(dest, maxlen, "%s=", type_p->name); @@ -113,10 +117,11 @@ static void fill_options(char *dest, unsigned char *option, "%ld ", (long) ntohl(val_s32)); break; case OPTION_STRING: - if ( (maxlen - (dest - odest)) < (unsigned)len) return; + if ( (maxlen - (dest - odest)) < (unsigned)len) + return -1; memcpy(dest, option, len); dest[len] = '\0'; - return; /* Short circuit this case */ + return 0; /* Short circuit this case */ } option += optlen; len -= optlen; @@ -124,6 +129,7 @@ static void fill_options(char *dest, unsigned char *option, break; *(dest++) = ':'; } + return 0; } static int open_ifch(void) { @@ -147,22 +153,20 @@ static int open_ifch(void) { static void sockwrite(int fd, const char *buf, size_t count) { int ret; - int remain = count; int sent = 0; while (1) { - ret = write(fd, buf + sent, remain); + ret = write(fd, buf + sent, count - sent); if (ret == -1) { if (errno == EINTR) continue; log_error("sockwrite: write failed: %s", strerror(errno)); break; } - remain =- ret; sent += ret; - if (remain == 0) + if (sent == count) break; } - log_line("writing: %s", (char *)buf); + log_line("writing: %s", buf); } static void deconfig_if(void) @@ -190,13 +194,15 @@ static void translate_option(int sockfd, struct dhcpMessage *packet, int opt) unsigned char *p; int i; - if (!packet) return; + if (!packet) + return; memset(buf, '\0', sizeof(buf)); memset(buf2, '\0', sizeof(buf2)); p = get_option(packet, options[opt].code); - fill_options(buf2, p, &options[opt], sizeof(buf2) - 1); + if (fill_options(buf2, p, &options[opt], sizeof(buf2) - 1) == -1) + return; snprintf(buf, sizeof buf, "%s:", buf2); for (i=0; i<256; i++) { if (buf[i] == '\0') break;