Use inet_ntop() in ifchange.c rather than a homebrew function.

Get rid of a lousy hack in ifchange.c that translated the output of ifchd_cmd()
by changing every '=' to a ':'.  ifchd_cmd() is not called anywhere else, so
just make ifchd_cmd() generate the proper output.
Make buffer size accounting stricter.
This commit is contained in:
Nicholas J. Kain 2011-03-30 11:16:38 -04:00
parent 97137ec3fc
commit 16460699fc

View File

@ -2,8 +2,7 @@
* *
* Functions to call the interface change daemon * Functions to call the interface change daemon
* *
* Russ Dill <Russ.Dill@asu.edu> July 2001 * Nicholas J. Kain <njkain at gmail dot com> 2004-2011
* Nicholas J. Kain <njkain at gmail dot com> 2004-2010
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -40,41 +39,26 @@
#include "io.h" #include "io.h"
#include "ifchange.h" #include "ifchange.h"
static int snprintip(char *dest, size_t size, unsigned char *ip)
{
if (!dest)
return -1;
return snprintf(dest, size, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
}
static int sprintip(char *dest, size_t size, char *pre, unsigned char *ip)
{
if (!dest)
return -1;
return snprintf(dest, size, "%s%d.%d.%d.%d",
pre, ip[0], ip[1], ip[2], ip[3]);
}
/* Fill buf with the ifchd command text of option 'option'. */ /* Fill buf with the ifchd command text of option 'option'. */
/* Returns 0 if successful, -1 if nothing was filled in. */ /* Returns 0 if successful, -1 if nothing was filled in. */
static int fill_options(char *buf, unsigned char *option, ssize_t optlen, static int ifchd_cmd(char *buf, unsigned char *option, ssize_t optlen,
struct dhcp_option *type_p, unsigned int maxlen) struct dhcp_option *type_p, unsigned int maxlen)
{ {
char *obuf = buf; char *obuf = buf;
uint8_t *ooption = option;
enum option_type type = type_p->type; enum option_type type = type_p->type;
ssize_t typelen = option_length(type); ssize_t typelen = option_length(type);
ssize_t rem = optlen;
uint8_t code = type_p->code; uint8_t code = type_p->code;
if (!option) if (!option)
return -1; return -1;
if (type == OPTION_STRING) { if (type == OPTION_STRING) {
buf += snprintf(buf, maxlen, "%s=", type_p->name); buf += snprintf(buf, maxlen, "%s:", type_p->name);
if (maxlen < rem + 1) if (maxlen < optlen + 1)
return -1; return -1;
memcpy(buf, option, rem); memcpy(buf, option, optlen);
buf[rem] = '\0'; buf[optlen] = ':';
return 0; return 0;
} }
@ -93,41 +77,43 @@ static int fill_options(char *buf, unsigned char *option, ssize_t optlen,
} }
} }
buf += snprintf(buf, maxlen, "%s=", type_p->name); buf += snprintf(buf, maxlen, "%s:", type_p->name);
for(;;) { for(;;) {
switch (type) { switch (type) {
case OPTION_IP: /* Works regardless of host byte order. */ case OPTION_IP: {
buf += sprintip(buf, maxlen - (buf - obuf), "", option); if (inet_ntop(AF_INET, option, buf, maxlen - (buf - obuf) - 1))
buf += strlen(buf);
break; break;
}
case OPTION_U8: case OPTION_U8:
buf += snprintf(buf, maxlen - (buf - obuf), "%u ", *option); buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%u ", *option);
break; break;
case OPTION_U16: { case OPTION_U16: {
uint16_t val_u16; uint16_t val_u16;
memcpy(&val_u16, option, 2); memcpy(&val_u16, option, 2);
buf += snprintf(buf, maxlen - (buf - obuf), "%u ", buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%u ",
ntohs(val_u16)); ntohs(val_u16));
break; break;
} }
case OPTION_S16: { case OPTION_S16: {
int16_t val_s16; int16_t val_s16;
memcpy(&val_s16, option, 2); memcpy(&val_s16, option, 2);
buf += snprintf(buf, maxlen - (buf - obuf), "%d ", buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%d ",
ntohs(val_s16)); ntohs(val_s16));
break; break;
} }
case OPTION_U32: { case OPTION_U32: {
uint32_t val_u32; uint32_t val_u32;
memcpy(&val_u32, option, 4); memcpy(&val_u32, option, 4);
buf += snprintf(buf, maxlen - (buf - obuf), "%u ", buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%u ",
ntohl(val_u32)); ntohl(val_u32));
break; break;
} }
case OPTION_S32: { case OPTION_S32: {
int32_t val_s32; int32_t val_s32;
memcpy(&val_s32, option, 4); memcpy(&val_s32, option, 4);
buf += snprintf(buf, maxlen - (buf - obuf), "%d ", buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%d ",
ntohl(val_s32)); ntohl(val_s32));
break; break;
} }
@ -135,11 +121,11 @@ static int fill_options(char *buf, unsigned char *option, ssize_t optlen,
return 0; return 0;
} }
option += typelen; option += typelen;
rem -= typelen; if ((option - ooption) >= optlen)
if (rem <= 0)
break; break;
*(buf++) = ':'; *(buf++) = ':';
} }
*(buf++) = ':';
return 0; return 0;
} }
@ -185,10 +171,10 @@ static void deconfig_if(void)
close(sockfd); close(sockfd);
} }
static void translate_option(int sockfd, struct dhcpMessage *packet, static void send_cmd(int sockfd, struct dhcpMessage *packet,
unsigned char code) unsigned char code)
{ {
char buf[256], buf2[256]; char buf[256];
unsigned char *p; unsigned char *p;
int i; int i;
struct dhcp_option *opt = NULL; struct dhcp_option *opt = NULL;
@ -206,21 +192,10 @@ static void translate_option(int sockfd, struct dhcpMessage *packet,
if (!opt) if (!opt)
return; return;
memset(buf, '\0', sizeof(buf)); memset(buf, '\0', sizeof buf);
memset(buf2, '\0', sizeof(buf2));
p = get_option(packet, code, &optlen); p = get_option(packet, code, &optlen);
if (fill_options(buf2, p, optlen, opt, sizeof buf2 - 1) == -1) if (ifchd_cmd(buf, p, optlen, opt, sizeof buf) == -1)
return; return;
snprintf(buf, sizeof buf, "%s:", buf2);
for (i = 0; i < 256; i++) {
if (buf[i] == '\0')
break;
if (buf[i] == '=') {
buf[i] = ':';
break;
}
}
sockwrite(sockfd, buf, strlen(buf)); sockwrite(sockfd, buf, strlen(buf));
} }
@ -238,18 +213,18 @@ static void bound_if(struct dhcpMessage *packet)
snprintf(buf, sizeof buf, "interface:%s:", client_config.interface); snprintf(buf, sizeof buf, "interface:%s:", client_config.interface);
sockwrite(sockfd, buf, strlen(buf)); sockwrite(sockfd, buf, strlen(buf));
snprintip(ip, sizeof ip, (unsigned char *) &packet->yiaddr); inet_ntop(AF_INET, &packet->yiaddr, ip, sizeof ip);
snprintf(buf, sizeof buf, "ip:%s:", ip); snprintf(buf, sizeof buf, "ip:%s:", ip);
sockwrite(sockfd, buf, strlen(buf)); sockwrite(sockfd, buf, strlen(buf));
translate_option(sockfd, packet, DHCP_SUBNET); send_cmd(sockfd, packet, DHCP_SUBNET);
translate_option(sockfd, packet, DHCP_ROUTER); send_cmd(sockfd, packet, DHCP_ROUTER);
translate_option(sockfd, packet, DHCP_DNS_SERVER); send_cmd(sockfd, packet, DHCP_DNS_SERVER);
translate_option(sockfd, packet, DHCP_HOST_NAME); send_cmd(sockfd, packet, DHCP_HOST_NAME);
translate_option(sockfd, packet, DHCP_DOMAIN_NAME); send_cmd(sockfd, packet, DHCP_DOMAIN_NAME);
translate_option(sockfd, packet, DHCP_MTU); send_cmd(sockfd, packet, DHCP_MTU);
translate_option(sockfd, packet, DHCP_BROADCAST); send_cmd(sockfd, packet, DHCP_BROADCAST);
translate_option(sockfd, packet, DHCP_WINS_SERVER); send_cmd(sockfd, packet, DHCP_WINS_SERVER);
close(sockfd); close(sockfd);
} }