Changeset a8196c9 in mainline
- Timestamp:
- 2013-06-27T12:08:23Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4fb794c
- Parents:
- 66cb7a2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/net/inet.c
r66cb7a2 ra8196c9 45 45 #include <str.h> 46 46 47 static int inet_ntop4(const uint8_t *data, char *address, size_t length) 48 { 49 /* Check output buffer size */ 50 if (length < INET_ADDRSTRLEN) 51 return ENOMEM; 52 53 /* Fill buffer with IPv4 address */ 54 snprintf(address, length, 55 "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8, 56 data[0], data[1], data[2], data[3]); 57 58 return EOK; 59 } 60 61 static int inet_ntop6(const uint8_t *data, char *address, size_t length) 62 { 63 /* Check output buffer size */ 64 if (length < INET6_ADDRSTRLEN) 65 return ENOMEM; 66 67 /* Find the longest zero subsequence */ 68 69 uint16_t zeroes[8]; 70 uint16_t bioctets[8]; 71 72 for (size_t i = 8; i > 0; i--) { 73 size_t j = i - 1; 74 75 bioctets[j] = (data[j << 1] << 8) | data[(j << 1) + 1]; 76 77 if (bioctets[j] == 0) { 78 zeroes[j] = 1; 79 if (j < 7) 80 zeroes[j] += zeroes[j + 1]; 81 } else 82 zeroes[j] = 0; 83 } 84 85 size_t wildcard_pos = (size_t) -1; 86 size_t wildcard_size = 0; 87 88 for (size_t i = 0; i < 8; i++) { 89 if (zeroes[i] > wildcard_size) { 90 wildcard_pos = i; 91 wildcard_size = zeroes[i]; 92 } 93 } 94 95 char *cur = address; 96 size_t rest = length; 97 bool tail_zero = false; 98 int ret; 99 100 for (size_t i = 0; i < 8; i++) { 101 if ((i == wildcard_pos) && (wildcard_size > 1)) { 102 ret = snprintf(cur, rest, ":"); 103 i += wildcard_size - 1; 104 tail_zero = true; 105 } else if (i == 0) { 106 ret = snprintf(cur, rest, "%" PRIx16, bioctets[i]); 107 tail_zero = false; 108 } else { 109 ret = snprintf(cur, rest, ":%" PRIx16, bioctets[i]); 110 tail_zero = false; 111 } 112 113 if (ret < 0) 114 return EINVAL; 115 116 cur += ret; 117 rest -= ret; 118 } 119 120 if (tail_zero) { 121 ret = snprintf(cur, rest, ":"); 122 if (ret < 0) 123 return EINVAL; 124 } 125 126 return EOK; 127 } 128 47 129 /** Prints the address into the character buffer. 48 130 * 49 * @param[in] family The address family. 50 * @param[in] data The address data. 51 * @param[out] address The character buffer to be filled. 52 * @param[in] length The buffer length. 53 * @return EOK on success. 54 * @return EINVAL if the data or address parameter is NULL. 55 * @return ENOMEM if the character buffer is not long enough. 56 * @return ENOTSUP if the address family is not supported. 57 */ 58 int 59 inet_ntop(uint16_t family, const uint8_t *data, char *address, size_t length) 60 { 61 if ((!data) || (!address)) 62 return EINVAL; 63 131 * @param[in] family Address family. 132 * @param[in] data Address data. 133 * @param[out] address Character buffer to be filled. 134 * @param[in] length Buffer length. 135 * 136 * @return EOK on success. 137 * @return EINVAL if the data or address parameter is NULL. 138 * @return ENOMEM if the character buffer is not long enough. 139 * @return ENOTSUP if the address family is not supported. 140 * 141 */ 142 int inet_ntop(uint16_t family, const uint8_t *data, char *address, size_t length) 143 { 64 144 switch (family) { 65 145 case AF_INET: 66 /* Check output buffer size */ 67 if (length < INET_ADDRSTRLEN) 68 return ENOMEM; 69 70 /* Fill buffer with IPv4 address */ 71 snprintf(address, length, "%hhu.%hhu.%hhu.%hhu", 72 data[0], data[1], data[2], data[3]); 73 74 return EOK; 75 146 return inet_ntop4(data, address, length); 76 147 case AF_INET6: 77 /* Check output buffer size */ 78 if (length < INET6_ADDRSTRLEN) 79 return ENOMEM; 80 81 /* Fill buffer with IPv6 address */ 82 snprintf(address, length, 83 "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:" 84 "%hhx%hhx:%hhx%hhx", 85 data[0], data[1], data[2], data[3], data[4], data[5], 86 data[6], data[7], data[8], data[9], data[10], data[11], 87 data[12], data[13], data[14], data[15]); 88 89 return EOK; 90 148 return inet_ntop6(data, address, length); 91 149 default: 92 150 return ENOTSUP; … … 126 184 static int inet_pton6(const char *address, uint8_t *data) 127 185 { 128 // FIXME TODO 129 return ENOTSUP; 186 memset(data, 0, 16); 187 188 const char *cur = address; 189 size_t i = 0; 190 size_t wildcard_pos = (size_t) -1; 191 size_t wildcard_size = 0; 192 193 /* Handle initial wildcard */ 194 if ((address[0] == ':') && (address[1] == ':')) { 195 cur = address + 2; 196 wildcard_pos = 0; 197 wildcard_size = 16; 198 199 /* Handle empty address */ 200 if (*cur == 0) 201 return EOK; 202 } 203 204 while (i < 16) { 205 uint16_t bioctet; 206 int rc = str_uint16_t(cur, &cur, 16, false, &bioctet); 207 if (rc != EOK) 208 return rc; 209 210 data[i] = (bioctet >> 8) & 0xff; 211 data[i + 1] = bioctet & 0xff; 212 213 if (wildcard_pos != (size_t) -1) { 214 if (wildcard_size < 2) 215 return EINVAL; 216 217 wildcard_size -= 2; 218 } 219 220 i += 2; 221 222 if (*cur == 0) 223 break; 224 225 if (*cur != ':') 226 return EINVAL; 227 228 if (i < 16) { 229 cur++; 230 231 /* Handle wildcard */ 232 if (*cur == ':') { 233 if (wildcard_pos != (size_t) -1) 234 return EINVAL; 235 236 wildcard_pos = i; 237 wildcard_size = 16 - i; 238 cur++; 239 240 if (*cur == 0) 241 break; 242 } 243 } 244 } 245 246 if ((i == 16) && (*cur != 0)) 247 return EINVAL; 248 249 /* Create wildcard positions */ 250 if ((wildcard_pos != (size_t) -1) && (wildcard_size > 0)) { 251 size_t wildcard_shift = 16 - wildcard_size; 252 253 for (i = wildcard_pos + wildcard_shift; i > wildcard_pos; i--) { 254 size_t j = i - 1; 255 data[j + wildcard_size] = data[j]; 256 data[j] = 0; 257 } 258 } 259 260 return EOK; 130 261 } 131 262
Note:
See TracChangeset
for help on using the changeset viewer.