Add new code for creating DHCP option data, and use it in ndhc.c.
This commit is contained in:
parent
13d9119f3a
commit
3c85228aaf
19
ndhc/ndhc.c
19
ndhc/ndhc.c
@ -296,10 +296,8 @@ int main(int argc, char **argv)
|
|||||||
len = strlen(optarg) > 64 ? 64 : strlen(optarg);
|
len = strlen(optarg) > 64 ? 64 : strlen(optarg);
|
||||||
if (client_config.clientid)
|
if (client_config.clientid)
|
||||||
free(client_config.clientid);
|
free(client_config.clientid);
|
||||||
client_config.clientid = xmalloc(len + 3);
|
client_config.clientid =
|
||||||
client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
|
alloc_dhcp_client_id_option(0, (unsigned char *)optarg, len);
|
||||||
client_config.clientid[OPT_LEN] = len + 1;
|
|
||||||
memcpy(client_config.clientid + 3, optarg, len);
|
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
client_config.foreground = 1;
|
client_config.foreground = 1;
|
||||||
@ -317,10 +315,8 @@ int main(int argc, char **argv)
|
|||||||
len = strlen(optarg) > 64 ? 64 : strlen(optarg);
|
len = strlen(optarg) > 64 ? 64 : strlen(optarg);
|
||||||
if (client_config.hostname)
|
if (client_config.hostname)
|
||||||
free(client_config.hostname);
|
free(client_config.hostname);
|
||||||
client_config.hostname = xmalloc(len + 3);
|
client_config.hostname =
|
||||||
client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
|
alloc_option(DHCP_HOST_NAME, (unsigned char *)optarg, len);
|
||||||
client_config.hostname[OPT_LEN] = len + 1;
|
|
||||||
memcpy(client_config.hostname + 3, optarg, len);
|
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
client_config.interface = optarg;
|
client_config.interface = optarg;
|
||||||
@ -376,11 +372,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!client_config.clientid) {
|
if (!client_config.clientid) {
|
||||||
client_config.clientid = xmalloc(6 + 3);
|
client_config.clientid =
|
||||||
client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
|
alloc_dhcp_client_id_option(1, client_config.arp, 6);
|
||||||
client_config.clientid[OPT_LEN] = 7;
|
|
||||||
client_config.clientid[OPT_DATA] = 1;
|
|
||||||
memcpy(client_config.clientid + 3, client_config.arp, 6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chdir(chroot_dir)) {
|
if (chdir(chroot_dir)) {
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "log.h"
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
|
||||||
/* supported options are easily added here */
|
/* supported options are easily added here */
|
||||||
struct dhcp_option options[] = {
|
struct dhcp_option options[] = {
|
||||||
/* name[10] flags code */
|
/* name[10] flags code */
|
||||||
@ -56,6 +58,55 @@ int option_lengths[] = {
|
|||||||
[OPTION_S32] = 4
|
[OPTION_S32] = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
size_t sizeof_option(unsigned char code, size_t datalen)
|
||||||
|
{
|
||||||
|
if (code == DHCP_PADDING || code == DHCP_END)
|
||||||
|
return 1;
|
||||||
|
return 2 + datalen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optdata can be NULL
|
||||||
|
size_t set_option(unsigned char *buf, size_t buflen, unsigned char code,
|
||||||
|
unsigned char *optdata, size_t datalen)
|
||||||
|
{
|
||||||
|
if (!optdata)
|
||||||
|
datalen = 0;
|
||||||
|
if (code == DHCP_PADDING || code == DHCP_END) {
|
||||||
|
if (buflen < 1)
|
||||||
|
return 0;
|
||||||
|
buf[0] = code;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (datalen > 255 || buflen < 2 + datalen)
|
||||||
|
return 0;
|
||||||
|
buf[0] = code;
|
||||||
|
buf[1] = datalen;
|
||||||
|
memcpy(buf + 2, optdata, datalen);
|
||||||
|
return 2 + datalen;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *alloc_option(unsigned char code, unsigned char *optdata,
|
||||||
|
size_t datalen)
|
||||||
|
{
|
||||||
|
unsigned char *ret;
|
||||||
|
size_t len = sizeof_option(code, datalen);
|
||||||
|
ret = xmalloc(len);
|
||||||
|
set_option(ret, len, code, optdata, datalen);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is tricky -- the data must be prefixed by one byte indicating the
|
||||||
|
// type of ARP MAC address (1 for ethernet) or 0 for a purely symbolic
|
||||||
|
// identifier.
|
||||||
|
unsigned char *alloc_dhcp_client_id_option(unsigned char type,
|
||||||
|
unsigned char *idstr, size_t idstrlen)
|
||||||
|
{
|
||||||
|
unsigned char data[idstrlen + 1];
|
||||||
|
data[0] = type;
|
||||||
|
memcpy(data + 1, idstr, idstrlen);
|
||||||
|
return alloc_option(DHCP_CLIENT_ID, data, sizeof data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get an option with bounds checking (warning, result is not aligned) */
|
/* Get an option with bounds checking (warning, result is not aligned) */
|
||||||
uint8_t* get_option(struct dhcpMessage *packet, int code)
|
uint8_t* get_option(struct dhcpMessage *packet, int code)
|
||||||
@ -161,6 +212,7 @@ int add_simple_option(unsigned char *optionptr, unsigned char code,
|
|||||||
length = option_lengths[options[i].flags & TYPE_MASK];
|
length = option_lengths[options[i].flags & TYPE_MASK];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_line("aso(): code=0x%02x length=0x%02x", code, length);
|
||||||
option[OPT_CODE] = code;
|
option[OPT_CODE] = code;
|
||||||
option[OPT_LEN] = (unsigned char)length;
|
option[OPT_LEN] = (unsigned char)length;
|
||||||
|
|
||||||
|
@ -88,6 +88,15 @@ struct option_set {
|
|||||||
extern struct dhcp_option options[];
|
extern struct dhcp_option options[];
|
||||||
extern int option_lengths[];
|
extern int option_lengths[];
|
||||||
|
|
||||||
|
size_t sizeof_option(unsigned char code, size_t datalen);
|
||||||
|
size_t set_option(unsigned char *buf, size_t buflen, unsigned char code,
|
||||||
|
unsigned char *optdata, size_t datalen);
|
||||||
|
unsigned char *alloc_option(unsigned char code, unsigned char *optdata,
|
||||||
|
size_t datalen);
|
||||||
|
|
||||||
|
unsigned char *alloc_dhcp_client_id_option(unsigned char type,
|
||||||
|
unsigned char *idstr, size_t idstrlen);
|
||||||
|
|
||||||
uint8_t *get_option(struct dhcpMessage *packet, int code);
|
uint8_t *get_option(struct dhcpMessage *packet, int code);
|
||||||
int end_option(uint8_t *optionptr);
|
int end_option(uint8_t *optionptr);
|
||||||
int add_option_string(unsigned char *optionptr, unsigned char *string);
|
int add_option_string(unsigned char *optionptr, unsigned char *string);
|
||||||
|
Loading…
Reference in New Issue
Block a user