lwip-1.4.1 (partial)

Dependents:   IGLOO_board

Committer:
ua1arn
Date:
Tue Jul 24 17:36:01 2018 +0000
Revision:
1:119c4f7144c8
lwip 1.4.1 with necessary servers

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ua1arn 1:119c4f7144c8 1 /*
ua1arn 1:119c4f7144c8 2 * The MIT License (MIT)
ua1arn 1:119c4f7144c8 3 *
ua1arn 1:119c4f7144c8 4 * Copyright (c) 2015 by Sergey Fetisov <fsenok@gmail.com>
ua1arn 1:119c4f7144c8 5 *
ua1arn 1:119c4f7144c8 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
ua1arn 1:119c4f7144c8 7 * of this software and associated documentation files (the "Software"), to deal
ua1arn 1:119c4f7144c8 8 * in the Software without restriction, including without limitation the rights
ua1arn 1:119c4f7144c8 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
ua1arn 1:119c4f7144c8 10 * copies of the Software, and to permit persons to whom the Software is
ua1arn 1:119c4f7144c8 11 * furnished to do so, subject to the following conditions:
ua1arn 1:119c4f7144c8 12 *
ua1arn 1:119c4f7144c8 13 * The above copyright notice and this permission notice shall be included in all
ua1arn 1:119c4f7144c8 14 * copies or substantial portions of the Software.
ua1arn 1:119c4f7144c8 15 *
ua1arn 1:119c4f7144c8 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
ua1arn 1:119c4f7144c8 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ua1arn 1:119c4f7144c8 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
ua1arn 1:119c4f7144c8 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
ua1arn 1:119c4f7144c8 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ua1arn 1:119c4f7144c8 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
ua1arn 1:119c4f7144c8 22 * SOFTWARE.
ua1arn 1:119c4f7144c8 23 */
ua1arn 1:119c4f7144c8 24
ua1arn 1:119c4f7144c8 25 #include "dhserver.h"
ua1arn 1:119c4f7144c8 26
ua1arn 1:119c4f7144c8 27 /* DHCP message type */
ua1arn 1:119c4f7144c8 28 #define DHCP_DISCOVER 1
ua1arn 1:119c4f7144c8 29 #define DHCP_OFFER 2
ua1arn 1:119c4f7144c8 30 #define DHCP_REQUEST 3
ua1arn 1:119c4f7144c8 31 #define DHCP_DECLINE 4
ua1arn 1:119c4f7144c8 32 #define DHCP_ACK 5
ua1arn 1:119c4f7144c8 33 #define DHCP_NAK 6
ua1arn 1:119c4f7144c8 34 #define DHCP_RELEASE 7
ua1arn 1:119c4f7144c8 35 #define DHCP_INFORM 8
ua1arn 1:119c4f7144c8 36
ua1arn 1:119c4f7144c8 37 /* DHCP options */
ua1arn 1:119c4f7144c8 38 enum DHCP_OPTIONS
ua1arn 1:119c4f7144c8 39 {
ua1arn 1:119c4f7144c8 40 DHCP_PAD = 0,
ua1arn 1:119c4f7144c8 41 DHCP_SUBNETMASK = 1,
ua1arn 1:119c4f7144c8 42 DHCP_ROUTER = 3,
ua1arn 1:119c4f7144c8 43 DHCP_DNSSERVER = 6,
ua1arn 1:119c4f7144c8 44 DHCP_HOSTNAME = 12,
ua1arn 1:119c4f7144c8 45 DHCP_DNSDOMAIN = 15,
ua1arn 1:119c4f7144c8 46 DHCP_MTU = 26,
ua1arn 1:119c4f7144c8 47 DHCP_BROADCAST = 28,
ua1arn 1:119c4f7144c8 48 DHCP_PERFORMROUTERDISC = 31,
ua1arn 1:119c4f7144c8 49 DHCP_STATICROUTE = 33,
ua1arn 1:119c4f7144c8 50 DHCP_NISDOMAIN = 40,
ua1arn 1:119c4f7144c8 51 DHCP_NISSERVER = 41,
ua1arn 1:119c4f7144c8 52 DHCP_NTPSERVER = 42,
ua1arn 1:119c4f7144c8 53 DHCP_VENDOR = 43,
ua1arn 1:119c4f7144c8 54 DHCP_IPADDRESS = 50,
ua1arn 1:119c4f7144c8 55 DHCP_LEASETIME = 51,
ua1arn 1:119c4f7144c8 56 DHCP_OPTIONSOVERLOADED = 52,
ua1arn 1:119c4f7144c8 57 DHCP_MESSAGETYPE = 53,
ua1arn 1:119c4f7144c8 58 DHCP_SERVERID = 54,
ua1arn 1:119c4f7144c8 59 DHCP_PARAMETERREQUESTLIST = 55,
ua1arn 1:119c4f7144c8 60 DHCP_MESSAGE = 56,
ua1arn 1:119c4f7144c8 61 DHCP_MAXMESSAGESIZE = 57,
ua1arn 1:119c4f7144c8 62 DHCP_RENEWALTIME = 58,
ua1arn 1:119c4f7144c8 63 DHCP_REBINDTIME = 59,
ua1arn 1:119c4f7144c8 64 DHCP_CLASSID = 60,
ua1arn 1:119c4f7144c8 65 DHCP_CLIENTID = 61,
ua1arn 1:119c4f7144c8 66 DHCP_USERCLASS = 77, /* RFC 3004 */
ua1arn 1:119c4f7144c8 67 DHCP_FQDN = 81,
ua1arn 1:119c4f7144c8 68 DHCP_DNSSEARCH = 119, /* RFC 3397 */
ua1arn 1:119c4f7144c8 69 DHCP_CSR = 121, /* RFC 3442 */
ua1arn 1:119c4f7144c8 70 DHCP_MSCSR = 249, /* MS code for RFC 3442 */
ua1arn 1:119c4f7144c8 71 DHCP_END = 255
ua1arn 1:119c4f7144c8 72 };
ua1arn 1:119c4f7144c8 73
ua1arn 1:119c4f7144c8 74 typedef struct
ua1arn 1:119c4f7144c8 75 {
ua1arn 1:119c4f7144c8 76 uint8_t dp_op; /* packet opcode type */
ua1arn 1:119c4f7144c8 77 uint8_t dp_htype; /* hardware addr type */
ua1arn 1:119c4f7144c8 78 uint8_t dp_hlen; /* hardware addr length */
ua1arn 1:119c4f7144c8 79 uint8_t dp_hops; /* gateway hops */
ua1arn 1:119c4f7144c8 80 uint32_t dp_xid; /* transaction ID */
ua1arn 1:119c4f7144c8 81 uint16_t dp_secs; /* seconds since boot began */
ua1arn 1:119c4f7144c8 82 uint16_t dp_flags;
ua1arn 1:119c4f7144c8 83 uint8_t dp_ciaddr[4]; /* client IP address */
ua1arn 1:119c4f7144c8 84 uint8_t dp_yiaddr[4]; /* 'your' IP address */
ua1arn 1:119c4f7144c8 85 uint8_t dp_siaddr[4]; /* server IP address */
ua1arn 1:119c4f7144c8 86 uint8_t dp_giaddr[4]; /* gateway IP address */
ua1arn 1:119c4f7144c8 87 uint8_t dp_chaddr[16]; /* client hardware address */
ua1arn 1:119c4f7144c8 88 uint8_t dp_legacy[192];
ua1arn 1:119c4f7144c8 89 uint8_t dp_magic[4];
ua1arn 1:119c4f7144c8 90 uint8_t dp_options[275]; /* options area */
ua1arn 1:119c4f7144c8 91 } DHCP_TYPE;
ua1arn 1:119c4f7144c8 92
ua1arn 1:119c4f7144c8 93 DHCP_TYPE dhcp_data;
ua1arn 1:119c4f7144c8 94 static struct udp_pcb *pcb = NULL;
ua1arn 1:119c4f7144c8 95 static dhcp_config_t *config = NULL;
ua1arn 1:119c4f7144c8 96
ua1arn 1:119c4f7144c8 97 char magic_cookie[] = {0x63,0x82,0x53,0x63};
ua1arn 1:119c4f7144c8 98
ua1arn 1:119c4f7144c8 99 static dhcp_entry_t *entry_by_ip(uint32_t ip)
ua1arn 1:119c4f7144c8 100 {
ua1arn 1:119c4f7144c8 101 int i;
ua1arn 1:119c4f7144c8 102 for (i = 0; i < config->num_entry; i++)
ua1arn 1:119c4f7144c8 103 if (*(uint32_t *)config->entries[i].addr == ip)
ua1arn 1:119c4f7144c8 104 return &config->entries[i];
ua1arn 1:119c4f7144c8 105 return NULL;
ua1arn 1:119c4f7144c8 106 }
ua1arn 1:119c4f7144c8 107
ua1arn 1:119c4f7144c8 108 static dhcp_entry_t *entry_by_mac(uint8_t *mac)
ua1arn 1:119c4f7144c8 109 {
ua1arn 1:119c4f7144c8 110 int i;
ua1arn 1:119c4f7144c8 111 for (i = 0; i < config->num_entry; i++)
ua1arn 1:119c4f7144c8 112 if (memcmp(config->entries[i].mac, mac, 6) == 0)
ua1arn 1:119c4f7144c8 113 return &config->entries[i];
ua1arn 1:119c4f7144c8 114 return NULL;
ua1arn 1:119c4f7144c8 115 }
ua1arn 1:119c4f7144c8 116
ua1arn 1:119c4f7144c8 117 static __inline bool is_vacant(dhcp_entry_t *entry)
ua1arn 1:119c4f7144c8 118 {
ua1arn 1:119c4f7144c8 119 return memcmp("\0\0\0\0\0", entry->mac, 6) == 0;
ua1arn 1:119c4f7144c8 120 }
ua1arn 1:119c4f7144c8 121
ua1arn 1:119c4f7144c8 122 static dhcp_entry_t *vacant_address()
ua1arn 1:119c4f7144c8 123 {
ua1arn 1:119c4f7144c8 124 int i;
ua1arn 1:119c4f7144c8 125 for (i = 0; i < config->num_entry; i++)
ua1arn 1:119c4f7144c8 126 if (is_vacant(config->entries + i))
ua1arn 1:119c4f7144c8 127 return config->entries + 1;
ua1arn 1:119c4f7144c8 128 return NULL;
ua1arn 1:119c4f7144c8 129 }
ua1arn 1:119c4f7144c8 130
ua1arn 1:119c4f7144c8 131 static __inline void free_entry(dhcp_entry_t *entry)
ua1arn 1:119c4f7144c8 132 {
ua1arn 1:119c4f7144c8 133 memset(entry->mac, 0, 6);
ua1arn 1:119c4f7144c8 134 }
ua1arn 1:119c4f7144c8 135
ua1arn 1:119c4f7144c8 136 uint8_t *find_dhcp_option(uint8_t *attrs, int size, uint8_t attr)
ua1arn 1:119c4f7144c8 137 {
ua1arn 1:119c4f7144c8 138 int i = 0;
ua1arn 1:119c4f7144c8 139 while ((i + 1) < size)
ua1arn 1:119c4f7144c8 140 {
ua1arn 1:119c4f7144c8 141 int next = i + attrs[i + 1] + 2;
ua1arn 1:119c4f7144c8 142 if (next > size) return NULL;
ua1arn 1:119c4f7144c8 143 if (attrs[i] == attr)
ua1arn 1:119c4f7144c8 144 return attrs + i;
ua1arn 1:119c4f7144c8 145 i = next;
ua1arn 1:119c4f7144c8 146 }
ua1arn 1:119c4f7144c8 147 return NULL;
ua1arn 1:119c4f7144c8 148 }
ua1arn 1:119c4f7144c8 149
ua1arn 1:119c4f7144c8 150 int fill_options(void *dest,
ua1arn 1:119c4f7144c8 151 uint8_t msg_type,
ua1arn 1:119c4f7144c8 152 const char *domain,
ua1arn 1:119c4f7144c8 153 uint32_t dns,
ua1arn 1:119c4f7144c8 154 int lease_time,
ua1arn 1:119c4f7144c8 155 uint32_t serverid,
ua1arn 1:119c4f7144c8 156 uint32_t router,
ua1arn 1:119c4f7144c8 157 uint32_t subnet)
ua1arn 1:119c4f7144c8 158 {
ua1arn 1:119c4f7144c8 159 uint8_t *ptr = (uint8_t *)dest;
ua1arn 1:119c4f7144c8 160 /* ACK message type */
ua1arn 1:119c4f7144c8 161 *ptr++ = 53;
ua1arn 1:119c4f7144c8 162 *ptr++ = 1;
ua1arn 1:119c4f7144c8 163 *ptr++ = msg_type;
ua1arn 1:119c4f7144c8 164
ua1arn 1:119c4f7144c8 165 /* dhcp server identifier */
ua1arn 1:119c4f7144c8 166 *ptr++ = DHCP_SERVERID;
ua1arn 1:119c4f7144c8 167 *ptr++ = 4;
ua1arn 1:119c4f7144c8 168 *(uint32_t *)ptr = serverid;
ua1arn 1:119c4f7144c8 169 ptr += 4;
ua1arn 1:119c4f7144c8 170
ua1arn 1:119c4f7144c8 171 /* lease time */
ua1arn 1:119c4f7144c8 172 *ptr++ = DHCP_LEASETIME;
ua1arn 1:119c4f7144c8 173 *ptr++ = 4;
ua1arn 1:119c4f7144c8 174 *ptr++ = (lease_time >> 24) & 0xFF;
ua1arn 1:119c4f7144c8 175 *ptr++ = (lease_time >> 16) & 0xFF;
ua1arn 1:119c4f7144c8 176 *ptr++ = (lease_time >> 8) & 0xFF;
ua1arn 1:119c4f7144c8 177 *ptr++ = (lease_time >> 0) & 0xFF;
ua1arn 1:119c4f7144c8 178
ua1arn 1:119c4f7144c8 179 /* subnet mask */
ua1arn 1:119c4f7144c8 180 *ptr++ = DHCP_SUBNETMASK;
ua1arn 1:119c4f7144c8 181 *ptr++ = 4;
ua1arn 1:119c4f7144c8 182 *(uint32_t *)ptr = subnet;
ua1arn 1:119c4f7144c8 183 ptr += 4;
ua1arn 1:119c4f7144c8 184
ua1arn 1:119c4f7144c8 185 /* router */
ua1arn 1:119c4f7144c8 186 if (router != 0)
ua1arn 1:119c4f7144c8 187 {
ua1arn 1:119c4f7144c8 188 *ptr++ = DHCP_ROUTER;
ua1arn 1:119c4f7144c8 189 *ptr++ = 4;
ua1arn 1:119c4f7144c8 190 *(uint32_t *)ptr = router;
ua1arn 1:119c4f7144c8 191 ptr += 4;
ua1arn 1:119c4f7144c8 192 }
ua1arn 1:119c4f7144c8 193
ua1arn 1:119c4f7144c8 194 /* domain name */
ua1arn 1:119c4f7144c8 195 if (domain != NULL)
ua1arn 1:119c4f7144c8 196 {
ua1arn 1:119c4f7144c8 197 int len = strlen(domain);
ua1arn 1:119c4f7144c8 198 *ptr++ = DHCP_DNSDOMAIN;
ua1arn 1:119c4f7144c8 199 *ptr++ = len;
ua1arn 1:119c4f7144c8 200 memcpy(ptr, domain, len);
ua1arn 1:119c4f7144c8 201 ptr += len;
ua1arn 1:119c4f7144c8 202 }
ua1arn 1:119c4f7144c8 203
ua1arn 1:119c4f7144c8 204 /* domain name server (DNS) */
ua1arn 1:119c4f7144c8 205 if (dns != 0)
ua1arn 1:119c4f7144c8 206 {
ua1arn 1:119c4f7144c8 207 *ptr++ = DHCP_DNSSERVER;
ua1arn 1:119c4f7144c8 208 *ptr++ = 4;
ua1arn 1:119c4f7144c8 209 *(uint32_t *)ptr = dns;
ua1arn 1:119c4f7144c8 210 ptr += 4;
ua1arn 1:119c4f7144c8 211 }
ua1arn 1:119c4f7144c8 212
ua1arn 1:119c4f7144c8 213 /* end */
ua1arn 1:119c4f7144c8 214 *ptr++ = DHCP_END;
ua1arn 1:119c4f7144c8 215 return ptr - (uint8_t *)dest;
ua1arn 1:119c4f7144c8 216 }
ua1arn 1:119c4f7144c8 217
ua1arn 1:119c4f7144c8 218 static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
ua1arn 1:119c4f7144c8 219 {
ua1arn 1:119c4f7144c8 220 uint8_t *ptr;
ua1arn 1:119c4f7144c8 221 dhcp_entry_t *entry;
ua1arn 1:119c4f7144c8 222 struct pbuf *pp;
ua1arn 1:119c4f7144c8 223
ua1arn 1:119c4f7144c8 224 int n = p->len;
ua1arn 1:119c4f7144c8 225 if (n > sizeof(dhcp_data)) n = sizeof(dhcp_data);
ua1arn 1:119c4f7144c8 226 memcpy(&dhcp_data, p->payload, n);
ua1arn 1:119c4f7144c8 227 switch (dhcp_data.dp_options[2])
ua1arn 1:119c4f7144c8 228 {
ua1arn 1:119c4f7144c8 229 case DHCP_DISCOVER:
ua1arn 1:119c4f7144c8 230 entry = entry_by_mac(dhcp_data.dp_chaddr);
ua1arn 1:119c4f7144c8 231 if (entry == NULL) entry = vacant_address();
ua1arn 1:119c4f7144c8 232 if (entry == NULL) break;
ua1arn 1:119c4f7144c8 233
ua1arn 1:119c4f7144c8 234 dhcp_data.dp_op = 2; /* reply */
ua1arn 1:119c4f7144c8 235 dhcp_data.dp_secs = 0;
ua1arn 1:119c4f7144c8 236 dhcp_data.dp_flags = 0;
ua1arn 1:119c4f7144c8 237 *(uint32_t *)dhcp_data.dp_yiaddr = *(uint32_t *)entry->addr;
ua1arn 1:119c4f7144c8 238 memcpy(dhcp_data.dp_magic, magic_cookie, 4);
ua1arn 1:119c4f7144c8 239
ua1arn 1:119c4f7144c8 240 memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options));
ua1arn 1:119c4f7144c8 241
ua1arn 1:119c4f7144c8 242 fill_options(dhcp_data.dp_options,
ua1arn 1:119c4f7144c8 243 DHCP_OFFER,
ua1arn 1:119c4f7144c8 244 config->domain,
ua1arn 1:119c4f7144c8 245 *(uint32_t *)config->dns,
ua1arn 1:119c4f7144c8 246 entry->lease,
ua1arn 1:119c4f7144c8 247 *(uint32_t *)config->addr,
ua1arn 1:119c4f7144c8 248 0,
ua1arn 1:119c4f7144c8 249 *(uint32_t *)entry->subnet);
ua1arn 1:119c4f7144c8 250
ua1arn 1:119c4f7144c8 251 pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL);
ua1arn 1:119c4f7144c8 252 if (pp == NULL) break;
ua1arn 1:119c4f7144c8 253 memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data));
ua1arn 1:119c4f7144c8 254 udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port);
ua1arn 1:119c4f7144c8 255 pbuf_free(pp);
ua1arn 1:119c4f7144c8 256 break;
ua1arn 1:119c4f7144c8 257
ua1arn 1:119c4f7144c8 258 case DHCP_REQUEST:
ua1arn 1:119c4f7144c8 259 /* 1. find requested ipaddr in option list */
ua1arn 1:119c4f7144c8 260 ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_IPADDRESS);
ua1arn 1:119c4f7144c8 261 if (ptr == NULL) break;
ua1arn 1:119c4f7144c8 262 if (ptr[1] != 4) break;
ua1arn 1:119c4f7144c8 263 ptr += 2;
ua1arn 1:119c4f7144c8 264
ua1arn 1:119c4f7144c8 265 /* 2. does hw-address registered? */
ua1arn 1:119c4f7144c8 266 entry = entry_by_mac(dhcp_data.dp_chaddr);
ua1arn 1:119c4f7144c8 267 if (entry != NULL) free_entry(entry);
ua1arn 1:119c4f7144c8 268
ua1arn 1:119c4f7144c8 269 /* 3. find requested ipaddr */
ua1arn 1:119c4f7144c8 270 entry = entry_by_ip(*(uint32_t *)ptr);
ua1arn 1:119c4f7144c8 271 if (entry == NULL) break;
ua1arn 1:119c4f7144c8 272 if (!is_vacant(entry)) break;
ua1arn 1:119c4f7144c8 273
ua1arn 1:119c4f7144c8 274 /* 4. fill struct fields */
ua1arn 1:119c4f7144c8 275 memcpy(dhcp_data.dp_yiaddr, ptr, 4);
ua1arn 1:119c4f7144c8 276 dhcp_data.dp_op = 2; /* reply */
ua1arn 1:119c4f7144c8 277 dhcp_data.dp_secs = 0;
ua1arn 1:119c4f7144c8 278 dhcp_data.dp_flags = 0;
ua1arn 1:119c4f7144c8 279 memcpy(dhcp_data.dp_magic, magic_cookie, 4);
ua1arn 1:119c4f7144c8 280
ua1arn 1:119c4f7144c8 281 /* 5. fill options */
ua1arn 1:119c4f7144c8 282 memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options));
ua1arn 1:119c4f7144c8 283
ua1arn 1:119c4f7144c8 284 fill_options(dhcp_data.dp_options,
ua1arn 1:119c4f7144c8 285 DHCP_ACK,
ua1arn 1:119c4f7144c8 286 config->domain,
ua1arn 1:119c4f7144c8 287 *(uint32_t *)config->dns,
ua1arn 1:119c4f7144c8 288 entry->lease,
ua1arn 1:119c4f7144c8 289 *(uint32_t *)config->addr,
ua1arn 1:119c4f7144c8 290 0,
ua1arn 1:119c4f7144c8 291 *(uint32_t *)entry->subnet);
ua1arn 1:119c4f7144c8 292
ua1arn 1:119c4f7144c8 293 /* 6. send ACK */
ua1arn 1:119c4f7144c8 294 pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL);
ua1arn 1:119c4f7144c8 295 if (pp == NULL) break;
ua1arn 1:119c4f7144c8 296 memcpy(entry->mac, dhcp_data.dp_chaddr, 6);
ua1arn 1:119c4f7144c8 297 memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data));
ua1arn 1:119c4f7144c8 298 udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port);
ua1arn 1:119c4f7144c8 299 pbuf_free(pp);
ua1arn 1:119c4f7144c8 300 break;
ua1arn 1:119c4f7144c8 301
ua1arn 1:119c4f7144c8 302 default:
ua1arn 1:119c4f7144c8 303 break;
ua1arn 1:119c4f7144c8 304 }
ua1arn 1:119c4f7144c8 305 pbuf_free(p);
ua1arn 1:119c4f7144c8 306 }
ua1arn 1:119c4f7144c8 307
ua1arn 1:119c4f7144c8 308 err_t dhserv_init(dhcp_config_t *c)
ua1arn 1:119c4f7144c8 309 {
ua1arn 1:119c4f7144c8 310 err_t err;
ua1arn 1:119c4f7144c8 311 udp_init();
ua1arn 1:119c4f7144c8 312 dhserv_free();
ua1arn 1:119c4f7144c8 313 pcb = udp_new();
ua1arn 1:119c4f7144c8 314 if (pcb == NULL)
ua1arn 1:119c4f7144c8 315 return ERR_MEM;
ua1arn 1:119c4f7144c8 316 err = udp_bind(pcb, IP_ADDR_ANY, c->port);
ua1arn 1:119c4f7144c8 317 if (err != ERR_OK)
ua1arn 1:119c4f7144c8 318 {
ua1arn 1:119c4f7144c8 319 dhserv_free();
ua1arn 1:119c4f7144c8 320 return err;
ua1arn 1:119c4f7144c8 321 }
ua1arn 1:119c4f7144c8 322 udp_recv(pcb, udp_recv_proc, NULL);
ua1arn 1:119c4f7144c8 323 config = c;
ua1arn 1:119c4f7144c8 324 return ERR_OK;
ua1arn 1:119c4f7144c8 325 }
ua1arn 1:119c4f7144c8 326
ua1arn 1:119c4f7144c8 327 void dhserv_free(void)
ua1arn 1:119c4f7144c8 328 {
ua1arn 1:119c4f7144c8 329 if (pcb == NULL) return;
ua1arn 1:119c4f7144c8 330 udp_remove(pcb);
ua1arn 1:119c4f7144c8 331 pcb = NULL;
ua1arn 1:119c4f7144c8 332 }