libnl  1.1.4
Abstract Address

Creating Abstract Addresses

struct nl_addr * nl_addr_alloc (size_t maxsize)
 Allocate new abstract address object. More...
 
struct nl_addr * nl_addr_build (int family, void *buf, size_t size)
 Allocate new abstract address object based on a binary address. More...
 
struct nl_addr * nl_addr_parse (const char *addrstr, int hint)
 Allocate abstract address object based on a character string. More...
 
struct nl_addr * nl_addr_clone (struct nl_addr *addr)
 Clone existing abstract address object. More...
 

Destroying Abstract Addresses

void nl_addr_destroy (struct nl_addr *addr)
 Destroy abstract address object. More...
 

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. More...
 

Miscellaneous

int nl_addr_cmp (struct nl_addr *a, struct nl_addr *b)
 Compares two abstract address objects. More...
 
int nl_addr_cmp_prefix (struct nl_addr *a, struct nl_addr *b)
 Compares the prefix of two abstract address objects. More...
 
int nl_addr_iszero (struct nl_addr *addr)
 Returns true if the address consists of all zeros. More...
 
int nl_addr_valid (char *addr, int family)
 Check if an address matches a certain family. More...
 
int nl_addr_guess_family (struct nl_addr *addr)
 Guess address family of an abstract address object based on address size. More...
 
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. More...
 

Getting Information About Addresses

struct addrinfo * nl_addr_info (struct nl_addr *addr)
 Call getaddrinfo() for an abstract address object. More...
 
int nl_addr_resolve (struct nl_addr *addr, char *host, size_t hostlen)
 Resolve abstract address object to a name using getnameinfo(). More...
 

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. More...
 
void * nl_addr_get_binary_addr (struct nl_addr *addr)
 Get binary address of abstract address object. More...
 
unsigned int nl_addr_get_len (struct nl_addr *addr)
 Get length of binary address of abstract address object. More...
 
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. More...
 

Translations to Strings

char * nl_addr2str (struct nl_addr *addr, char *buf, size_t size)
 Convert abstract address object to character string. More...
 

Address Family Transformations

char * nl_af2str (int family, char *buf, size_t size)
 
int nl_str2af (const char *name)
 

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)
Parameters
maxsizeMaximum 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().

165 {
166  struct nl_addr *addr;
167 
168  addr = calloc(1, sizeof(*addr) + maxsize);
169  if (!addr) {
170  nl_errno(ENOMEM);
171  return NULL;
172  }
173 
174  addr->a_refcnt = 1;
175  addr->a_maxsize = maxsize;
176 
177  return addr;
178 }
struct nl_addr* nl_addr_build ( int  family,
void *  buf,
size_t  size 
)
Parameters
familyAddress family.
bufBuffer containing the binary address.
sizeLength 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().

188 {
189  struct nl_addr *addr;
190 
191  addr = nl_addr_alloc(size);
192  if (!addr)
193  return NULL;
194 
195  addr->a_family = family;
196  addr->a_len = size;
197  addr->a_prefixlen = size*8;
198 
199  if (size)
200  memcpy(addr->a_addr, buf, size);
201 
202  return addr;
203 }
struct nl_addr * nl_addr_alloc(size_t maxsize)
Allocate new abstract address object.
Definition: addr.c:164
struct nl_addr* nl_addr_parse ( const char *  addrstr,
int  hint 
)
Parameters
addrstrAddress represented as character string.
hintAddress 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().

