Isolate the dhcp_option options[] array to options.c and provide abstract
accessors for its data.
This commit is contained in:
parent
16460699fc
commit
97978711de
@ -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
|
* (c) 2004-2011 Nicholas J. Kain <njkain at gmail dot com>
|
||||||
*
|
|
||||||
* Nicholas J. Kain <njkain at gmail dot com> 2004-2011
|
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -41,21 +40,20 @@
|
|||||||
|
|
||||||
/* 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 ifchd_cmd(char *buf, unsigned char *option, ssize_t optlen,
|
static int ifchd_cmd(char *buf, size_t buflen,
|
||||||
struct dhcp_option *type_p, unsigned int maxlen)
|
unsigned char *option, ssize_t optlen,
|
||||||
|
uint8_t code, enum option_type type, const char *optname)
|
||||||
{
|
{
|
||||||
char *obuf = buf;
|
char *obuf = buf;
|
||||||
uint8_t *ooption = option;
|
uint8_t *ooption = option;
|
||||||
enum option_type type = type_p->type;
|
|
||||||
ssize_t typelen = option_length(type);
|
ssize_t typelen = option_length(type);
|
||||||
uint8_t code = type_p->code;
|
|
||||||
|
|
||||||
if (!option)
|
if (!option || type == OPTION_NONE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (type == OPTION_STRING) {
|
if (type == OPTION_STRING) {
|
||||||
buf += snprintf(buf, maxlen, "%s:", type_p->name);
|
buf += snprintf(buf, buflen, "%s:", optname);
|
||||||
if (maxlen < optlen + 1)
|
if (buflen < optlen + 1)
|
||||||
return -1;
|
return -1;
|
||||||
memcpy(buf, option, optlen);
|
memcpy(buf, option, optlen);
|
||||||
buf[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(;;) {
|
for(;;) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OPTION_IP: {
|
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);
|
buf += strlen(buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPTION_U8:
|
case OPTION_U8:
|
||||||
buf += snprintf(buf, maxlen - (buf - obuf) - 1, "%u ", *option);
|
buf += snprintf(buf, buflen - (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) - 1, "%u ",
|
buf += snprintf(buf, buflen - (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) - 1, "%d ",
|
buf += snprintf(buf, buflen - (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) - 1, "%u ",
|
buf += snprintf(buf, buflen - (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) - 1, "%d ",
|
buf += snprintf(buf, buflen - (buf - obuf) - 1, "%d ",
|
||||||
ntohl(val_s32));
|
ntohl(val_s32));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -175,26 +173,16 @@ static void send_cmd(int sockfd, struct dhcpMessage *packet,
|
|||||||
unsigned char code)
|
unsigned char code)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
unsigned char *p;
|
unsigned char *optdata;
|
||||||
int i;
|
|
||||||
struct dhcp_option *opt = NULL;
|
|
||||||
ssize_t optlen;
|
ssize_t optlen;
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return;
|
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);
|
memset(buf, '\0', sizeof buf);
|
||||||
p = get_option(packet, code, &optlen);
|
optdata = get_option(packet, code, &optlen);
|
||||||
if (ifchd_cmd(buf, p, optlen, opt, sizeof buf) == -1)
|
if (ifchd_cmd(buf, sizeof buf, optdata, optlen, code, option_type(code),
|
||||||
|
option_name(code)) == -1)
|
||||||
return;
|
return;
|
||||||
sockwrite(sockfd, buf, strlen(buf));
|
sockwrite(sockfd, buf, strlen(buf));
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,14 @@ enum {
|
|||||||
OPT_DATA = 2
|
OPT_DATA = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dhcp_option {
|
||||||
|
char name[10];
|
||||||
|
enum option_type type;
|
||||||
|
unsigned char code;
|
||||||
|
};
|
||||||
|
|
||||||
/* supported options are easily added here */
|
/* supported options are easily added here */
|
||||||
struct dhcp_option options[] = {
|
static struct dhcp_option options[] = {
|
||||||
/* name[10] type code */
|
/* name[10] type code */
|
||||||
{"subnet" , OPTION_IP, 0x01},
|
{"subnet" , OPTION_IP, 0x01},
|
||||||
{"timezone" , OPTION_S32, 0x02},
|
{"timezone" , OPTION_S32, 0x02},
|
||||||
@ -77,6 +83,25 @@ static unsigned char list_opts[] = {
|
|||||||
0x00
|
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)
|
uint8_t option_length(enum option_type type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -62,14 +62,8 @@ enum option_type {
|
|||||||
OPTION_S32
|
OPTION_S32
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dhcp_option {
|
const char *option_name(uint8_t code);
|
||||||
char name[10];
|
enum option_type option_type(uint8_t code);
|
||||||
enum option_type type;
|
|
||||||
unsigned char code;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct dhcp_option options[];
|
|
||||||
|
|
||||||
uint8_t option_length(enum option_type type);
|
uint8_t option_length(enum option_type type);
|
||||||
int option_valid_list(uint8_t code);
|
int option_valid_list(uint8_t code);
|
||||||
size_t sizeof_option(unsigned char code, size_t datalen);
|
size_t sizeof_option(unsigned char code, size_t datalen);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user