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 picotcp@tass.be
Date:
Mon Feb 17 15:42:24 2014 +0100
Revision:
141:fb35b52d1c80
Parent:
131:4758606c9316
Child:
149:5f4cb161cec3
Moved ifdef to fix linker bug in mbed online compiler (because it uses pico_config to specify modules)

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