232 {
233  int err, copy = 0, len = 0, family = AF_UNSPEC;
234  char *str, *prefix, buf[32];
235  struct nl_addr *addr = NULL; /* gcc ain't that smart */
236 
237  str = strdup(addrstr);
238  if (!str) {
239  err = nl_errno(ENOMEM);
240  goto errout;
241  }
242 
243  prefix = strchr(str, '/');
244  if (prefix)
245  *prefix = '\0';
246 
247  if (!strcasecmp(str, "none")) {
248  family = hint;
249  goto prefix;
250  }
251 
252  if (!strcasecmp(str, "default") ||
253  !strcasecmp(str, "all") ||
254  !strcasecmp(str, "any")) {
255 
256  switch (hint) {
257  case AF_INET:
258  case AF_UNSPEC:
259  /* Kind of a hack, we assume that if there is
260  * no hint given the user wants to have a IPv4
261  * address given back. */
262  family = AF_INET;
263  len = 4;
264  goto prefix;
265 
266  case AF_INET6:
267  family = AF_INET6;
268  len = 16;
269  goto prefix;
270 
271  case AF_LLC:
272  family = AF_LLC;
273  len = 6;
274  goto prefix;
275 
276  default:
277  err = nl_error(EINVAL, "Unsuported address" \
278  "family for default address");
279  goto errout;
280  }
281  }
282 
283  copy = 1;
284 
285  if (hint == AF_INET || hint == AF_UNSPEC) {
286  if (inet_pton(AF_INET, str, buf) > 0) {
287  family = AF_INET;
288  len = 4;
289  goto prefix;
290  }
291  if (hint == AF_INET) {
292  err = nl_error(EINVAL, "Invalid IPv4 address");
293  goto errout;
294  }
295  }
296 
297  if (hint == AF_INET6 || hint == AF_UNSPEC) {
298  if (inet_pton(AF_INET6, str, buf) > 0) {
299  family = AF_INET6;
300  len = 16;
301  goto prefix;
302  }
303  if (hint == AF_INET6) {
304  err = nl_error(EINVAL, "Invalid IPv6 address");
305  goto errout;
306  }
307  }
308 
309  if ((hint == AF_LLC || hint == AF_UNSPEC) && strchr(str, ':')) {
310  unsigned int a, b, c, d, e, f;
311 
312  if (sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
313  &a, &b, &c, &d, &e, &f) == 6) {
314  family = AF_LLC;
315  len = 6;
316  buf[0] = (unsigned char) a;
317  buf[1] = (unsigned char) b;
318  buf[2] = (unsigned char) c;
319  buf[3] = (unsigned char) d;
320  buf[4] = (unsigned char) e;
321  buf[5] = (unsigned char) f;
322  goto prefix;
323  }
324 
325  if (hint == AF_LLC) {
326  err = nl_error(EINVAL, "Invalid link layer address");
327  goto errout;
328  }
329  }
330 
331  if ((hint == AF_DECnet || hint == AF_UNSPEC) &&
332  (strchr(str, '.') || strchr(str, ','))) {
333  if (dnet_pton(str, buf) > 0) {
334  family = AF_DECnet;
335  len = 2;
336  goto prefix;
337  }
338  if (hint == AF_DECnet) {
339  err = nl_error(EINVAL, "Invalid DECnet address");
340  goto errout;
341  }
342  }
343 
344  if (hint == AF_UNSPEC && strchr(str, ':')) {
345  int i = 0;
346  char *s = str, *p;
347  for (;;) {
348  long l = strtol(s, &p, 16);
349 
350  if (s == p || l > 0xff || i >= sizeof(buf)) {
351  err = -EINVAL;
352  goto errout;
353  }
354 
355  buf[i++] = (unsigned char) l;
356  if (*p == '\0')
357  break;
358  s = ++p;
359  }
360 
361  len = i;
362  family = AF_UNSPEC;
363  goto prefix;
364  }
365 
366  err = nl_error(EINVAL, "Invalid address");
367  goto errout;
368 
369 prefix:
370  addr = nl_addr_alloc(len);
371  if (!addr) {
372  err = nl_errno(ENOMEM);
373  goto errout;
374  }
375 
376  nl_addr_set_family(addr, family);
377 
378  if (copy)
379  nl_addr_set_binary_addr(addr, buf, len);
380 
381  if (prefix) {
382  char *p;
383  long pl = strtol(++prefix, &p, 0);
384  if (p == prefix) {
385  nl_addr_destroy(addr);
386  err = -EINVAL;
387  goto errout;
388  }
389  nl_addr_set_prefixlen(addr, pl);
390  } else
391  nl_addr_set_prefixlen(addr, len * 8);
392 
393  err = 0;
394 errout:
395  free(str);
396 
397  return err ? NULL : addr;
398 }
struct nl_addr * nl_addr_alloc(size_t maxsize)
Allocate new abstract address object.
Definition: addr.c:164
int nl_addr_set_binary_addr(struct nl_addr *addr, void *buf, size_t len)
Set binary address of abstract address object.
Definition: addr.c:741
void nl_addr_destroy(struct nl_addr *addr)
Destroy abstract address object.
Definition: addr.c:428
struct nl_addr* nl_addr_clone ( struct nl_addr *  addr)
Parameters
addrAbstract 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().

