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 Belgium NV
Date:
Mon Dec 16 11:25:54 2013 +0100
Revision:
131:4758606c9316
Parent:
70:cd218dd180e5
Child:
141:fb35b52d1c80
Syncronized with master branch

Who changed what in which revision?

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