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:
Wed Dec 23 19:43:09 2020 +0000
Revision:
174:60e5ab296671
Parent:
160:6a1d1d368f80
Child:
178:52714fef5ca1
Modified DhcpIpNeedsToBeRouted to take into account that broadcast and multicast addresses don't need to be routed

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