A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Mon Jan 04 16:07:45 2021 +0000
Revision:
181:169881ecd52f
Parent:
180:0a30cff6b36a
Child:
183:ee809769bf89
Added vendor information to address and name resolutions. Also did some tidied DHCP.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 61:aad055f1b0d1 1 #include <stdint.h>
andrewboyson 61:aad055f1b0d1 2 #include <stdbool.h>
andrewboyson 61:aad055f1b0d1 3 #include <string.h>
andrewboyson 61:aad055f1b0d1 4
andrewboyson 128:79052cb4a41c 5 #include "log.h"
andrewboyson 128:79052cb4a41c 6 #include "mstimer.h"
andrewboyson 128:79052cb4a41c 7 #include "net.h"
andrewboyson 178:52714fef5ca1 8 #include "net-this.h"
andrewboyson 128:79052cb4a41c 9 #include "action.h"
andrewboyson 128:79052cb4a41c 10 #include "eth.h"
andrewboyson 128:79052cb4a41c 11 #include "ip4addr.h"
andrewboyson 128:79052cb4a41c 12 #include "mac.h"
andrewboyson 128:79052cb4a41c 13 #include "udp.h"
andrewboyson 128:79052cb4a41c 14 #include "dnslabel.h"
andrewboyson 136:8a65abb0dc63 15 #include "dhcphdr.h"
andrewboyson 10:f0854784e960 16
andrewboyson 37:793b39683406 17 bool DhcpTrace = false;
andrewboyson 10:f0854784e960 18
andrewboyson 10:f0854784e960 19 #define REQUEST 1
andrewboyson 10:f0854784e960 20 #define REPLY 2
andrewboyson 10:f0854784e960 21
andrewboyson 10:f0854784e960 22 #define DHCPDISCOVER 1
andrewboyson 10:f0854784e960 23 #define DHCPOFFER 2
andrewboyson 10:f0854784e960 24 #define DHCPREQUEST 3
andrewboyson 10:f0854784e960 25 #define DHCPDECLINE 4
andrewboyson 10:f0854784e960 26 #define DHCPACK 5
andrewboyson 10:f0854784e960 27 #define DHCPNAK 6
andrewboyson 10:f0854784e960 28 #define DHCPRELEASE 7
andrewboyson 10:f0854784e960 29 #define DHCPINFORM 8
andrewboyson 10:f0854784e960 30
andrewboyson 181:169881ecd52f 31 #define ID 0x12345
andrewboyson 10:f0854784e960 32 #define COOKIE 0x63825363
andrewboyson 10:f0854784e960 33
andrewboyson 116:60521b29e4c9 34 #define MAX_REPEAT_DELAY_TIME_MS 60000
andrewboyson 119:8e1a7805b801 35 #define MIN_REPEAT_DELAY_TIME_MS 900
andrewboyson 119:8e1a7805b801 36 static uint32_t repeatDelayMsTimer = (uint32_t)-MIN_REPEAT_DELAY_TIME_MS; //Initial value ensures no delay at startup
andrewboyson 119:8e1a7805b801 37 static uint32_t delayMs = MIN_REPEAT_DELAY_TIME_MS; //Doubles on failure up to max; reset to min whenever an IP address request has been acknowledged
andrewboyson 116:60521b29e4c9 38
andrewboyson 136:8a65abb0dc63 39 static uint32_t elapsedLifeMsTimer = 0; //Started whenever an IP address request has been acknowledged
andrewboyson 93:580fc113d9e9 40
andrewboyson 93:580fc113d9e9 41 uint32_t DhcpGetElapsedLife()
andrewboyson 10:f0854784e960 42 {
andrewboyson 119:8e1a7805b801 43 if (!elapsedLifeMsTimer) return 0;
andrewboyson 119:8e1a7805b801 44 return (MsTimerCount - elapsedLifeMsTimer) / 1000;
andrewboyson 10:f0854784e960 45 }
andrewboyson 10:f0854784e960 46
andrewboyson 10:f0854784e960 47 static uint8_t dhcpMessageType = 0;
andrewboyson 10:f0854784e960 48 uint32_t DhcpLeaseTime = 0;
andrewboyson 116:60521b29e4c9 49 uint32_t DhcpServerIp = 0;
andrewboyson 116:60521b29e4c9 50 uint32_t DhcpRouterIp = 0;
andrewboyson 10:f0854784e960 51 uint32_t DhcpSubnetMask = 0;
andrewboyson 116:60521b29e4c9 52 uint32_t DhcpNtpIp = 0;
andrewboyson 10:f0854784e960 53 uint32_t DhcpRenewalT1 = 0;
andrewboyson 10:f0854784e960 54 uint32_t DhcpRenewalT2 = 0;
andrewboyson 10:f0854784e960 55 uint32_t DhcpBroadcastIp = 0;
andrewboyson 10:f0854784e960 56 uint32_t DhcpLocalIp = 0;
andrewboyson 116:60521b29e4c9 57 uint32_t DhcpDnsServerIp = 0;
andrewboyson 128:79052cb4a41c 58 char DhcpDomainName[DNS_MAX_LABEL_LENGTH+1];
andrewboyson 128:79052cb4a41c 59 char DhcpHostName [DNS_MAX_LABEL_LENGTH+1];
andrewboyson 44:83ce5ace337b 60
andrewboyson 179:55342264fca1 61 static void clearAll()
andrewboyson 179:55342264fca1 62 {
andrewboyson 179:55342264fca1 63 DhcpLeaseTime = 0;
andrewboyson 179:55342264fca1 64 DhcpServerIp = 0;
andrewboyson 179:55342264fca1 65 DhcpRouterIp = 0;
andrewboyson 179:55342264fca1 66 DhcpSubnetMask = 0;
andrewboyson 179:55342264fca1 67 DhcpNtpIp = 0;
andrewboyson 179:55342264fca1 68 DhcpRenewalT1 = 0;
andrewboyson 179:55342264fca1 69 DhcpRenewalT2 = 0;
andrewboyson 179:55342264fca1 70 DhcpBroadcastIp = 0;
andrewboyson 179:55342264fca1 71 DhcpLocalIp = 0;
andrewboyson 179:55342264fca1 72 DhcpDnsServerIp = 0;
andrewboyson 179:55342264fca1 73 DhcpDomainName[0] = 0;
andrewboyson 179:55342264fca1 74 DhcpHostName [0] = 0;
andrewboyson 179:55342264fca1 75 }
andrewboyson 179:55342264fca1 76
andrewboyson 44:83ce5ace337b 77 bool DhcpIpNeedsToBeRouted(uint32_t ip)
andrewboyson 174:60e5ab296671 78 {
andrewboyson 174:60e5ab296671 79 if ((ip & 0x000000FF) == 0xFF) return false; //Broadcast 255.xxx.xxx.xxx
andrewboyson 174:60e5ab296671 80 if ((ip & 0x000000FF) == 0xE0) return false; //Multicast 224.xxx.xxx.xxx
andrewboyson 174:60e5ab296671 81 if (ip == (DhcpLocalIp | 0xFF000000)) return false; //Local broadcast ip == 192.168.0.255
andrewboyson 174:60e5ab296671 82
andrewboyson 174:60e5ab296671 83 return (ip & DhcpSubnetMask) != (DhcpLocalIp & DhcpSubnetMask); //ip != 192.168.0.xxx
andrewboyson 44:83ce5ace337b 84 }
andrewboyson 44:83ce5ace337b 85
andrewboyson 10:f0854784e960 86 static uint32_t readOption32(char** pp)
andrewboyson 10:f0854784e960 87 {
andrewboyson 10:f0854784e960 88 uint32_t value = 0;
andrewboyson 10:f0854784e960 89 char* p = *pp;
andrewboyson 10:f0854784e960 90 int len = *++p;
andrewboyson 10:f0854784e960 91 if (len >= 4)
andrewboyson 10:f0854784e960 92 {
andrewboyson 10:f0854784e960 93 value = *++p << 24;
andrewboyson 10:f0854784e960 94 value |= *++p << 16;
andrewboyson 10:f0854784e960 95 value |= *++p << 8;
andrewboyson 10:f0854784e960 96 value |= *++p << 0;
andrewboyson 10:f0854784e960 97 }
andrewboyson 10:f0854784e960 98 *pp += len + 1;
andrewboyson 10:f0854784e960 99 return value;
andrewboyson 10:f0854784e960 100 }
andrewboyson 10:f0854784e960 101 static uint32_t readIp(char** pp)
andrewboyson 10:f0854784e960 102 {
andrewboyson 10:f0854784e960 103 uint32_t value = 0;
andrewboyson 10:f0854784e960 104 char* p = *pp;
andrewboyson 10:f0854784e960 105 int len = *++p;
andrewboyson 10:f0854784e960 106 if (len >= 4)
andrewboyson 10:f0854784e960 107 {
andrewboyson 10:f0854784e960 108 value = *++p << 0;
andrewboyson 10:f0854784e960 109 value |= *++p << 8;
andrewboyson 10:f0854784e960 110 value |= *++p << 16;
andrewboyson 10:f0854784e960 111 value |= *++p << 24;
andrewboyson 10:f0854784e960 112 }
andrewboyson 10:f0854784e960 113 *pp += len + 1;
andrewboyson 10:f0854784e960 114 return value;
andrewboyson 10:f0854784e960 115 }
andrewboyson 10:f0854784e960 116 static void readString(char** pp, char* pText)
andrewboyson 10:f0854784e960 117 {
andrewboyson 10:f0854784e960 118 char* p = *pp;
andrewboyson 10:f0854784e960 119 int len = *++p;
andrewboyson 10:f0854784e960 120 for (int i = 0; i < len; i++) pText[i] = *++p;
andrewboyson 10:f0854784e960 121 *pp += len + 1;
andrewboyson 10:f0854784e960 122 }
andrewboyson 10:f0854784e960 123 static void readOptions(int size, char * pOptions)
andrewboyson 10:f0854784e960 124 {
andrewboyson 10:f0854784e960 125 int len = 0;
andrewboyson 10:f0854784e960 126 char* p = pOptions;
andrewboyson 10:f0854784e960 127 char* pE = pOptions + size;
andrewboyson 10:f0854784e960 128 while( p < pE)
andrewboyson 10:f0854784e960 129 {
andrewboyson 10:f0854784e960 130 switch (*p)
andrewboyson 10:f0854784e960 131 {
andrewboyson 10:f0854784e960 132 case 0: break; //NOP
andrewboyson 10:f0854784e960 133 case 255: return; //End of options
andrewboyson 136:8a65abb0dc63 134 case 1: DhcpSubnetMask = readIp(&p); break; //Subnet Mask
andrewboyson 136:8a65abb0dc63 135 case 3: DhcpRouterIp = readIp(&p); break; //Router
andrewboyson 136:8a65abb0dc63 136 case 6: DhcpDnsServerIp = readIp(&p); break; //DNS server
andrewboyson 10:f0854784e960 137 case 12: readString(&p, DhcpHostName); break; //Host name
andrewboyson 10:f0854784e960 138 case 15: readString(&p, DhcpDomainName); break; //Domain name
andrewboyson 10:f0854784e960 139 case 19: len = *++p; p+= len; break; //IP forwarding yes/no
andrewboyson 136:8a65abb0dc63 140 case 28: DhcpBroadcastIp = readIp(&p); break; //Broadcast IP
andrewboyson 136:8a65abb0dc63 141 case 42: DhcpNtpIp = readIp(&p); break; //NTP
andrewboyson 10:f0854784e960 142 case 44: len = *++p; p+= len; break; //NetBIOS name server
andrewboyson 10:f0854784e960 143 case 45: len = *++p; p+= len; break; //NetBIOS datagram server
andrewboyson 10:f0854784e960 144 case 46: len = *++p; p+= len; break; //NetBIOS node type
andrewboyson 10:f0854784e960 145 case 47: len = *++p; p+= len; break; //NetBIOS scope
andrewboyson 10:f0854784e960 146 case 53: len = *++p; dhcpMessageType = *++p; break; //DHCP message type
andrewboyson 10:f0854784e960 147 case 51: DhcpLeaseTime = readOption32(&p); break; //Address lease time
andrewboyson 116:60521b29e4c9 148 case 54: DhcpServerIp = readIp(&p); break; //DHCP server
andrewboyson 10:f0854784e960 149 case 58: DhcpRenewalT1 = readOption32(&p); break; //T1
andrewboyson 10:f0854784e960 150 case 59: DhcpRenewalT2 = readOption32(&p); break; //T2
andrewboyson 10:f0854784e960 151 default:
andrewboyson 37:793b39683406 152 if (DhcpTrace) LogTimeF("Ignoring option %d\r\n", *p);
andrewboyson 10:f0854784e960 153 len = *++p;
andrewboyson 10:f0854784e960 154 p += len;
andrewboyson 10:f0854784e960 155 return;
andrewboyson 10:f0854784e960 156 }
andrewboyson 10:f0854784e960 157 p++;
andrewboyson 10:f0854784e960 158 }
andrewboyson 10:f0854784e960 159 }
andrewboyson 10:f0854784e960 160 static void writeIp(uint8_t code, uint32_t value, char** pp)
andrewboyson 10:f0854784e960 161 {
andrewboyson 10:f0854784e960 162 if (!value) return;
andrewboyson 136:8a65abb0dc63 163
andrewboyson 10:f0854784e960 164 char* p = *pp;
andrewboyson 136:8a65abb0dc63 165
andrewboyson 10:f0854784e960 166 *p++ = code;
andrewboyson 10:f0854784e960 167 *p++ = 4;
andrewboyson 10:f0854784e960 168 *p++ = (value & 0x000000FF) >> 0;
andrewboyson 10:f0854784e960 169 *p++ = (value & 0x0000FF00) >> 8;
andrewboyson 10:f0854784e960 170 *p++ = (value & 0x00FF0000) >> 16;
andrewboyson 10:f0854784e960 171 *p++ = (value & 0xFF000000) >> 24;
andrewboyson 136:8a65abb0dc63 172
andrewboyson 10:f0854784e960 173 *pp += 6;
andrewboyson 10:f0854784e960 174 }
andrewboyson 178:52714fef5ca1 175 static void writeText(uint8_t code, const char* pText, char** pp)
andrewboyson 178:52714fef5ca1 176 {
andrewboyson 178:52714fef5ca1 177 if (!pText) return;
andrewboyson 178:52714fef5ca1 178 if (!*pText) return;
andrewboyson 178:52714fef5ca1 179
andrewboyson 178:52714fef5ca1 180 char* p = *pp;
andrewboyson 178:52714fef5ca1 181
andrewboyson 178:52714fef5ca1 182 *p++ = code;
andrewboyson 178:52714fef5ca1 183 char* pLength = p++;
andrewboyson 178:52714fef5ca1 184 while (true) //Copy pText without the end zero
andrewboyson 178:52714fef5ca1 185 {
andrewboyson 178:52714fef5ca1 186 *p = *pText;
andrewboyson 178:52714fef5ca1 187 pText++;
andrewboyson 178:52714fef5ca1 188 if (!*pText) break;
andrewboyson 178:52714fef5ca1 189 p++;
andrewboyson 178:52714fef5ca1 190 }
andrewboyson 178:52714fef5ca1 191
andrewboyson 178:52714fef5ca1 192 *pLength = p - pLength;
andrewboyson 178:52714fef5ca1 193
andrewboyson 178:52714fef5ca1 194 *pp += *pLength + 2;
andrewboyson 178:52714fef5ca1 195 }
andrewboyson 10:f0854784e960 196 int sendRequest(void* pPacket, uint8_t code, uint32_t srvIp, uint32_t reqIp)
andrewboyson 10:f0854784e960 197 {
andrewboyson 136:8a65abb0dc63 198
andrewboyson 10:f0854784e960 199 switch (code)
andrewboyson 10:f0854784e960 200 {
andrewboyson 10:f0854784e960 201 case DHCPDISCOVER:
andrewboyson 37:793b39683406 202 if (DhcpTrace) LogTimeF("DHCP -> discover");
andrewboyson 10:f0854784e960 203 break;
andrewboyson 10:f0854784e960 204 case DHCPREQUEST:
andrewboyson 37:793b39683406 205 if (DhcpTrace) LogTimeF("DHCP -> request");
andrewboyson 10:f0854784e960 206 break;
andrewboyson 10:f0854784e960 207 default:
andrewboyson 10:f0854784e960 208 LogTimeF("DHCP -> unknown message %d", code);
andrewboyson 10:f0854784e960 209 break;
andrewboyson 10:f0854784e960 210 }
andrewboyson 37:793b39683406 211 if (DhcpTrace)
andrewboyson 10:f0854784e960 212 {
andrewboyson 47:73af5c0b0dc2 213 Log(" server=" ); Ip4AddressLog(srvIp);
andrewboyson 47:73af5c0b0dc2 214 Log(" request="); Ip4AddressLog(reqIp);
andrewboyson 47:73af5c0b0dc2 215 Log("\r\n");
andrewboyson 10:f0854784e960 216 }
andrewboyson 136:8a65abb0dc63 217
andrewboyson 10:f0854784e960 218 bool broadcast = DhcpLocalIp == 0;
andrewboyson 10:f0854784e960 219 uint16_t flags = 0;
andrewboyson 136:8a65abb0dc63 220 if (broadcast) flags |= 0x8000;
andrewboyson 136:8a65abb0dc63 221 DhcpHdrSetOp (pPacket, REQUEST );
andrewboyson 136:8a65abb0dc63 222 DhcpHdrSetHtype (pPacket, ETHERNET );
andrewboyson 136:8a65abb0dc63 223 DhcpHdrSetHlen (pPacket, 6 );
andrewboyson 136:8a65abb0dc63 224 DhcpHdrSetHops (pPacket, 0 );
andrewboyson 136:8a65abb0dc63 225 DhcpHdrSetXid (pPacket, ID ); //Randomly chosed transaction id used to associate messages to responses
andrewboyson 136:8a65abb0dc63 226 DhcpHdrSetSecs (pPacket, 0 ); //Seconds since started to boot
andrewboyson 136:8a65abb0dc63 227 DhcpHdrSetFlags (pPacket, flags ); //Broadcast (1) Unicast (0)
andrewboyson 181:169881ecd52f 228 //DhcpHdrSetCiaddr(pPacket, reqIp ); //'Client' address set by client or 0 if don't know address
andrewboyson 181:169881ecd52f 229 DhcpHdrSetCiaddr(pPacket, 0 ); //'Client' address set by client or 0 if don't know address
andrewboyson 136:8a65abb0dc63 230 DhcpHdrSetYiaddr(pPacket, 0 ); //'Your' address returned by server
andrewboyson 181:169881ecd52f 231 //DhcpHdrSetSiaddr(pPacket, srvIp ); //'Server' address to use if required
andrewboyson 181:169881ecd52f 232 DhcpHdrSetSiaddr(pPacket, 0 ); //'Server' address to use if required
andrewboyson 136:8a65abb0dc63 233 DhcpHdrSetGiaddr(pPacket, 0 ); //'Gateway' address
andrewboyson 136:8a65abb0dc63 234 memcpy(DhcpHdrPtrChaddr(pPacket), MacLocal, 6); //'Client hardware' address. 6 bytes for ethernet
andrewboyson 136:8a65abb0dc63 235 memset(DhcpHdrPtrLegacy(pPacket), 0, 192 ); //BootP legacy fill with zeros
andrewboyson 136:8a65abb0dc63 236 DhcpHdrSetCookie(pPacket, COOKIE ); //Magic cookie
andrewboyson 136:8a65abb0dc63 237
andrewboyson 136:8a65abb0dc63 238 char* pOptions = (char*)pPacket + DHCP_HEADER_LENGTH;
andrewboyson 10:f0854784e960 239 char* p = pOptions;
andrewboyson 10:f0854784e960 240 *p++ = 53; //Message code
andrewboyson 10:f0854784e960 241 *p++ = 1;
andrewboyson 10:f0854784e960 242 *p++ = code;
andrewboyson 136:8a65abb0dc63 243
andrewboyson 181:169881ecd52f 244 if (reqIp) writeIp(50, reqIp, &p); //Requested IP
andrewboyson 181:169881ecd52f 245 if (srvIp) writeIp(54, srvIp, &p); //Server ip
andrewboyson 178:52714fef5ca1 246
andrewboyson 178:52714fef5ca1 247 writeText(12, NET_NAME, &p);
andrewboyson 136:8a65abb0dc63 248
andrewboyson 10:f0854784e960 249 *p++ = 255; //End of options
andrewboyson 10:f0854784e960 250
andrewboyson 136:8a65abb0dc63 251 return DHCP_HEADER_LENGTH + p - pOptions;
andrewboyson 136:8a65abb0dc63 252 }
andrewboyson 136:8a65abb0dc63 253 int DhcpHandleResponse(void (*traceback)(void), int sizeRx, char* pPacketRx, int* pSizeTx, char* pPacketTx)
andrewboyson 136:8a65abb0dc63 254 {
andrewboyson 136:8a65abb0dc63 255 uint8_t op = DhcpHdrGetOp (pPacketRx);
andrewboyson 136:8a65abb0dc63 256 uint8_t htype = DhcpHdrGetHtype (pPacketRx);
andrewboyson 136:8a65abb0dc63 257 uint8_t hlen = DhcpHdrGetHlen (pPacketRx);
andrewboyson 136:8a65abb0dc63 258 uint32_t xid = DhcpHdrGetXid (pPacketRx); //Randomly chosen transaction id used to associate messages to responses
andrewboyson 136:8a65abb0dc63 259 uint32_t yiaddr = DhcpHdrGetYiaddr(pPacketRx);
andrewboyson 136:8a65abb0dc63 260 uint32_t siaddr = DhcpHdrGetSiaddr(pPacketRx);
andrewboyson 136:8a65abb0dc63 261 uint32_t cookie = DhcpHdrGetCookie(pPacketRx);
andrewboyson 136:8a65abb0dc63 262
andrewboyson 136:8a65abb0dc63 263 if (op != REPLY) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 264 if (htype != ETHERNET) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 265 if (hlen != 6) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 266 if (memcmp(DhcpHdrPtrChaddr(pPacketRx), MacLocal, 6)) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 267 if (xid != ID) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 268 if (cookie != COOKIE) return DO_NOTHING;
andrewboyson 136:8a65abb0dc63 269
andrewboyson 136:8a65abb0dc63 270 char* pOptions = (char*)pPacketRx + DHCP_HEADER_LENGTH;
andrewboyson 136:8a65abb0dc63 271 readOptions(sizeRx - DHCP_HEADER_LENGTH, pOptions);
andrewboyson 136:8a65abb0dc63 272
andrewboyson 10:f0854784e960 273 switch (dhcpMessageType)
andrewboyson 10:f0854784e960 274 {
andrewboyson 10:f0854784e960 275 case DHCPOFFER:
andrewboyson 181:169881ecd52f 276 if (DhcpTrace) { LogTime("DHCP <- offer ip "); Ip4AddressLog(yiaddr); Log(" server ip "); Ip4AddressLog(DhcpServerIp); Log("\r\n"); }
andrewboyson 181:169881ecd52f 277 //*pSizeTx = sendRequest(pPacketTx, DHCPREQUEST, siaddr, yiaddr);
andrewboyson 181:169881ecd52f 278 *pSizeTx = sendRequest(pPacketTx, DHCPREQUEST, DhcpServerIp, yiaddr);
andrewboyson 10:f0854784e960 279 return BROADCAST;
andrewboyson 10:f0854784e960 280 case DHCPACK:
andrewboyson 181:169881ecd52f 281 if (DhcpTrace) { LogTime("DHCP <- ack ip "); Ip4AddressLog(yiaddr); Log(" server ip "); Ip4AddressLog(DhcpServerIp); Log("\r\n"); }
andrewboyson 180:0a30cff6b36a 282 DhcpLocalIp = yiaddr; //Save our IP
andrewboyson 119:8e1a7805b801 283 elapsedLifeMsTimer = MsTimerCount; //Start the life timer
andrewboyson 116:60521b29e4c9 284 delayMs = MIN_REPEAT_DELAY_TIME_MS; //Set the delay time back to minimum
andrewboyson 10:f0854784e960 285 break;
andrewboyson 10:f0854784e960 286 case DHCPNAK:
andrewboyson 181:169881ecd52f 287 if (DhcpTrace) { LogTime("DHCP <- nack ip "); Ip4AddressLog(yiaddr); Log(" server ip "); Ip4AddressLog(DhcpServerIp); Log("\r\n"); }
andrewboyson 179:55342264fca1 288 clearAll();
andrewboyson 10:f0854784e960 289 break;
andrewboyson 10:f0854784e960 290 default:
andrewboyson 10:f0854784e960 291 LogTimeF("DHCP <- unknown message %d\r\n", dhcpMessageType);
andrewboyson 10:f0854784e960 292 break;
andrewboyson 10:f0854784e960 293 }
andrewboyson 10:f0854784e960 294 return DO_NOTHING;
andrewboyson 10:f0854784e960 295 }
andrewboyson 10:f0854784e960 296
andrewboyson 10:f0854784e960 297 int DhcpPollForRequestToSend(void* pPacket, int* pSize)
andrewboyson 116:60521b29e4c9 298 {
andrewboyson 119:8e1a7805b801 299 //Check if time to update
andrewboyson 119:8e1a7805b801 300 uint32_t elapsedTimeMs = MsTimerCount - elapsedLifeMsTimer;
andrewboyson 93:580fc113d9e9 301 uint32_t leaseTimeMs = DhcpLeaseTime * 1000;
andrewboyson 93:580fc113d9e9 302
andrewboyson 119:8e1a7805b801 303 if (DhcpLocalIp && elapsedTimeMs < (leaseTimeMs >> 1)) return DO_NOTHING; //Do nothing if have address and within T1
andrewboyson 136:8a65abb0dc63 304
andrewboyson 119:8e1a7805b801 305 //Limit retries with a backoff delay
andrewboyson 133:a37eb35a03f1 306 if (!MsTimerRelative(repeatDelayMsTimer, delayMs)) return DO_NOTHING; //Don't retry within the delay time
andrewboyson 119:8e1a7805b801 307 delayMs <<= 1; //Backoff (double) the delay time after each attempt
andrewboyson 119:8e1a7805b801 308 if (delayMs > MAX_REPEAT_DELAY_TIME_MS) delayMs = MAX_REPEAT_DELAY_TIME_MS; //Don't go beyond a maximum
andrewboyson 119:8e1a7805b801 309 repeatDelayMsTimer = MsTimerCount; //Start the delay timer
andrewboyson 136:8a65abb0dc63 310
andrewboyson 119:8e1a7805b801 311 //Send the renewal request
andrewboyson 10:f0854784e960 312 *pSize = 0;
andrewboyson 37:793b39683406 313 int dest = DO_NOTHING;
andrewboyson 93:580fc113d9e9 314 if (DhcpLocalIp && elapsedTimeMs < leaseTimeMs)
andrewboyson 10:f0854784e960 315 {
andrewboyson 116:60521b29e4c9 316 *pSize = sendRequest(pPacket, DHCPREQUEST, DhcpServerIp, DhcpLocalIp); //if within T2 then send request to the server - not broadcast
andrewboyson 37:793b39683406 317 dest = UNICAST_DHCP;
andrewboyson 10:f0854784e960 318 }
andrewboyson 10:f0854784e960 319 else
andrewboyson 10:f0854784e960 320 {
andrewboyson 37:793b39683406 321 if (DhcpTrace) LogTimeF("DHCP lease has expired\r\n");
andrewboyson 179:55342264fca1 322 clearAll();
andrewboyson 10:f0854784e960 323 *pSize = sendRequest(pPacket, DHCPDISCOVER, 0, 0); //If outside T2 then start from scratch to do a full DHCP
andrewboyson 37:793b39683406 324 dest = BROADCAST;
andrewboyson 10:f0854784e960 325 }
andrewboyson 181:169881ecd52f 326 return ActionMakeFromDestAndTrace(dest, DhcpTrace && NetTraceStack);
andrewboyson 136:8a65abb0dc63 327 }