407 {
408  struct nl_addr *new;
409 
410  new = nl_addr_build(addr->a_family, addr->a_addr, addr->a_len);
411  if (new)
412  new->a_prefixlen = addr->a_prefixlen;
413 
414  return new;
415 }
struct nl_addr * nl_addr_build(int family, void *buf, size_t size)
Allocate new abstract address object based on a binary address.
Definition: addr.c:187
void nl_addr_destroy ( struct nl_addr *  addr)
Parameters
addrAbstract address object.

Definition at line 428 of file addr.c.

Referenced by nl_addr_parse().

429 {
430  if (!addr)
431  return;
432 
433  if (addr->a_refcnt != 1)
434  BUG();
435 
436  free(addr);
437 }
int nl_addr_shared ( struct nl_addr *  addr)
Parameters
addrAbstract address object.
Returns
Non-zero if the abstract address object is shared, otherwise 0.

Definition at line 469 of file addr.c.

470 {
471  return addr->a_refcnt > 1;
472 }
int nl_addr_cmp ( struct nl_addr *  a,
struct nl_addr *  b 
)
Parameters
aA abstract address object.
bAnother 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().

490 {
491  int d = a->a_family - b->a_family;
492 
493  if (d == 0) {
494  d = a->a_len - b->a_len;
495 
496  if (a->a_len && d == 0)
497  return memcmp(a->a_addr, b->a_addr, a->a_len);
498  }
499 
500  return d;
501 }
int nl_addr_cmp_prefix ( struct nl_addr *  a,
struct nl_addr *  b 
)
Parameters
aA abstract address object.
bAnother 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.

512 {
513  int d = a->a_family - b->a_family;
514 
515  if (d == 0) {
516  int len = min(a->a_prefixlen, b->a_prefixlen);
517  int bytes = len / 8;
518 
519  d = memcmp(a->a_addr, b->a_addr, bytes);
520  if (d == 0) {
521  int mask = (1UL << (len % 8)) - 1UL;
522 
523  d = (a->a_addr[bytes] & mask) -
524  (b->a_addr[bytes] & mask);
525  }
526  }
527 
528  return d;
529 }
int nl_addr_iszero ( struct nl_addr *  addr)
Parameters
addrAddress to look at.

Definition at line 535 of file addr.c.

536 {
537  int i;
538 
539  for (i = 0; i < addr->a_len; i++)
540  if (addr->a_addr[i])
541  return 0;
542 
543  return 1;
544 }
int nl_addr_valid ( char *  addr,
int  family 
)
Parameters
addrAddress represented as character string.
familyDesired 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.

555 {
556  int ret;
557  char buf[32];
558 
559  switch (family) {
560  case AF_INET:
561  case AF_INET6:
562  ret = inet_pton(family, addr, buf);
563  if (ret <= 0)
564  return 0;
565  break;
566 
567  case AF_DECnet:
568  ret = dnet_pton(addr, buf);
569  if (ret <= 0)
570  return 0;
571  break;
572 
573  case AF_LLC:
574  if (sscanf(addr, "%*02x:%*02x:%*02x:%*02x:%*02x:%*02x") != 6)
575  return 0;
576  break;
577  }
578 
579  return 1;
580 }
int nl_addr_guess_family ( struct nl_addr *  addr)
Parameters
addrAbstract address object.
Returns
Address family or AF_UNSPEC if guessing wasn't successful.

Definition at line 587 of file addr.c.

588 {
589  switch (addr->a_len) {
590  case 4:
591  return AF_INET;
592  case 6:
593  return AF_LLC;
594  case 16:
595  return AF_INET6;
596  default:
597  return AF_UNSPEC;
598  }
599 }
int nl_addr_fill_sockaddr ( struct nl_addr *  addr,
struct sockaddr *  sa,
socklen_t *  salen 
)
Parameters
addrAbstract address object.
saDestination sockaddr structure buffer.
salenLength 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().

616 {
617  switch (addr->a_family) {
618  case AF_INET: {
619  struct sockaddr_in *sai = (struct sockaddr_in *) sa;
620 
621  if (*salen < sizeof(*sai))
622  return -EINVAL;
623 
624  sai->sin_family = addr->a_family;
625  memcpy(&sai->sin_addr, addr->a_addr, 4);
626  *salen = sizeof(*sai);
627  }
628  break;
629 
630  case AF_INET6: {
631  struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
632 
633  if (*salen < sizeof(*sa6))
634  return -EINVAL;
635 
636  sa6->sin6_family = addr->a_family;
637  memcpy(&sa6->sin6_addr, addr->a_addr, 16);
638  *salen = sizeof(*sa6);
639  }
640  break;
641 
642  default:
643  return -EINVAL;
644  }
645 
646  return 0;
647 }
struct addrinfo* nl_addr_info ( struct nl_addr *  addr)
Parameters
addrAbstract 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().

