summaryrefslogtreecommitdiffstats
path: root/net/dhcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dhcp.c')
-rw-r--r--net/dhcp.c568
1 files changed, 228 insertions, 340 deletions
diff --git a/net/dhcp.c b/net/dhcp.c
index c5386fe942..18f347d2f8 100644
--- a/net/dhcp.c
+++ b/net/dhcp.c
@@ -76,243 +76,30 @@ typedef enum {
static uint32_t Bootp_id;
static dhcp_state_t dhcp_state;
-static uint32_t dhcp_leasetime;
static IPaddr_t net_dhcp_server_ip;
static uint64_t dhcp_start;
-static char dhcp_tftpname[256];
-
-static const char* dhcp_get_barebox_global(const char * var)
-{
- char * var_global = basprintf("global.dhcp.%s", var);
- const char *val;
-
- if (!var_global)
- return NULL;
-
- val = getenv(var_global);
- free(var_global);
- return val;
-}
-
-static int dhcp_set_barebox_global(const char * var, char *val)
-{
- char * var_global = basprintf("global.dhcp.%s", var);
- int ret;
-
- if (!var_global)
- return -ENOMEM;
-
- ret = setenv(var_global, val);
- free(var_global);
- return ret;
-}
-
-struct dhcp_opt {
- unsigned char option;
- /* request automatically the option when creating the DHCP request */
- bool optional;
- bool copy_only_if_valid;
- const char *barebox_var_name;
- const char *barebox_dhcp_global;
- void (*handle)(struct dhcp_opt *opt, unsigned char *data, int tlen);
- int (*handle_param)(struct dhcp_opt *dhcp_opt, u8 *e);
- void *data;
-
- struct bootp *bp;
+static struct eth_device *dhcp_edev;
+struct dhcp_req_param dhcp_param;
+struct dhcp_result *dhcp_result;
+
+struct dhcp_receivce_opts {
+ IPaddr_t netmask;
+ IPaddr_t gateway;
+ IPaddr_t nameserver;
+ IPaddr_t serverip;
+ char *hostname;
+ char *domainname;
+ char *rootpath;
+ char *devicetree;
+ char *bootfile;
};
-static void netmask_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
-{
- IPaddr_t ip;
-
- ip = net_read_ip(popt);
- net_set_netmask(ip);
-}
-
-static void gateway_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
-{
- IPaddr_t ip;
-
- ip = net_read_ip(popt);
- net_set_gateway(ip);
-}
-
-static void env_ip_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
-{
- IPaddr_t ip;
-
- ip = net_read_ip(popt);
- if (IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES))
- setenv_ip(opt->barebox_var_name, ip);
-}
-
-static void env_str_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
-{
- char str[256];
- char *tmp = str;
-
- if (opt->data)
- tmp = opt->data;
-
- memcpy(tmp, popt, optlen);
- tmp[optlen] = 0;
-
- if (opt->copy_only_if_valid && !strlen(tmp))
- return;
- if (opt->barebox_var_name && IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES))
- setenv(opt->barebox_var_name, tmp);
- if (opt->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
- dhcp_set_barebox_global(opt->barebox_dhcp_global, tmp);
-
-}
-
-static void copy_uint32_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
-{
- net_copy_uint32(opt->data, (uint32_t *)popt);
-};
-
-static void copy_ip_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
-{
- net_copy_ip(opt->data, popt);
-};
-
-static void bootfile_vendorex_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
-{
- if (opt->bp->bp_file[0] != '\0')
- return;
-
- /*
- * only use vendor boot file if we didn't
- * receive a boot file in the main non-vendor
- * part of the packet - god only knows why
- * some vendors chose not to use this perfectly
- * good spot to store the boot file (join on
- * Tru64 Unix) it seems mind bogglingly crazy
- * to me
- */
- pr_warn("*** WARNING: using vendor optional boot file\n");
-
- /*
- * I can't use dhcp_vendorex_proc here because I need
- * to write into the bootp packet - even then I had to
- * pass the bootp packet pointer into here as the
- * second arg
- */
- env_str_handle(opt, popt, optlen);
-}
-
-static int dhcp_set_string_options(struct dhcp_opt *param, u8 *e)
-{
- int str_len;
- const char *str = param->data;
-
- if (!str && param->barebox_var_name && IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES))
- str = getenv(param->barebox_var_name);
-
- if (!str && param->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
- str = dhcp_get_barebox_global(param->barebox_dhcp_global);
-
- 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_HOSTNAME 12
#define DHCP_VENDOR_ID 60
#define DHCP_CLIENT_ID 61
#define DHCP_USER_CLASS 77
#define DHCP_CLIENT_UUID 97
-struct dhcp_opt dhcp_options[] = {
- {
- .option = 1,
- .handle = netmask_handle,
- }, {
- .option = 3,
- .handle = gateway_handle,
- }, {
- .option = 6,
- .handle = env_ip_handle,
- .barebox_var_name = "net.nameserver",
- }, {
- .option = DHCP_HOSTNAME,
- .copy_only_if_valid = 1,
- .handle = env_str_handle,
- .handle_param = dhcp_set_string_options,
- .barebox_var_name = "global.hostname",
- }, {
- .option = 15,
- .handle = env_str_handle,
- .barebox_var_name = "net.domainname",
- }, {
- .option = 17,
- .handle = env_str_handle,
- .barebox_dhcp_global = "rootpath",
- }, {
- .option = 51,
- .handle = copy_uint32_handle,
- .data = &dhcp_leasetime,
- }, {
- .option = 54,
- .handle = copy_ip_handle,
- .data = &net_dhcp_server_ip,
- .optional = true,
- }, {
- .option = DHCP_VENDOR_ID,
- .handle_param = dhcp_set_string_options,
- .barebox_dhcp_global = "vendor_id",
- },{
- .option = 66,
- .handle = env_str_handle,
- .barebox_dhcp_global = "tftp_server_name",
- .data = dhcp_tftpname,
- }, {
- .option = 67,
- .handle = bootfile_vendorex_handle,
- .barebox_dhcp_global = "bootfile",
- }, {
- .option = DHCP_CLIENT_ID,
- .handle_param = dhcp_set_string_options,
- .barebox_dhcp_global = "client_id",
- }, {
- .option = DHCP_USER_CLASS,
- .handle_param = dhcp_set_string_options,
- .barebox_dhcp_global = "user_class",
- }, {
- .option = DHCP_CLIENT_UUID,
- .handle_param = dhcp_set_string_options,
- .barebox_dhcp_global = "client_uuid",
- }, {
- .option = 224,
- .handle = env_str_handle,
- .barebox_dhcp_global = "oftree_file",
- },
-};
-
-static void dhcp_set_param_data(int option, void* data)
-{
- struct dhcp_opt *opt;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
- opt = &dhcp_options[i];
-
- if (opt->option == option) {
- opt->data = data;
- return;
- }
- }
-}
-
static int dhcp_set_ip_options(int option, u8 *e, IPaddr_t ip)
{
int tmp;
@@ -366,35 +153,43 @@ static int bootp_check_packet(unsigned char *pkt, unsigned src, unsigned len)
*/
static void bootp_copy_net_params(struct bootp *bp)
{
- IPaddr_t tmp_ip;
- tmp_ip = net_read_ip(&bp->bp_yiaddr);
- net_set_ip(tmp_ip);
+ dhcp_result->ip = net_read_ip(&bp->bp_yiaddr);
+ dhcp_result->serverip = net_read_ip(&bp->bp_siaddr);
- tmp_ip = net_read_ip(&bp->bp_siaddr);
- if (tmp_ip != 0)
- net_set_serverip(tmp_ip);
+ if (strlen(bp->bp_file) > 0)
+ dhcp_result->bootfile = xstrdup(bp->bp_file);
+}
- if (strlen(bp->bp_file) > 0) {
- if (IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES))
- setenv("bootfile", bp->bp_file);
- if (IS_ENABLED(CONFIG_GLOBALVAR))
- dhcp_set_barebox_global("bootfile", bp->bp_file);
- }
+static int dhcp_set_string_options(int option, const char *str, u8 *e)
+{
+ int str_len;
- debug("bootfile: %s\n", bp->bp_file);
+ if (!str)
+ return 0;
+
+ str_len = strlen(str);
+ if (!str_len)
+ return 0;
+
+ *e++ = option;
+ *e++ = str_len;
+ memcpy(e, str, str_len);
+
+ return str_len + 2;
}
/*
* Initialize BOOTP extension fields in the request.
*/
-static int dhcp_extended (u8 *e, int message_type, IPaddr_t ServerID,
+static int dhcp_extended(u8 *e, int message_type, IPaddr_t ServerID,
IPaddr_t RequestedIP)
{
- struct dhcp_opt *opt;
int i;
u8 *start = e;
u8 *cnt;
+ u8 dhcp_options[] = {1, 3, 6, DHCP_HOSTNAME, 15, 17, 51, DHCP_VENDOR_ID, 66, 67, DHCP_CLIENT_ID,
+ DHCP_USER_CLASS, DHCP_CLIENT_UUID, 224};
*e++ = 99; /* RFC1048 Magic Cookie */
*e++ = 130;
@@ -410,26 +205,23 @@ static int dhcp_extended (u8 *e, int message_type, IPaddr_t ServerID,
*e++ = (576 - 312 + OPT_SIZE) >> 8;
*e++ = (576 - 312 + OPT_SIZE) & 0xff;
-
e += dhcp_set_ip_options(50, e, RequestedIP);
e += dhcp_set_ip_options(54, e, ServerID);
- for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
- opt = &dhcp_options[i];
- if (opt->handle_param)
- e += opt->handle_param(opt, e);
- }
+ e += dhcp_set_string_options(DHCP_HOSTNAME, dhcp_param.hostname, e);
+ e += dhcp_set_string_options(DHCP_VENDOR_ID, dhcp_param.vendor_id, e);
+ e += dhcp_set_string_options(DHCP_CLIENT_ID, dhcp_param.client_id, e);
+ e += dhcp_set_string_options(DHCP_USER_CLASS, dhcp_param.user_class, e);
+ e += dhcp_set_string_options(DHCP_CLIENT_UUID, dhcp_param.client_uuid, e);
*e++ = 55; /* Parameter Request List */
- cnt = e++; /* Pointer to count of requested items */
- *cnt = 0;
-
- for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
- if (dhcp_options[i].optional)
- continue;
- *e++ = dhcp_options[i].option;
- *cnt += 1;
- }
+ cnt = e++; /* Pointer to count of requested items */
+
+ for (i = 0; i < ARRAY_SIZE(dhcp_options); i++)
+ *e++ = dhcp_options[i];
+
+ *cnt = ARRAY_SIZE(dhcp_options);
+
*e++ = 255; /* End of the list */
/* Pad to minimal length */
@@ -446,14 +238,13 @@ static int bootp_request(void)
struct bootp *bp;
int ext_len;
int ret;
- unsigned char *payload = net_udp_get_payload(dhcp_con);
const char *bfile;
dhcp_state = INIT;
debug("BOOTP broadcast\n");
- bp = (struct bootp *)payload;
+ bp = net_udp_get_payload(dhcp_con);;
bp->bp_op = OP_BOOTREQUEST;
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
@@ -467,10 +258,10 @@ static int bootp_request(void)
bfile = getenv("bootfile");
if (bfile)
- safe_strncpy (bp->bp_file, bfile, sizeof(bp->bp_file));
+ 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);
+ ext_len = dhcp_extended(bp->bp_vend, DHCP_DISCOVER, 0, 0);
Bootp_id = (uint32_t)get_time_ns();
net_copy_uint32(&bp->bp_id, &Bootp_id);
@@ -482,23 +273,47 @@ static int bootp_request(void)
return ret;
}
-static void dhcp_options_handle(unsigned char option, unsigned char *popt,
+static void dhcp_options_handle(unsigned char option, void *popt,
int optlen, struct bootp *bp)
{
- int i;
- struct dhcp_opt *opt;
-
- for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
- opt = &dhcp_options[i];
- if (opt->option == option) {
- opt->bp = bp;
- if (opt->handle)
- opt->handle(opt, popt, optlen);
- return;
- }
+ switch (option) {
+ case 1:
+ dhcp_result->netmask = net_read_ip(popt);
+ break;
+ case 3:
+ dhcp_result->gateway = net_read_ip(popt);
+ break;
+ case 6:
+ dhcp_result->nameserver = net_read_ip(popt);
+ break;
+ case DHCP_HOSTNAME:
+ dhcp_result->hostname = xstrndup(popt, optlen);
+ break;
+ case 15:
+ dhcp_result->domainname = xstrndup(popt, optlen);
+ break;
+ case 17:
+ dhcp_result->rootpath = xstrndup(popt, optlen);
+ break;
+ case 51:
+ net_copy_uint32(&dhcp_result->leasetime, popt);
+ break;
+ case 54:
+ dhcp_result->serverip = net_read_ip(popt);
+ break;
+ case 66:
+ dhcp_result->tftp_server_name = xstrndup(popt, optlen);
+ break;
+ case 67:
+ if (!dhcp_result->bootfile)
+ dhcp_result->bootfile = xstrndup(popt, optlen);
+ break;
+ case 224:
+ dhcp_result->devicetree = xstrndup(popt, optlen);
+ break;
+ default:
+ debug("*** Unhandled DHCP Option in OFFER/ACK: %d\n", option);
}
-
- debug("*** Unhandled DHCP Option in OFFER/ACK: %d\n", option);
}
static void dhcp_options_process(unsigned char *popt, struct bootp *bp)
@@ -523,8 +338,8 @@ static int dhcp_message_type(unsigned char *popt)
return -1;
popt += 4;
- while ( *popt != 0xff ) {
- if ( *popt == 53 ) /* DHCP Message Type */
+ while (*popt != 0xff) {
+ if (*popt == 53) /* DHCP Message Type */
return *(popt + 2);
popt += *(popt + 1) + 2; /* Scan through all options */
}
@@ -536,11 +351,10 @@ static void dhcp_send_request_packet(struct bootp *bp_offer)
struct bootp *bp;
int extlen;
IPaddr_t OfferedIP;
- unsigned char *payload = net_udp_get_payload(dhcp_con);
debug("%s: Sending DHCPREQUEST\n", __func__);
- bp = (struct bootp *)payload;
+ bp = net_udp_get_payload(dhcp_con);
bp->bp_op = OP_BOOTREQUEST;
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
@@ -565,7 +379,7 @@ static void dhcp_send_request_packet(struct bootp *bp_offer)
* Copy options from OFFER packet if present
*/
net_copy_ip(&OfferedIP, &bp_offer->bp_yiaddr);
- extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST, net_dhcp_server_ip,
+ extlen = dhcp_extended(bp->bp_vend, DHCP_REQUEST, net_dhcp_server_ip,
OfferedIP);
debug("Transmitting DHCPREQUEST packet\n");
@@ -597,10 +411,10 @@ static void dhcp_handler(void *ctx, char *packet, unsigned int len)
* If filename is in format we recognize, assume it is a valid
* OFFER from a server we want.
*/
- debug ("%s: state SELECTING, bp_file: \"%s\"\n", __func__, bp->bp_file);
+ debug("%s: state SELECTING, bp_file: \"%s\"\n", __func__, bp->bp_file);
dhcp_state = REQUESTING;
- if (net_read_uint32((uint32_t *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
+ if (net_read_uint32(&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
dhcp_options_process((u8 *)&bp->bp_vend[4], bp);
bootp_copy_net_params(bp); /* Store net params from reply */
@@ -610,16 +424,14 @@ static void dhcp_handler(void *ctx, char *packet, unsigned int len)
break;
case REQUESTING:
- debug ("%s: State REQUESTING\n", __func__);
+ debug("%s: State REQUESTING\n", __func__);
if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK ) {
- IPaddr_t ip;
- if (net_read_uint32((uint32_t *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
- dhcp_options_process((u8 *)&bp->bp_vend[4], bp);
+ if (net_read_uint32(&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
+ dhcp_options_process(&bp->bp_vend[4], bp);
bootp_copy_net_params(bp); /* Store net params from reply */
dhcp_state = BOUND;
- ip = net_get_ip();
- printf("DHCP client bound to address %pI4\n", &ip);
+ dev_info(&dhcp_edev->dev, "DHCP client bound to address %pI4\n", &dhcp_result->ip);
return;
}
break;
@@ -629,39 +441,50 @@ static void dhcp_handler(void *ctx, char *packet, unsigned int len)
}
}
-static void dhcp_reset_env(void)
-{
- struct dhcp_opt *opt;
- int i;
+static char *global_dhcp_user_class;
+static char *global_dhcp_vendor_id;
+static char *global_dhcp_client_uuid;
+static char *global_dhcp_client_id;
+static char *global_dhcp_bootfile;
+static char *global_dhcp_oftree_file;
+static char *global_dhcp_rootpath;
+static char *global_dhcp_tftp_server_name;
- for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
- opt = &dhcp_options[i];
- if (!opt->barebox_var_name || opt->copy_only_if_valid)
- continue;
+static void set_res(char **var, const char *res)
+{
+ free(*var);
- if (IS_ENABLED(CONFIG_ENVIRONMENT_VARIABLES))
- setenv(opt->barebox_var_name, "");
- if (opt->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
- dhcp_set_barebox_global(opt->barebox_dhcp_global, "");
- }
+ if (res)
+ *var = xstrdup(res);
+ else
+ *var = xstrdup("");
}
-int dhcp(int retries, struct dhcp_req_param *param)
+int dhcp_request(struct eth_device *edev, const struct dhcp_req_param *param,
+ struct dhcp_result **res)
{
int ret = 0;
- dhcp_reset_env();
-
- dhcp_set_param_data(DHCP_HOSTNAME, param->hostname);
- dhcp_set_param_data(DHCP_VENDOR_ID, param->vendor_id);
- dhcp_set_param_data(DHCP_CLIENT_ID, param->client_id);
- dhcp_set_param_data(DHCP_USER_CLASS, param->user_class);
- dhcp_set_param_data(DHCP_CLIENT_UUID, param->client_uuid);
-
- if (!retries)
- retries = DHCP_DEFAULT_RETRY;
-
- dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
+ dhcp_edev = edev;
+ if (param)
+ dhcp_param = *param;
+ else
+ memset(&dhcp_param, 0, sizeof(dhcp_param));
+
+ dhcp_result = xzalloc(sizeof(*dhcp_result));
+
+ if (!dhcp_param.user_class)
+ dhcp_param.user_class = global_dhcp_user_class;
+ if (!dhcp_param.vendor_id)
+ dhcp_param.vendor_id = global_dhcp_vendor_id;
+ if (!dhcp_param.client_uuid)
+ dhcp_param.client_uuid = global_dhcp_client_uuid;
+ if (!dhcp_param.client_id)
+ dhcp_param.client_id = global_dhcp_client_id;
+ if (!dhcp_param.retries)
+ dhcp_param.retries = DHCP_DEFAULT_RETRY;
+
+ dhcp_con = net_udp_eth_new(edev, IP_BROADCAST, PORT_BOOTPS, dhcp_handler, NULL);
if (IS_ERR(dhcp_con)) {
ret = PTR_ERR(dhcp_con);
goto out;
@@ -671,7 +494,7 @@ int dhcp(int retries, struct dhcp_req_param *param)
if (ret)
goto out1;
- net_set_ip(0);
+ net_set_ip(edev, 0);
dhcp_start = get_time_ns();
ret = bootp_request(); /* Basically same as BOOTP */
@@ -683,7 +506,7 @@ int dhcp(int retries, struct dhcp_req_param *param)
ret = -EINTR;
goto out1;
}
- if (!retries) {
+ if (!dhcp_param.retries) {
ret = -ETIMEDOUT;
goto out1;
}
@@ -693,56 +516,122 @@ int dhcp(int retries, struct dhcp_req_param *param)
printf("T ");
ret = bootp_request();
/* no need to check if retries > 0 as we check if != 0 */
- retries--;
+ dhcp_param.retries--;
if (ret)
goto out1;
}
}
- if (dhcp_tftpname[0] != 0) {
- IPaddr_t tftpserver = resolv(dhcp_tftpname);
- if (tftpserver)
- net_set_serverip(tftpserver);
- }
+ pr_debug("DHCP result:\n"
+ " ip: %pI4\n"
+ " netmask: %pI4\n"
+ " gateway: %pI4\n"
+ " serverip: %pI4\n"
+ " nameserver: %pI4\n"
+ " hostname: %s\n"
+ " domainname: %s\n"
+ " rootpath: %s\n"
+ " devicetree: %s\n"
+ " tftp_server_name: %s\n",
+ &dhcp_result->ip,
+ &dhcp_result->netmask,
+ &dhcp_result->gateway,
+ &dhcp_result->serverip,
+ &dhcp_result->nameserver,
+ dhcp_result->hostname ? dhcp_result->hostname : "",
+ dhcp_result->domainname ? dhcp_result->domainname : "",
+ dhcp_result->rootpath ? dhcp_result->rootpath : "",
+ dhcp_result->devicetree ? dhcp_result->devicetree : "",
+ dhcp_result->tftp_server_name ? dhcp_result->tftp_server_name : "");
out1:
net_unregister(dhcp_con);
out:
- if (ret)
+ if (ret) {
debug("dhcp failed: %s\n", strerror(-ret));
+ free(dhcp_result);
+ } else {
+ *res = dhcp_result;
+ }
return ret;
}
-#ifdef CONFIG_GLOBALVAR
-static void dhcp_global_add(const char *var)
+int dhcp_set_result(struct eth_device *edev, struct dhcp_result *res)
{
- char *var_global = basprintf("dhcp.%s", var);
+ net_set_ip(edev, res->ip);
+ net_set_netmask(edev, res->netmask);
+ net_set_gateway(res->gateway);
+ net_set_nameserver(res->nameserver);
+
+ set_res(&global_dhcp_bootfile, res->bootfile);
+ set_res(&global_dhcp_oftree_file, res->devicetree);
+ set_res(&global_dhcp_rootpath, res->rootpath);
+ set_res(&global_dhcp_tftp_server_name, res->tftp_server_name);
+
+ if (res->hostname)
+ barebox_set_hostname(res->hostname);
+ if (res->domainname)
+ net_set_domainname(res->domainname);
+
+ if (res->tftp_server_name) {
+ IPaddr_t ip;
+
+ ip = resolv(res->tftp_server_name);
+ if (ip)
+ net_set_serverip_empty(ip);
+ } else if (res->serverip) {
+ net_set_serverip_empty(res->serverip);
+ }
- if (!var_global)
- return;
+ return 0;
+}
- globalvar_add_simple(var_global, NULL);
- free(var_global);
+void dhcp_result_free(struct dhcp_result *res)
+{
+ free(res->hostname);
+ free(res->domainname);
+ free(res->rootpath);
+ free(res->devicetree);
+ free(res->bootfile);
+ free(res->tftp_server_name);
+
+ free(res);
}
-static int dhcp_global_init(void)
+int dhcp(struct eth_device *edev, const struct dhcp_req_param *param)
{
- struct dhcp_opt *opt;
- int i;
+ struct dhcp_result *res;
+ int ret;
- for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
- opt = &dhcp_options[i];
+ ret = dhcp_request(edev, param, &res);
+ if (ret)
+ return ret;
- if (!opt->barebox_dhcp_global)
- continue;
+ ret = dhcp_set_result(edev, res);
- dhcp_global_add(opt->barebox_dhcp_global);
- }
+ dhcp_result_free(res);
+
+ return ret;
+}
+
+#ifdef CONFIG_GLOBALVAR
+
+static int dhcp_global_init(void)
+{
+ globalvar_add_simple_string("dhcp.bootfile", &global_dhcp_bootfile);
+ globalvar_add_simple_string("dhcp.rootpath", &global_dhcp_rootpath);
+ globalvar_add_simple_string("dhcp.vendor_id", &global_dhcp_vendor_id);
+ globalvar_add_simple_string("dhcp.client_uuid", &global_dhcp_client_uuid);
+ globalvar_add_simple_string("dhcp.client_id", &global_dhcp_client_id);
+ globalvar_add_simple_string("dhcp.user_class", &global_dhcp_user_class);
+ globalvar_add_simple_string("dhcp.oftree_file", &global_dhcp_oftree_file);
+ globalvar_add_simple_string("dhcp.tftp_server_name", &global_dhcp_tftp_server_name);
return 0;
}
late_initcall(dhcp_global_init);
+#endif
BAREBOX_MAGICVAR_NAMED(global_dhcp_bootfile, global.dhcp.bootfile, "bootfile returned from DHCP request");
BAREBOX_MAGICVAR_NAMED(global_dhcp_rootpath, global.dhcp.rootpath, "rootpath returned from DHCP request");
@@ -753,4 +642,3 @@ BAREBOX_MAGICVAR_NAMED(global_dhcp_user_class, global.dhcp.user_class, "user cla
BAREBOX_MAGICVAR_NAMED(global_dhcp_tftp_server_name, global.dhcp.tftp_server_name, "TFTP server Name returned from DHCP request");
BAREBOX_MAGICVAR_NAMED(global_dhcp_oftree_file, global.dhcp.oftree_file, "OF tree returned from DHCP request (option 224)");
BAREBOX_MAGICVAR_NAMED(global_dhcp_retries, global.dhcp.retries, "retry limit");
-#endif