Changeset 02a09ed in mainline for uspace/lib/c/generic/inet/addr.c
- Timestamp:
- 2013-06-28T20:20:03Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1d24ad3
- Parents:
- edf0d27
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/inet/addr.c
redf0d27 r02a09ed 39 39 #include <net/inet.h> 40 40 #include <stdio.h> 41 42 static inet_addr_t inet_addr_any_addr = { 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 = { 43 55 .family = AF_INET, 44 .addr = {0, 0, 0, 0}56 .addr = 0 45 57 }; 46 58 47 static inet_addr_t inet_addr_any_addr6 = {59 static const inet_addr_t inet_addr_any_addr6 = { 48 60 .family = AF_INET6, 49 .addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}61 .addr6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 50 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 } 51 182 52 183 /** Parse network address family. … … 72 203 } 73 204 74 *af = AF_NONE;75 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 } 76 291 } 77 292 … … 90 305 return rc; 91 306 92 rc = inet_pton(addr->family, text, addr->addr); 307 uint8_t buf[16]; 308 rc = inet_pton(addr->family, text, buf); 93 309 if (rc != EOK) 94 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 } 95 323 96 324 return EOK; … … 117 345 return rc; 118 346 119 rc = inet_pton(naddr->family, text, naddr->addr); 347 uint8_t buf[16]; 348 rc = inet_pton(naddr->family, text, buf); 120 349 *slash = '/'; 121 350 … … 124 353 125 354 slash++; 355 uint8_t prefix; 126 356 127 357 switch (naddr->family) { 128 358 case AF_INET: 129 naddr->prefix = strtoul(slash, &slash, 10);130 if ( naddr->prefix > 32)359 prefix = strtoul(slash, &slash, 10); 360 if (prefix > 32) 131 361 return EINVAL; 132 break; 133 case AF_INET6: 134 naddr->prefix = strtoul(slash, &slash, 10); 135 if (naddr->prefix > 128) 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) 136 371 return EINVAL; 372 373 memcpy(naddr->addr6, buf, 16); 374 naddr->prefix = prefix; 375 137 376 break; 138 377 default: … … 153 392 * 154 393 */ 155 int inet_addr_format( inet_addr_t *addr, char **bufp)156 { 157 int rc ;394 int inet_addr_format(const inet_addr_t *addr, char **bufp) 395 { 396 int rc = 0; 158 397 159 398 switch (addr->family) { … … 162 401 break; 163 402 case AF_INET: 164 rc = asprintf(bufp, "%u.%u.%u.%u", addr->addr[0], 165 addr->addr[1], addr->addr[2], addr->addr[3]); 166 break; 167 case AF_INET6: 168 // FIXME TODO 169 return ENOTSUP; 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); 170 413 default: 171 414 return ENOTSUP; … … 188 431 * 189 432 */ 190 int inet_naddr_format(inet_naddr_t *naddr, char **bufp) 191 { 192 int rc; 433 int inet_naddr_format(const inet_naddr_t *naddr, char **bufp) 434 { 435 int rc = 0; 436 char prefix[INET_PREFIXSTRSIZE]; 193 437 194 438 switch (naddr->family) { … … 197 441 break; 198 442 case AF_INET: 199 rc = asprintf(bufp, "%u.%u.%u.%u/%u", naddr->addr[0], 200 naddr->addr[1], naddr->addr[2], naddr->addr[3], 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, 201 461 naddr->prefix); 202 break; 203 case AF_INET6: 204 // FIXME TODO 205 return ENOTSUP; 462 if (rc < 0) { 463 free(*bufp); 464 return ENOMEM; 465 } 466 467 str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix); 468 469 break; 206 470 default: 207 471 return ENOTSUP; … … 214 478 } 215 479 216 /** Create packed IPv4 address 217 * 218 * Convert an IPv4 address to a packed 32 bit representation. 219 * 220 * @param addr Source address. 221 * @param packed Place to store the packed 32 bit representation. 222 * 223 * @return EOK on success. 224 * @return EINVAL if addr is not an IPv4 address. 225 * 226 */ 227 int inet_addr_pack(inet_addr_t *addr, uint32_t *packed) 228 { 229 if (addr->family != AF_INET) 230 return EINVAL; 231 232 *packed = (addr->addr[0] << 24) | (addr->addr[1] << 16) | 233 (addr->addr[2] << 8) | addr->addr[3]; 234 return EOK; 235 } 236 237 /** Create packed IPv4 address 238 * 239 * Convert an IPv4 address to a packed 32 bit representation. 240 * 241 * @param naddr Source address. 242 * @param packed Place to store the packed 32 bit representation. 243 * @param prefix Place to store the number of valid bits. 244 * 245 * @return EOK on success. 246 * @return EINVAL if addr is not an IPv4 address. 247 * 248 */ 249 int inet_naddr_pack(inet_naddr_t *naddr, uint32_t *packed, uint8_t *prefix) 250 { 251 if (naddr->family != AF_INET) 252 return EINVAL; 253 254 *packed = (naddr->addr[0] << 24) | (naddr->addr[1] << 16) | 255 (naddr->addr[2] << 8) | naddr->addr[3]; 256 *prefix = naddr->prefix; 257 258 return EOK; 259 } 260 261 void inet_addr_unpack(uint32_t packed, inet_addr_t *addr) 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) 262 524 { 263 525 addr->family = AF_INET; 264 addr->addr[0] = (packed >> 24) & 0xff; 265 addr->addr[1] = (packed >> 16) & 0xff; 266 addr->addr[2] = (packed >> 8) & 0xff; 267 addr->addr[3] = packed & 0xff; 268 } 269 270 void inet_naddr_unpack(uint32_t packed, uint8_t prefix, inet_naddr_t *naddr) 526 addr->addr = v4; 527 } 528 529 void inet_naddr_set(addr32_t v4, uint8_t prefix, inet_naddr_t *naddr) 271 530 { 272 531 naddr->family = AF_INET; 273 naddr->addr[0] = (packed >> 24) & 0xff; 274 naddr->addr[1] = (packed >> 16) & 0xff; 275 naddr->addr[2] = (packed >> 8) & 0xff; 276 naddr->addr[3] = packed & 0xff; 532 naddr->addr = v4; 277 533 naddr->prefix = prefix; 278 534 } 279 535 280 int inet_addr_sockaddr_in(inet_addr_t *addr, sockaddr_in_t *sockaddr_in) 281 { 282 uint32_t packed; 283 int rc = inet_addr_pack(addr, &packed); 284 if (rc != EOK) 285 return rc; 286 287 sockaddr_in->sin_family = AF_INET; 288 sockaddr_in->sin_addr.s_addr = host2uint32_t_be(packed); 289 return EOK; 290 } 291 292 void inet_naddr_addr(inet_naddr_t *naddr, inet_addr_t *addr) 293 { 294 addr->family = naddr->family; 295 memcpy(addr->addr, naddr->addr, INET_ADDR_SIZE); 296 } 297 298 void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d) 536 void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr) 299 537 { 300 538 addr->family = AF_INET; 301 addr->addr[0] = a; 302 addr->addr[1] = b; 303 addr->addr[2] = c; 304 addr->addr[3] = d; 305 } 306 307 void inet_naddr(inet_naddr_t *naddr, uint8_t a, uint8_t b, uint8_t c, uint8_t d, 308 uint8_t prefix) 309 { 310 naddr->family = AF_INET; 311 naddr->addr[0] = a; 312 naddr->addr[1] = b; 313 naddr->addr[2] = c; 314 naddr->addr[3] = d; 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); 315 552 naddr->prefix = prefix; 316 553 } 317 554 318 void inet_addr_any(inet_addr_t *addr) 319 { 320 addr->family = 0; 321 memset(addr->addr, 0, INET_ADDR_SIZE); 322 } 323 324 void inet_naddr_any(inet_naddr_t *naddr) 325 { 326 naddr->family = 0; 327 memset(naddr->addr, 0, INET_ADDR_SIZE); 328 naddr->prefix = 0; 329 } 330 331 int inet_addr_compare(inet_addr_t *a, inet_addr_t *b) 332 { 333 if (a->family != b->family) 334 return 0; 335 336 switch (a->family) { 337 case AF_INET: 338 return ((a->addr[0] == b->addr[0]) && (a->addr[1] == b->addr[1]) && 339 (a->addr[2] == b->addr[2]) && (a->addr[3] == b->addr[3])); 340 case AF_INET6: 341 // FIXME TODO 342 return 0; 343 default: 344 return 0; 345 } 346 } 347 348 int inet_addr_is_any(inet_addr_t *addr) 349 { 350 return ((addr->family == 0) || 351 (inet_addr_compare(addr, &inet_addr_any_addr)) || 352 (inet_addr_compare(addr, &inet_addr_any_addr6))); 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; 353 583 } 354 584
Note:
See TracChangeset
for help on using the changeset viewer.