Changeset 29834 in vbox
- Timestamp:
- May 27, 2010 9:03:34 AM (15 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/misc/cidr.cpp
r28800 r29834 37 37 38 38 39 /**40 * Scan a digit of an IPv4 address.41 *42 * @returns IPRT status code.43 *44 * @param iDigit The index of the IPv4 digit to scan.45 * @param psz Pointer to the begin of the string.46 * @param ppszNext Pointer to variable that should be set pointing to the first invalid character. (output)47 * @param pu8 Pointer to the digit to write (output).48 */49 static int scanIPv4Digit(int iDigit, const char *psz, char **ppszNext, uint8_t *pu8)50 {51 int rc = RTStrToUInt8Ex(psz, ppszNext, 10, pu8);52 if ( ( rc != VINF_SUCCESS53 && rc != VWRN_TRAILING_CHARS)54 || *pu8 > 254)55 return VERR_INVALID_PARAMETER;56 57 /* first digit cannot be 0 */58 if ( iDigit == 159 && *pu8 < 1)60 return VERR_INVALID_PARAMETER;61 62 if (**ppszNext == '/')63 return VINF_SUCCESS;64 65 if ( iDigit != 466 && ( **ppszNext == '\0'67 || **ppszNext != '.'))68 return VERR_INVALID_PARAMETER;69 70 return VINF_SUCCESS;71 }72 73 74 39 RTDECL(int) RTCidrStrToIPv4(const char *pszAddress, PRTIPV4ADDR pNetwork, PRTIPV4ADDR pNetmask) 75 40 { 76 41 uint8_t cBits; 77 uint8_t a; 78 uint8_t b = 0; 79 uint8_t c = 0; 80 uint8_t d = 0; 42 uint8_t addr[4]; 43 uint32_t u32Netmask; 44 uint32_t u32Network; 81 45 const char *psz = pszAddress; 82 46 char *pszNext; 83 int rc; 84 85 do 86 { 87 /* 1st digit */ 88 rc = scanIPv4Digit(1, psz, &pszNext, &a); 89 if (RT_FAILURE(rc)) 90 return rc; 91 if (*pszNext == '/') 92 break; 93 psz = pszNext + 1; 94 95 /* 2nd digit */ 96 rc = scanIPv4Digit(2, psz, &pszNext, &b); 97 if (RT_FAILURE(rc)) 98 return rc; 99 if (*pszNext == '/') 100 break; 101 psz = pszNext + 1; 102 103 /* 3rd digit */ 104 rc = scanIPv4Digit(3, psz, &pszNext, &c); 105 if (RT_FAILURE(rc)) 106 return rc; 107 if (*pszNext == '/') 108 break; 109 psz = pszNext + 1; 110 111 /* 4th digit */ 112 rc = scanIPv4Digit(4, psz, &pszNext, &d); 113 if (RT_FAILURE(rc)) 114 return rc; 115 } while (0); 116 117 if (*pszNext == '/') 118 { 119 psz = pszNext + 1; 120 rc = RTStrToUInt8Ex(psz, &pszNext, 10, &cBits); 121 if (rc != VINF_SUCCESS || cBits < 8 || cBits > 28) 47 int rc = VINF_SUCCESS; 48 int cDelimiter = 0; 49 int cDelimiterLimit = 0; 50 if ( pszAddress == NULL 51 || pNetwork == NULL 52 || pNetmask == NULL) 53 return VERR_INVALID_PARAMETER; 54 char *pszNetmask = RTStrStr(psz, "/"); 55 *(uint32_t *)addr = 0; 56 if (pszNetmask == NULL) 57 cBits = 0; 58 else 59 { 60 rc = RTStrToUInt8Ex(pszNetmask + 1, &pszNext, 10, &cBits); 61 if ( RT_FAILURE(rc) 62 || cBits > 32 63 || rc != 0) /* No trailing symbols are accptable after the digit */ 122 64 return VERR_INVALID_PARAMETER; 123 65 } 124 else 125 cBits = 0; 66 u32Netmask = ~(uint32_t)((1<< (32 - cBits)) - 1); 126 67 127 for (psz = pszNext; RT_C_IS_SPACE(*psz); psz++) 128 /* nothing */; 129 if (*psz != '\0') 68 rc = RTStrToUInt8Ex(psz, &pszNext, 10, &addr[0]); 69 if (RT_FAILURE(rc)) 70 return rc; 71 72 if (cBits < 9) 73 cDelimiterLimit = 0; 74 else if (cBits < 16) 75 cDelimiterLimit = 1; 76 else if (cBits < 25) 77 cDelimiterLimit = 2; 78 else if (cBits <= 32) 79 cDelimiterLimit = 3; 80 81 rc = RTStrToUInt8Ex(psz, &pszNext, 10, &addr[cDelimiter]); 82 while (RT_SUCCESS(rc)) 83 { 84 if (*pszNext == '.') 85 cDelimiter++; 86 else if(cDelimiter >= cDelimiterLimit) 87 break; 88 else 89 return VERR_INVALID_PARAMETER; 90 rc = RTStrToUInt8Ex(pszNext + 1, &pszNext, 10, &addr[cDelimiter]); 91 if (rc == VWRN_NUMBER_TOO_BIG) 92 break; 93 } 94 if ( RT_FAILURE(rc) 95 || rc == VWRN_NUMBER_TOO_BIG) 96 return VERR_INVALID_PARAMETER; 97 u32Network = RT_MAKE_U32_FROM_U8(addr[3], addr[2], addr[1], addr[0]); 98 /* corner case: see rfc 790 page 2 and rfc 4632 page 6*/ 99 if ( addr[0] == 0 100 && ( *(uint32_t *)addr != 0 101 || u32Netmask == (uint32_t)~0)) 130 102 return VERR_INVALID_PARAMETER; 131 103 132 *pNetwork = RT_MAKE_U32_FROM_U8(d, c, b, a); 133 *pNetmask = ~(((uint32_t)1 << (32 - cBits)) - 1); 104 if ((u32Network & ~u32Netmask) != 0) 105 return VERR_INVALID_PARAMETER; 106 107 *pNetmask = u32Netmask; 108 *pNetwork = u32Network; 134 109 return VINF_SUCCESS; 135 110 } -
trunk/src/VBox/Runtime/testcase/tstRTCidr.cpp
r28800 r29834 67 67 RTTestBanner(hTest); 68 68 69 CHECKNETWORK("10.0.0/45", VERR_INVALID_PARAMETER, 0, 0); 70 CHECKNETWORK("10.0.0/-45", VERR_INVALID_PARAMETER, 0, 0); 69 71 CHECKNETWORK("10.0.0/24", VINF_SUCCESS, 0x0A000000, 0xFFFFFF00); 70 72 CHECKNETWORK("10.0.0/8", VINF_SUCCESS, 0x0A000000, 0xFF000000); 71 73 CHECKNETWORK("10.0.0./24", VERR_INVALID_PARAMETER, 0, 0); 72 74 CHECKNETWORK("0.1.0/24", VERR_INVALID_PARAMETER, 0, 0); 73 CHECKNETWORK("10.255.0.0/24", VERR_INVALID_PARAMETER, 0, 0); 75 /* vvl: (changed exp to VINF_SUCCESS) according to rfc 4632 s3.1: n.n.n.0/24, where n is an 8-bit decimal octet value*/ 76 CHECKNETWORK("10.255.0.0/24", VINF_SUCCESS, 0x0AFF0000, 0xFFFFFF00); 74 77 CHECKNETWORK("10.1234.0.0/24", VERR_INVALID_PARAMETER, 0, 0); 75 78 CHECKNETWORK("10.256.0.0/24", VERR_INVALID_PARAMETER, 0, 0); 76 79 CHECKNETWORK("10.0.0/3", VERR_INVALID_PARAMETER, 0, 0); 77 CHECKNETWORK("10.1.2.3/8", VINF_SUCCESS, 0x0A010203, 0xFF000000); 80 /* vvl: (changed exp to VERR_INVALID_PARAMETER) according to rfc 4632 s3.1: legacy "Class A" is n.0.0.0/8 */ 81 CHECKNETWORK("10.1.2.3/8", VERR_INVALID_PARAMETER, 0, 0); 82 CHECKNETWORK("10.1.2.4/30", VINF_SUCCESS, 0x0A010204, 0xFFFFFFFC); 78 83 CHECKNETWORK("10.0.0/29", VERR_INVALID_PARAMETER, 0, 0); 79 84 CHECKNETWORK("10.0.0/240", VERR_INVALID_PARAMETER, 0, 0); 80 85 CHECKNETWORK("10.0.0/24.", VERR_INVALID_PARAMETER, 0, 0); 81 CHECKNETWORK("10.1.2/16", VINF_SUCCESS, 0x0A010200, 0xFFFF0000); 86 /* vvl: (changed exp to VERR_INVALID_PARAMETER) according to rfc 4632 s3.1: legacy "Class B" is n.n.0.0/16 */ 87 CHECKNETWORK("10.1.2/16", VERR_INVALID_PARAMETER, 0, 0); 82 88 CHECKNETWORK("1.2.3.4", VINF_SUCCESS, 0x01020304, 0xFFFFFFFF); 89 CHECKNETWORK("10.1.255/24", VINF_SUCCESS, 0x0A01FF00, 0xFFFFFF00); 90 CHECKNETWORK("10.1.254/24", VINF_SUCCESS, 0x0A01FE00, 0xFFFFFF00); 91 CHECKNETWORK("10.255.1/24", VINF_SUCCESS, 0x0AFF0100, 0xFFFFFF00); 83 92 84 93 return RTTestSummaryAndDestroy(hTest);
Note:
See TracChangeset
for help on using the changeset viewer.