Free (GPLv2) TCP/IP stack developed by TASS Belgium

Dependents:   lpc1768-picotcp-demo ZeroMQ_PicoTCP_Publisher_demo TCPSocket_HelloWorld_PicoTCP Pico_TCP_UDP_Test ... more

PicoTCP. Copyright (c) 2013 TASS Belgium NV.

Released under the GNU General Public License, version 2.

Different licensing models may exist, at the sole discretion of the Copyright holders.

Official homepage: http://www.picotcp.com

Bug tracker: https://github.com/tass-belgium/picotcp/issues

Development steps:

  • initial integration with mbed RTOS
  • generic mbed Ethernet driver
  • high performance NXP LPC1768 specific Ethernet driver
  • Multi-threading support for mbed RTOS
  • Berkeley sockets and integration with the New Socket API
  • Fork of the apps running on top of the New Socket API
  • Scheduling optimizations
  • Debugging/benchmarking/testing

Demo application (measuring TCP sender performance):

Import programlpc1768-picotcp-demo

A PicoTCP demo app testing the ethernet throughput on the lpc1768 mbed board.

Committer:
tass
Date:
Thu Sep 19 12:38:53 2013 +0000
Revision:
63:97f481e33cb2
Parent:
51:ab4529a384a6
Update from the master branch

Who changed what in which revision?

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