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 13:26:14 2013 +0000
Revision:
68:0847e35d08a6
Child:
70:cd218dd180e5
Imported from masterbranch, again

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 68:0847e35d08a6 1 /*********************************************************************
tass 68:0847e35d08a6 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
tass 68:0847e35d08a6 3 See LICENSE and COPYING for usage.
tass 68:0847e35d08a6 4
tass 68:0847e35d08a6 5
tass 68:0847e35d08a6 6 Authors: Frederik Van Slycken, Kristof Roelants
tass 68:0847e35d08a6 7 *********************************************************************/
tass 68:0847e35d08a6 8
tass 68:0847e35d08a6 9 #ifdef PICO_SUPPORT_DHCPD
tass 68:0847e35d08a6 10 #include "pico_dhcp_server.h"
tass 68:0847e35d08a6 11 #include "pico_config.h"
tass 68:0847e35d08a6 12 #include "pico_addressing.h"
tass 68:0847e35d08a6 13 #include "pico_socket.h"
tass 68:0847e35d08a6 14 #include "pico_udp.h"
tass 68:0847e35d08a6 15 #include "pico_stack.h"
tass 68:0847e35d08a6 16 #include "pico_arp.h"
tass 68:0847e35d08a6 17
tass 68:0847e35d08a6 18 #define dhcps_dbg(...) do{}while(0)
tass 68:0847e35d08a6 19 //#define dhcps_dbg dbg
tass 68:0847e35d08a6 20
tass 68:0847e35d08a6 21 /* default configurations */
tass 68:0847e35d08a6 22 #define DHCP_SERVER_OPENDNS long_be(0xd043dede) /* OpenDNS DNS server 208.67.222.222 */
tass 68:0847e35d08a6 23 #define DHCP_SERVER_POOL_START long_be(0x00000064)
tass 68:0847e35d08a6 24 #define DHCP_SERVER_POOL_END long_be(0x000000fe)
tass 68:0847e35d08a6 25 #define DHCP_SERVER_LEASE_TIME long_be(0x00000078)
tass 68:0847e35d08a6 26
tass 68:0847e35d08a6 27 /* maximum size of a DHCP message */
tass 68:0847e35d08a6 28 #define DHCP_SERVER_MAXMSGSIZE (PICO_IP_MTU - sizeof(struct pico_ipv4_hdr) - sizeof(struct pico_udp_hdr))
tass 68:0847e35d08a6 29
tass 68:0847e35d08a6 30 #define ip_inrange(x) ((long_be(x) >= long_be(dhcpn->dhcps->pool_start)) && (long_be(x) <= long_be(dhcpn->dhcps->pool_end)))
tass 68:0847e35d08a6 31
tass 68:0847e35d08a6 32 enum dhcp_server_state {
tass 68:0847e35d08a6 33 PICO_DHCP_STATE_DISCOVER = 0,
tass 68:0847e35d08a6 34 PICO_DHCP_STATE_OFFER,
tass 68:0847e35d08a6 35 PICO_DHCP_STATE_REQUEST,
tass 68:0847e35d08a6 36 PICO_DHCP_STATE_BOUND,
tass 68:0847e35d08a6 37 PICO_DHCP_STATE_RENEWING
tass 68:0847e35d08a6 38 };
tass 68:0847e35d08a6 39
tass 68:0847e35d08a6 40 struct pico_dhcp_server_negotiation {
tass 68:0847e35d08a6 41 uint32_t xid;
tass 68:0847e35d08a6 42 enum dhcp_server_state state;
tass 68:0847e35d08a6 43 struct pico_dhcp_server_setting *dhcps;
tass 68:0847e35d08a6 44 struct pico_ip4 ciaddr;
tass 68:0847e35d08a6 45 struct pico_eth hwaddr;
tass 68:0847e35d08a6 46 };
tass 68:0847e35d08a6 47
tass 68:0847e35d08a6 48 static void pico_dhcpd_wakeup(uint16_t ev, struct pico_socket *s);
tass 68:0847e35d08a6 49
tass 68:0847e35d08a6 50 static int dhcp_settings_cmp(void *ka, void *kb)
tass 68:0847e35d08a6 51 {
tass 68:0847e35d08a6 52 struct pico_dhcp_server_setting *a = ka, *b = kb;
tass 68:0847e35d08a6 53 if (a->dev == b->dev)
tass 68:0847e35d08a6 54 return 0;
tass 68:0847e35d08a6 55 return (a->dev < b->dev) ? -1 : 1;
tass 68:0847e35d08a6 56 }
tass 68:0847e35d08a6 57 PICO_TREE_DECLARE(DHCPSettings, dhcp_settings_cmp);
tass 68:0847e35d08a6 58
tass 68:0847e35d08a6 59 static int dhcp_negotiations_cmp(void *ka, void *kb)
tass 68:0847e35d08a6 60 {
tass 68:0847e35d08a6 61 struct pico_dhcp_server_negotiation *a = ka, *b = kb;
tass 68:0847e35d08a6 62 if (a->xid == b->xid)
tass 68:0847e35d08a6 63 return 0;
tass 68:0847e35d08a6 64 return (a->xid < b->xid) ? -1 : 1;
tass 68:0847e35d08a6 65 }
tass 68:0847e35d08a6 66 PICO_TREE_DECLARE(DHCPNegotiations, dhcp_negotiations_cmp);
tass 68:0847e35d08a6 67
tass 68:0847e35d08a6 68 static struct pico_dhcp_server_setting *pico_dhcp_server_add_setting(struct pico_dhcp_server_setting *setting)
tass 68:0847e35d08a6 69 {
tass 68:0847e35d08a6 70 uint16_t port = PICO_DHCPD_PORT;
tass 68:0847e35d08a6 71 struct pico_dhcp_server_setting *dhcps = NULL, *found = NULL, test = {0};
tass 68:0847e35d08a6 72 struct pico_ipv4_link *link = NULL;
tass 68:0847e35d08a6 73
tass 68:0847e35d08a6 74 link = pico_ipv4_link_get(&setting->server_ip);
tass 68:0847e35d08a6 75 if (!link) {
tass 68:0847e35d08a6 76 pico_err = PICO_ERR_EINVAL;
tass 68:0847e35d08a6 77 return NULL;
tass 68:0847e35d08a6 78 }
tass 68:0847e35d08a6 79 test.dev = setting->dev;
tass 68:0847e35d08a6 80 found = pico_tree_findKey(&DHCPSettings, &test);
tass 68:0847e35d08a6 81 if (found) {
tass 68:0847e35d08a6 82 pico_err = PICO_ERR_EINVAL;
tass 68:0847e35d08a6 83 return NULL;
tass 68:0847e35d08a6 84 }
tass 68:0847e35d08a6 85 dhcps = pico_zalloc(sizeof(struct pico_dhcp_server_setting));
tass 68:0847e35d08a6 86 if (!dhcps) {
tass 68:0847e35d08a6 87 pico_err = PICO_ERR_ENOMEM;
tass 68:0847e35d08a6 88 return NULL;
tass 68:0847e35d08a6 89 }
tass 68:0847e35d08a6 90
tass 68:0847e35d08a6 91 dhcps->lease_time = setting->lease_time;
tass 68:0847e35d08a6 92 dhcps->pool_start = setting->pool_start;
tass 68:0847e35d08a6 93 dhcps->pool_next = setting->pool_next;
tass 68:0847e35d08a6 94 dhcps->pool_end = setting->pool_end;
tass 68:0847e35d08a6 95 dhcps->dev = link->dev;
tass 68:0847e35d08a6 96 dhcps->server_ip = link->address;
tass 68:0847e35d08a6 97 dhcps->netmask = link->netmask;
tass 68:0847e35d08a6 98
tass 68:0847e35d08a6 99 /* default values if not provided */
tass 68:0847e35d08a6 100 if (!dhcps->pool_start)
tass 68:0847e35d08a6 101 dhcps->pool_start = (dhcps->server_ip.addr & dhcps->netmask.addr) | DHCP_SERVER_POOL_START;
tass 68:0847e35d08a6 102 if (!dhcps->pool_end)
tass 68:0847e35d08a6 103 dhcps->pool_end = (dhcps->server_ip.addr & dhcps->netmask.addr) | DHCP_SERVER_POOL_END;
tass 68:0847e35d08a6 104 if (!dhcps->lease_time)
tass 68:0847e35d08a6 105 dhcps->lease_time = DHCP_SERVER_LEASE_TIME;
tass 68:0847e35d08a6 106 dhcps->pool_next = dhcps->pool_start;
tass 68:0847e35d08a6 107
tass 68:0847e35d08a6 108 dhcps->s = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &pico_dhcpd_wakeup);
tass 68:0847e35d08a6 109 if (!dhcps->s) {
tass 68:0847e35d08a6 110 dhcps_dbg("DHCP server ERROR: failure opening socket (%s)\n", strerror(pico_err));
tass 68:0847e35d08a6 111 pico_free(dhcps);
tass 68:0847e35d08a6 112 return NULL;
tass 68:0847e35d08a6 113 }
tass 68:0847e35d08a6 114 if (pico_socket_bind(dhcps->s, &dhcps->server_ip, &port) < 0) {
tass 68:0847e35d08a6 115 dhcps_dbg("DHCP server ERROR: failure binding socket (%s)\n", strerror(pico_err));
tass 68:0847e35d08a6 116 pico_free(dhcps);
tass 68:0847e35d08a6 117 return NULL;
tass 68:0847e35d08a6 118 }
tass 68:0847e35d08a6 119
tass 68:0847e35d08a6 120 pico_tree_insert(&DHCPSettings, dhcps);
tass 68:0847e35d08a6 121 return dhcps;
tass 68:0847e35d08a6 122 }
tass 68:0847e35d08a6 123
tass 68:0847e35d08a6 124 static struct pico_dhcp_server_negotiation *pico_dhcp_server_find_negotiation(uint32_t xid)
tass 68:0847e35d08a6 125 {
tass 68:0847e35d08a6 126 struct pico_dhcp_server_negotiation test = {0}, *found = NULL;
tass 68:0847e35d08a6 127
tass 68:0847e35d08a6 128 test.xid = xid;
tass 68:0847e35d08a6 129 found = pico_tree_findKey(&DHCPNegotiations, &test);
tass 68:0847e35d08a6 130 if (found)
tass 68:0847e35d08a6 131 return found;
tass 68:0847e35d08a6 132 else
tass 68:0847e35d08a6 133 return NULL;
tass 68:0847e35d08a6 134 }
tass 68:0847e35d08a6 135
tass 68:0847e35d08a6 136 static struct pico_dhcp_server_negotiation *pico_dhcp_server_add_negotiation(struct pico_device *dev, struct pico_dhcp_hdr *hdr)
tass 68:0847e35d08a6 137 {
tass 68:0847e35d08a6 138 struct pico_dhcp_server_negotiation *dhcpn = NULL;
tass 68:0847e35d08a6 139 struct pico_dhcp_server_setting test = {0};
tass 68:0847e35d08a6 140 struct pico_ip4 *ciaddr = NULL;
tass 68:0847e35d08a6 141
tass 68:0847e35d08a6 142 if (pico_dhcp_server_find_negotiation(hdr->xid))
tass 68:0847e35d08a6 143 return NULL;
tass 68:0847e35d08a6 144
tass 68:0847e35d08a6 145 dhcpn = pico_zalloc(sizeof(struct pico_dhcp_server_negotiation));
tass 68:0847e35d08a6 146 if (!dhcpn) {
tass 68:0847e35d08a6 147 pico_err = PICO_ERR_ENOMEM;
tass 68:0847e35d08a6 148 return NULL;
tass 68:0847e35d08a6 149 }
tass 68:0847e35d08a6 150
tass 68:0847e35d08a6 151 dhcpn->xid = hdr->xid;
tass 68:0847e35d08a6 152 dhcpn->state = PICO_DHCP_STATE_DISCOVER;
tass 68:0847e35d08a6 153 memcpy(dhcpn->hwaddr.addr, hdr->hwaddr, PICO_SIZE_ETH);
tass 68:0847e35d08a6 154
tass 68:0847e35d08a6 155 test.dev = dev;
tass 68:0847e35d08a6 156 dhcpn->dhcps = pico_tree_findKey(&DHCPSettings, &test);
tass 68:0847e35d08a6 157 if (!dhcpn->dhcps) {
tass 68:0847e35d08a6 158 dhcps_dbg("DHCP server WARNING: received DHCP message on unconfigured link %s\n", dev->name);
tass 68:0847e35d08a6 159 pico_free(dhcpn);
tass 68:0847e35d08a6 160 return NULL;
tass 68:0847e35d08a6 161 }
tass 68:0847e35d08a6 162
tass 68:0847e35d08a6 163 ciaddr = pico_arp_reverse_lookup(&dhcpn->hwaddr);
tass 68:0847e35d08a6 164 if (!ciaddr) {
tass 68:0847e35d08a6 165 dhcpn->ciaddr.addr = dhcpn->dhcps->pool_next;
tass 68:0847e35d08a6 166 dhcpn->dhcps->pool_next = long_be(long_be(dhcpn->dhcps->pool_next) + 1);
tass 68:0847e35d08a6 167 pico_arp_create_entry(dhcpn->hwaddr.addr, dhcpn->ciaddr, dhcpn->dhcps->dev);
tass 68:0847e35d08a6 168 } else {
tass 68:0847e35d08a6 169 dhcpn->ciaddr = *ciaddr;
tass 68:0847e35d08a6 170 }
tass 68:0847e35d08a6 171
tass 68:0847e35d08a6 172 pico_tree_insert(&DHCPNegotiations, dhcpn);
tass 68:0847e35d08a6 173 return dhcpn;
tass 68:0847e35d08a6 174 }
tass 68:0847e35d08a6 175
tass 68:0847e35d08a6 176 static void dhcpd_make_reply(struct pico_dhcp_server_negotiation *dhcpn, uint8_t msg_type)
tass 68:0847e35d08a6 177 {
tass 68:0847e35d08a6 178 int r = 0, optlen = 0, offset = 0;
tass 68:0847e35d08a6 179 struct pico_ip4 broadcast = {0}, dns = {0}, destination = { .addr = 0xFFFFFFFF};
tass 68:0847e35d08a6 180 struct pico_dhcp_hdr *hdr = NULL;
tass 68:0847e35d08a6 181
tass 68:0847e35d08a6 182 dns.addr = DHCP_SERVER_OPENDNS;
tass 68:0847e35d08a6 183 broadcast.addr = dhcpn->dhcps->server_ip.addr | ~(dhcpn->dhcps->netmask.addr);
tass 68:0847e35d08a6 184
tass 68:0847e35d08a6 185 optlen = PICO_DHCP_OPTLEN_MSGTYPE + PICO_DHCP_OPTLEN_SERVERID + PICO_DHCP_OPTLEN_LEASETIME + PICO_DHCP_OPTLEN_NETMASK + PICO_DHCP_OPTLEN_ROUTER
tass 68:0847e35d08a6 186 + PICO_DHCP_OPTLEN_BROADCAST + PICO_DHCP_OPTLEN_DNS + PICO_DHCP_OPTLEN_END;
tass 68:0847e35d08a6 187 hdr = pico_zalloc(sizeof(struct pico_dhcp_hdr) + optlen);
tass 68:0847e35d08a6 188
tass 68:0847e35d08a6 189 hdr->op = PICO_DHCP_OP_REPLY;
tass 68:0847e35d08a6 190 hdr->htype = PICO_DHCP_HTYPE_ETH;
tass 68:0847e35d08a6 191 hdr->hlen = PICO_SIZE_ETH;
tass 68:0847e35d08a6 192 hdr->xid = dhcpn->xid;
tass 68:0847e35d08a6 193 hdr->yiaddr = dhcpn->ciaddr.addr;
tass 68:0847e35d08a6 194 hdr->siaddr = dhcpn->dhcps->server_ip.addr;
tass 68:0847e35d08a6 195 hdr->dhcp_magic = PICO_DHCPD_MAGIC_COOKIE;
tass 68:0847e35d08a6 196 memcpy(hdr->hwaddr, dhcpn->hwaddr.addr, PICO_SIZE_ETH);
tass 68:0847e35d08a6 197
tass 68:0847e35d08a6 198 /* options */
tass 68:0847e35d08a6 199 offset += pico_dhcp_opt_msgtype(&hdr->options[offset], msg_type);
tass 68:0847e35d08a6 200 offset += pico_dhcp_opt_serverid(&hdr->options[offset], &dhcpn->dhcps->server_ip);
tass 68:0847e35d08a6 201 offset += pico_dhcp_opt_leasetime(&hdr->options[offset], dhcpn->dhcps->lease_time);
tass 68:0847e35d08a6 202 offset += pico_dhcp_opt_netmask(&hdr->options[offset], &dhcpn->dhcps->netmask);
tass 68:0847e35d08a6 203 offset += pico_dhcp_opt_router(&hdr->options[offset], &dhcpn->dhcps->server_ip);
tass 68:0847e35d08a6 204 offset += pico_dhcp_opt_broadcast(&hdr->options[offset], &broadcast);
tass 68:0847e35d08a6 205 offset += pico_dhcp_opt_dns(&hdr->options[offset], &dns);
tass 68:0847e35d08a6 206 offset += pico_dhcp_opt_end(&hdr->options[offset]);
tass 68:0847e35d08a6 207
tass 68:0847e35d08a6 208 destination.addr = hdr->yiaddr;
tass 68:0847e35d08a6 209 r = pico_socket_sendto(dhcpn->dhcps->s, hdr, sizeof(struct pico_dhcp_hdr) + optlen, &destination, PICO_DHCP_CLIENT_PORT);
tass 68:0847e35d08a6 210 if (r < 0)
tass 68:0847e35d08a6 211 dhcps_dbg("DHCP server WARNING: failure sending: %s!\n", strerror(pico_err));
tass 68:0847e35d08a6 212
tass 68:0847e35d08a6 213 return;
tass 68:0847e35d08a6 214 }
tass 68:0847e35d08a6 215
tass 68:0847e35d08a6 216 static void pico_dhcp_server_recv(struct pico_socket *s, uint8_t *buf, int len)
tass 68:0847e35d08a6 217 {
tass 68:0847e35d08a6 218 uint8_t msgtype = 0;
tass 68:0847e35d08a6 219 int optlen = len - sizeof(struct pico_dhcp_hdr);
tass 68:0847e35d08a6 220 struct pico_dhcp_hdr *hdr = (struct pico_dhcp_hdr *)buf;
tass 68:0847e35d08a6 221 struct pico_dhcp_opt *opt = (struct pico_dhcp_opt *)hdr->options;
tass 68:0847e35d08a6 222 struct pico_dhcp_server_negotiation *dhcpn = NULL;
tass 68:0847e35d08a6 223 struct pico_ip4 reqip = {0}, server_id = {0};
tass 68:0847e35d08a6 224 struct pico_device *dev = NULL;
tass 68:0847e35d08a6 225
tass 68:0847e35d08a6 226 if (!pico_dhcp_are_options_valid(hdr->options, optlen))
tass 68:0847e35d08a6 227 return;
tass 68:0847e35d08a6 228
tass 68:0847e35d08a6 229 dev = pico_ipv4_link_find(&s->local_addr.ip4);
tass 68:0847e35d08a6 230 dhcpn = pico_dhcp_server_find_negotiation(hdr->xid);
tass 68:0847e35d08a6 231 if (!dhcpn)
tass 68:0847e35d08a6 232 dhcpn = pico_dhcp_server_add_negotiation(dev, hdr);
tass 68:0847e35d08a6 233
tass 68:0847e35d08a6 234 if (!ip_inrange(dhcpn->ciaddr.addr))
tass 68:0847e35d08a6 235 return;
tass 68:0847e35d08a6 236
tass 68:0847e35d08a6 237 do {
tass 68:0847e35d08a6 238 switch (opt->code)
tass 68:0847e35d08a6 239 {
tass 68:0847e35d08a6 240 case PICO_DHCP_OPT_PAD:
tass 68:0847e35d08a6 241 break;
tass 68:0847e35d08a6 242
tass 68:0847e35d08a6 243 case PICO_DHCP_OPT_END:
tass 68:0847e35d08a6 244 break;
tass 68:0847e35d08a6 245
tass 68:0847e35d08a6 246 case PICO_DHCP_OPT_MSGTYPE:
tass 68:0847e35d08a6 247 msgtype = opt->ext.msg_type.type;
tass 68:0847e35d08a6 248 dhcps_dbg("DHCP server: message type %u\n", msgtype);
tass 68:0847e35d08a6 249 break;
tass 68:0847e35d08a6 250
tass 68:0847e35d08a6 251 case PICO_DHCP_OPT_REQIP:
tass 68:0847e35d08a6 252 reqip = opt->ext.req_ip.ip;
tass 68:0847e35d08a6 253 dhcps_dbg("DHCP server: requested IP %08X\n", reqip.addr);
tass 68:0847e35d08a6 254 break;
tass 68:0847e35d08a6 255
tass 68:0847e35d08a6 256 case PICO_DHCP_OPT_SERVERID:
tass 68:0847e35d08a6 257 server_id = opt->ext.server_id.ip;
tass 68:0847e35d08a6 258 dhcps_dbg("DHCP server: server ID %08X\n", server_id.addr);
tass 68:0847e35d08a6 259 break;
tass 68:0847e35d08a6 260
tass 68:0847e35d08a6 261 default:
tass 68:0847e35d08a6 262 dhcps_dbg("DHCP server WARNING: unsupported option %u\n", opt->code);
tass 68:0847e35d08a6 263 break;
tass 68:0847e35d08a6 264 }
tass 68:0847e35d08a6 265 } while (pico_dhcp_next_option(&opt));
tass 68:0847e35d08a6 266
tass 68:0847e35d08a6 267 switch (msgtype)
tass 68:0847e35d08a6 268 {
tass 68:0847e35d08a6 269 case PICO_DHCP_MSG_DISCOVER:
tass 68:0847e35d08a6 270 dhcpd_make_reply(dhcpn, PICO_DHCP_MSG_OFFER);
tass 68:0847e35d08a6 271 dhcpn->state = PICO_DHCP_STATE_OFFER;
tass 68:0847e35d08a6 272 break;
tass 68:0847e35d08a6 273
tass 68:0847e35d08a6 274 case PICO_DHCP_MSG_REQUEST:
tass 68:0847e35d08a6 275 if ((dhcpn->state == PICO_DHCP_STATE_BOUND) && (!reqip.addr) && (!server_id.addr) && (hdr->ciaddr == dhcpn->ciaddr.addr))
tass 68:0847e35d08a6 276 dhcpd_make_reply(dhcpn, PICO_DHCP_MSG_ACK);
tass 68:0847e35d08a6 277 if (dhcpn->state == PICO_DHCP_STATE_OFFER) {
tass 68:0847e35d08a6 278 dhcpn->state = PICO_DHCP_STATE_BOUND;
tass 68:0847e35d08a6 279 dhcpd_make_reply(dhcpn, PICO_DHCP_MSG_ACK);
tass 68:0847e35d08a6 280 }
tass 68:0847e35d08a6 281 break;
tass 68:0847e35d08a6 282
tass 68:0847e35d08a6 283 default:
tass 68:0847e35d08a6 284 dhcps_dbg("DHCP server WARNING: unsupported message type %u\n", msgtype);
tass 68:0847e35d08a6 285 break;
tass 68:0847e35d08a6 286 }
tass 68:0847e35d08a6 287 return;
tass 68:0847e35d08a6 288 }
tass 68:0847e35d08a6 289
tass 68:0847e35d08a6 290 static void pico_dhcpd_wakeup(uint16_t ev, struct pico_socket *s)
tass 68:0847e35d08a6 291 {
tass 68:0847e35d08a6 292 uint8_t buf[DHCP_SERVER_MAXMSGSIZE] = {0};
tass 68:0847e35d08a6 293 int r = 0;
tass 68:0847e35d08a6 294
tass 68:0847e35d08a6 295 if (ev != PICO_SOCK_EV_RD)
tass 68:0847e35d08a6 296 return;
tass 68:0847e35d08a6 297 r = pico_socket_recvfrom(s, buf, DHCP_SERVER_MAXMSGSIZE, NULL, NULL);
tass 68:0847e35d08a6 298 if (r < 0)
tass 68:0847e35d08a6 299 return;
tass 68:0847e35d08a6 300
tass 68:0847e35d08a6 301 pico_dhcp_server_recv(s, buf, r);
tass 68:0847e35d08a6 302 return;
tass 68:0847e35d08a6 303 }
tass 68:0847e35d08a6 304
tass 68:0847e35d08a6 305 int pico_dhcp_server_initiate(struct pico_dhcp_server_setting *setting)
tass 68:0847e35d08a6 306 {
tass 68:0847e35d08a6 307 if (!setting || !setting->server_ip.addr) {
tass 68:0847e35d08a6 308 pico_err = PICO_ERR_EINVAL;
tass 68:0847e35d08a6 309 return -1;
tass 68:0847e35d08a6 310 }
tass 68:0847e35d08a6 311
tass 68:0847e35d08a6 312 if (pico_dhcp_server_add_setting(setting) == NULL)
tass 68:0847e35d08a6 313 return -1;
tass 68:0847e35d08a6 314
tass 68:0847e35d08a6 315 return 0;
tass 68:0847e35d08a6 316 }
tass 68:0847e35d08a6 317 #endif /* PICO_SUPPORT_DHCP */