Isolate the dhcp_option options[] array to options.c and provide abstract

accessors for its data.
This commit is contained in:
Nicholas J. Kain 2011-03-30 11:36:27 -04:00
parent 16460699fc
commit 97978711de
3 changed files with 48 additions and 41 deletions

View File

@ -1,8 +1,7 @@
/* ifchange.c
/* ifchange.c - functions to call the interface change daemon
* Time-stamp: <2011-03-30 11:33:42 nk>
*
* Functions to call the interface change daemon
*
* Nicholas J. Kain <njkain at gmail dot com> 2004-2011
* (c) 2004-2011 Nicholas J. Kain <njkain at gmail dot com>
*
* 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
@ -41,21 +40,20 @@
/* Fill buf with the ifchd command text of option 'option'. */
/* Returns 0 if successful, -1 if nothing was filled in. */
static int ifchd_cmd(char *buf, unsigned char *option, ssize_t optlen,
struct dhcp_option *type_p, unsigned int maxlen)
static int ifchd_cmd(char *buf, size_t buflen,
unsigned char *option, ssize_t optlen,
uint8_t code, enum option_type type, const char *optname)
{
char *obuf = buf;
uint8_t *ooption = option;
enum option_type type = type_p->type;
ssize_t typelen = option_length(type);
uint8_t code = type_p->code;
if (!option)
if (!option || type == OPTION_NONE)
return -1;
if (type == OPTION_STRING) {
buf += snprintf(buf, maxlen, "%s:", type_p->name);
if (maxlen < optlen + 1)
buf += snprintf(buf, buflen, "%s:", optname);
if (buflen < optlen + 1)
return -1;
memcpy(buf, option, optlen);
buf[optlen] = ':';
@ -77,43 +75,43 @@ static int ifchd_cmd(char *buf, unsigned char *option, ssize_t optlen,
}
}
buf += snprintf(buf, maxlen, "%s:", type_p->name);
buf += snprintf(buf, buflen, "%s:", optname);
for(;;) {
switch (type) {
case OPTION_IP: {
if (inet_ntop(AF_INET, option, buf, maxlen - (buf - obuf) - 1))
if (inet_ntop(AF_INET, option, buf, buflen - (buf - obuf) - 1))
buf += strlen(buf);
break;
}
case OPTION_U8:
buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%u ", *option);
buf += snprintf(buf, buflen - (buf - obuf) - 1, "%u ", *option);
break;
case OPTION_U16: {
uint16_t val_u16;
memcpy(&val_u16, option, 2);
buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%u ",
buf += snprintf(buf, buflen - (buf - obuf) - 1, "%u ",
ntohs(val_u16));
break;
}
case OPTION_S16: {
int16_t val_s16;
memcpy(&val_s16, option, 2);
buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%d ",
buf += snprintf(buf, buflen - (buf - obuf) - 1, "%d ",
ntohs(val_s16));
break;
}
case OPTION_U32: {
uint32_t val_u32;
memcpy(&val_u32, option, 4);
buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%u ",
buf += snprintf(buf, buflen - (buf - obuf) - 1, "%u ",
ntohl(val_u32));
break;
}
case OPTION_S32: {
int32_t val_s32;
memcpy(&val_s32, option, 4);
buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%d ",
buf += snprintf(buf, buflen - (buf - obuf) - 1, "%d ",
ntohl(val_s32));
break;
}
@ -175,26 +173,16 @@ static void send_cmd(int sockfd, struct dhcpMessage *packet,
unsigned char code)
{
char buf[256];
unsigned char *p;
int i;
struct dhcp_option *opt = NULL;
unsigned char *optdata;
ssize_t optlen;
if (!packet)
return;
for (i = 0; options[i].code; ++i) {
if (options[i].code == code) {
opt = &options[i];
break;
}
}
if (!opt)
return;
memset(buf, '\0', sizeof buf);
p = get_option(packet, code, &optlen);
if (ifchd_cmd(buf, p, optlen, opt, sizeof buf) == -1)
optdata = get_option(packet, code, &optlen);
if (ifchd_cmd(buf, sizeof buf, optdata, optlen, code, option_type(code),
option_name(code)) == -1)
return;
sockwrite(sockfd, buf, strlen(buf));
}

View File

@ -19,8 +19,14 @@ enum {
OPT_DATA = 2
};
struct dhcp_option {
char name[10];
enum option_type type;
unsigned char code;
};
/* supported options are easily added here */
struct dhcp_option options[] = {
static struct dhcp_option options[] = {
/* name[10] type code */
{"subnet" , OPTION_IP, 0x01},
{"timezone" , OPTION_S32, 0x02},
@ -77,6 +83,25 @@ static unsigned char list_opts[] = {
0x00
};
enum option_type option_type(uint8_t code)
{
int i;
for (i = 0; options[i].code; ++i)
if (options[i].code == code)
return options[i].type;
return OPTION_NONE;
}
static const char bad_option_name[] = "BADOPTION";
const char *option_name(uint8_t code)
{
int i;
for (i = 0; options[i].code; ++i)
if (options[i].code == code)
return options[i].name;
return bad_option_name;
}
uint8_t option_length(enum option_type type)
{
switch (type) {

View File

@ -62,14 +62,8 @@ enum option_type {
OPTION_S32
};
struct dhcp_option {
char name[10];
enum option_type type;
unsigned char code;
};
extern struct dhcp_option options[];
const char *option_name(uint8_t code);
enum option_type option_type(uint8_t code);
uint8_t option_length(enum option_type type);
int option_valid_list(uint8_t code);
size_t sizeof_option(unsigned char code, size_t datalen);