Fork of Smoothie to port to mbed non-LPC targets.
Fork of Smoothie by
libs/Network/uip/dhcpc/dhcpc.c@2:1df0b61d3b5a, 2014-02-28 (annotated)
- Committer:
- Michael J. Spencer
- Date:
- Fri Feb 28 18:52:52 2014 -0800
- Revision:
- 2:1df0b61d3b5a
Update to latest Smoothie.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Michael J. Spencer |
2:1df0b61d3b5a | 1 | /* |
Michael J. Spencer |
2:1df0b61d3b5a | 2 | * Copyright (c) 2005, Swedish Institute of Computer Science |
Michael J. Spencer |
2:1df0b61d3b5a | 3 | * All rights reserved. |
Michael J. Spencer |
2:1df0b61d3b5a | 4 | * |
Michael J. Spencer |
2:1df0b61d3b5a | 5 | * Redistribution and use in source and binary forms, with or without |
Michael J. Spencer |
2:1df0b61d3b5a | 6 | * modification, are permitted provided that the following conditions |
Michael J. Spencer |
2:1df0b61d3b5a | 7 | * are met: |
Michael J. Spencer |
2:1df0b61d3b5a | 8 | * 1. Redistributions of source code must retain the above copyright |
Michael J. Spencer |
2:1df0b61d3b5a | 9 | * notice, this list of conditions and the following disclaimer. |
Michael J. Spencer |
2:1df0b61d3b5a | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
Michael J. Spencer |
2:1df0b61d3b5a | 11 | * notice, this list of conditions and the following disclaimer in the |
Michael J. Spencer |
2:1df0b61d3b5a | 12 | * documentation and/or other materials provided with the distribution. |
Michael J. Spencer |
2:1df0b61d3b5a | 13 | * 3. Neither the name of the Institute nor the names of its contributors |
Michael J. Spencer |
2:1df0b61d3b5a | 14 | * may be used to endorse or promote products derived from this software |
Michael J. Spencer |
2:1df0b61d3b5a | 15 | * without specific prior written permission. |
Michael J. Spencer |
2:1df0b61d3b5a | 16 | * |
Michael J. Spencer |
2:1df0b61d3b5a | 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |
Michael J. Spencer |
2:1df0b61d3b5a | 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
Michael J. Spencer |
2:1df0b61d3b5a | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
Michael J. Spencer |
2:1df0b61d3b5a | 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |
Michael J. Spencer |
2:1df0b61d3b5a | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
Michael J. Spencer |
2:1df0b61d3b5a | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
Michael J. Spencer |
2:1df0b61d3b5a | 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
Michael J. Spencer |
2:1df0b61d3b5a | 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
Michael J. Spencer |
2:1df0b61d3b5a | 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
Michael J. Spencer |
2:1df0b61d3b5a | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
Michael J. Spencer |
2:1df0b61d3b5a | 27 | * SUCH DAMAGE. |
Michael J. Spencer |
2:1df0b61d3b5a | 28 | * |
Michael J. Spencer |
2:1df0b61d3b5a | 29 | * This file is part of the uIP TCP/IP stack |
Michael J. Spencer |
2:1df0b61d3b5a | 30 | * |
Michael J. Spencer |
2:1df0b61d3b5a | 31 | * @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $ |
Michael J. Spencer |
2:1df0b61d3b5a | 32 | */ |
Michael J. Spencer |
2:1df0b61d3b5a | 33 | |
Michael J. Spencer |
2:1df0b61d3b5a | 34 | #include <stdio.h> |
Michael J. Spencer |
2:1df0b61d3b5a | 35 | #include <string.h> |
Michael J. Spencer |
2:1df0b61d3b5a | 36 | |
Michael J. Spencer |
2:1df0b61d3b5a | 37 | #include "uip.h" |
Michael J. Spencer |
2:1df0b61d3b5a | 38 | #include "dhcpc.h" |
Michael J. Spencer |
2:1df0b61d3b5a | 39 | #include "timer.h" |
Michael J. Spencer |
2:1df0b61d3b5a | 40 | #include "pt.h" |
Michael J. Spencer |
2:1df0b61d3b5a | 41 | |
Michael J. Spencer |
2:1df0b61d3b5a | 42 | #if UIP_CONF_UDP |
Michael J. Spencer |
2:1df0b61d3b5a | 43 | |
Michael J. Spencer |
2:1df0b61d3b5a | 44 | #define STATE_INITIAL 0 |
Michael J. Spencer |
2:1df0b61d3b5a | 45 | #define STATE_SENDING 1 |
Michael J. Spencer |
2:1df0b61d3b5a | 46 | #define STATE_OFFER_RECEIVED 2 |
Michael J. Spencer |
2:1df0b61d3b5a | 47 | #define STATE_CONFIG_RECEIVED 3 |
Michael J. Spencer |
2:1df0b61d3b5a | 48 | |
Michael J. Spencer |
2:1df0b61d3b5a | 49 | #define ntohl(a) ((((a) >> 24) & 0x000000FF) | (((a) >> 8) & 0x0000FF00) | (((a) << 8) & 0x00FF0000) | (((a) << 24) & 0xFF000000)) |
Michael J. Spencer |
2:1df0b61d3b5a | 50 | static struct dhcpc_state s __attribute__ ((section ("AHBSRAM1"))); |
Michael J. Spencer |
2:1df0b61d3b5a | 51 | //#define UIP_CONF_DHCP_LIGHT |
Michael J. Spencer |
2:1df0b61d3b5a | 52 | |
Michael J. Spencer |
2:1df0b61d3b5a | 53 | struct dhcp_msg { |
Michael J. Spencer |
2:1df0b61d3b5a | 54 | u8_t op, htype, hlen, hops; |
Michael J. Spencer |
2:1df0b61d3b5a | 55 | u8_t xid[4]; |
Michael J. Spencer |
2:1df0b61d3b5a | 56 | u16_t secs, flags; |
Michael J. Spencer |
2:1df0b61d3b5a | 57 | u8_t ciaddr[4]; |
Michael J. Spencer |
2:1df0b61d3b5a | 58 | u8_t yiaddr[4]; |
Michael J. Spencer |
2:1df0b61d3b5a | 59 | u8_t siaddr[4]; |
Michael J. Spencer |
2:1df0b61d3b5a | 60 | u8_t giaddr[4]; |
Michael J. Spencer |
2:1df0b61d3b5a | 61 | u8_t chaddr[16]; |
Michael J. Spencer |
2:1df0b61d3b5a | 62 | #ifndef UIP_CONF_DHCP_LIGHT |
Michael J. Spencer |
2:1df0b61d3b5a | 63 | u8_t sname[64]; |
Michael J. Spencer |
2:1df0b61d3b5a | 64 | u8_t file[128]; |
Michael J. Spencer |
2:1df0b61d3b5a | 65 | #endif |
Michael J. Spencer |
2:1df0b61d3b5a | 66 | u8_t options[312]; |
Michael J. Spencer |
2:1df0b61d3b5a | 67 | }; |
Michael J. Spencer |
2:1df0b61d3b5a | 68 | |
Michael J. Spencer |
2:1df0b61d3b5a | 69 | #define BOOTP_BROADCAST 0x8000 |
Michael J. Spencer |
2:1df0b61d3b5a | 70 | |
Michael J. Spencer |
2:1df0b61d3b5a | 71 | #define DHCP_REQUEST 1 |
Michael J. Spencer |
2:1df0b61d3b5a | 72 | #define DHCP_REPLY 2 |
Michael J. Spencer |
2:1df0b61d3b5a | 73 | #define DHCP_HTYPE_ETHERNET 1 |
Michael J. Spencer |
2:1df0b61d3b5a | 74 | #define DHCP_HLEN_ETHERNET 6 |
Michael J. Spencer |
2:1df0b61d3b5a | 75 | #define DHCP_MSG_LEN 236 |
Michael J. Spencer |
2:1df0b61d3b5a | 76 | |
Michael J. Spencer |
2:1df0b61d3b5a | 77 | #define DHCPC_SERVER_PORT 67 |
Michael J. Spencer |
2:1df0b61d3b5a | 78 | #define DHCPC_CLIENT_PORT 68 |
Michael J. Spencer |
2:1df0b61d3b5a | 79 | |
Michael J. Spencer |
2:1df0b61d3b5a | 80 | #define DHCPDISCOVER 1 |
Michael J. Spencer |
2:1df0b61d3b5a | 81 | #define DHCPOFFER 2 |
Michael J. Spencer |
2:1df0b61d3b5a | 82 | #define DHCPREQUEST 3 |
Michael J. Spencer |
2:1df0b61d3b5a | 83 | #define DHCPDECLINE 4 |
Michael J. Spencer |
2:1df0b61d3b5a | 84 | #define DHCPACK 5 |
Michael J. Spencer |
2:1df0b61d3b5a | 85 | #define DHCPNAK 6 |
Michael J. Spencer |
2:1df0b61d3b5a | 86 | #define DHCPRELEASE 7 |
Michael J. Spencer |
2:1df0b61d3b5a | 87 | |
Michael J. Spencer |
2:1df0b61d3b5a | 88 | #define DHCP_OPTION_SUBNET_MASK 1 |
Michael J. Spencer |
2:1df0b61d3b5a | 89 | #define DHCP_OPTION_ROUTER 3 |
Michael J. Spencer |
2:1df0b61d3b5a | 90 | #define DHCP_OPTION_DNS_SERVER 6 |
Michael J. Spencer |
2:1df0b61d3b5a | 91 | #define DHCP_OPTION_REQ_IPADDR 50 |
Michael J. Spencer |
2:1df0b61d3b5a | 92 | #define DHCP_OPTION_LEASE_TIME 51 |
Michael J. Spencer |
2:1df0b61d3b5a | 93 | #define DHCP_OPTION_MSG_TYPE 53 |
Michael J. Spencer |
2:1df0b61d3b5a | 94 | #define DHCP_OPTION_SERVER_ID 54 |
Michael J. Spencer |
2:1df0b61d3b5a | 95 | #define DHCP_OPTION_REQ_LIST 55 |
Michael J. Spencer |
2:1df0b61d3b5a | 96 | #define DHCP_OPTION_END 255 |
Michael J. Spencer |
2:1df0b61d3b5a | 97 | |
Michael J. Spencer |
2:1df0b61d3b5a | 98 | static uint32_t xid= 0x00112233; |
Michael J. Spencer |
2:1df0b61d3b5a | 99 | |
Michael J. Spencer |
2:1df0b61d3b5a | 100 | static const u8_t magic_cookie[4] = {99, 130, 83, 99}; |
Michael J. Spencer |
2:1df0b61d3b5a | 101 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 102 | static u8_t * |
Michael J. Spencer |
2:1df0b61d3b5a | 103 | add_msg_type(u8_t *optptr, u8_t type) |
Michael J. Spencer |
2:1df0b61d3b5a | 104 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 105 | *optptr++ = DHCP_OPTION_MSG_TYPE; |
Michael J. Spencer |
2:1df0b61d3b5a | 106 | *optptr++ = 1; |
Michael J. Spencer |
2:1df0b61d3b5a | 107 | *optptr++ = type; |
Michael J. Spencer |
2:1df0b61d3b5a | 108 | return optptr; |
Michael J. Spencer |
2:1df0b61d3b5a | 109 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 110 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 111 | static u8_t * |
Michael J. Spencer |
2:1df0b61d3b5a | 112 | add_server_id(u8_t *optptr) |
Michael J. Spencer |
2:1df0b61d3b5a | 113 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 114 | *optptr++ = DHCP_OPTION_SERVER_ID; |
Michael J. Spencer |
2:1df0b61d3b5a | 115 | *optptr++ = 4; |
Michael J. Spencer |
2:1df0b61d3b5a | 116 | memcpy(optptr, &s.serverid, 4); |
Michael J. Spencer |
2:1df0b61d3b5a | 117 | return optptr + 4; |
Michael J. Spencer |
2:1df0b61d3b5a | 118 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 119 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 120 | static u8_t * |
Michael J. Spencer |
2:1df0b61d3b5a | 121 | add_req_ipaddr(u8_t *optptr) |
Michael J. Spencer |
2:1df0b61d3b5a | 122 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 123 | *optptr++ = DHCP_OPTION_REQ_IPADDR; |
Michael J. Spencer |
2:1df0b61d3b5a | 124 | *optptr++ = 4; |
Michael J. Spencer |
2:1df0b61d3b5a | 125 | memcpy(optptr, &s.ipaddr, 4); |
Michael J. Spencer |
2:1df0b61d3b5a | 126 | return optptr + 4; |
Michael J. Spencer |
2:1df0b61d3b5a | 127 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 128 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 129 | static u8_t * |
Michael J. Spencer |
2:1df0b61d3b5a | 130 | add_req_options(u8_t *optptr) |
Michael J. Spencer |
2:1df0b61d3b5a | 131 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 132 | *optptr++ = DHCP_OPTION_REQ_LIST; |
Michael J. Spencer |
2:1df0b61d3b5a | 133 | *optptr++ = 3; |
Michael J. Spencer |
2:1df0b61d3b5a | 134 | *optptr++ = DHCP_OPTION_SUBNET_MASK; |
Michael J. Spencer |
2:1df0b61d3b5a | 135 | *optptr++ = DHCP_OPTION_ROUTER; |
Michael J. Spencer |
2:1df0b61d3b5a | 136 | *optptr++ = DHCP_OPTION_DNS_SERVER; |
Michael J. Spencer |
2:1df0b61d3b5a | 137 | return optptr; |
Michael J. Spencer |
2:1df0b61d3b5a | 138 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 139 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 140 | static u8_t * |
Michael J. Spencer |
2:1df0b61d3b5a | 141 | add_end(u8_t *optptr) |
Michael J. Spencer |
2:1df0b61d3b5a | 142 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 143 | *optptr++ = DHCP_OPTION_END; |
Michael J. Spencer |
2:1df0b61d3b5a | 144 | return optptr; |
Michael J. Spencer |
2:1df0b61d3b5a | 145 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 146 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 147 | static void |
Michael J. Spencer |
2:1df0b61d3b5a | 148 | create_msg(register struct dhcp_msg *m, int rea) |
Michael J. Spencer |
2:1df0b61d3b5a | 149 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 150 | m->op = DHCP_REQUEST; |
Michael J. Spencer |
2:1df0b61d3b5a | 151 | m->htype = DHCP_HTYPE_ETHERNET; |
Michael J. Spencer |
2:1df0b61d3b5a | 152 | m->hlen = s.mac_len; |
Michael J. Spencer |
2:1df0b61d3b5a | 153 | m->hops = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 154 | memcpy(m->xid, &xid, sizeof(m->xid)); |
Michael J. Spencer |
2:1df0b61d3b5a | 155 | m->secs = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 156 | m->flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ |
Michael J. Spencer |
2:1df0b61d3b5a | 157 | /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 158 | if(rea == 0 ) memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr)); |
Michael J. Spencer |
2:1df0b61d3b5a | 159 | else memset(m->ciaddr, 0, sizeof(m->ciaddr)); |
Michael J. Spencer |
2:1df0b61d3b5a | 160 | memset(m->yiaddr, 0, sizeof(m->yiaddr)); |
Michael J. Spencer |
2:1df0b61d3b5a | 161 | memset(m->siaddr, 0, sizeof(m->siaddr)); |
Michael J. Spencer |
2:1df0b61d3b5a | 162 | memset(m->giaddr, 0, sizeof(m->giaddr)); |
Michael J. Spencer |
2:1df0b61d3b5a | 163 | memcpy(m->chaddr, s.mac_addr, s.mac_len); |
Michael J. Spencer |
2:1df0b61d3b5a | 164 | memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len); |
Michael J. Spencer |
2:1df0b61d3b5a | 165 | #ifndef UIP_CONF_DHCP_LIGHT |
Michael J. Spencer |
2:1df0b61d3b5a | 166 | memset(m->sname, 0, sizeof(m->sname)); |
Michael J. Spencer |
2:1df0b61d3b5a | 167 | memset(m->file, 0, sizeof(m->file)); |
Michael J. Spencer |
2:1df0b61d3b5a | 168 | #endif |
Michael J. Spencer |
2:1df0b61d3b5a | 169 | |
Michael J. Spencer |
2:1df0b61d3b5a | 170 | memcpy(m->options, magic_cookie, sizeof(magic_cookie)); |
Michael J. Spencer |
2:1df0b61d3b5a | 171 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 172 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 173 | static void |
Michael J. Spencer |
2:1df0b61d3b5a | 174 | send_discover(void) |
Michael J. Spencer |
2:1df0b61d3b5a | 175 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 176 | u8_t *end; |
Michael J. Spencer |
2:1df0b61d3b5a | 177 | struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; |
Michael J. Spencer |
2:1df0b61d3b5a | 178 | |
Michael J. Spencer |
2:1df0b61d3b5a | 179 | create_msg(m, 0); |
Michael J. Spencer |
2:1df0b61d3b5a | 180 | |
Michael J. Spencer |
2:1df0b61d3b5a | 181 | end = add_msg_type(&m->options[4], DHCPDISCOVER); |
Michael J. Spencer |
2:1df0b61d3b5a | 182 | end = add_req_options(end); |
Michael J. Spencer |
2:1df0b61d3b5a | 183 | end = add_end(end); |
Michael J. Spencer |
2:1df0b61d3b5a | 184 | |
Michael J. Spencer |
2:1df0b61d3b5a | 185 | uip_send(uip_appdata, end - (u8_t *)uip_appdata); |
Michael J. Spencer |
2:1df0b61d3b5a | 186 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 187 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 188 | static void |
Michael J. Spencer |
2:1df0b61d3b5a | 189 | send_request(int rea) |
Michael J. Spencer |
2:1df0b61d3b5a | 190 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 191 | u8_t *end; |
Michael J. Spencer |
2:1df0b61d3b5a | 192 | struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; |
Michael J. Spencer |
2:1df0b61d3b5a | 193 | |
Michael J. Spencer |
2:1df0b61d3b5a | 194 | create_msg(m, rea); |
Michael J. Spencer |
2:1df0b61d3b5a | 195 | |
Michael J. Spencer |
2:1df0b61d3b5a | 196 | end = add_msg_type(&m->options[4], DHCPREQUEST); |
Michael J. Spencer |
2:1df0b61d3b5a | 197 | end = add_server_id(end); |
Michael J. Spencer |
2:1df0b61d3b5a | 198 | end = add_req_ipaddr(end); |
Michael J. Spencer |
2:1df0b61d3b5a | 199 | end = add_end(end); |
Michael J. Spencer |
2:1df0b61d3b5a | 200 | |
Michael J. Spencer |
2:1df0b61d3b5a | 201 | uip_send(uip_appdata, end - (u8_t *)uip_appdata); |
Michael J. Spencer |
2:1df0b61d3b5a | 202 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 203 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 204 | static u8_t |
Michael J. Spencer |
2:1df0b61d3b5a | 205 | parse_options(u8_t *optptr, int len) |
Michael J. Spencer |
2:1df0b61d3b5a | 206 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 207 | u8_t *end = optptr + len; |
Michael J. Spencer |
2:1df0b61d3b5a | 208 | u8_t type = 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 209 | |
Michael J. Spencer |
2:1df0b61d3b5a | 210 | while (optptr < end) { |
Michael J. Spencer |
2:1df0b61d3b5a | 211 | switch (*optptr) { |
Michael J. Spencer |
2:1df0b61d3b5a | 212 | case DHCP_OPTION_SUBNET_MASK: |
Michael J. Spencer |
2:1df0b61d3b5a | 213 | memcpy(&s.netmask, optptr + 2, 4); |
Michael J. Spencer |
2:1df0b61d3b5a | 214 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 215 | case DHCP_OPTION_ROUTER: |
Michael J. Spencer |
2:1df0b61d3b5a | 216 | memcpy(&s.default_router, optptr + 2, 4); |
Michael J. Spencer |
2:1df0b61d3b5a | 217 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 218 | case DHCP_OPTION_DNS_SERVER: |
Michael J. Spencer |
2:1df0b61d3b5a | 219 | memcpy(&s.dnsaddr, optptr + 2, 4); |
Michael J. Spencer |
2:1df0b61d3b5a | 220 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 221 | case DHCP_OPTION_MSG_TYPE: |
Michael J. Spencer |
2:1df0b61d3b5a | 222 | type = *(optptr + 2); |
Michael J. Spencer |
2:1df0b61d3b5a | 223 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 224 | case DHCP_OPTION_SERVER_ID: |
Michael J. Spencer |
2:1df0b61d3b5a | 225 | memcpy(s.serverid, optptr + 2, 4); |
Michael J. Spencer |
2:1df0b61d3b5a | 226 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 227 | case DHCP_OPTION_LEASE_TIME: |
Michael J. Spencer |
2:1df0b61d3b5a | 228 | memcpy(&s.lease_time, optptr + 2, 4); |
Michael J. Spencer |
2:1df0b61d3b5a | 229 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 230 | case DHCP_OPTION_END: |
Michael J. Spencer |
2:1df0b61d3b5a | 231 | return type; |
Michael J. Spencer |
2:1df0b61d3b5a | 232 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 233 | |
Michael J. Spencer |
2:1df0b61d3b5a | 234 | optptr += optptr[1] + 2; |
Michael J. Spencer |
2:1df0b61d3b5a | 235 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 236 | return type; |
Michael J. Spencer |
2:1df0b61d3b5a | 237 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 238 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 239 | u8_t |
Michael J. Spencer |
2:1df0b61d3b5a | 240 | parse_msg(void) |
Michael J. Spencer |
2:1df0b61d3b5a | 241 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 242 | struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; |
Michael J. Spencer |
2:1df0b61d3b5a | 243 | |
Michael J. Spencer |
2:1df0b61d3b5a | 244 | if (m->op == DHCP_REPLY && |
Michael J. Spencer |
2:1df0b61d3b5a | 245 | memcmp(m->xid, &xid, sizeof(xid)) == 0 && |
Michael J. Spencer |
2:1df0b61d3b5a | 246 | memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { |
Michael J. Spencer |
2:1df0b61d3b5a | 247 | memcpy(&s.ipaddr, m->yiaddr, 4); |
Michael J. Spencer |
2:1df0b61d3b5a | 248 | return parse_options(&m->options[4], uip_datalen()); |
Michael J. Spencer |
2:1df0b61d3b5a | 249 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 250 | return 0; |
Michael J. Spencer |
2:1df0b61d3b5a | 251 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 252 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 253 | static |
Michael J. Spencer |
2:1df0b61d3b5a | 254 | PT_THREAD(handle_dhcp(void)) |
Michael J. Spencer |
2:1df0b61d3b5a | 255 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 256 | PT_BEGIN(&s.pt); |
Michael J. Spencer |
2:1df0b61d3b5a | 257 | |
Michael J. Spencer |
2:1df0b61d3b5a | 258 | /* try_again:*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 259 | s.state = STATE_SENDING; |
Michael J. Spencer |
2:1df0b61d3b5a | 260 | s.ticks = CLOCK_SECOND; |
Michael J. Spencer |
2:1df0b61d3b5a | 261 | xid++; |
Michael J. Spencer |
2:1df0b61d3b5a | 262 | |
Michael J. Spencer |
2:1df0b61d3b5a | 263 | send_discover(); |
Michael J. Spencer |
2:1df0b61d3b5a | 264 | do { |
Michael J. Spencer |
2:1df0b61d3b5a | 265 | timer_set(&s.timer, s.ticks); |
Michael J. Spencer |
2:1df0b61d3b5a | 266 | PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); |
Michael J. Spencer |
2:1df0b61d3b5a | 267 | // if we timed out then increase time out and send discover again |
Michael J. Spencer |
2:1df0b61d3b5a | 268 | if (timer_expired(&s.timer)) { |
Michael J. Spencer |
2:1df0b61d3b5a | 269 | if (s.ticks < CLOCK_SECOND * 60) { |
Michael J. Spencer |
2:1df0b61d3b5a | 270 | s.ticks *= 2; |
Michael J. Spencer |
2:1df0b61d3b5a | 271 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 272 | send_discover(); |
Michael J. Spencer |
2:1df0b61d3b5a | 273 | }else{ |
Michael J. Spencer |
2:1df0b61d3b5a | 274 | // we may have gotten some other UDP packet in which case just wait some more for the right packet |
Michael J. Spencer |
2:1df0b61d3b5a | 275 | if (uip_newdata() && parse_msg() == DHCPOFFER) { |
Michael J. Spencer |
2:1df0b61d3b5a | 276 | s.state = STATE_OFFER_RECEIVED; |
Michael J. Spencer |
2:1df0b61d3b5a | 277 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 278 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 279 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 280 | PT_YIELD(&s.pt); |
Michael J. Spencer |
2:1df0b61d3b5a | 281 | |
Michael J. Spencer |
2:1df0b61d3b5a | 282 | } while (s.state != STATE_OFFER_RECEIVED); |
Michael J. Spencer |
2:1df0b61d3b5a | 283 | |
Michael J. Spencer |
2:1df0b61d3b5a | 284 | s.ticks = CLOCK_SECOND; |
Michael J. Spencer |
2:1df0b61d3b5a | 285 | xid++; |
Michael J. Spencer |
2:1df0b61d3b5a | 286 | |
Michael J. Spencer |
2:1df0b61d3b5a | 287 | send_request(0); |
Michael J. Spencer |
2:1df0b61d3b5a | 288 | do { |
Michael J. Spencer |
2:1df0b61d3b5a | 289 | timer_set(&s.timer, s.ticks); |
Michael J. Spencer |
2:1df0b61d3b5a | 290 | PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); |
Michael J. Spencer |
2:1df0b61d3b5a | 291 | |
Michael J. Spencer |
2:1df0b61d3b5a | 292 | if (timer_expired(&s.timer)) { |
Michael J. Spencer |
2:1df0b61d3b5a | 293 | if (s.ticks <= CLOCK_SECOND * 10) { |
Michael J. Spencer |
2:1df0b61d3b5a | 294 | s.ticks += CLOCK_SECOND; |
Michael J. Spencer |
2:1df0b61d3b5a | 295 | send_request(0); // resend only on timeout |
Michael J. Spencer |
2:1df0b61d3b5a | 296 | } else { |
Michael J. Spencer |
2:1df0b61d3b5a | 297 | PT_RESTART(&s.pt); |
Michael J. Spencer |
2:1df0b61d3b5a | 298 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 299 | }else{ |
Michael J. Spencer |
2:1df0b61d3b5a | 300 | if (uip_newdata() && parse_msg() == DHCPACK) { |
Michael J. Spencer |
2:1df0b61d3b5a | 301 | s.state = STATE_CONFIG_RECEIVED; |
Michael J. Spencer |
2:1df0b61d3b5a | 302 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 303 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 304 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 305 | PT_YIELD(&s.pt); |
Michael J. Spencer |
2:1df0b61d3b5a | 306 | |
Michael J. Spencer |
2:1df0b61d3b5a | 307 | } while (s.state != STATE_CONFIG_RECEIVED); |
Michael J. Spencer |
2:1df0b61d3b5a | 308 | |
Michael J. Spencer |
2:1df0b61d3b5a | 309 | dhcpc_configured(&s); |
Michael J. Spencer |
2:1df0b61d3b5a | 310 | |
Michael J. Spencer |
2:1df0b61d3b5a | 311 | // now we wait for close to expiration and renew the lease |
Michael J. Spencer |
2:1df0b61d3b5a | 312 | do { |
Michael J. Spencer |
2:1df0b61d3b5a | 313 | // we should reacquire expired leases here. |
Michael J. Spencer |
2:1df0b61d3b5a | 314 | timer_set(&s.timer, (ntohl(s.lease_time) * 0.5)*CLOCK_SECOND); // half of lease expire time |
Michael J. Spencer |
2:1df0b61d3b5a | 315 | PT_WAIT_UNTIL(&s.pt, timer_expired(&s.timer)); |
Michael J. Spencer |
2:1df0b61d3b5a | 316 | |
Michael J. Spencer |
2:1df0b61d3b5a | 317 | uip_log("reaquire dhcp lease"); |
Michael J. Spencer |
2:1df0b61d3b5a | 318 | |
Michael J. Spencer |
2:1df0b61d3b5a | 319 | // spec says send request direct to server that gave it to us, but seems to be unecessary |
Michael J. Spencer |
2:1df0b61d3b5a | 320 | //uip_ipaddr_copy(&s.conn->ripaddr, s.serverid); |
Michael J. Spencer |
2:1df0b61d3b5a | 321 | |
Michael J. Spencer |
2:1df0b61d3b5a | 322 | s.ticks = CLOCK_SECOND; |
Michael J. Spencer |
2:1df0b61d3b5a | 323 | xid++; |
Michael J. Spencer |
2:1df0b61d3b5a | 324 | send_request(0); |
Michael J. Spencer |
2:1df0b61d3b5a | 325 | do { |
Michael J. Spencer |
2:1df0b61d3b5a | 326 | timer_set(&s.timer, s.ticks); |
Michael J. Spencer |
2:1df0b61d3b5a | 327 | PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); |
Michael J. Spencer |
2:1df0b61d3b5a | 328 | |
Michael J. Spencer |
2:1df0b61d3b5a | 329 | if (timer_expired(&s.timer)) { |
Michael J. Spencer |
2:1df0b61d3b5a | 330 | if (s.ticks <= CLOCK_SECOND * 10) { |
Michael J. Spencer |
2:1df0b61d3b5a | 331 | s.ticks += CLOCK_SECOND; |
Michael J. Spencer |
2:1df0b61d3b5a | 332 | send_request(0); // resend only on timeout |
Michael J. Spencer |
2:1df0b61d3b5a | 333 | } else { |
Michael J. Spencer |
2:1df0b61d3b5a | 334 | // give up |
Michael J. Spencer |
2:1df0b61d3b5a | 335 | // TODO probably need to deal with upstream apps and stop them then reinit them |
Michael J. Spencer |
2:1df0b61d3b5a | 336 | PT_RESTART(&s.pt); |
Michael J. Spencer |
2:1df0b61d3b5a | 337 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 338 | }else{ |
Michael J. Spencer |
2:1df0b61d3b5a | 339 | if (parse_msg() == DHCPACK) { |
Michael J. Spencer |
2:1df0b61d3b5a | 340 | uip_log("dhcp lease renewed"); |
Michael J. Spencer |
2:1df0b61d3b5a | 341 | break; |
Michael J. Spencer |
2:1df0b61d3b5a | 342 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 343 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 344 | PT_YIELD(&s.pt); |
Michael J. Spencer |
2:1df0b61d3b5a | 345 | }while(1); |
Michael J. Spencer |
2:1df0b61d3b5a | 346 | |
Michael J. Spencer |
2:1df0b61d3b5a | 347 | }while(1); |
Michael J. Spencer |
2:1df0b61d3b5a | 348 | |
Michael J. Spencer |
2:1df0b61d3b5a | 349 | PT_END(&s.pt); |
Michael J. Spencer |
2:1df0b61d3b5a | 350 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 351 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 352 | void |
Michael J. Spencer |
2:1df0b61d3b5a | 353 | dhcpc_init(const void *mac_addr, int mac_len) |
Michael J. Spencer |
2:1df0b61d3b5a | 354 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 355 | uip_ipaddr_t addr; |
Michael J. Spencer |
2:1df0b61d3b5a | 356 | |
Michael J. Spencer |
2:1df0b61d3b5a | 357 | s.mac_addr = mac_addr; |
Michael J. Spencer |
2:1df0b61d3b5a | 358 | s.mac_len = mac_len; |
Michael J. Spencer |
2:1df0b61d3b5a | 359 | |
Michael J. Spencer |
2:1df0b61d3b5a | 360 | s.state = STATE_INITIAL; |
Michael J. Spencer |
2:1df0b61d3b5a | 361 | uip_ipaddr(addr, 255, 255, 255, 255); |
Michael J. Spencer |
2:1df0b61d3b5a | 362 | s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT)); |
Michael J. Spencer |
2:1df0b61d3b5a | 363 | if (s.conn != NULL) { |
Michael J. Spencer |
2:1df0b61d3b5a | 364 | uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT)); |
Michael J. Spencer |
2:1df0b61d3b5a | 365 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 366 | PT_INIT(&s.pt); |
Michael J. Spencer |
2:1df0b61d3b5a | 367 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 368 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 369 | void |
Michael J. Spencer |
2:1df0b61d3b5a | 370 | dhcpc_appcall(void) |
Michael J. Spencer |
2:1df0b61d3b5a | 371 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 372 | handle_dhcp(); |
Michael J. Spencer |
2:1df0b61d3b5a | 373 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 374 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 375 | void |
Michael J. Spencer |
2:1df0b61d3b5a | 376 | dhcpc_request(void) |
Michael J. Spencer |
2:1df0b61d3b5a | 377 | { |
Michael J. Spencer |
2:1df0b61d3b5a | 378 | u16_t ipaddr[2]; |
Michael J. Spencer |
2:1df0b61d3b5a | 379 | |
Michael J. Spencer |
2:1df0b61d3b5a | 380 | if (s.state == STATE_INITIAL) { |
Michael J. Spencer |
2:1df0b61d3b5a | 381 | uip_ipaddr(ipaddr, 0, 0, 0, 0); |
Michael J. Spencer |
2:1df0b61d3b5a | 382 | uip_sethostaddr(ipaddr); |
Michael J. Spencer |
2:1df0b61d3b5a | 383 | /* handle_dhcp(PROCESS_EVENT_NONE, NULL);*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 384 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 385 | } |
Michael J. Spencer |
2:1df0b61d3b5a | 386 | /*---------------------------------------------------------------------------*/ |
Michael J. Spencer |
2:1df0b61d3b5a | 387 | |
Michael J. Spencer |
2:1df0b61d3b5a | 388 | #endif |