191 lines
5.4 KiB
C
191 lines
5.4 KiB
C
/*********************************************************************
|
|
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
|
|
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
|
|
|
|
.
|
|
|
|
Authors: Frederik Van Slycken
|
|
*********************************************************************/
|
|
|
|
#include "pico_config.h"
|
|
#include "pico_stack.h"
|
|
#include "pico_dhcp_common.h"
|
|
|
|
#if defined (PICO_SUPPORT_DHCPC) || defined (PICO_SUPPORT_DHCPD)
|
|
/* pico_dhcp_are_options_valid needs to be called first to prevent illegal memory access */
|
|
/* The argument pointer is moved forward to the next option */
|
|
struct pico_dhcp_opt *pico_dhcp_next_option(struct pico_dhcp_opt **ptr)
|
|
{
|
|
uint8_t **p = (uint8_t **)ptr;
|
|
struct pico_dhcp_opt *opt = *ptr;
|
|
|
|
if (opt->code == PICO_DHCP_OPT_END)
|
|
return NULL;
|
|
|
|
if (opt->code == PICO_DHCP_OPT_PAD) {
|
|
*p += 1;
|
|
return *ptr;
|
|
}
|
|
|
|
*p += (opt->len + 2); /* (len + 2) to account for code and len octet */
|
|
return *ptr;
|
|
}
|
|
|
|
uint8_t pico_dhcp_are_options_valid(void *ptr, int32_t len)
|
|
{
|
|
uint8_t optlen = 0, *p = ptr;
|
|
|
|
while (len > 0) {
|
|
switch (*p)
|
|
{
|
|
case PICO_DHCP_OPT_END:
|
|
return 1;
|
|
|
|
case PICO_DHCP_OPT_PAD:
|
|
p++;
|
|
len--;
|
|
break;
|
|
|
|
default:
|
|
p++; /* move pointer from code octet to len octet */
|
|
len--;
|
|
if ((len <= 0) || (len - (*p + 1) < 0)) /* (*p + 1) to account for len octet */
|
|
return 0;
|
|
|
|
optlen = *p;
|
|
p += optlen + 1;
|
|
len -= optlen;
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_netmask(void *ptr, struct pico_ip4 *ip)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: netmask */
|
|
opt->code = PICO_DHCP_OPT_NETMASK;
|
|
opt->len = PICO_DHCP_OPTLEN_NETMASK - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.netmask.ip = *ip;
|
|
return PICO_DHCP_OPTLEN_NETMASK;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_router(void *ptr, struct pico_ip4 *ip)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: router */
|
|
opt->code = PICO_DHCP_OPT_ROUTER;
|
|
opt->len = PICO_DHCP_OPTLEN_ROUTER - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.router.ip = *ip;
|
|
return PICO_DHCP_OPTLEN_ROUTER;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_dns(void *ptr, struct pico_ip4 *ip)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: dns */
|
|
opt->code = PICO_DHCP_OPT_DNS;
|
|
opt->len = PICO_DHCP_OPTLEN_DNS - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.dns1.ip = *ip;
|
|
return PICO_DHCP_OPTLEN_DNS;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_broadcast(void *ptr, struct pico_ip4 *ip)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: broadcast */
|
|
opt->code = PICO_DHCP_OPT_BROADCAST;
|
|
opt->len = PICO_DHCP_OPTLEN_BROADCAST - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.broadcast.ip = *ip;
|
|
return PICO_DHCP_OPTLEN_BROADCAST;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_reqip(void *ptr, struct pico_ip4 *ip)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: request IP address */
|
|
opt->code = PICO_DHCP_OPT_REQIP;
|
|
opt->len = PICO_DHCP_OPTLEN_REQIP - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.req_ip.ip = *ip;
|
|
return PICO_DHCP_OPTLEN_REQIP;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_leasetime(void *ptr, uint32_t time)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: lease time */
|
|
opt->code = PICO_DHCP_OPT_LEASETIME;
|
|
opt->len = PICO_DHCP_OPTLEN_LEASETIME - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.lease_time.time = time;
|
|
return PICO_DHCP_OPTLEN_LEASETIME;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_msgtype(void *ptr, uint8_t type)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: message type */
|
|
opt->code = PICO_DHCP_OPT_MSGTYPE;
|
|
opt->len = PICO_DHCP_OPTLEN_MSGTYPE - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.msg_type.type = type;
|
|
return PICO_DHCP_OPTLEN_MSGTYPE;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_serverid(void *ptr, struct pico_ip4 *ip)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: server identifier */
|
|
opt->code = PICO_DHCP_OPT_SERVERID;
|
|
opt->len = PICO_DHCP_OPTLEN_SERVERID - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.server_id.ip = *ip;
|
|
return PICO_DHCP_OPTLEN_SERVERID;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_paramlist(void *ptr)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
uint8_t *param_code = &(opt->ext.param_list.code[0]);
|
|
|
|
/* option: parameter list */
|
|
opt->code = PICO_DHCP_OPT_PARAMLIST;
|
|
opt->len = PICO_DHCP_OPTLEN_PARAMLIST - PICO_DHCP_OPTLEN_HDR;
|
|
param_code[0] = PICO_DHCP_OPT_NETMASK;
|
|
param_code[1] = PICO_DHCP_OPT_TIME;
|
|
param_code[2] = PICO_DHCP_OPT_ROUTER;
|
|
param_code[3] = PICO_DHCP_OPT_HOSTNAME;
|
|
param_code[4] = PICO_DHCP_OPT_RENEWALTIME;
|
|
param_code[5] = PICO_DHCP_OPT_REBINDINGTIME;
|
|
param_code[6] = PICO_DHCP_OPT_DNS;
|
|
return PICO_DHCP_OPTLEN_PARAMLIST;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_maxmsgsize(void *ptr, uint16_t size)
|
|
{
|
|
struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)ptr;
|
|
|
|
/* option: maximum message size */
|
|
opt->code = PICO_DHCP_OPT_MAXMSGSIZE;
|
|
opt->len = PICO_DHCP_OPTLEN_MAXMSGSIZE - PICO_DHCP_OPTLEN_HDR;
|
|
opt->ext.max_msg_size.size = short_be(size);
|
|
return PICO_DHCP_OPTLEN_MAXMSGSIZE;
|
|
}
|
|
|
|
uint8_t pico_dhcp_opt_end(void *ptr)
|
|
{
|
|
uint8_t *opt = (uint8_t *)ptr;
|
|
|
|
/* option: end of options */
|
|
*opt = PICO_DHCP_OPT_END;
|
|
return PICO_DHCP_OPTLEN_END;
|
|
}
|
|
|
|
#endif
|