Changeset 79761 in vbox for trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.cpp
- Timestamp:
- Jul 14, 2019 3:18:41 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.cpp
r79524 r79761 16 16 */ 17 17 18 19 /********************************************************************************************************************************* 20 * Header Files * 21 *********************************************************************************************************************************/ 18 22 #include "DhcpdInternal.h" 19 23 #include "DhcpOptions.h" 20 24 #include "DhcpMessage.h" 25 26 #include <iprt/cidr.h> 21 27 22 28 … … 102 108 103 109 110 int DhcpOption::parse1(bool &aValue, const char *pcszValue) 111 { 112 pcszValue = RTStrStripL(pcszValue); 113 if ( strcmp(pcszValue, "true") == 0 114 || strcmp(pcszValue, "1") == 0 115 || strcmp(pcszValue, "yes") == 0 116 || strcmp(pcszValue, "on") == 0 ) 117 { 118 aValue = true; 119 return VINF_SUCCESS; 120 } 121 122 if ( strcmp(pcszValue, "false") == 0 123 || strcmp(pcszValue, "0") == 0 124 || strcmp(pcszValue, "no") == 0 125 || strcmp(pcszValue, "off") == 0 ) 126 { 127 aValue = false; 128 return VINF_SUCCESS; 129 } 130 131 uint8_t bTmp; 132 int rc = RTStrToUInt8Full(RTStrStripL(pcszValue), 10, &bTmp); 133 if (rc == VERR_TRAILING_SPACES) 134 rc = VINF_SUCCESS; 135 if (RT_SUCCESS(rc)) 136 aValue = bTmp != 0; 137 138 return rc; 139 } 140 141 104 142 int DhcpOption::parse1(uint8_t &aValue, const char *pcszValue) 105 143 { 106 144 int rc = RTStrToUInt8Full(RTStrStripL(pcszValue), 10, &aValue); 107 108 145 if (rc == VERR_TRAILING_SPACES) 109 146 rc = VINF_SUCCESS; … … 138 175 139 176 140 int DhcpOption::parseList(std::vector<RTNETADDRIPV4> &aList, const char *pcszValue) 141 { 142 std::vector<RTNETADDRIPV4> l; 143 int rc; 177 int DhcpOption::parse1(DhcpIpv4AddrAndMask &aValue, const char *pcszValue) 178 { 179 return RTCidrStrToIPv4(pcszValue, &aValue.Ipv4, &aValue.Mask); 180 } 181 182 183 template <typename a_Type> 184 static int DhcpOption::parseList(std::vector<a_Type> &aList, const char *pcszValue) 185 { 186 std::vector<a_Type> vecTmp; 144 187 145 188 pcszValue = RTStrStripL(pcszValue); 146 do { 147 RTNETADDRIPV4 Addr; 148 char *pszNext; 149 150 rc = RTNetStrToIPv4AddrEx(pcszValue, &Addr, &pszNext); 151 if (RT_FAILURE(rc)) 189 for (;;) 190 { 191 /* Assume space, tab, comma or semicolon is used as separator (superset of RTStrStrip): */ 192 const char *pszNext = strpbrk(pcszValue, " ,;:\t\n\r"); 193 char szTmp[256]; 194 if (pszNext) 195 { 196 size_t cchToCopy = pszNext - pcszValue; 197 if (cchToCopy >= sizeof(szTmp)) 198 return VERR_INVALID_PARAMETER; 199 memcpy(szTmp, pcszValue, cchToCopy); 200 szTmp[cchToCopy] = '\0'; 201 pcszValue = szTmp; 202 203 /* Advance pszNext past the separator character and fluff: */ 204 char ch; 205 do 206 pszNext++; 207 while ((ch = *pszNext) == ' ' || ch == ':' || ch == ';' || ch == '\t' || ch == '\n' || ch == '\r'); 208 if (ch == '\0') 209 pszNext = NULL; 210 } 211 212 /* Try convert it: */ 213 a_Type Value; 214 int rc = DhcpOption::parse1(Value, pcszValue); 215 if (RT_SUCCESS(rc)) 216 vecTmp.push_back(Value); 217 else 152 218 return VERR_INVALID_PARAMETER; 153 219 154 if (rc == VWRN_TRAILING_CHARS) 220 if (pszNext) 221 pcszValue = pszNext; 222 else 223 break; 224 } 225 226 aList.swap(vecTmp); 227 return VINF_SUCCESS; 228 229 } 230 231 /** ASSUME that uint8_t means hex byte strings. */ 232 template <> 233 static int DhcpOption::parseList(std::vector<uint8_t> &aList, const char *pcszValue) 234 { 235 uint8_t abBuf[256]; 236 const char *pszNext = NULL; 237 size_t cbReturned = 0; 238 int rc = RTStrConvertHexBytesEx(RTStrStripL(pcszValue), abBuf, sizeof(abBuf), RTSTRCONVERTHEXBYTES_F_SEP_COLON, 239 &pszNext, &cbReturned); 240 if (RT_SUCCESS(rc)) 241 { 242 if (pszNext) 243 pszNext = RTStrStripL(pszNext); 244 if (*pszNext) 155 245 { 156 pcszValue = RTStrStripL(pszNext);157 if (pcszValue == pszNext) /* garbage after address */158 return VERR_INVALID_PARAMETER;246 for (size_t i = 0; i < cbReturned; i++) 247 aList.push_back(abBuf[i]); 248 return VINF_SUCCESS; 159 249 } 160 161 l.push_back(Addr); 162 163 /* 164 * If we got VINF_SUCCESS or VWRN_TRAILING_SPACES then this 165 * was the last address and we are done. 166 */ 167 } while (rc == VWRN_TRAILING_CHARS); 168 169 aList.swap(l); 170 return VINF_SUCCESS; 171 } 250 rc = VERR_TRAILING_CHARS; 251 } 252 return rc; 253 } 254 172 255 173 256 … … 208 291 209 292 210 DhcpOption *DhcpOption::parse(uint8_t aOptCode, int aEnc, const char *pcszValue) 211 { 293 DhcpOption *DhcpOption::parse(uint8_t aOptCode, int aEnc, const char *pcszValue, int *prc /*= NULL*/) 294 { 295 int rcIgn; 296 if (!prc) 297 prc = &rcIgn; 298 212 299 switch (aEnc) 213 300 { 214 case 0: /* DhcpOptEncoding_Legacy */ 215 switch (aOptCode) 216 { 217 #define HANDLE(_OptClass) \ 218 case _OptClass::optcode: \ 219 return _OptClass::parse(pcszValue); 220 221 HANDLE(OptSubnetMask); 222 HANDLE(OptRouter); 223 HANDLE(OptDNS); 224 HANDLE(OptHostName); 225 HANDLE(OptDomainName); 226 HANDLE(OptRootPath); 227 HANDLE(OptLeaseTime); 228 HANDLE(OptRenewalTime); 229 HANDLE(OptRebindingTime); 301 case 0: /* DhcpOptEncoding_Legacy */ 302 switch (aOptCode) 303 { 304 #define HANDLE(a_OptClass) \ 305 case a_OptClass::optcode: \ 306 return a_OptClass::parse(pcszValue, prc) 307 308 HANDLE(OptSubnetMask); // 1 309 HANDLE(OptTimeOffset); // 2 310 HANDLE(OptRouters); // 3 311 HANDLE(OptTimeServers); // 4 312 HANDLE(OptNameServers); // 5 313 HANDLE(OptDNSes); // 6 314 HANDLE(OptLogServers); // 7 315 HANDLE(OptCookieServers); // 8 316 HANDLE(OptLPRServers); // 9 317 HANDLE(OptImpressServers); // 10 318 HANDLE(OptResourceLocationServers); // 11 319 HANDLE(OptHostName); // 12 320 HANDLE(OptBootFileSize); // 13 321 HANDLE(OptMeritDumpFile); // 14 322 HANDLE(OptDomainName); // 15 323 HANDLE(OptSwapServer); // 16 324 HANDLE(OptRootPath); // 17 325 HANDLE(OptExtensionPath); // 18 326 HANDLE(OptIPForwarding); // 19 327 HANDLE(OptNonLocalSourceRouting); // 20 328 HANDLE(OptPolicyFilter); // 21 329 HANDLE(OptMaxDatagramReassemblySize); // 22 330 HANDLE(OptDefaultIPTTL); // 23 331 HANDLE(OptDefaultPathMTUAgingTimeout); // 24 332 HANDLE(OptPathMTUPlateauTable); // 25 333 HANDLE(OptInterfaceMTU); // 26 334 HANDLE(OptAllSubnetsAreLocal); // 27 335 HANDLE(OptBroadcastAddress); // 28 336 HANDLE(OptPerformMaskDiscovery); // 29 337 HANDLE(OptMaskSupplier); // 30 338 HANDLE(OptPerformRouterDiscovery); // 31 339 HANDLE(OptRouterSolicitationAddress); // 32 340 HANDLE(OptStaticRoute); // 33 341 HANDLE(OptTrailerEncapsulation); // 34 342 HANDLE(OptARPCacheTimeout); // 35 343 HANDLE(OptEthernetEncapsulation); // 36 344 HANDLE(OptTCPDefaultTTL); // 37 345 HANDLE(OptTCPKeepaliveInterval); // 38 346 HANDLE(OptTCPKeepaliveGarbage); // 39 347 HANDLE(OptNISDomain); // 40 348 HANDLE(OptNISServers); // 41 349 HANDLE(OptNTPServers); // 42 350 HANDLE(OptVendorSpecificInfo); // 43 351 HANDLE(OptNetBIOSNameServers); // 44 352 HANDLE(OptNetBIOSDatagramServers); // 45 353 HANDLE(OptNetBIOSNodeType); // 46 354 HANDLE(OptNetBIOSScope); // 47 355 HANDLE(OptXWindowsFontServers); // 48 356 HANDLE(OptXWindowsDisplayManager); // 49 357 #ifndef IN_VBOXSVC /* Don't allow these in new configs */ 358 // OptRequestedAddress (50) is client only and not configurable. 359 HANDLE(OptLeaseTime); // 51 - for historical reasons? Configuable elsewhere now. 360 // OptOptionOverload (52) is part of the protocol and not configurable. 361 // OptMessageType (53) is part of the protocol and not configurable. 362 // OptServerId (54) is the IP address of the server and configurable elsewhere. 363 // OptParameterRequest (55) is client only and not configurable. 364 // OptMessage (56) is server failure message and not configurable. 365 // OptMaxDHCPMessageSize (57) is client only (?) and not configurable. 366 HANDLE(OptRenewalTime); // 58 - for historical reasons? 367 HANDLE(OptRebindingTime); // 59 - for historical reasons? 368 // OptVendorClassId (60) is client only and not configurable. 369 // OptClientId (61) is client only and not configurable. 370 #endif 371 HANDLE(OptNetWareIPDomainName); // 62 372 HANDLE(OptNetWareIPInformation); // 63 373 HANDLE(OptNISPlusDomain); // 64 374 HANDLE(OptNISPlusServers); // 65 375 HANDLE(OptTFTPServer); // 66 - perhaps we should use an alternative way to configure these. 376 HANDLE(OptBootFileName); // 67 - perhaps we should use an alternative way to configure these. 377 HANDLE(OptMobileIPHomeAgents); // 68 378 HANDLE(OptSMTPServers); // 69 379 HANDLE(OptPOP3Servers); // 70 380 HANDLE(OptNNTPServers); // 71 381 HANDLE(OptWWWServers); // 72 382 HANDLE(OptFingerServers); // 73 383 HANDLE(OptIRCServers); // 74 384 HANDLE(OptStreetTalkServers); // 75 385 HANDLE(OptSTDAServers); // 76 386 // OptUserClassId (77) is client only and not configurable. 387 HANDLE(OptSLPDirectoryAgent); // 78 388 HANDLE(OptSLPServiceScope); // 79 389 // OptRapidCommit (80) is not configurable. 230 390 231 391 #undef HANDLE 392 default: 393 if (prc) 394 *prc = VERR_NOT_IMPLEMENTED; 395 return NULL; 396 } 397 break; 398 399 case 1: 400 return RawOption::parse(aOptCode, pcszValue, prc); 401 232 402 default: 403 if (prc) 404 *prc = VERR_WRONG_TYPE; 233 405 return NULL; 234 } 235 break; 236 237 case 1: 238 return RawOption::parse(aOptCode, pcszValue); 239 240 default: 241 return NULL; 242 } 243 } 406 } 407 }
Note:
See TracChangeset
for help on using the changeset viewer.