37 #include "contiki-net.h" 38 #include "net/dhcpc.h" 40 #define STATE_INITIAL 0 41 #define STATE_SENDING 1 42 #define STATE_OFFER_RECEIVED 2 43 #define STATE_CONFIG_RECEIVED 3 45 static struct dhcpc_state s;
48 uint8_t op, htype, hlen, hops;
56 #ifndef UIP_CONF_DHCP_LIGHT 63 #define BOOTP_BROADCAST 0x8000 65 #define DHCP_REQUEST 1 67 #define DHCP_HTYPE_ETHERNET 1 68 #define DHCP_HLEN_ETHERNET 6 69 #define DHCP_MSG_LEN 236 71 #define DHCPC_SERVER_PORT 67 72 #define DHCPC_CLIENT_PORT 68 74 #define DHCPDISCOVER 1 82 #define DHCP_OPTION_SUBNET_MASK 1 83 #define DHCP_OPTION_ROUTER 3 84 #define DHCP_OPTION_DNS_SERVER 6 85 #define DHCP_OPTION_REQ_IPADDR 50 86 #define DHCP_OPTION_LEASE_TIME 51 87 #define DHCP_OPTION_MSG_TYPE 53 88 #define DHCP_OPTION_SERVER_ID 54 89 #define DHCP_OPTION_REQ_LIST 55 90 #define DHCP_OPTION_END 255 93 static const uint8_t magic_cookie[4] = {99, 130, 83, 99};
96 add_msg_type(uint8_t *optptr, uint8_t type)
98 *optptr++ = DHCP_OPTION_MSG_TYPE;
105 add_server_id(uint8_t *optptr)
107 *optptr++ = DHCP_OPTION_SERVER_ID;
109 memcpy(optptr, s.serverid, 4);
114 add_req_ipaddr(uint8_t *optptr)
116 *optptr++ = DHCP_OPTION_REQ_IPADDR;
118 memcpy(optptr, s.ipaddr.u16, 4);
123 add_req_options(uint8_t *optptr)
125 *optptr++ = DHCP_OPTION_REQ_LIST;
127 *optptr++ = DHCP_OPTION_SUBNET_MASK;
128 *optptr++ = DHCP_OPTION_ROUTER;
129 *optptr++ = DHCP_OPTION_DNS_SERVER;
134 add_end(uint8_t *optptr)
136 *optptr++ = DHCP_OPTION_END;
143 m->op = DHCP_REQUEST;
144 m->htype = DHCP_HTYPE_ETHERNET;
147 memcpy(m->xid, &xid,
sizeof(m->xid));
151 memcpy(m->ciaddr, uip_hostaddr.u16,
sizeof(m->ciaddr));
152 memset(m->yiaddr, 0,
sizeof(m->yiaddr));
153 memset(m->siaddr, 0,
sizeof(m->siaddr));
154 memset(m->giaddr, 0,
sizeof(m->giaddr));
155 memcpy(m->chaddr, s.mac_addr, s.mac_len);
156 memset(&m->chaddr[s.mac_len], 0,
sizeof(m->chaddr) - s.mac_len);
157 #ifndef UIP_CONF_DHCP_LIGHT 158 memset(m->sname, 0,
sizeof(m->sname));
159 memset(m->file, 0,
sizeof(m->file));
162 memcpy(m->options, magic_cookie,
sizeof(magic_cookie));
169 struct dhcp_msg *m = (
struct dhcp_msg *)
uip_appdata;
173 end = add_msg_type(&m->options[4], DHCPDISCOVER);
174 end = add_req_options(end);
184 struct dhcp_msg *m = (
struct dhcp_msg *)
uip_appdata;
188 end = add_msg_type(&m->options[4], DHCPREQUEST);
189 end = add_server_id(end);
190 end = add_req_ipaddr(end);
197 parse_options(uint8_t *optptr,
int len)
199 uint8_t *end = optptr + len;
202 while(optptr < end) {
204 case DHCP_OPTION_SUBNET_MASK:
205 memcpy(s.netmask.u16, optptr + 2, 4);
207 case DHCP_OPTION_ROUTER:
208 memcpy(s.default_router.u16, optptr + 2, 4);
210 case DHCP_OPTION_DNS_SERVER:
211 memcpy(s.dnsaddr.u16, optptr + 2, 4);
213 case DHCP_OPTION_MSG_TYPE:
214 type = *(optptr + 2);
216 case DHCP_OPTION_SERVER_ID:
217 memcpy(s.serverid, optptr + 2, 4);
219 case DHCP_OPTION_LEASE_TIME:
220 memcpy(s.lease_time, optptr + 2, 4);
222 case DHCP_OPTION_END:
226 optptr += optptr[1] + 2;
234 struct dhcp_msg *m = (
struct dhcp_msg *)
uip_appdata;
236 if(m->op == DHCP_REPLY &&
237 memcmp(m->xid, &xid,
sizeof(xid)) == 0 &&
238 memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
239 memcpy(s.ipaddr.u16, m->yiaddr, 4);
240 return parse_options(&m->options[4],
uip_datalen());
251 struct dhcp_msg *m = (
struct dhcp_msg *)
uip_appdata;
252 uint8_t *optptr = &m->options[4];
255 if(m->op == DHCP_REPLY &&
256 memcmp(m->xid, &xid,
sizeof(xid)) == 0 &&
257 memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
258 while(optptr < end) {
259 if(*optptr == DHCP_OPTION_MSG_TYPE) {
260 return *(optptr + 2);
261 }
else if (*optptr == DHCP_OPTION_END) {
264 optptr += optptr[1] + 2;
279 s.state = STATE_SENDING;
292 s.state = STATE_OFFER_RECEIVED;
316 s.state = STATE_CONFIG_RECEIVED;
326 }
while(s.state != STATE_CONFIG_RECEIVED);
333 printf(
"Got default router %d.%d.%d.%d\n",
335 printf(
"Lease expires in %ld seconds\n",
336 uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]));
339 dhcpc_configured(&s);
341 #define MAX_TICKS (~((clock_time_t)0) / 2) 342 #define MAX_TICKS32 (~((uint32_t)0)) 343 #define IMIN(a, b) ((a) < (b) ? (a) : (b)) 345 if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*
CLOCK_SECOND/2
347 s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1])
350 s.ticks = MAX_TICKS32;
354 ticks = IMIN(s.ticks, MAX_TICKS);
360 if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*
CLOCK_SECOND/2
362 s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1])
365 s.ticks = MAX_TICKS32;
376 ticks = IMIN(s.ticks / 2, MAX_TICKS);
391 dhcpc_unconfigured(&s);
395 #ifdef ECLIPSE_STUB_CODE_ANALYSE 401 dhcpc_init(
const void *mac_addr,
int mac_len)
405 s.mac_addr = mac_addr;
410 s.state = STATE_INITIAL;
425 s.conn->appstate.p = NULL;
426 s.conn->appstate.state = NULL;
432 dhcpc_appcall(process_event_t ev,
void *data)
434 if(ev ==
tcpip_event || ev == PROCESS_EVENT_TIMER) {
435 handle_dhcp(ev, data);
444 if(s.state == STATE_INITIAL) {
447 handle_dhcp(PROCESS_EVENT_NONE, NULL);
#define uip_ipaddr_to_quad(a)
#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
void uip_send(const void *data, int len)
process_event_t tcpip_event
#define PT_YIELD_UNTIL(pt, cond)
Yield from the protothread until a condition occurs.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
#define PT_THREAD(name_args)
CCIF struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
uint8_t data[USBNET_RX_BUF_SIZE]
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define uip_sethostaddr(addr)
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn)
#define udp_bind(conn, port)