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