Abstract Address
[Utilities]

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.

Detailed Description

1) Transform character string to abstract address
 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);

Function Documentation

struct nl_addr* nl_addr_alloc ( size_t  maxsize  )  [read]
Parameters:
maxsize Maximum size of the binary address.
Returns:
Newly allocated address object or NULL

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]
Parameters:
family Address family.
buf Buffer containing the binary address.
size Length of binary address buffer.
Returns:
Newly allocated address handle or NULL

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]
Parameters:
addrstr Address represented as character string.
hint Address family hint or AF_UNSPEC.

Regognizes the following address formats:

  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:

  • none: All bits and length set to 0.
  • {default|all|any}: All bits set to 0, length based on hint or AF_INET if no hint is given.

The prefix length may be appened at the end prefixed with a slash, e.g. 10.0.0.0/8.

Returns:
Newly allocated abstract address object or NULL.

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]
Parameters:
addr Abstract address object.
Returns:
Newly allocated abstract address object being a duplicate of the specified address object or NULL if a failure occured.

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  ) 
Parameters:
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  ) 
Parameters:
addr Abstract address object.
Returns:
Non-zero if the abstract address object is shared, otherwise 0.

Definition at line 469 of file addr.c.

00470 {
00471         return addr->a_refcnt > 1;
00472 }

int nl_addr_cmp ( struct nl_addr *  a,
struct nl_addr *  b 
)
Parameters:
a A abstract address object.
b Another abstract address object.
Returns:
Integer less than, equal to or greather than zero if 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 
)
Parameters:
a A abstract address object.
b Another abstract address object.
Returns:
Integer less than, equal to or greather than zero if 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  ) 
Parameters:
addr Address to look at.

Definition at line 535 of file addr.c.

00536 {
00537         int i;
00538 
00539         for (i = 0; i < addr->a_len; i++)
00540                 if (addr->a_addr[i])
00541                         return 0;
00542 
00543         return 1;
00544 }

int nl_addr_valid ( char *  addr,
int  family 
)
Parameters:
addr Address represented as character string.
family Desired address family.
Returns:
1 if the address is of the desired address family, otherwise 0 is returned.

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  ) 
Parameters:
addr Abstract address object.
Returns:
Address family or AF_UNSPEC if guessing wasn't successful.

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 
)
Parameters:
addr Abstract address object.
sa Destination sockaddr structure buffer.
salen Length of sockaddr structure buffer.

Fills out the specified sockaddr structure with the data found in the specified abstract address. The salen argument needs to be set to the size of sa but will be modified to the actual size used during before the function exits.

Returns:
0 on success or a negative error code

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]
Parameters:
addr Abstract address object.

Calls getaddrinfo() for the specified abstract address in AI_NUMERICHOST mode.

Note:
The caller is responsible for freeing the linked list using the interface provided by getaddrinfo(3).
Returns:
A linked list of addrinfo handles or NULL with an error message associated.

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 
)
Parameters:
addr Abstract address object.
host Destination buffer for host name.
hostlen Length of destination buffer.

Resolves the abstract address to a name and writes the looked up result into the host buffer. getnameinfo() is used to perform the lookup and is put into NI_NAMEREQD mode so the function will fail if the lookup couldn't be performed.

Returns:
0 on success or a negative error code.

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 
)
Parameters:
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  ) 
Parameters:
addr Abstract address object.

Definition at line 756 of file addr.c.

Referenced by flnl_lookup_build_request(), and nla_put_addr().

00757 {
00758         return addr->a_addr;
00759 }

unsigned int nl_addr_get_len ( struct nl_addr *  addr  ) 
Parameters:
addr Abstract address object.

Definition at line 765 of file addr.c.

Referenced by nla_put_addr().

00766 {
00767         return addr->a_len;
00768 }

unsigned int nl_addr_get_prefixlen ( struct nl_addr *  addr  ) 
Parameters:
addr Abstract address object.

Definition at line 779 of file addr.c.

00780 {
00781         return addr->a_prefixlen;
00782 }

char* nl_addr2str ( struct nl_addr *  addr,
char *  buf,
size_t  size 
)
Parameters:
addr Abstract address object.
buf Destination buffer.
size Size of destination buffer.

Converts an abstract address to a character string and stores the result in the specified destination buffer.

Returns:
Address represented in ASCII stored in 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 }


Generated on 30 Oct 2009 for libnl by  doxygen 1.6.1