Changes in uspace/lib/c/generic/inet/addr.c [3495654:02a09ed] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/inet/addr.c
r3495654 r02a09ed 34 34 35 35 #include <errno.h> 36 #include <unistd.h> 37 #include <net/socket_codes.h> 36 38 #include <inet/addr.h> 39 #include <net/inet.h> 37 40 #include <stdio.h> 41 #include <malloc.h> 42 #include <bitops.h> 43 44 #define INET_PREFIXSTRSIZE 5 45 46 #if !(defined(__BE__) ^ defined(__LE__)) 47 #error The architecture must be either big-endian or little-endian. 48 #endif 49 50 const addr48_t addr48_broadcast = { 51 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 52 }; 53 54 static const inet_addr_t inet_addr_any_addr = { 55 .family = AF_INET, 56 .addr = 0 57 }; 58 59 static const inet_addr_t inet_addr_any_addr6 = { 60 .family = AF_INET6, 61 .addr6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 62 }; 63 64 void addr48(const addr48_t src, addr48_t dst) 65 { 66 memcpy(dst, src, 6); 67 } 68 69 void addr128(const addr128_t src, addr128_t dst) 70 { 71 memcpy(dst, src, 16); 72 } 73 74 void host2addr128_t_be(const addr128_t host, addr128_t be) 75 { 76 #ifdef __BE__ 77 memcpy(be, host, 16); 78 #else 79 be[0] = host[15]; 80 be[1] = host[14]; 81 be[2] = host[13]; 82 be[3] = host[12]; 83 be[4] = host[11]; 84 be[5] = host[10]; 85 be[6] = host[9]; 86 be[7] = host[8]; 87 be[8] = host[7]; 88 be[9] = host[6]; 89 be[10] = host[5]; 90 be[11] = host[4]; 91 be[12] = host[3]; 92 be[13] = host[2]; 93 be[14] = host[1]; 94 be[15] = host[0]; 95 #endif 96 } 97 98 void addr128_t_be2host(const addr128_t be, addr128_t host) 99 { 100 #ifdef __BE__ 101 memcpy(host, be, 16); 102 #else 103 host[0] = be[15]; 104 host[1] = be[14]; 105 host[2] = be[13]; 106 host[3] = be[12]; 107 host[4] = be[11]; 108 host[5] = be[10]; 109 host[6] = be[9]; 110 host[7] = be[8]; 111 host[8] = be[7]; 112 host[9] = be[6]; 113 host[10] = be[5]; 114 host[11] = be[4]; 115 host[12] = be[3]; 116 host[13] = be[2]; 117 host[14] = be[1]; 118 host[15] = be[0]; 119 #endif 120 } 121 122 void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d) 123 { 124 addr->family = AF_INET; 125 addr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) | 126 ((addr32_t) c << 8) | ((addr32_t) d); 127 } 128 129 void inet_naddr(inet_naddr_t *naddr, uint8_t a, uint8_t b, uint8_t c, uint8_t d, 130 uint8_t prefix) 131 { 132 naddr->family = AF_INET; 133 naddr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) | 134 ((addr32_t) c << 8) | ((addr32_t) d); 135 naddr->prefix = prefix; 136 } 137 138 void inet_addr6(inet_addr_t *addr, uint16_t a, uint16_t b, uint16_t c, 139 uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h) 140 { 141 addr->family = AF_INET6; 142 addr->addr6[0] = (a >> 8) & 0xff; 143 addr->addr6[1] = a & 0xff; 144 addr->addr6[2] = (b >> 8) & 0xff; 145 addr->addr6[3] = b & 0xff; 146 addr->addr6[4] = (c >> 8) & 0xff; 147 addr->addr6[5] = c & 0xff; 148 addr->addr6[6] = (d >> 8) & 0xff; 149 addr->addr6[7] = d & 0xff; 150 addr->addr6[8] = (e >> 8) & 0xff; 151 addr->addr6[9] = e & 0xff; 152 addr->addr6[10] = (f >> 8) & 0xff; 153 addr->addr6[11] = f & 0xff; 154 addr->addr6[12] = (g >> 8) & 0xff; 155 addr->addr6[13] = g & 0xff; 156 addr->addr6[14] = (h >> 8) & 0xff; 157 addr->addr6[15] = h & 0xff; 158 } 159 160 void inet_naddr6(inet_naddr_t *naddr, uint16_t a, uint16_t b, uint16_t c, 161 uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h, uint8_t prefix) 162 { 163 naddr->family = AF_INET6; 164 naddr->addr6[0] = (a >> 8) & 0xff; 165 naddr->addr6[1] = a & 0xff; 166 naddr->addr6[2] = (b >> 8) & 0xff; 167 naddr->addr6[3] = b & 0xff; 168 naddr->addr6[4] = (c >> 8) & 0xff; 169 naddr->addr6[5] = c & 0xff; 170 naddr->addr6[6] = (d >> 8) & 0xff; 171 naddr->addr6[7] = d & 0xff; 172 naddr->addr6[8] = (e >> 8) & 0xff; 173 naddr->addr6[9] = e & 0xff; 174 naddr->addr6[10] = (f >> 8) & 0xff; 175 naddr->addr6[11] = f & 0xff; 176 naddr->addr6[12] = (g >> 8) & 0xff; 177 naddr->addr6[13] = g & 0xff; 178 naddr->addr6[14] = (h >> 8) & 0xff; 179 naddr->addr6[15] = h & 0xff; 180 naddr->prefix = prefix; 181 } 182 183 /** Parse network address family. 184 * 185 * @param text Network address in common notation. 186 * @param af Place to store network address family. 187 * 188 * @return EOK on success, EINVAL if input is not in valid format. 189 * 190 */ 191 int inet_addr_family(const char *text, uint16_t *af) 192 { 193 char *dot = str_chr(text, '.'); 194 if (dot != NULL) { 195 *af = AF_INET; 196 return EOK; 197 } 198 199 char *collon = str_chr(text, ':'); 200 if (collon != NULL) { 201 *af = AF_INET6; 202 return EOK; 203 } 204 205 return EINVAL; 206 } 207 208 void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr) 209 { 210 addr->family = naddr->family; 211 memcpy(addr->addr6, naddr->addr6, 16); 212 } 213 214 void inet_addr_any(inet_addr_t *addr) 215 { 216 addr->family = AF_NONE; 217 memset(addr->addr6, 0, 16); 218 } 219 220 void inet_naddr_any(inet_naddr_t *naddr) 221 { 222 naddr->family = AF_NONE; 223 memset(naddr->addr6, 0, 16); 224 naddr->prefix = 0; 225 } 226 227 int inet_addr_compare(const inet_addr_t *a, const inet_addr_t *b) 228 { 229 if (a->family != b->family) 230 return 0; 231 232 switch (a->family) { 233 case AF_INET: 234 return (a->addr == b->addr); 235 case AF_INET6: 236 return memcmp(&a->addr6, &b->addr6, 16); 237 default: 238 return 0; 239 } 240 } 241 242 int inet_addr_is_any(const inet_addr_t *addr) 243 { 244 return ((addr->family == 0) || 245 (inet_addr_compare(addr, &inet_addr_any_addr)) || 246 (inet_addr_compare(addr, &inet_addr_any_addr6))); 247 } 248 249 int inet_naddr_compare_mask(const inet_naddr_t *naddr, const inet_addr_t *addr) 250 { 251 if (naddr->family != addr->family) 252 return 0; 253 254 switch (naddr->family) { 255 case AF_INET: 256 if (naddr->prefix > 32) 257 return 0; 258 259 addr32_t mask = 260 BIT_RANGE(addr32_t, 31, 31 - (naddr->prefix - 1)); 261 return ((naddr->addr & mask) == (addr->addr & mask)); 262 case AF_INET6: 263 if (naddr->prefix > 128) 264 return 0; 265 266 size_t pos = 0; 267 for (size_t i = 0; i < 16; i++) { 268 /* Further bits do not matter */ 269 if (naddr->prefix < pos) 270 break; 271 272 if (naddr->prefix - pos > 8) { 273 /* Comparison without masking */ 274 if (naddr->addr6[i] != addr->addr6[i]) 275 return 0; 276 } else { 277 /* Comparison with masking */ 278 uint8_t mask = 279 BIT_RANGE(uint8_t, 8, 8 - (naddr->prefix - pos - 1)); 280 if ((naddr->addr6[i] & mask) != (addr->addr6[i] & mask)) 281 return 0; 282 } 283 284 pos += 8; 285 } 286 287 return 1; 288 default: 289 return 0; 290 } 291 } 292 293 /** Parse node address. 294 * 295 * @param text Network address in common notation. 296 * @param addr Place to store node address. 297 * 298 * @return EOK on success, EINVAL if input is not in valid format. 299 * 300 */ 301 int inet_addr_parse(const char *text, inet_addr_t *addr) 302 { 303 int rc = inet_addr_family(text, &addr->family); 304 if (rc != EOK) 305 return rc; 306 307 uint8_t buf[16]; 308 rc = inet_pton(addr->family, text, buf); 309 if (rc != EOK) 310 return rc; 311 312 switch (addr->family) { 313 case AF_INET: 314 addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | 315 buf[3]; 316 break; 317 case AF_INET6: 318 memcpy(addr->addr6, buf, 16); 319 break; 320 default: 321 return EINVAL; 322 } 323 324 return EOK; 325 } 38 326 39 327 /** Parse network address. 40 328 * 41 * @param text Network address in CIDR notation (a.b.c.d/w) 42 * @param naddr Place to store network address 43 * 44 * @return EOK on success, EINVAL if input is not in valid format 329 * @param text Network address in common notation. 330 * @param naddr Place to store network address. 331 * 332 * @return EOK on success, EINVAL if input is not in valid format. 333 * 45 334 */ 46 335 int inet_naddr_parse(const char *text, inet_naddr_t *naddr) 47 336 { 48 unsigned long a[4], bits; 49 char *cp = (char *)text; 50 int i; 51 52 for (i = 0; i < 3; i++) { 53 a[i] = strtoul(cp, &cp, 10); 54 if (*cp != '.') 337 char *slash = str_chr(text, '/'); 338 if (slash == NULL) 339 return EINVAL; 340 341 *slash = 0; 342 343 int rc = inet_addr_family(text, &naddr->family); 344 if (rc != EOK) 345 return rc; 346 347 uint8_t buf[16]; 348 rc = inet_pton(naddr->family, text, buf); 349 *slash = '/'; 350 351 if (rc != EOK) 352 return rc; 353 354 slash++; 355 uint8_t prefix; 356 357 switch (naddr->family) { 358 case AF_INET: 359 prefix = strtoul(slash, &slash, 10); 360 if (prefix > 32) 55 361 return EINVAL; 56 ++cp; 57 } 58 59 a[3] = strtoul(cp, &cp, 10); 60 if (*cp != '/') 61 return EINVAL; 62 ++cp; 63 64 bits = strtoul(cp, &cp, 10); 65 if (*cp != '\0') 66 return EINVAL; 67 68 naddr->ipv4 = 0; 69 for (i = 0; i < 4; i++) { 70 if (a[i] > 255) 362 363 naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | 364 buf[3]; 365 naddr->prefix = prefix; 366 367 break; 368 case AF_INET6: 369 prefix = strtoul(slash, &slash, 10); 370 if (prefix > 128) 71 371 return EINVAL; 72 naddr->ipv4 = (naddr->ipv4 << 8) | a[i]; 73 } 74 75 if (bits > 31) 76 return EINVAL; 77 78 naddr->bits = bits; 372 373 memcpy(naddr->addr6, buf, 16); 374 naddr->prefix = prefix; 375 376 break; 377 default: 378 return ENOTSUP; 379 } 380 79 381 return EOK; 80 382 } 81 383 82 /** Parse node address. 83 * 84 * @param text Network address in dot notation (a.b.c.d) 85 * @param addr Place to store node address 86 * 87 * @return EOK on success, EINVAL if input is not in valid format 88 */ 89 int inet_addr_parse(const char *text, inet_addr_t *addr) 90 { 91 unsigned long a[4]; 92 char *cp = (char *)text; 93 int i; 94 95 for (i = 0; i < 3; i++) { 96 a[i] = strtoul(cp, &cp, 10); 97 if (*cp != '.') 98 return EINVAL; 99 ++cp; 100 } 101 102 a[3] = strtoul(cp, &cp, 10); 103 if (*cp != '\0') 104 return EINVAL; 105 106 addr->ipv4 = 0; 107 for (i = 0; i < 4; i++) { 108 if (a[i] > 255) 109 return EINVAL; 110 addr->ipv4 = (addr->ipv4 << 8) | a[i]; 111 } 112 113 return EOK; 114 } 115 116 /** Format network address. 117 * 118 * @param naddr Network address 119 * @param bufp Place to store pointer to formatted string (CIDR notation) 120 * 121 * @return EOK on success, ENOMEM if out of memory. 122 */ 123 int inet_naddr_format(inet_naddr_t *naddr, char **bufp) 124 { 125 int rc; 126 127 rc = asprintf(bufp, "%d.%d.%d.%d/%d", naddr->ipv4 >> 24, 128 (naddr->ipv4 >> 16) & 0xff, (naddr->ipv4 >> 8) & 0xff, 129 naddr->ipv4 & 0xff, naddr->bits); 130 384 /** Format node address. 385 * 386 * @param addr Node address. 387 * @param bufp Place to store pointer to formatted string. 388 * 389 * @return EOK on success. 390 * @return ENOMEM if out of memory. 391 * @return ENOTSUP on unsupported address family. 392 * 393 */ 394 int inet_addr_format(const inet_addr_t *addr, char **bufp) 395 { 396 int rc = 0; 397 398 switch (addr->family) { 399 case AF_NONE: 400 rc = asprintf(bufp, "none"); 401 break; 402 case AF_INET: 403 rc = asprintf(bufp, "%u.%u.%u.%u", (addr->addr >> 24) & 0xff, 404 (addr->addr >> 16) & 0xff, (addr->addr >> 8) & 0xff, 405 addr->addr & 0xff); 406 break; 407 case AF_INET6: 408 *bufp = (char *) malloc(INET6_ADDRSTRLEN); 409 if (*bufp == NULL) 410 return ENOMEM; 411 412 return inet_ntop(AF_INET6, addr->addr6, *bufp, INET6_ADDRSTRLEN); 413 default: 414 return ENOTSUP; 415 } 416 131 417 if (rc < 0) 132 418 return ENOMEM; 133 419 134 420 return EOK; 135 421 } 136 422 137 /** Format node address. 138 * 139 * @param addr Node address 140 * @param bufp Place to store pointer to formatted string (dot notation) 141 * 142 * @return EOK on success, ENOMEM if out of memory. 143 */ 144 int inet_addr_format(inet_addr_t *addr, char **bufp) 145 { 146 int rc; 147 148 rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24, 149 (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff, 150 addr->ipv4 & 0xff); 151 423 /** Format network address. 424 * 425 * @param naddr Network address. 426 * @param bufp Place to store pointer to formatted string. 427 * 428 * @return EOK on success. 429 * @return ENOMEM if out of memory. 430 * @return ENOTSUP on unsupported address family. 431 * 432 */ 433 int inet_naddr_format(const inet_naddr_t *naddr, char **bufp) 434 { 435 int rc = 0; 436 char prefix[INET_PREFIXSTRSIZE]; 437 438 switch (naddr->family) { 439 case AF_NONE: 440 rc = asprintf(bufp, "none"); 441 break; 442 case AF_INET: 443 rc = asprintf(bufp, "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 444 "/%" PRIu8, (naddr->addr >> 24) & 0xff, 445 (naddr->addr >> 16) & 0xff, (naddr->addr >> 8) & 0xff, 446 naddr->addr & 0xff, naddr->prefix); 447 break; 448 case AF_INET6: 449 *bufp = (char *) malloc(INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE); 450 if (*bufp == NULL) 451 return ENOMEM; 452 453 rc = inet_ntop(AF_INET6, naddr->addr6, *bufp, 454 INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE); 455 if (rc != EOK) { 456 free(*bufp); 457 return rc; 458 } 459 460 rc = snprintf(prefix, INET_PREFIXSTRSIZE, "/%" PRIu8, 461 naddr->prefix); 462 if (rc < 0) { 463 free(*bufp); 464 return ENOMEM; 465 } 466 467 str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix); 468 469 break; 470 default: 471 return ENOTSUP; 472 } 473 152 474 if (rc < 0) 153 475 return ENOMEM; 154 476 155 477 return EOK; 156 478 } 157 479 480 uint16_t inet_addr_get(const inet_addr_t *addr, addr32_t *v4, addr128_t *v6) 481 { 482 switch (addr->family) { 483 case AF_INET: 484 if (v4 != NULL) 485 *v4 = addr->addr; 486 487 break; 488 case AF_INET6: 489 if (v6 != NULL) 490 memcpy(*v6, addr->addr6, 16); 491 492 break; 493 } 494 495 return addr->family; 496 } 497 498 uint16_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6, 499 uint8_t *prefix) 500 { 501 switch (naddr->family) { 502 case AF_INET: 503 if (v4 != NULL) 504 *v4 = naddr->addr; 505 506 if (prefix != NULL) 507 *prefix = naddr->prefix; 508 509 break; 510 case AF_INET6: 511 if (v6 != NULL) 512 memcpy(*v6, naddr->addr6, 16); 513 514 if (prefix != NULL) 515 *prefix = naddr->prefix; 516 517 break; 518 } 519 520 return naddr->family; 521 } 522 523 void inet_addr_set(addr32_t v4, inet_addr_t *addr) 524 { 525 addr->family = AF_INET; 526 addr->addr = v4; 527 } 528 529 void inet_naddr_set(addr32_t v4, uint8_t prefix, inet_naddr_t *naddr) 530 { 531 naddr->family = AF_INET; 532 naddr->addr = v4; 533 naddr->prefix = prefix; 534 } 535 536 void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr) 537 { 538 addr->family = AF_INET; 539 addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr); 540 } 541 542 void inet_addr_set6(addr128_t v6, inet_addr_t *addr) 543 { 544 addr->family = AF_INET6; 545 memcpy(addr->addr6, v6, 16); 546 } 547 548 void inet_naddr_set6(addr128_t v6, uint8_t prefix, inet_naddr_t *naddr) 549 { 550 naddr->family = AF_INET6; 551 memcpy(naddr->addr6, v6, 16); 552 naddr->prefix = prefix; 553 } 554 555 void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6, 556 inet_addr_t *addr) 557 { 558 addr->family = AF_INET6; 559 addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6); 560 } 561 562 uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr, 563 sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6) 564 { 565 switch (addr->family) { 566 case AF_INET: 567 if (sockaddr_in != NULL) { 568 sockaddr_in->sin_family = AF_INET; 569 sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr); 570 } 571 572 break; 573 case AF_INET6: 574 if (sockaddr_in6 != NULL) { 575 sockaddr_in6->sin6_family = AF_INET6; 576 host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr); 577 } 578 579 break; 580 } 581 582 return addr->family; 583 } 584 158 585 /** @} 159 586 */
Note:
See TracChangeset
for help on using the changeset viewer.