9
0
Fork 0

net: dhcp: factorise setting option code

This will allow to add more easly new option with less impact in the binary.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
This commit is contained in:
Jean-Christophe PLAGNIOL-VILLARD 2012-03-30 02:25:14 +08:00
parent 1f9e76d840
commit 7fd2d7658e
1 changed files with 87 additions and 34 deletions

View File

@ -204,6 +204,79 @@ struct dhcp_opt dhcp_options[] = {
},
};
struct dhcp_param {
unsigned char option;
const char *barebox_var_name;
int (*handle)(struct dhcp_param *param, u8 *e);
void *data;
};
static int dhcp_set_string_options(struct dhcp_param *param, u8 *e)
{
int str_len;
char* str = param->data;
if (!str && param->barebox_var_name)
str = (char*)getenv(param->barebox_var_name);
if (!str)
return 0;
str_len = strlen(str);
if (!str_len)
return 0;
*e++ = param->option;
*e++ = str_len;
memcpy(e, str, str_len);
return str_len + 2;
}
#define DHCP_VENDOR_ID 60
struct dhcp_param dhcp_params[] = {
{
.option = DHCP_VENDOR_ID,
.handle = dhcp_set_string_options,
.barebox_var_name = "dhcp_vendor_id",
}
};
static void dhcp_set_param_data(int option, void* data)
{
struct dhcp_param *param;
int i;
for (i = 0; i < ARRAY_SIZE(dhcp_params); i++) {
param = &dhcp_params[i];
if (param->option == option) {
param->data = data;
return;
}
}
}
static int dhcp_set_ip_options(int option, u8 *e, IPaddr_t ip)
{
int tmp;
if (!ip)
return 0;
tmp = ntohl(ip);
*e++ = option;
*e++ = 4;
*e++ = tmp >> 24;
*e++ = tmp >> 16;
*e++ = tmp >> 8;
*e++ = tmp & 0xff;
return 6;
}
static int bootp_check_packet(unsigned char *pkt, unsigned src, unsigned len)
{
struct bootp *bp = (struct bootp *) pkt;
@ -257,12 +330,11 @@ static void bootp_copy_net_params(struct bootp *bp)
* Initialize BOOTP extension fields in the request.
*/
static int dhcp_extended (u8 *e, int message_type, IPaddr_t ServerID,
IPaddr_t RequestedIP, char *vendor_id)
IPaddr_t RequestedIP)
{
int i;
u8 *start = e;
u8 *cnt;
int vendor_id_len = vendor_id ? strlen(vendor_id) : 0;
*e++ = 99; /* RFC1048 Magic Cookie */
*e++ = 130;
@ -278,34 +350,12 @@ static int dhcp_extended (u8 *e, int message_type, IPaddr_t ServerID,
*e++ = (576 - 312 + OPT_SIZE) >> 8;
*e++ = (576 - 312 + OPT_SIZE) & 0xff;
if (ServerID) {
int tmp = ntohl (ServerID);
*e++ = 54; /* ServerID */
*e++ = 4;
*e++ = tmp >> 24;
*e++ = tmp >> 16;
*e++ = tmp >> 8;
*e++ = tmp & 0xff;
}
e += dhcp_set_ip_options(50, e, RequestedIP);
e += dhcp_set_ip_options(54, e, ServerID);
if (RequestedIP) {
int tmp = ntohl (RequestedIP);
*e++ = 50; /* Requested IP */
*e++ = 4;
*e++ = tmp >> 24;
*e++ = tmp >> 16;
*e++ = tmp >> 8;
*e++ = tmp & 0xff;
}
if (vendor_id_len > 0) {
*e++ = 60;
*e++ = vendor_id_len;
memcpy(e, vendor_id, vendor_id_len);
e += vendor_id_len;
}
for (i = 0; i < ARRAY_SIZE(dhcp_params); i++)
e += dhcp_params[i].handle(&dhcp_params[i], e);
*e++ = 55; /* Parameter Request List */
cnt = e++; /* Pointer to count of requested items */
@ -357,8 +407,7 @@ static int bootp_request(void)
safe_strncpy (bp->bp_file, bfile, sizeof(bp->bp_file));
/* Request additional information from the BOOTP/DHCP server */
ext_len = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0,
dhcp_con->priv);
ext_len = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0);
Bootp_id = (uint32_t)get_time_ns();
net_copy_uint32(&bp->bp_id, &Bootp_id);
@ -463,7 +512,7 @@ static void dhcp_send_request_packet(struct bootp *bp_offer)
*/
net_copy_ip(&OfferedIP, &bp->bp_yiaddr);
extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST, net_dhcp_server_ip,
OfferedIP, dhcp_con->priv);
OfferedIP);
debug("Transmitting DHCPREQUEST packet\n");
net_udp_send(dhcp_con, sizeof(*bp) + extlen);
@ -543,19 +592,18 @@ static void dhcp_reset_env(void)
static int do_dhcp(int argc, char *argv[])
{
int ret, opt;
char *vendor_id = (char*)getenv("dhcp_vendor_id");
dhcp_reset_env();
while((opt = getopt(argc, argv, "v:")) > 0) {
switch(opt) {
case 'v':
vendor_id = optarg;
dhcp_set_param_data(DHCP_VENDOR_ID, optarg);
break;
}
}
dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, vendor_id);
dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
if (IS_ERR(dhcp_con)) {
ret = PTR_ERR(dhcp_con);
goto out;
@ -599,6 +647,10 @@ BAREBOX_CMD_HELP_SHORT("Invoke dhcp client to obtain ip/boot params.\n")
BAREBOX_CMD_HELP_OPT ("-v <vendor_id>",
"DHCP Vendor ID (code 60) submitted in DHCP requests. It can\n"
"be used in the DHCP server's configuration to select options\n"
"(e.g. bootfile or server) which are valid for barebox clients only.\n")
BAREBOX_CMD_HELP_OPT ("-c <client_id>",
"DHCP Client ID (code 61) submitted in DHCP requests. It can\n"
"be used in the DHCP server's configuration to select options\n"
"(e.g. bootfile or server) which are valid for barebox clients only.\n");
BAREBOX_CMD_HELP_END
@ -614,4 +666,5 @@ BAREBOX_MAGICVAR(hostname, "hostname returned from DHCP request");
BAREBOX_MAGICVAR(domainname, "domainname returned from DHCP request");
BAREBOX_MAGICVAR(rootpath, "rootpath returned from DHCP request");
BAREBOX_MAGICVAR(dhcp_vendor_id, "vendor id to send to the DHCP server");
BAREBOX_MAGICVAR(dhcp_client_id, "cliend id to send to the DHCP server");
BAREBOX_MAGICVAR(dhcp_tftp_server_name, "TFTP server Name returned from DHCP request");