Update get_option() to use the function from busybox's udhcp variant;
it's much easier to read. The original one is indecipherable, and thus it is difficult to verify correctness.
This commit is contained in:
parent
1ffd1d9df3
commit
5a38e49a81
21
ndhc/dhcpd.h
21
ndhc/dhcpd.h
@ -5,13 +5,6 @@
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
/************************************/
|
||||
/* Defaults _you_ may want to tweak */
|
||||
/************************************/
|
||||
|
||||
/* the period of time the client is allowed to use that address */
|
||||
#define LEASE_TIME (60*60*24*10) /* 10 days of seconds */
|
||||
|
||||
/*****************************************************************/
|
||||
/* Do not modify below here unless you know what you are doing!! */
|
||||
/*****************************************************************/
|
||||
@ -42,11 +35,13 @@
|
||||
#define DHCP_IP_TTL 0x17
|
||||
#define DHCP_MTU 0x1a
|
||||
#define DHCP_BROADCAST 0x1c
|
||||
#define DHCP_NIS_DOMAIN 0x28
|
||||
#define DHCP_NIS_SERVER 0x29
|
||||
#define DHCP_NTP_SERVER 0x2a
|
||||
#define DHCP_WINS_SERVER 0x2c
|
||||
#define DHCP_REQUESTED_IP 0x32
|
||||
#define DHCP_LEASE_TIME 0x33
|
||||
#define DHCP_OPTION_OVER 0x34
|
||||
#define DHCP_OPTION_OVERLOAD 0x34
|
||||
#define DHCP_MESSAGE_TYPE 0x35
|
||||
#define DHCP_SERVER_ID 0x36
|
||||
#define DHCP_PARAM_REQ 0x37
|
||||
@ -56,7 +51,15 @@
|
||||
#define DHCP_T2 0x3b
|
||||
#define DHCP_VENDOR 0x3c
|
||||
#define DHCP_CLIENT_ID 0x3d
|
||||
#define DHCP_END 0xFF
|
||||
#define DHCP_TFTP_SERVER_NAME 0x42
|
||||
#define DHCP_BOOT_FILE 0x43
|
||||
#define DHCP_USER_CLASS 0x4d
|
||||
#define DHCP_FQDN 0x51
|
||||
#define DHCP_DOMAIN_SEARCH 0x77
|
||||
#define DHCP_SIP_SERVERS 0x78
|
||||
#define DHCP_STATIC_ROUTES 0x79
|
||||
#define DHCP_WPAD 0xfc
|
||||
#define DHCP_END 0xff
|
||||
|
||||
enum {
|
||||
BOOTREQUEST = 1,
|
||||
|
@ -58,59 +58,63 @@ int option_lengths[] = {
|
||||
};
|
||||
|
||||
|
||||
/* get an option with bounds checking (warning, not aligned). */
|
||||
unsigned char *get_option(struct dhcpMessage *packet, int code)
|
||||
/* Get an option with bounds checking (warning, result is not aligned) */
|
||||
uint8_t* get_option(struct dhcpMessage *packet, int code)
|
||||
{
|
||||
int i = 0, length = DHCP_OPTIONS_BUFSIZE;
|
||||
unsigned char *optionptr;
|
||||
int over = 0, done = 0, curr = OPTION_FIELD;
|
||||
uint8_t *optionptr;
|
||||
int len, rem, overload = 0;
|
||||
enum {
|
||||
FILE_FIELD101 = FILE_FIELD * 0x101,
|
||||
SNAME_FIELD101 = SNAME_FIELD * 0x101,
|
||||
};
|
||||
|
||||
/* option bytes: [code][len][data1][data2]..[dataLEN] */
|
||||
optionptr = packet->options;
|
||||
while (!done) {
|
||||
if (i >= length) {
|
||||
log_warning("bogus packet, option fields too long.");
|
||||
rem = sizeof packet->options;
|
||||
while (1) {
|
||||
if (rem <= 0) {
|
||||
log_warning("Bad packet, malformed option field.");
|
||||
return NULL;
|
||||
}
|
||||
if (optionptr[i + OPT_CODE] == code) {
|
||||
if (i + 1 + optionptr[i + OPT_LEN] >= length) {
|
||||
log_warning("bogus packet, option fields too long.");
|
||||
return NULL;
|
||||
if (optionptr[OPT_CODE] == DHCP_PADDING) {
|
||||
rem--;
|
||||
optionptr++;
|
||||
continue;
|
||||
}
|
||||
if (optionptr[OPT_CODE] == DHCP_END) {
|
||||
if ((overload & FILE_FIELD101) == FILE_FIELD) {
|
||||
/* can use packet->file, and didn't look at it yet */
|
||||
overload |= FILE_FIELD101; /* "we looked at it" */
|
||||
optionptr = packet->file;
|
||||
rem = sizeof packet->file;
|
||||
continue;
|
||||
}
|
||||
return optionptr + i + 2;
|
||||
if ((overload & SNAME_FIELD101) == SNAME_FIELD) {
|
||||
/* can use packet->sname, and didn't look at it yet */
|
||||
overload |= SNAME_FIELD101; /* "we looked at it" */
|
||||
optionptr = packet->sname;
|
||||
rem = sizeof packet->sname;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (optionptr[i + OPT_CODE]) {
|
||||
case DHCP_PADDING:
|
||||
i++;
|
||||
break;
|
||||
case DHCP_OPTION_OVER:
|
||||
if (i + 1 + optionptr[i + OPT_LEN] >= length) {
|
||||
log_warning("bogus packet, option fields too long.");
|
||||
return NULL;
|
||||
}
|
||||
over = optionptr[i + 3];
|
||||
i += optionptr[OPT_LEN] + 2;
|
||||
break;
|
||||
case DHCP_END:
|
||||
if (curr == OPTION_FIELD && over & FILE_FIELD) {
|
||||
optionptr = packet->file;
|
||||
i = 0;
|
||||
length = 128;
|
||||
curr = FILE_FIELD;
|
||||
} else if (curr == FILE_FIELD && over & SNAME_FIELD) {
|
||||
optionptr = packet->sname;
|
||||
i = 0;
|
||||
length = 64;
|
||||
curr = SNAME_FIELD;
|
||||
} else done = 1;
|
||||
break;
|
||||
default:
|
||||
i += optionptr[OPT_LEN + i] + 2;
|
||||
len = 2 + optionptr[OPT_LEN];
|
||||
rem -= len;
|
||||
if (rem < 0)
|
||||
continue; /* complain and return NULL */
|
||||
|
||||
if (optionptr[OPT_CODE] == code)
|
||||
return optionptr + OPT_DATA;
|
||||
|
||||
if (optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD) {
|
||||
overload |= optionptr[OPT_DATA];
|
||||
/* fall through */
|
||||
}
|
||||
optionptr += len;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* return the position of the 'end' option */
|
||||
int end_option(unsigned char *optionptr)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ struct dhcp_option {
|
||||
extern struct dhcp_option options[];
|
||||
extern int option_lengths[];
|
||||
|
||||
unsigned char *get_option(struct dhcpMessage *packet, int code);
|
||||
uint8_t *get_option(struct dhcpMessage *packet, int code);
|
||||
int end_option(unsigned char *optionptr);
|
||||
int add_option_string(unsigned char *optionptr, unsigned char *string);
|
||||
int add_simple_option(unsigned char *optionptr, unsigned char code, uint32_t data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user