CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2

Dependents:   USBEthernet_TEST

Fork of USB_Ethernet by Daniele Lacamera

Committer:
daniele
Date:
Sat Aug 03 13:16:14 2013 +0000
Revision:
2:540f6e142d59
Moved to single package

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniele 2:540f6e142d59 1 /*********************************************************************
daniele 2:540f6e142d59 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
daniele 2:540f6e142d59 3 See LICENSE and COPYING for usage.
daniele 2:540f6e142d59 4
daniele 2:540f6e142d59 5
daniele 2:540f6e142d59 6 Authors: Frederik Van Slycken, Kristof Roelants
daniele 2:540f6e142d59 7 *********************************************************************/
daniele 2:540f6e142d59 8
daniele 2:540f6e142d59 9 #ifdef PICO_SUPPORT_DHCPD
daniele 2:540f6e142d59 10
daniele 2:540f6e142d59 11 #include "pico_dhcp_server.h"
daniele 2:540f6e142d59 12 #include "pico_stack.h"
daniele 2:540f6e142d59 13 #include "pico_config.h"
daniele 2:540f6e142d59 14 #include "pico_addressing.h"
daniele 2:540f6e142d59 15 #include "pico_socket.h"
daniele 2:540f6e142d59 16 #include "pico_arp.h"
daniele 2:540f6e142d59 17 #include <stdlib.h>
daniele 2:540f6e142d59 18
daniele 2:540f6e142d59 19 # define dhcpd_dbg(...) do{}while(0)
daniele 2:540f6e142d59 20 //# define dhcpd_dbg dbg
daniele 2:540f6e142d59 21
daniele 2:540f6e142d59 22 #define dhcpd_make_offer(x) dhcpd_make_reply(x, PICO_DHCP_MSG_OFFER)
daniele 2:540f6e142d59 23 #define dhcpd_make_ack(x) dhcpd_make_reply(x, PICO_DHCP_MSG_ACK)
daniele 2:540f6e142d59 24 #define ip_inrange(x) ((long_be(x) >= long_be(dn->settings->pool_start)) && (long_be(x) <= long_be(dn->settings->pool_end)))
daniele 2:540f6e142d59 25
daniele 2:540f6e142d59 26 static int dhcp_settings_cmp(void *ka, void *kb)
daniele 2:540f6e142d59 27 {
daniele 2:540f6e142d59 28 struct pico_dhcpd_settings *a = ka, *b = kb;
daniele 2:540f6e142d59 29 if (a->dev < b->dev)
daniele 2:540f6e142d59 30 return -1;
daniele 2:540f6e142d59 31 else if (a->dev > b->dev)
daniele 2:540f6e142d59 32 return 1;
daniele 2:540f6e142d59 33 else
daniele 2:540f6e142d59 34 return 0;
daniele 2:540f6e142d59 35 }
daniele 2:540f6e142d59 36 PICO_TREE_DECLARE(DHCPSettings, dhcp_settings_cmp);
daniele 2:540f6e142d59 37
daniele 2:540f6e142d59 38 static int dhcp_negotiations_cmp(void *ka, void *kb)
daniele 2:540f6e142d59 39 {
daniele 2:540f6e142d59 40 struct pico_dhcp_negotiation *a = ka, *b = kb;
daniele 2:540f6e142d59 41 if (a->xid < b->xid)
daniele 2:540f6e142d59 42 return -1;
daniele 2:540f6e142d59 43 else if (a->xid > b->xid)
daniele 2:540f6e142d59 44 return 1;
daniele 2:540f6e142d59 45 else
daniele 2:540f6e142d59 46 return 0;
daniele 2:540f6e142d59 47 }
daniele 2:540f6e142d59 48 PICO_TREE_DECLARE(DHCPNegotiations, dhcp_negotiations_cmp);
daniele 2:540f6e142d59 49
daniele 2:540f6e142d59 50 static struct pico_dhcp_negotiation *get_negotiation_by_xid(uint32_t xid)
daniele 2:540f6e142d59 51 {
daniele 2:540f6e142d59 52 struct pico_dhcp_negotiation test = { }, *neg = NULL;
daniele 2:540f6e142d59 53
daniele 2:540f6e142d59 54 test.xid = xid;
daniele 2:540f6e142d59 55 neg = pico_tree_findKey(&DHCPNegotiations, &test);
daniele 2:540f6e142d59 56 if (!neg)
daniele 2:540f6e142d59 57 return NULL;
daniele 2:540f6e142d59 58 else
daniele 2:540f6e142d59 59 return neg;
daniele 2:540f6e142d59 60 }
daniele 2:540f6e142d59 61
daniele 2:540f6e142d59 62 static void dhcpd_make_reply(struct pico_dhcp_negotiation *dn, uint8_t reply_type)
daniele 2:540f6e142d59 63 {
daniele 2:540f6e142d59 64 uint8_t buf_out[DHCPD_DATAGRAM_SIZE] = {0};
daniele 2:540f6e142d59 65 struct pico_dhcphdr *dh_out = (struct pico_dhcphdr *) buf_out;
daniele 2:540f6e142d59 66 struct pico_ip4 destination = { };
daniele 2:540f6e142d59 67 uint32_t bcast = dn->settings->my_ip.addr | ~(dn->settings->netmask.addr);
daniele 2:540f6e142d59 68 uint32_t dns_server = OPENDNS;
daniele 2:540f6e142d59 69 uint16_t port = PICO_DHCP_CLIENT_PORT;
daniele 2:540f6e142d59 70 int sent = 0;
daniele 2:540f6e142d59 71
daniele 2:540f6e142d59 72 memcpy(dh_out->hwaddr, dn->eth.addr, PICO_HLEN_ETHER);
daniele 2:540f6e142d59 73 dh_out->op = PICO_DHCP_OP_REPLY;
daniele 2:540f6e142d59 74 dh_out->htype = PICO_HTYPE_ETHER;
daniele 2:540f6e142d59 75 dh_out->hlen = PICO_HLEN_ETHER;
daniele 2:540f6e142d59 76 dh_out->xid = dn->xid;
daniele 2:540f6e142d59 77 dh_out->yiaddr = dn->ipv4.addr;
daniele 2:540f6e142d59 78 dh_out->siaddr = dn->settings->my_ip.addr;
daniele 2:540f6e142d59 79 dh_out->dhcp_magic = PICO_DHCPD_MAGIC_COOKIE;
daniele 2:540f6e142d59 80
daniele 2:540f6e142d59 81 /* Option: msg type, len 1 */
daniele 2:540f6e142d59 82 dh_out->options[0] = PICO_DHCPOPT_MSGTYPE;
daniele 2:540f6e142d59 83 dh_out->options[1] = 1;
daniele 2:540f6e142d59 84 dh_out->options[2] = reply_type;
daniele 2:540f6e142d59 85
daniele 2:540f6e142d59 86 /* Option: server id, len 4 */
daniele 2:540f6e142d59 87 dh_out->options[3] = PICO_DHCPOPT_SERVERID;
daniele 2:540f6e142d59 88 dh_out->options[4] = 4;
daniele 2:540f6e142d59 89 memcpy(dh_out->options + 5, &dn->settings->my_ip.addr, 4);
daniele 2:540f6e142d59 90
daniele 2:540f6e142d59 91 /* Option: Lease time, len 4 */
daniele 2:540f6e142d59 92 dh_out->options[9] = PICO_DHCPOPT_LEASETIME;
daniele 2:540f6e142d59 93 dh_out->options[10] = 4;
daniele 2:540f6e142d59 94 memcpy(dh_out->options + 11, &dn->settings->lease_time, 4);
daniele 2:540f6e142d59 95
daniele 2:540f6e142d59 96 /* Option: Netmask, len 4 */
daniele 2:540f6e142d59 97 dh_out->options[15] = PICO_DHCPOPT_NETMASK;
daniele 2:540f6e142d59 98 dh_out->options[16] = 4;
daniele 2:540f6e142d59 99 memcpy(dh_out->options + 17, &dn->settings->netmask.addr, 4);
daniele 2:540f6e142d59 100
daniele 2:540f6e142d59 101 /* Option: Router, len 4 */
daniele 2:540f6e142d59 102 dh_out->options[21] = PICO_DHCPOPT_ROUTER;
daniele 2:540f6e142d59 103 dh_out->options[22] = 4;
daniele 2:540f6e142d59 104 memcpy(dh_out->options + 23, &dn->settings->my_ip.addr, 4);
daniele 2:540f6e142d59 105
daniele 2:540f6e142d59 106 /* Option: Broadcast, len 4 */
daniele 2:540f6e142d59 107 dh_out->options[27] = PICO_DHCPOPT_BCAST;
daniele 2:540f6e142d59 108 dh_out->options[28] = 4;
daniele 2:540f6e142d59 109 memcpy(dh_out->options + 29, &bcast, 4);
daniele 2:540f6e142d59 110
daniele 2:540f6e142d59 111 /* Option: DNS, len 4 */
daniele 2:540f6e142d59 112 dh_out->options[33] = PICO_DHCPOPT_DNS;
daniele 2:540f6e142d59 113 dh_out->options[34] = 4;
daniele 2:540f6e142d59 114 memcpy(dh_out->options + 35, &dns_server, 4);
daniele 2:540f6e142d59 115
daniele 2:540f6e142d59 116 dh_out->options[40] = PICO_DHCPOPT_END;
daniele 2:540f6e142d59 117
daniele 2:540f6e142d59 118 destination.addr = dh_out->yiaddr;
daniele 2:540f6e142d59 119
daniele 2:540f6e142d59 120 sent = pico_socket_sendto(dn->settings->s, buf_out, DHCPD_DATAGRAM_SIZE, &destination, port);
daniele 2:540f6e142d59 121 if (sent < 0) {
daniele 2:540f6e142d59 122 dhcpd_dbg("DHCPD: sendto failed with code %d!\n", pico_err);
daniele 2:540f6e142d59 123 }
daniele 2:540f6e142d59 124 }
daniele 2:540f6e142d59 125
daniele 2:540f6e142d59 126 static void dhcp_recv(struct pico_socket *s, uint8_t *buffer, int len)
daniele 2:540f6e142d59 127 {
daniele 2:540f6e142d59 128 struct pico_dhcphdr *dhdr = (struct pico_dhcphdr *) buffer;
daniele 2:540f6e142d59 129 struct pico_dhcp_negotiation *dn = get_negotiation_by_xid(dhdr->xid);
daniele 2:540f6e142d59 130 struct pico_ip4* ipv4 = NULL;
daniele 2:540f6e142d59 131 struct pico_dhcpd_settings test, *settings = NULL;
daniele 2:540f6e142d59 132 uint8_t *nextopt, opt_data[20], opt_type;
daniele 2:540f6e142d59 133 int opt_len = 20;
daniele 2:540f6e142d59 134 uint8_t msg_type;
daniele 2:540f6e142d59 135 uint32_t msg_reqIP = 0;
daniele 2:540f6e142d59 136 uint32_t msg_servID = 0;
daniele 2:540f6e142d59 137
daniele 2:540f6e142d59 138 if (!is_options_valid(dhdr->options, len - sizeof(struct pico_dhcphdr))) {
daniele 2:540f6e142d59 139 dhcpd_dbg("DHCPD WARNING: invalid options in dhcp message\n");
daniele 2:540f6e142d59 140 return;
daniele 2:540f6e142d59 141 }
daniele 2:540f6e142d59 142
daniele 2:540f6e142d59 143 if (!dn) {
daniele 2:540f6e142d59 144 dn = pico_zalloc(sizeof(struct pico_dhcp_negotiation));
daniele 2:540f6e142d59 145 if (!dn) {
daniele 2:540f6e142d59 146 pico_err = PICO_ERR_ENOMEM;
daniele 2:540f6e142d59 147 return;
daniele 2:540f6e142d59 148 }
daniele 2:540f6e142d59 149 dn->xid = dhdr->xid;
daniele 2:540f6e142d59 150 dn->state = DHCPSTATE_DISCOVER;
daniele 2:540f6e142d59 151 memcpy(dn->eth.addr, dhdr->hwaddr, PICO_HLEN_ETHER);
daniele 2:540f6e142d59 152
daniele 2:540f6e142d59 153 test.dev = pico_ipv4_link_find(&s->local_addr.ip4);
daniele 2:540f6e142d59 154 settings = pico_tree_findKey(&DHCPSettings, &test);
daniele 2:540f6e142d59 155 if (settings) {
daniele 2:540f6e142d59 156 dn->settings = settings;
daniele 2:540f6e142d59 157 } else {
daniele 2:540f6e142d59 158 dhcpd_dbg("DHCPD WARNING: received DHCP message on unconfigured link %s\n", test.dev->name);
daniele 2:540f6e142d59 159 pico_free(dn);
daniele 2:540f6e142d59 160 return;
daniele 2:540f6e142d59 161 }
daniele 2:540f6e142d59 162
daniele 2:540f6e142d59 163 ipv4 = pico_arp_reverse_lookup(&dn->eth);
daniele 2:540f6e142d59 164 if (!ipv4) {
daniele 2:540f6e142d59 165 dn->ipv4.addr = settings->pool_next;
daniele 2:540f6e142d59 166 pico_arp_create_entry(dn->eth.addr, dn->ipv4, settings->dev);
daniele 2:540f6e142d59 167 settings->pool_next = long_be(long_be(settings->pool_next) + 1);
daniele 2:540f6e142d59 168 } else {
daniele 2:540f6e142d59 169 dn->ipv4.addr = ipv4->addr;
daniele 2:540f6e142d59 170 }
daniele 2:540f6e142d59 171
daniele 2:540f6e142d59 172 if (pico_tree_insert(&DHCPNegotiations, dn)) {
daniele 2:540f6e142d59 173 dhcpd_dbg("DHCPD WARNING: tried creating new negotation for existing xid %u\n", dn->xid);
daniele 2:540f6e142d59 174 pico_free(dn);
daniele 2:540f6e142d59 175 return; /* Element key already exists */
daniele 2:540f6e142d59 176 }
daniele 2:540f6e142d59 177 }
daniele 2:540f6e142d59 178
daniele 2:540f6e142d59 179 if (!ip_inrange(dn->ipv4.addr))
daniele 2:540f6e142d59 180 return;
daniele 2:540f6e142d59 181
daniele 2:540f6e142d59 182 opt_type = dhcp_get_next_option(dhdr->options, opt_data, &opt_len, &nextopt);
daniele 2:540f6e142d59 183 while (opt_type != PICO_DHCPOPT_END) {
daniele 2:540f6e142d59 184 /* parse interesting options here */
daniele 2:540f6e142d59 185 //dhcpd_dbg("DHCPD sever: opt_type %x, opt_data[0]%d\n", opt_type, opt_data[0]);
daniele 2:540f6e142d59 186 switch(opt_type){
daniele 2:540f6e142d59 187 case PICO_DHCPOPT_MSGTYPE:
daniele 2:540f6e142d59 188 msg_type = opt_data[0];
daniele 2:540f6e142d59 189 break;
daniele 2:540f6e142d59 190 case PICO_DHCPOPT_REQIP:
daniele 2:540f6e142d59 191 //dhcpd_dbg("DHCPD sever: opt_type %x, opt_len%d\n", opt_type, opt_len);
daniele 2:540f6e142d59 192 if( opt_len == 4)
daniele 2:540f6e142d59 193 {
daniele 2:540f6e142d59 194 msg_reqIP = ( opt_data[0] << 24 );
daniele 2:540f6e142d59 195 msg_reqIP |= ( opt_data[1] << 16 );
daniele 2:540f6e142d59 196 msg_reqIP |= ( opt_data[2] << 8 );
daniele 2:540f6e142d59 197 msg_reqIP |= ( opt_data[3] );
daniele 2:540f6e142d59 198 //dhcpd_dbg("DHCPD sever: msg_reqIP %x, opt_data[0] %x,[1] %x,[2] %x,[3] %x\n", msg_reqIP, opt_data[0],opt_data[1],opt_data[2],opt_data[3]);
daniele 2:540f6e142d59 199 };
daniele 2:540f6e142d59 200 break;
daniele 2:540f6e142d59 201 case PICO_DHCPOPT_SERVERID:
daniele 2:540f6e142d59 202 //dhcpd_dbg("DHCPD sever: opt_type %x, opt_len%d\n", opt_type, opt_len);
daniele 2:540f6e142d59 203 if( opt_len == 4)
daniele 2:540f6e142d59 204 {
daniele 2:540f6e142d59 205 msg_servID = ( opt_data[0] << 24 );
daniele 2:540f6e142d59 206 msg_servID |= ( opt_data[1] << 16 );
daniele 2:540f6e142d59 207 msg_servID |= ( opt_data[2] << 8 );
daniele 2:540f6e142d59 208 msg_servID |= ( opt_data[3] );
daniele 2:540f6e142d59 209 //dhcpd_dbg("DHCPD sever: msg_servID %x, opt_data[0] %x,[1] %x,[2] %x,[3] %x\n", msg_servID, opt_data[0],opt_data[1],opt_data[2],opt_data[3]);
daniele 2:540f6e142d59 210 };
daniele 2:540f6e142d59 211 break;
daniele 2:540f6e142d59 212 default:
daniele 2:540f6e142d59 213 break;
daniele 2:540f6e142d59 214 }
daniele 2:540f6e142d59 215
daniele 2:540f6e142d59 216 opt_len = 20;
daniele 2:540f6e142d59 217 opt_type = dhcp_get_next_option(NULL, opt_data, &opt_len, &nextopt);
daniele 2:540f6e142d59 218 }
daniele 2:540f6e142d59 219
daniele 2:540f6e142d59 220 //dhcpd_dbg("DHCPD sever: msg_type %d, dn->state %d\n", msg_type, dn->state);
daniele 2:540f6e142d59 221 //dhcpd_dbg("DHCPD sever: msg_reqIP %x, dn->msg_servID %x\n", msg_reqIP, msg_servID);
daniele 2:540f6e142d59 222 //dhcpd_dbg("DHCPD sever: dhdr->ciaddr %x, dhdr->yiaddr %x, dn->ipv4.addr %x\n", dhdr->ciaddr,dhdr->yiaddr,dn->ipv4.addr);
daniele 2:540f6e142d59 223
daniele 2:540f6e142d59 224 if (msg_type == PICO_DHCP_MSG_DISCOVER)
daniele 2:540f6e142d59 225 {
daniele 2:540f6e142d59 226 dhcpd_make_offer(dn);
daniele 2:540f6e142d59 227 dn->state = DHCPSTATE_OFFER;
daniele 2:540f6e142d59 228 return;
daniele 2:540f6e142d59 229 }
daniele 2:540f6e142d59 230 else if ((msg_type == PICO_DHCP_MSG_REQUEST)&&( dn->state == DHCPSTATE_OFFER))
daniele 2:540f6e142d59 231 {
daniele 2:540f6e142d59 232 dhcpd_make_ack(dn);
daniele 2:540f6e142d59 233 dn->state = DHCPSTATE_BOUND;
daniele 2:540f6e142d59 234 return;
daniele 2:540f6e142d59 235 }
daniele 2:540f6e142d59 236 else if ((msg_type == PICO_DHCP_MSG_REQUEST)&&( dn->state == DHCPSTATE_BOUND))
daniele 2:540f6e142d59 237 {
daniele 2:540f6e142d59 238 if( ( msg_servID == 0 )
daniele 2:540f6e142d59 239 &&( msg_reqIP == 0 )
daniele 2:540f6e142d59 240 &&( dhdr->ciaddr == dn->ipv4.addr)
daniele 2:540f6e142d59 241 )
daniele 2:540f6e142d59 242 {
daniele 2:540f6e142d59 243 dhcpd_make_ack(dn);
daniele 2:540f6e142d59 244 return;
daniele 2:540f6e142d59 245 }
daniele 2:540f6e142d59 246 }
daniele 2:540f6e142d59 247 }
daniele 2:540f6e142d59 248
daniele 2:540f6e142d59 249 static void pico_dhcpd_wakeup(uint16_t ev, struct pico_socket *s)
daniele 2:540f6e142d59 250 {
daniele 2:540f6e142d59 251 uint8_t buf[DHCPD_DATAGRAM_SIZE] = { };
daniele 2:540f6e142d59 252 int r = 0;
daniele 2:540f6e142d59 253 uint32_t peer = 0;
daniele 2:540f6e142d59 254 uint16_t port = 0;
daniele 2:540f6e142d59 255
daniele 2:540f6e142d59 256 dhcpd_dbg("DHCPD: called dhcpd_wakeup\n");
daniele 2:540f6e142d59 257 if (ev == PICO_SOCK_EV_RD) {
daniele 2:540f6e142d59 258 do {
daniele 2:540f6e142d59 259 r = pico_socket_recvfrom(s, buf, DHCPD_DATAGRAM_SIZE, &peer, &port);
daniele 2:540f6e142d59 260 if (r > 0 && port == PICO_DHCP_CLIENT_PORT) {
daniele 2:540f6e142d59 261 dhcp_recv(s, buf, r);
daniele 2:540f6e142d59 262 }
daniele 2:540f6e142d59 263 } while(r>0);
daniele 2:540f6e142d59 264 }
daniele 2:540f6e142d59 265 }
daniele 2:540f6e142d59 266
daniele 2:540f6e142d59 267 int pico_dhcp_server_initiate(struct pico_dhcpd_settings *setting)
daniele 2:540f6e142d59 268 {
daniele 2:540f6e142d59 269 struct pico_dhcpd_settings *settings = NULL;
daniele 2:540f6e142d59 270 struct pico_ipv4_link *link = NULL;
daniele 2:540f6e142d59 271 uint16_t port = PICO_DHCPD_PORT;
daniele 2:540f6e142d59 272
daniele 2:540f6e142d59 273 if (!setting) {
daniele 2:540f6e142d59 274 pico_err = PICO_ERR_EINVAL;
daniele 2:540f6e142d59 275 return -1;
daniele 2:540f6e142d59 276 }
daniele 2:540f6e142d59 277
daniele 2:540f6e142d59 278 if (!setting->my_ip.addr) {
daniele 2:540f6e142d59 279 pico_err = PICO_ERR_EINVAL;
daniele 2:540f6e142d59 280 dhcpd_dbg("DHCPD: IP address of interface was not supplied\n");
daniele 2:540f6e142d59 281 return -1;
daniele 2:540f6e142d59 282 }
daniele 2:540f6e142d59 283
daniele 2:540f6e142d59 284 link = pico_ipv4_link_get(&setting->my_ip);
daniele 2:540f6e142d59 285 if (!link) {
daniele 2:540f6e142d59 286 pico_err = PICO_ERR_EINVAL;
daniele 2:540f6e142d59 287 dhcpd_dbg("DHCPD: no link with IP %X found\n", setting->my_ip.addr);
daniele 2:540f6e142d59 288 return -1;
daniele 2:540f6e142d59 289 }
daniele 2:540f6e142d59 290
daniele 2:540f6e142d59 291 settings = pico_zalloc(sizeof(struct pico_dhcpd_settings));
daniele 2:540f6e142d59 292 if (!settings) {
daniele 2:540f6e142d59 293 pico_err = PICO_ERR_ENOMEM;
daniele 2:540f6e142d59 294 return -1;
daniele 2:540f6e142d59 295 }
daniele 2:540f6e142d59 296 memcpy(settings, setting, sizeof(struct pico_dhcpd_settings));
daniele 2:540f6e142d59 297
daniele 2:540f6e142d59 298 settings->dev = link->dev;
daniele 2:540f6e142d59 299 dhcpd_dbg("DHCPD: configuring DHCP server for link %s\n", link->dev->name);
daniele 2:540f6e142d59 300 settings->my_ip.addr = link->address.addr;
daniele 2:540f6e142d59 301 dhcpd_dbg("DHCPD: using server addr %X\n", long_be(settings->my_ip.addr));
daniele 2:540f6e142d59 302 settings->netmask.addr = link->netmask.addr;
daniele 2:540f6e142d59 303 dhcpd_dbg("DHCPD: using netmask %X\n", long_be(settings->netmask.addr));
daniele 2:540f6e142d59 304
daniele 2:540f6e142d59 305 /* default values if not provided */
daniele 2:540f6e142d59 306 if (settings->pool_start == 0)
daniele 2:540f6e142d59 307 settings->pool_start = (settings->my_ip.addr & settings->netmask.addr) | POOL_START;
daniele 2:540f6e142d59 308 dhcpd_dbg("DHCPD: using pool_start %X\n", long_be(settings->pool_start));
daniele 2:540f6e142d59 309 if (settings->pool_end == 0)
daniele 2:540f6e142d59 310 settings->pool_end = (settings->my_ip.addr & settings->netmask.addr) | POOL_END;
daniele 2:540f6e142d59 311 dhcpd_dbg("DHCPD: using pool_end %x\n", long_be(settings->pool_end));
daniele 2:540f6e142d59 312 if (settings->lease_time == 0)
daniele 2:540f6e142d59 313 settings->lease_time = LEASE_TIME;
daniele 2:540f6e142d59 314 dhcpd_dbg("DHCPD: using lease time %x\n", long_be(settings->lease_time));
daniele 2:540f6e142d59 315 settings->pool_next = settings->pool_start;
daniele 2:540f6e142d59 316
daniele 2:540f6e142d59 317 settings->s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dhcpd_wakeup);
daniele 2:540f6e142d59 318 if (!settings->s) {
daniele 2:540f6e142d59 319 dhcpd_dbg("DHCP: could not open client socket\n");
daniele 2:540f6e142d59 320 pico_free(settings);
daniele 2:540f6e142d59 321 return -1;
daniele 2:540f6e142d59 322 }
daniele 2:540f6e142d59 323 if (pico_socket_bind(settings->s, &settings->my_ip, &port) != 0) {
daniele 2:540f6e142d59 324 dhcpd_dbg("DHCP: could not bind server socket (%s)\n", strerror(pico_err));
daniele 2:540f6e142d59 325 pico_free(settings);
daniele 2:540f6e142d59 326 return -1;
daniele 2:540f6e142d59 327 }
daniele 2:540f6e142d59 328
daniele 2:540f6e142d59 329 if (pico_tree_insert(&DHCPSettings, settings)) {
daniele 2:540f6e142d59 330 dhcpd_dbg("DHCPD ERROR: link %s already configured\n", link->dev->name);
daniele 2:540f6e142d59 331 pico_err = PICO_ERR_EINVAL;
daniele 2:540f6e142d59 332 pico_free(settings);
daniele 2:540f6e142d59 333 return -1; /* Element key already exists */
daniele 2:540f6e142d59 334 }
daniele 2:540f6e142d59 335 dhcpd_dbg("DHCPD: configured DHCP server for link %s\n", link->dev->name);
daniele 2:540f6e142d59 336
daniele 2:540f6e142d59 337 return 0;
daniele 2:540f6e142d59 338 }
daniele 2:540f6e142d59 339 #endif /* PICO_SUPPORT_DHCP */