Address Family Transformations | |
char * | nl_af2str (int family, char *buf, size_t size) |
int | nl_str2af (const char *name) |
Creating Abstract Addresses | |
struct nl_addr * | nl_addr_alloc (size_t maxsize) |
Allocate new abstract address object. | |
struct nl_addr * | nl_addr_build (int family, void *buf, size_t size) |
Allocate new abstract address object based on a binary address. | |
struct nl_addr * | nl_addr_parse (const char *addrstr, int hint) |
Allocate abstract address object based on a character string. | |
struct nl_addr * | nl_addr_clone (struct nl_addr *addr) |
Clone existing abstract address object. | |
Destroying Abstract Addresses | |
void | nl_addr_destroy (struct nl_addr *addr) |
Destroy abstract address object. | |
Managing Usage References | |
struct nl_addr * | nl_addr_get (struct nl_addr *addr) |
void | nl_addr_put (struct nl_addr *addr) |
int | nl_addr_shared (struct nl_addr *addr) |
Check whether an abstract address object is shared. | |
Miscellaneous | |
int | nl_addr_cmp (struct nl_addr *a, struct nl_addr *b) |
Compares two abstract address objects. | |
int | nl_addr_cmp_prefix (struct nl_addr *a, struct nl_addr *b) |
Compares the prefix of two abstract address objects. | |
int | nl_addr_iszero (struct nl_addr *addr) |
Returns true if the address consists of all zeros. | |
int | nl_addr_valid (char *addr, int family) |
Check if an address matches a certain family. | |
int | nl_addr_guess_family (struct nl_addr *addr) |
Guess address family of an abstract address object based on address size. | |
int | nl_addr_fill_sockaddr (struct nl_addr *addr, struct sockaddr *sa, socklen_t *salen) |
Fill out sockaddr structure with values from abstract address object. | |
Getting Information About Addresses | |
struct addrinfo * | nl_addr_info (struct nl_addr *addr) |
Call getaddrinfo() for an abstract address object. | |
int | nl_addr_resolve (struct nl_addr *addr, char *host, size_t hostlen) |
Resolve abstract address object to a name using getnameinfo(). | |
Attributes | |
void | nl_addr_set_family (struct nl_addr *addr, int family) |
int | nl_addr_get_family (struct nl_addr *addr) |
int | nl_addr_set_binary_addr (struct nl_addr *addr, void *buf, size_t len) |
Set binary address of abstract address object. | |
void * | nl_addr_get_binary_addr (struct nl_addr *addr) |
Get binary address of abstract address object. | |
unsigned int | nl_addr_get_len (struct nl_addr *addr) |
Get length of binary address of abstract address object. | |
void | nl_addr_set_prefixlen (struct nl_addr *addr, int prefixlen) |
unsigned int | nl_addr_get_prefixlen (struct nl_addr *addr) |
Get prefix length of abstract address object. | |
Translations to Strings | |
char * | nl_addr2str (struct nl_addr *addr, char *buf, size_t size) |
Convert abstract address object to character string. |
struct nl_addr *a = nl_addr_parse("::1", AF_UNSPEC); printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a))); nl_addr_put(a); a = nl_addr_parse("11:22:33:44:55:66", AF_UNSPEC); printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a))); nl_addr_put(a);
struct nl_addr* nl_addr_alloc | ( | size_t | maxsize | ) | [read] |
maxsize | Maximum size of the binary address. |
Definition at line 164 of file addr.c.
Referenced by nl_addr_build(), and nl_addr_parse().
00165 { 00166 struct nl_addr *addr; 00167 00168 addr = calloc(1, sizeof(*addr) + maxsize); 00169 if (!addr) { 00170 nl_errno(ENOMEM); 00171 return NULL; 00172 } 00173 00174 addr->a_refcnt = 1; 00175 addr->a_maxsize = maxsize; 00176 00177 return addr; 00178 }
struct nl_addr* nl_addr_build | ( | int | family, | |
void * | buf, | |||
size_t | size | |||
) | [read] |
family | Address family. | |
buf | Buffer containing the binary address. | |
size | Length of binary address buffer. |
Definition at line 187 of file addr.c.
References nl_addr_alloc().
Referenced by nl_addr_clone(), and nla_get_addr().
00188 { 00189 struct nl_addr *addr; 00190 00191 addr = nl_addr_alloc(size); 00192 if (!addr) 00193 return NULL; 00194 00195 addr->a_family = family; 00196 addr->a_len = size; 00197 addr->a_prefixlen = size*8; 00198 00199 if (size) 00200 memcpy(addr->a_addr, buf, size); 00201 00202 return addr; 00203 }
struct nl_addr* nl_addr_parse | ( | const char * | addrstr, | |
int | hint | |||
) | [read] |
addrstr | Address represented as character string. | |
hint | Address family hint or AF_UNSPEC. |
Format Len Family ---------------------------------------------------------------- IPv6 address format 16 AF_INET6 ddd.ddd.ddd.ddd 4 AF_INET HH:HH:HH:HH:HH:HH 6 AF_LLC AA{.|,}NNNN 2 AF_DECnet HH:HH:HH:... variable AF_UNSPEC
Special values:
The prefix length may be appened at the end prefixed with a slash, e.g. 10.0.0.0/8.
Definition at line 231 of file addr.c.
References nl_addr_alloc(), nl_addr_destroy(), and nl_addr_set_binary_addr().
00232 { 00233 int err, copy = 0, len = 0, family = AF_UNSPEC; 00234 char *str, *prefix, buf[32]; 00235 struct nl_addr *addr = NULL; /* gcc ain't that smart */ 00236 00237 str = strdup(addrstr); 00238 if (!str) { 00239 err = nl_errno(ENOMEM); 00240 goto errout; 00241 } 00242 00243 prefix = strchr(str, '/'); 00244 if (prefix) 00245 *prefix = '\0'; 00246 00247 if (!strcasecmp(str, "none")) { 00248 family = hint; 00249 goto prefix; 00250 } 00251 00252 if (!strcasecmp(str, "default") || 00253 !strcasecmp(str, "all") || 00254 !strcasecmp(str, "any")) { 00255 00256 switch (hint) { 00257 case AF_INET: 00258 case AF_UNSPEC: 00259 /* Kind of a hack, we assume that if there is 00260 * no hint given the user wants to have a IPv4 00261 * address given back. */ 00262 family = AF_INET; 00263 len = 4; 00264 goto prefix; 00265 00266 case AF_INET6: 00267 family = AF_INET6; 00268 len = 16; 00269 goto prefix; 00270 00271 case AF_LLC: 00272 family = AF_LLC; 00273 len = 6; 00274 goto prefix; 00275 00276 default: 00277 err = nl_error(EINVAL, "Unsuported address" \ 00278 "family for default address"); 00279 goto errout; 00280 } 00281 } 00282 00283 copy = 1; 00284 00285 if (hint == AF_INET || hint == AF_UNSPEC) { 00286 if (inet_pton(AF_INET, str, buf) > 0) { 00287 family = AF_INET; 00288 len = 4; 00289 goto prefix; 00290 } 00291 if (hint == AF_INET) { 00292 err = nl_error(EINVAL, "Invalid IPv4 address"); 00293 goto errout; 00294 } 00295 } 00296 00297 if (hint == AF_INET6 || hint == AF_UNSPEC) { 00298 if (inet_pton(AF_INET6, str, buf) > 0) { 00299 family = AF_INET6; 00300 len = 16; 00301 goto prefix; 00302 } 00303 if (hint == AF_INET6) { 00304 err = nl_error(EINVAL, "Invalid IPv6 address"); 00305 goto errout; 00306 } 00307 } 00308 00309 if ((hint == AF_LLC || hint == AF_UNSPEC) && strchr(str, ':')) { 00310 unsigned int a, b, c, d, e, f; 00311 00312 if (sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x", 00313 &a, &b, &c, &d, &e, &f) == 6) { 00314 family = AF_LLC; 00315 len = 6; 00316 buf[0] = (unsigned char) a; 00317 buf[1] = (unsigned char) b; 00318 buf[2] = (unsigned char) c; 00319 buf[3] = (unsigned char) d; 00320 buf[4] = (unsigned char) e; 00321 buf[5] = (unsigned char) f; 00322 goto prefix; 00323 } 00324 00325 if (hint == AF_LLC) { 00326 err = nl_error(EINVAL, "Invalid link layer address"); 00327 goto errout; 00328 } 00329 } 00330 00331 if ((hint == AF_DECnet || hint == AF_UNSPEC) && 00332 (strchr(str, '.') || strchr(str, ','))) { 00333 if (dnet_pton(str, buf) > 0) { 00334 family = AF_DECnet; 00335 len = 2; 00336 goto prefix; 00337 } 00338 if (hint == AF_DECnet) { 00339 err = nl_error(EINVAL, "Invalid DECnet address"); 00340 goto errout; 00341 } 00342 } 00343 00344 if (hint == AF_UNSPEC && strchr(str, ':')) { 00345 int i = 0; 00346 char *s = str, *p; 00347 for (;;) { 00348 long l = strtol(s, &p, 16); 00349 00350 if (s == p || l > 0xff || i >= sizeof(buf)) { 00351 err = -EINVAL; 00352 goto errout; 00353 } 00354 00355 buf[i++] = (unsigned char) l; 00356 if (*p == '\0') 00357 break; 00358 s = ++p; 00359 } 00360 00361 len = i; 00362 family = AF_UNSPEC; 00363 goto prefix; 00364 } 00365 00366 err = nl_error(EINVAL, "Invalid address"); 00367 goto errout; 00368 00369 prefix: 00370 addr = nl_addr_alloc(len); 00371 if (!addr) { 00372 err = nl_errno(ENOMEM); 00373 goto errout; 00374 } 00375 00376 nl_addr_set_family(addr, family); 00377 00378 if (copy) 00379 nl_addr_set_binary_addr(addr, buf, len); 00380 00381 if (prefix) { 00382 char *p; 00383 long pl = strtol(++prefix, &p, 0); 00384 if (p == prefix) { 00385 nl_addr_destroy(addr); 00386 err = -EINVAL; 00387 goto errout; 00388 } 00389 nl_addr_set_prefixlen(addr, pl); 00390 } else 00391 nl_addr_set_prefixlen(addr, len * 8); 00392 00393 err = 0; 00394 errout: 00395 free(str); 00396 00397 return err ? NULL : addr; 00398 }
struct nl_addr* nl_addr_clone | ( | struct nl_addr * | addr | ) | [read] |
addr | Abstract address object. |
Definition at line 406 of file addr.c.
References nl_addr_build().
00407 { 00408 struct nl_addr *new; 00409 00410 new = nl_addr_build(addr->a_family, addr->a_addr, addr->a_len); 00411 if (new) 00412 new->a_prefixlen = addr->a_prefixlen; 00413 00414 return new; 00415 }
void nl_addr_destroy | ( | struct nl_addr * | addr | ) |
addr | Abstract address object. |
Definition at line 428 of file addr.c.
Referenced by nl_addr_parse().
00429 { 00430 if (!addr) 00431 return; 00432 00433 if (addr->a_refcnt != 1) 00434 BUG(); 00435 00436 free(addr); 00437 }
int nl_addr_shared | ( | struct nl_addr * | addr | ) |
int nl_addr_cmp | ( | struct nl_addr * | a, | |
struct nl_addr * | b | |||
) |
a | A abstract address object. | |
b | Another abstract address object. |
is
found, respectively to be less than, to, or be greater than b
. Definition at line 489 of file addr.c.
Referenced by rtnl_neigh_get().
00490 { 00491 int d = a->a_family - b->a_family; 00492 00493 if (d == 0) { 00494 d = a->a_len - b->a_len; 00495 00496 if (a->a_len && d == 0) 00497 return memcmp(a->a_addr, b->a_addr, a->a_len); 00498 } 00499 00500 return d; 00501 }
int nl_addr_cmp_prefix | ( | struct nl_addr * | a, | |
struct nl_addr * | b | |||
) |
a | A abstract address object. | |
b | Another abstract address object. |
is
found, respectively to be less than, to, or be greater than b
. Definition at line 511 of file addr.c.
00512 { 00513 int d = a->a_family - b->a_family; 00514 00515 if (d == 0) { 00516 int len = min(a->a_prefixlen, b->a_prefixlen); 00517 int bytes = len / 8; 00518 00519 d = memcmp(a->a_addr, b->a_addr, bytes); 00520 if (d == 0) { 00521 int mask = (1UL << (len % 8)) - 1UL; 00522 00523 d = (a->a_addr[bytes] & mask) - 00524 (b->a_addr[bytes] & mask); 00525 } 00526 } 00527 00528 return d; 00529 }
int nl_addr_iszero | ( | struct nl_addr * | addr | ) |
int nl_addr_valid | ( | char * | addr, | |
int | family | |||
) |
addr | Address represented as character string. | |
family | Desired address family. |
Definition at line 554 of file addr.c.
00555 { 00556 int ret; 00557 char buf[32]; 00558 00559 switch (family) { 00560 case AF_INET: 00561 case AF_INET6: 00562 ret = inet_pton(family, addr, buf); 00563 if (ret <= 0) 00564 return 0; 00565 break; 00566 00567 case AF_DECnet: 00568 ret = dnet_pton(addr, buf); 00569 if (ret <= 0) 00570 return 0; 00571 break; 00572 00573 case AF_LLC: 00574 if (sscanf(addr, "%*02x:%*02x:%*02x:%*02x:%*02x:%*02x") != 6) 00575 return 0; 00576 break; 00577 } 00578 00579 return 1; 00580 }
int nl_addr_guess_family | ( | struct nl_addr * | addr | ) |
addr | Abstract address object. |
Definition at line 587 of file addr.c.
00588 { 00589 switch (addr->a_len) { 00590 case 4: 00591 return AF_INET; 00592 case 6: 00593 return AF_LLC; 00594 case 16: 00595 return AF_INET6; 00596 default: 00597 return AF_UNSPEC; 00598 } 00599 }
int nl_addr_fill_sockaddr | ( | struct nl_addr * | addr, | |
struct sockaddr * | sa, | |||
socklen_t * | salen | |||
) |
addr | Abstract address object. | |
sa | Destination sockaddr structure buffer. | |
salen | Length of sockaddr structure buffer. |
Definition at line 614 of file addr.c.
Referenced by nl_addr_resolve().
00616 { 00617 switch (addr->a_family) { 00618 case AF_INET: { 00619 struct sockaddr_in *sai = (struct sockaddr_in *) sa; 00620 00621 if (*salen < sizeof(*sai)) 00622 return -EINVAL; 00623 00624 sai->sin_family = addr->a_family; 00625 memcpy(&sai->sin_addr, addr->a_addr, 4); 00626 *salen = sizeof(*sai); 00627 } 00628 break; 00629 00630 case AF_INET6: { 00631 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa; 00632 00633 if (*salen < sizeof(*sa6)) 00634 return -EINVAL; 00635 00636 sa6->sin6_family = addr->a_family; 00637 memcpy(&sa6->sin6_addr, addr->a_addr, 16); 00638 *salen = sizeof(*sa6); 00639 } 00640 break; 00641 00642 default: 00643 return -EINVAL; 00644 } 00645 00646 return 0; 00647 }
struct addrinfo* nl_addr_info | ( | struct nl_addr * | addr | ) | [read] |
addr | Abstract address object. |
Definition at line 670 of file addr.c.
References nl_addr2str().
00671 { 00672 int err; 00673 struct addrinfo *res; 00674 char buf[INET6_ADDRSTRLEN+5]; 00675 struct addrinfo hint = { 00676 .ai_flags = AI_NUMERICHOST, 00677 .ai_family = addr->a_family, 00678 }; 00679 00680 nl_addr2str(addr, buf, sizeof(buf)); 00681 00682 err = getaddrinfo(buf, NULL, &hint, &res); 00683 if (err != 0) { 00684 nl_error(err, gai_strerror(err)); 00685 return NULL; 00686 } 00687 00688 return res; 00689 }
int nl_addr_resolve | ( | struct nl_addr * | addr, | |
char * | host, | |||
size_t | hostlen | |||
) |
addr | Abstract address object. | |
host | Destination buffer for host name. | |
hostlen | Length of destination buffer. |
Definition at line 704 of file addr.c.
References nl_addr_fill_sockaddr().
00705 { 00706 int err; 00707 struct sockaddr_in6 buf; 00708 socklen_t salen = sizeof(buf); 00709 00710 err = nl_addr_fill_sockaddr(addr, (struct sockaddr *) &buf, &salen); 00711 if (err < 0) 00712 return err; 00713 00714 return getnameinfo((struct sockaddr *) &buf, salen, 00715 host, hostlen, NULL, 0, NI_NAMEREQD); 00716 }
int nl_addr_set_binary_addr | ( | struct nl_addr * | addr, | |
void * | buf, | |||
size_t | len | |||
) |
addr | Abstract address object. | |
buf | Buffer containing binary address. | |
len | Length of buffer containing binary address. |
Definition at line 741 of file addr.c.
Referenced by nl_addr_parse().
00742 { 00743 if (len > addr->a_maxsize) 00744 return -ERANGE; 00745 00746 addr->a_len = len; 00747 memcpy(addr->a_addr, buf, len); 00748 00749 return 0; 00750 }
void* nl_addr_get_binary_addr | ( | struct nl_addr * | addr | ) |
addr | Abstract address object. |
Definition at line 756 of file addr.c.
Referenced by flnl_lookup_build_request(), and nla_put_addr().
unsigned int nl_addr_get_len | ( | struct nl_addr * | addr | ) |
addr | Abstract address object. |
Definition at line 765 of file addr.c.
Referenced by nla_put_addr().
unsigned int nl_addr_get_prefixlen | ( | struct nl_addr * | addr | ) |
char* nl_addr2str | ( | struct nl_addr * | addr, | |
char * | buf, | |||
size_t | size | |||
) |
addr | Abstract address object. | |
buf | Destination buffer. | |
size | Size of destination buffer. |
Definition at line 802 of file addr.c.
Referenced by nl_addr_info().
00803 { 00804 int i; 00805 char tmp[16]; 00806 00807 if (!addr->a_len) { 00808 snprintf(buf, size, "none"); 00809 goto prefix; 00810 } 00811 00812 switch (addr->a_family) { 00813 case AF_INET: 00814 inet_ntop(AF_INET, addr->a_addr, buf, size); 00815 break; 00816 00817 case AF_INET6: 00818 inet_ntop(AF_INET6, addr->a_addr, buf, size); 00819 break; 00820 00821 case AF_DECnet: 00822 dnet_ntop(addr->a_addr, addr->a_len, buf, size); 00823 break; 00824 00825 case AF_LLC: 00826 default: 00827 snprintf(buf, size, "%02x", 00828 (unsigned char) addr->a_addr[0]); 00829 for (i = 1; i < addr->a_len; i++) { 00830 snprintf(tmp, sizeof(tmp), ":%02x", 00831 (unsigned char) addr->a_addr[i]); 00832 strncat(buf, tmp, size - strlen(buf) - 1); 00833 } 00834 break; 00835 } 00836 00837 prefix: 00838 if (addr->a_prefixlen != (8 * addr->a_len)) { 00839 snprintf(tmp, sizeof(tmp), "/%u", addr->a_prefixlen); 00840 strncat(buf, tmp, size - strlen(buf) - 1); 00841 } 00842 00843 return buf; 00844 }