Basic DHPC client functionality
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@419 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
fedadd3064
commit
929a52b3e0
@ -260,4 +260,8 @@
|
|||||||
|
|
||||||
0.3.4 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
0.3.4 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
* Added netutils/dhcpd
|
* Added and partially verified DHCP server logic (netutils/dhcpd)
|
||||||
|
* Fix BROADCAST=y compilation problems
|
||||||
|
* Fix UDP recvfrom timeout bug
|
||||||
|
* Correct processing of input UDP broadcast packets.
|
||||||
|
* Verfied basic DHCP client functionality (netutils/dhcpc)
|
||||||
|
@ -748,7 +748,11 @@ Other memory:
|
|||||||
<pre><ul>
|
<pre><ul>
|
||||||
0.3.4 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
0.3.4 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
* Added netutils/dhcpd
|
* Added and partially verified DHCP server logic (netutils/dhcpd)
|
||||||
|
* Fix BROADCAST=y compilation problems
|
||||||
|
* Fix UDP recvfrom timeout bug
|
||||||
|
* Correct processing of input UDP broadcast packets.
|
||||||
|
* Verfied basic DHCP client functionality (netutils/dhcpc)
|
||||||
</pre></ul>
|
</pre></ul>
|
||||||
|
|
||||||
<table width ="100%">
|
<table width ="100%">
|
||||||
|
@ -187,10 +187,19 @@ int user_start(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
struct dhcpc_state ds;
|
struct dhcpc_state ds;
|
||||||
(void)dhcpc_request(handle, &ds);
|
(void)dhcpc_request(handle, &ds);
|
||||||
uip_sethostaddr("eth0", &ds.ipaddr);
|
uip_sethostaddr("eth1", &ds.ipaddr);
|
||||||
uip_setnetmask("eth0", &ds.netmask);
|
if (ds.netmask.s_addr != 0)
|
||||||
uip_setdraddr("eth0", &ds.default_router);
|
{
|
||||||
resolv_conf(&ds.dnsaddr);
|
uip_setnetmask("eth0", &ds.netmask);
|
||||||
|
}
|
||||||
|
if (ds.default_router.s_addr != 0)
|
||||||
|
{
|
||||||
|
uip_setdraddr("eth0", &ds.default_router);
|
||||||
|
}
|
||||||
|
if (ds.dnsaddr.s_addr != 0)
|
||||||
|
{
|
||||||
|
resolv_conf(&ds.dnsaddr);
|
||||||
|
}
|
||||||
dhcpc_close(handle);
|
dhcpc_close(handle);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -70,14 +70,14 @@ const uip_ipaddr_t g_alloneaddr =
|
|||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
|
{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
|
||||||
#else
|
#else
|
||||||
{0xffffffff};
|
0xffffffff;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uip_ipaddr_t g_allzeroaddr =
|
const uip_ipaddr_t g_allzeroaddr =
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
|
{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
|
||||||
#else
|
#else
|
||||||
{0x00000000};
|
0x00000000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Reassembly timer (units: deci-seconds) */
|
/* Reassembly timer (units: deci-seconds) */
|
||||||
|
@ -1,5 +1,20 @@
|
|||||||
netutils
|
netutils
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
This directory contains most of the network applications contained under the uIP-1.0 apps directory.
|
This directory contains most of the network applications contained
|
||||||
As the uIP apps/README says, these applications "are not all heavily tested."
|
under the uIP-1.0 apps directory. As the uIP apps/README says,
|
||||||
|
these applications "are not all heavily tested." These uIP apps
|
||||||
|
include:
|
||||||
|
|
||||||
|
dhcpc - Dynamic Host Configuration Protocol (DHCP) client
|
||||||
|
resolv - uIP DNS resolver
|
||||||
|
smtp - Simple Mail Transfer Protocol (SMTP) client
|
||||||
|
telnetd - TELNET server
|
||||||
|
webclient - HTTP web client
|
||||||
|
webserver - HTTP web server
|
||||||
|
|
||||||
|
Additional applications that were not part of uIP (but which are
|
||||||
|
highly influenced by uIP) include:
|
||||||
|
|
||||||
|
dhcpd - Dynamic Host Configuration Protocol (DHCP) server
|
||||||
|
|
||||||
|
@ -183,18 +183,12 @@ static uint8 *add_end(uint8 *optptr)
|
|||||||
|
|
||||||
static void create_msg(struct dhcpc_state_s *pdhcpc)
|
static void create_msg(struct dhcpc_state_s *pdhcpc)
|
||||||
{
|
{
|
||||||
struct in_addr addr;
|
|
||||||
|
|
||||||
memset(&pdhcpc->packet, 0, sizeof(struct dhcp_msg));
|
memset(&pdhcpc->packet, 0, sizeof(struct dhcp_msg));
|
||||||
pdhcpc->packet.op = DHCP_REQUEST;
|
pdhcpc->packet.op = DHCP_REQUEST;
|
||||||
pdhcpc->packet.htype = DHCP_HTYPE_ETHERNET;
|
pdhcpc->packet.htype = DHCP_HTYPE_ETHERNET;
|
||||||
pdhcpc->packet.hlen = pdhcpc->ds_maclen;
|
pdhcpc->packet.hlen = pdhcpc->ds_maclen;
|
||||||
memcpy(pdhcpc->packet.xid, xid, 4);
|
memcpy(pdhcpc->packet.xid, xid, 4);
|
||||||
pdhcpc->packet.flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */
|
pdhcpc->packet.flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */
|
||||||
|
|
||||||
uip_gethostaddr("eth0", &addr);
|
|
||||||
memcpy(&pdhcpc->packet.ciaddr, &addr.s_addr, 4);
|
|
||||||
|
|
||||||
memcpy(pdhcpc->packet.chaddr, pdhcpc->ds_macaddr, pdhcpc->ds_maclen);
|
memcpy(pdhcpc->packet.chaddr, pdhcpc->ds_macaddr, pdhcpc->ds_maclen);
|
||||||
memset(&pdhcpc->packet.chaddr[pdhcpc->ds_maclen], 0, 16 - pdhcpc->ds_maclen);
|
memset(&pdhcpc->packet.chaddr[pdhcpc->ds_maclen], 0, 16 - pdhcpc->ds_maclen);
|
||||||
memcpy(pdhcpc->packet.options, magic_cookie, sizeof(magic_cookie));
|
memcpy(pdhcpc->packet.options, magic_cookie, sizeof(magic_cookie));
|
||||||
@ -206,13 +200,20 @@ static int send_discover(struct dhcpc_state_s *pdhcpc)
|
|||||||
uint8 *pend;
|
uint8 *pend;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
/* Create the basic message header */
|
||||||
|
|
||||||
create_msg(pdhcpc);
|
create_msg(pdhcpc);
|
||||||
|
|
||||||
|
/* Add the options */
|
||||||
|
|
||||||
pend = &pdhcpc->packet.options[4];
|
pend = &pdhcpc->packet.options[4];
|
||||||
pend = add_msg_type(pend, DHCPDISCOVER);
|
pend = add_msg_type(pend, DHCPDISCOVER);
|
||||||
pend = add_req_options(pend);
|
pend = add_req_options(pend);
|
||||||
pend = add_end(pend);
|
pend = add_end(pend);
|
||||||
len = pend - (uint8*)&pdhcpc->packet;
|
len = pend - (uint8*)&pdhcpc->packet;
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = HTONS(DHCPC_SERVER_PORT);
|
addr.sin_port = HTONS(DHCPC_SERVER_PORT);
|
||||||
addr.sin_addr.s_addr = INADDR_BROADCAST;
|
addr.sin_addr.s_addr = INADDR_BROADCAST;
|
||||||
@ -226,7 +227,13 @@ static int send_request(struct dhcpc_state_s *pdhcpc, struct dhcpc_state *presul
|
|||||||
uint8 *pend;
|
uint8 *pend;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
/* Create the basic message header */
|
||||||
|
|
||||||
create_msg(pdhcpc);
|
create_msg(pdhcpc);
|
||||||
|
memcpy(pdhcpc->packet.ciaddr, &presult->ipaddr.s_addr, 4);
|
||||||
|
|
||||||
|
/* Add the options */
|
||||||
|
|
||||||
pend = &pdhcpc->packet.options[4];
|
pend = &pdhcpc->packet.options[4];
|
||||||
pend = add_msg_type(pend, DHCPREQUEST);
|
pend = add_msg_type(pend, DHCPREQUEST);
|
||||||
pend = add_server_id(presult, pend);
|
pend = add_server_id(presult, pend);
|
||||||
@ -234,6 +241,8 @@ static int send_request(struct dhcpc_state_s *pdhcpc, struct dhcpc_state *presul
|
|||||||
pend = add_end(pend);
|
pend = add_end(pend);
|
||||||
len = pend - (uint8*)&pdhcpc->packet;
|
len = pend - (uint8*)&pdhcpc->packet;
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = HTONS(DHCPC_SERVER_PORT);
|
addr.sin_port = HTONS(DHCPC_SERVER_PORT);
|
||||||
addr.sin_addr.s_addr = INADDR_BROADCAST;
|
addr.sin_addr.s_addr = INADDR_BROADCAST;
|
||||||
@ -336,7 +345,7 @@ void *dhcpc_open(const void *macaddr, int maclen)
|
|||||||
|
|
||||||
/* Configure for read timeouts */
|
/* Configure for read timeouts */
|
||||||
|
|
||||||
tv.tv_sec = 30;
|
tv.tv_sec = 10;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
if (setsockopt(pdhcpc->sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0)
|
if (setsockopt(pdhcpc->sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0)
|
||||||
{
|
{
|
||||||
@ -361,9 +370,15 @@ void dhcpc_close(void *handle)
|
|||||||
int dhcpc_request(void *handle, struct dhcpc_state *presult)
|
int dhcpc_request(void *handle, struct dhcpc_state *presult)
|
||||||
{
|
{
|
||||||
struct dhcpc_state_s *pdhcpc = (struct dhcpc_state_s *)handle;
|
struct dhcpc_state_s *pdhcpc = (struct dhcpc_state_s *)handle;
|
||||||
|
struct in_addr oldaddr;
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
|
/* Save the currently assigned IP address (should be zero) */
|
||||||
|
|
||||||
|
oldaddr.s_addr = 0;
|
||||||
|
uip_gethostaddr("eth0", &oldaddr);
|
||||||
|
|
||||||
/* Loop until we receive the offer */
|
/* Loop until we receive the offer */
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -386,6 +401,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
|
|||||||
{
|
{
|
||||||
if (parse_msg(pdhcpc, result, presult) == DHCPOFFER)
|
if (parse_msg(pdhcpc, result, presult) == DHCPOFFER)
|
||||||
{
|
{
|
||||||
|
(void)uip_sethostaddr("eth0", &presult->ipaddr);
|
||||||
state = STATE_OFFER_RECEIVED;
|
state = STATE_OFFER_RECEIVED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -421,6 +437,7 @@ int dhcpc_request(void *handle, struct dhcpc_state *presult)
|
|||||||
{
|
{
|
||||||
/* An error other than a timeout was received */
|
/* An error other than a timeout was received */
|
||||||
|
|
||||||
|
(void)uip_sethostaddr("eth0", &oldaddr);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -692,8 +692,8 @@ static inline int dhcpd_socket(void)
|
|||||||
int sockfd;
|
int sockfd;
|
||||||
#if defined(HAVE_SO_REUSEADDR) || defined(HAVE_SO_BROADCAST)
|
#if defined(HAVE_SO_REUSEADDR) || defined(HAVE_SO_BROADCAST)
|
||||||
int optval;
|
int optval;
|
||||||
#endif
|
|
||||||
int ret;
|
int ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create a socket to listen for requests from DHCP clients */
|
/* Create a socket to listen for requests from DHCP clients */
|
||||||
|
|
||||||
@ -815,6 +815,7 @@ static int dhcpd_sendpacket(int bbroadcast)
|
|||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
in_addr_t ipaddr;
|
in_addr_t ipaddr;
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
int len;
|
||||||
int ret = ERROR;
|
int ret = ERROR;
|
||||||
|
|
||||||
/* Determine which address to respond to (or if we need to broadcast the response) */
|
/* Determine which address to respond to (or if we need to broadcast the response) */
|
||||||
@ -850,8 +851,10 @@ static int dhcpd_sendpacket(int bbroadcast)
|
|||||||
addr.sin_port = HTONS(DHCP_CLIENT_PORT);
|
addr.sin_port = HTONS(DHCP_CLIENT_PORT);
|
||||||
addr.sin_addr.s_addr = ipaddr;
|
addr.sin_addr.s_addr = ipaddr;
|
||||||
|
|
||||||
ret = sendto(sockfd,
|
/* Send the minimum sized packet that includes the END option */
|
||||||
&g_state.ds_outpacket, sizeof(struct dhcpmsg_s), 0,
|
|
||||||
|
len = (g_state.ds_optend - (uint8*)&g_state.ds_outpacket) + 1;
|
||||||
|
ret = sendto(sockfd, &g_state.ds_outpacket, len, 0,
|
||||||
(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
}
|
}
|
||||||
@ -1031,9 +1034,8 @@ static inline int dhcpd_request(void)
|
|||||||
* already offered to the client.
|
* already offered to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (g_state.ds_optserverip == g_state.ds_serverip &&
|
if (g_state.ds_optserverip == ntohl(g_state.ds_serverip) &&
|
||||||
g_state.ds_optreqip != 0 &&
|
(g_state.ds_optreqip != 0 || g_state.ds_optreqip == ipaddr))
|
||||||
g_state.ds_optreqip == ipaddr)
|
|
||||||
{
|
{
|
||||||
response = DHCPACK;
|
response = DHCPACK;
|
||||||
}
|
}
|
||||||
@ -1278,6 +1280,12 @@ int dhcpd_run(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETUTILS_DHCPD_HOST
|
||||||
|
/* Get the poor little uC a change to get its recvfrom in place */
|
||||||
|
|
||||||
|
sleep(2);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Now process the incoming DHCP message by its message type */
|
/* Now process the incoming DHCP message by its message type */
|
||||||
|
|
||||||
switch (g_state.ds_optmsgtype)
|
switch (g_state.ds_optmsgtype)
|
||||||
|
Loading…
Reference in New Issue
Block a user