671 {
672  int err;
673  struct addrinfo *res;
674  char buf[INET6_ADDRSTRLEN+5];
675  struct addrinfo hint = {
676  .ai_flags = AI_NUMERICHOST,
677  .ai_family = addr->a_family,
678  };
679 
680  nl_addr2str(addr, buf, sizeof(buf));
681 
682  err = getaddrinfo(buf, NULL, &hint, &res);
683  if (err != 0) {
684  nl_error(err, gai_strerror(err));
685  return NULL;
686  }
687 
688  return res;
689 }
char * nl_addr2str(struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:802
int nl_addr_resolve ( struct nl_addr *  addr,
char *  host,
size_t  hostlen 
)
Parameters
addrAbstract address object.
hostDestination buffer for host name.
hostlenLength 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().

705 {
706  int err;
707  struct sockaddr_in6 buf;
708  socklen_t salen = sizeof(buf);
709 
710  err = nl_addr_fill_sockaddr(addr, (struct sockaddr *) &buf, &salen);
711  if (err < 0)
712  return err;
713 
714  return getnameinfo((struct sockaddr *) &buf, salen,
715  host, hostlen, NULL, 0, NI_NAMEREQD);
716 }
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.
Definition: addr.c:614
int nl_addr_set_binary_addr ( struct nl_addr *  addr,
void *  buf,
size_t  len 
)
Parameters
addrAbstract address object.
bufBuffer containing binary address.
lenLength of buffer containing binary address.

Definition at line 741 of file addr.c.

Referenced by nl_addr_parse().

742 {
743  if (len > addr->a_maxsize)
744  return -ERANGE;
745 
746  addr->a_len = len;
747  memcpy(addr->a_addr, buf, len);
748 
749  return 0;
750 }
void* nl_addr_get_binary_addr ( struct nl_addr *  addr)
Parameters
addrAbstract address object.

Definition at line 756 of file addr.c.

Referenced by flnl_lookup_build_request(), and nla_put_addr().

757 {
758  return addr->a_addr;
759 }
unsigned int nl_addr_get_len ( struct nl_addr *  addr)
Parameters
addrAbstract address object.

Definition at line 765 of file addr.c.

Referenced by nla_put_addr().

766 {
767  return addr->a_len;
768 }
unsigned int nl_addr_get_prefixlen ( struct nl_addr *  addr)
Parameters
addrAbstract address object.

Definition at line 779 of file addr.c.

780 {
781  return addr->a_prefixlen;
782 }
char* nl_addr2str ( struct nl_addr *  addr,
char *  buf,
size_t  size 
)
Parameters
addrAbstract address object.
bufDestination buffer.
sizeSize 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().

803 {
804  int i;
805  char tmp[16];
806 
807  if (!addr->a_len) {
808  snprintf(buf, size, "none");
809  goto prefix;
810  }
811 
812  switch (addr->a_family) {
813  case AF_INET:
814  inet_ntop(AF_INET, addr->a_addr, buf, size);
815  break;
816 
817  case AF_INET6:
818  inet_ntop(AF_INET6, addr->a_addr, buf, size);
819  break;
820 
821  case AF_DECnet:
822  dnet_ntop(addr->a_addr, addr->a_len, buf, size);
823  break;
824 
825  case AF_LLC:
826  default:
827  snprintf(buf, size, "%02x",
828  (unsigned char) addr->a_addr[0]);
829  for (i = 1; i < addr->a_len; i++) {
830  snprintf(tmp, sizeof(tmp), ":%02x",
831  (unsigned char) addr->a_addr[i]);
832  strncat(buf, tmp, size - strlen(buf) - 1);
833  }
834  break;
835  }
836 
837 prefix:
838  if (addr->a_prefixlen != (8 * addr->a_len)) {
839  snprintf(tmp, sizeof(tmp), "/%u", addr->a_prefixlen);
840  strncat(buf, tmp, size - strlen(buf) - 1);
841  }
842 
843  return buf;
844 }