libnl  3.3.0
addr.c
1 /*
2  * lib/addr.c Network Address
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 /**
13  * @ingroup core_types
14  * @defgroup addr Network Address
15  *
16  * Abstract data type representing any kind of network address
17  *
18  * Related sections in the development guide:
19  * - @core_doc{_abstract_address, Network Addresses}
20  *
21  * @{
22  *
23  * Header
24  * ------
25  * ~~~~{.c}
26  * #include <netlink/addr.h>
27  * ~~~~
28  */
29 
30 #include <netlink-private/netlink.h>
31 #include <netlink/netlink.h>
32 #include <netlink/utils.h>
33 #include <netlink/addr.h>
34 #include <linux/socket.h>
35 
36 /* All this DECnet stuff is stolen from iproute2, thanks to whoever wrote
37  * this, probably Alexey. */
38 static inline uint16_t dn_ntohs(uint16_t addr)
39 {
40  union {
41  uint8_t byte[2];
42  uint16_t word;
43  } u = {
44  .word = addr,
45  };
46 
47  return ((uint16_t) u.byte[0]) | (((uint16_t) u.byte[1]) << 8);
48 }
49 
50 static inline int do_digit(char *str, uint16_t *addr, uint16_t scale,
51  size_t *pos, size_t len, int *started)
52 {
53  uint16_t tmp = *addr / scale;
54 
55  if (*pos == len)
56  return 1;
57 
58  if (((tmp) > 0) || *started || (scale == 1)) {
59  *str = tmp + '0';
60  *started = 1;
61  (*pos)++;
62  *addr -= (tmp * scale);
63  }
64 
65  return 0;
66 }
67 
68 static const char *dnet_ntop(const char *addrbuf, size_t addrlen, char *str,
69  size_t len)
70 {
71  uint16_t addr = dn_ntohs(*(uint16_t *)addrbuf);
72  uint16_t area = addr >> 10;
73  size_t pos = 0;
74  int started = 0;
75 
76  if (addrlen != 2)
77  return NULL;
78 
79  addr &= 0x03ff;
80 
81  if (len == 0)
82  return str;
83 
84  if (do_digit(str + pos, &area, 10, &pos, len, &started))
85  return str;
86 
87  if (do_digit(str + pos, &area, 1, &pos, len, &started))
88  return str;
89 
90  if (pos == len)
91  return str;
92 
93  *(str + pos) = '.';
94  pos++;
95  started = 0;
96 
97  if (do_digit(str + pos, &addr, 1000, &pos, len, &started))
98  return str;
99 
100  if (do_digit(str + pos, &addr, 100, &pos, len, &started))
101  return str;
102 
103  if (do_digit(str + pos, &addr, 10, &pos, len, &started))
104  return str;
105 
106  if (do_digit(str + pos, &addr, 1, &pos, len, &started))
107  return str;
108 
109  if (pos == len)
110  return str;
111 
112  *(str + pos) = 0;
113 
114  return str;
115 }
116 
117 static int dnet_num(const char *src, uint16_t * dst)
118 {
119  int rv = 0;
120  int tmp;
121  *dst = 0;
122 
123  while ((tmp = *src++) != 0) {
124  tmp -= '0';
125  if ((tmp < 0) || (tmp > 9))
126  return rv;
127 
128  rv++;
129  (*dst) *= 10;
130  (*dst) += tmp;
131  }
132 
133  return rv;
134 }
135 
136 static inline int dnet_pton(const char *src, char *addrbuf)
137 {
138  uint16_t area = 0;
139  uint16_t node = 0;
140  int pos;
141 
142  pos = dnet_num(src, &area);
143  if ((pos == 0) || (area > 63) ||
144  ((*(src + pos) != '.') && (*(src + pos) != ',')))
145  return -NLE_INVAL;
146 
147  pos = dnet_num(src + pos + 1, &node);
148  if ((pos == 0) || (node > 1023))
149  return -NLE_INVAL;
150 
151  *(uint16_t *)addrbuf = dn_ntohs((area << 10) | node);
152 
153  return 1;
154 }
155 
156 static void addr_destroy(struct nl_addr *addr)
157 {
158  if (!addr)
159  return;
160 
161  if (addr->a_refcnt != 1)
162  BUG();
163 
164  free(addr);
165 }
166 
167 /**
168  * @name Creating Abstract Network Addresses
169  * @{
170  */
171 
172 /**
173  * Allocate empty abstract address
174  * @arg maxsize Upper limit of the binary address to be stored
175  *
176  * The new address object will be empty with a prefix length of 0 and will
177  * be capable of holding binary addresses up to the specified limit.
178  *
179  * @see nl_addr_build()
180  * @see nl_addr_parse()
181  * @see nl_addr_put()
182  *
183  * @return Allocated address object or NULL upon failure.
184  */
185 struct nl_addr *nl_addr_alloc(size_t maxsize)
186 {
187  struct nl_addr *addr;
188 
189  addr = calloc(1, sizeof(*addr) + maxsize);
190  if (!addr)
191  return NULL;
192 
193  addr->a_refcnt = 1;
194  addr->a_maxsize = maxsize;
195 
196  return addr;
197 }
198 
199 /**
200  * Allocate abstract address based on a binary address.
201  * @arg family Address family
202  * @arg buf Binary address
203  * @arg size Length of binary address
204  *
205  * This function will allocate an abstract address capable of holding the
206  * binary address specified. The prefix length will be set to the full
207  * length of the binary address provided.
208  *
209  * @see nl_addr_alloc()
210  * @see nl_addr_alloc_attr()
211  * @see nl_addr_parse()
212  * @see nl_addr_put()
213  *
214  * @return Allocated address object or NULL upon failure.
215  */
216 struct nl_addr *nl_addr_build(int family, const void *buf, size_t size)
217 {
218  struct nl_addr *addr;
219 
220  addr = nl_addr_alloc(size);
221  if (!addr)
222  return NULL;
223 
224  addr->a_family = family;
225  addr->a_len = size;
226  addr->a_prefixlen = size*8;
227 
228  if (size)
229  memcpy(addr->a_addr, buf, size);
230 
231  return addr;
232 }
233 
234 /**
235  * Allocate abstract address based on Netlink attribute.
236  * @arg nla Netlink attribute
237  * @arg family Address family.
238  *
239  * Allocates an abstract address based on the specified Netlink attribute
240  * by interpreting the payload of the Netlink attribute as the binary
241  * address.
242  *
243  * This function is identical to:
244  * @code
245  * nl_addr_build(family, nla_data(nla), nla_len(nla));
246  * @endcode
247  *
248  * @see nl_addr_alloc()
249  * @see nl_addr_build()
250  * @see nl_addr_parse()
251  * @see nl_addr_put()
252  *
253  * @return Allocated address object or NULL upon failure.
254  */
255 struct nl_addr *nl_addr_alloc_attr(const struct nlattr *nla, int family)
256 {
257  return nl_addr_build(family, nla_data(nla), nla_len(nla));
258 }
259 
260 /**
261  * Allocate abstract address based on character string
262  * @arg addrstr Address represented as character string.
263  * @arg hint Address family hint or AF_UNSPEC.
264  * @arg result Pointer to store resulting address.
265  *
266  * Regognizes the following address formats:
267  * @code
268  * Format Len Family
269  * ----------------------------------------------------------------
270  * IPv6 address format 16 AF_INET6
271  * ddd.ddd.ddd.ddd 4 AF_INET
272  * HH:HH:HH:HH:HH:HH 6 AF_LLC
273  * AA{.|,}NNNN 2 AF_DECnet
274  * HH:HH:HH:... variable AF_UNSPEC
275  * @endcode
276  *
277  * Special values:
278  * - none: All bits and length set to 0.
279  * - {default|all|any}: All bits set to 0, length based on hint or
280  * AF_INET if no hint is given.
281  *
282  * The prefix length may be appened at the end prefixed with a
283  * slash, e.g. 10.0.0.0/8.
284  *
285  * @see nl_addr_alloc()
286  * @see nl_addr_build()
287  * @see nl_addr_put()
288  *
289  * @return 0 on success or a negative error code.
290  */
291 int nl_addr_parse(const char *addrstr, int hint, struct nl_addr **result)
292 {
293  int err, copy = 0, len = 0, family = AF_UNSPEC;
294  char *str, *prefix, buf[32];
295  struct nl_addr *addr = NULL; /* gcc ain't that smart */
296 
297  str = strdup(addrstr);
298  if (!str) {
299  err = -NLE_NOMEM;
300  goto errout;
301  }
302 
303  prefix = strchr(str, '/');
304  if (prefix)
305  *prefix = '\0';
306 
307  if (!strcasecmp(str, "none")) {
308  family = hint;
309  goto prefix;
310  }
311 
312  if (!strcasecmp(str, "default") ||
313  !strcasecmp(str, "all") ||
314  !strcasecmp(str, "any")) {
315 
316  len = 0;
317 
318  switch (hint) {
319  case AF_INET:
320  case AF_UNSPEC:
321  /* Kind of a hack, we assume that if there is
322  * no hint given the user wants to have a IPv4
323  * address given back. */
324  family = AF_INET;
325  goto prefix;
326 
327  case AF_INET6:
328  family = AF_INET6;
329  goto prefix;
330 
331  case AF_LLC:
332  family = AF_LLC;
333  goto prefix;
334 
335  default:
336  err = -NLE_AF_NOSUPPORT;
337  goto errout;
338  }
339  }
340 
341  copy = 1;
342 
343  if (hint == AF_INET || hint == AF_UNSPEC) {
344  if (inet_pton(AF_INET, str, buf) > 0) {
345  family = AF_INET;
346  len = 4;
347  goto prefix;
348  }
349  if (hint == AF_INET) {
350  err = -NLE_NOADDR;
351  goto errout;
352  }
353  }
354 
355  if (hint == AF_INET6 || hint == AF_UNSPEC) {
356  if (inet_pton(AF_INET6, str, buf) > 0) {
357  family = AF_INET6;
358  len = 16;
359  goto prefix;
360  }
361  if (hint == AF_INET6) {
362  err = -NLE_NOADDR;
363  goto errout;
364  }
365  }
366 
367  if ((hint == AF_LLC || hint == AF_UNSPEC) && strchr(str, ':')) {
368  unsigned int a, b, c, d, e, f;
369 
370  if (sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
371  &a, &b, &c, &d, &e, &f) == 6) {
372  family = AF_LLC;
373  len = 6;
374  buf[0] = (unsigned char) a;
375  buf[1] = (unsigned char) b;
376  buf[2] = (unsigned char) c;
377  buf[3] = (unsigned char) d;
378  buf[4] = (unsigned char) e;
379  buf[5] = (unsigned char) f;
380  goto prefix;
381  }
382 
383  if (hint == AF_LLC) {
384  err = -NLE_NOADDR;
385  goto errout;
386  }
387  }
388 
389  if ((hint == AF_DECnet || hint == AF_UNSPEC) &&
390  (strchr(str, '.') || strchr(str, ','))) {
391  if (dnet_pton(str, buf) > 0) {
392  family = AF_DECnet;
393  len = 2;
394  goto prefix;
395  }
396  if (hint == AF_DECnet) {
397  err = -NLE_NOADDR;
398  goto errout;
399  }
400  }
401 
402  if (hint == AF_UNSPEC && strchr(str, ':')) {
403  size_t i = 0;
404  char *s = str, *p;
405  for (;;) {
406  long l = strtol(s, &p, 16);
407 
408  if (s == p || l > 0xff || i >= sizeof(buf)) {
409  err = -NLE_INVAL;
410  goto errout;
411  }
412 
413  buf[i++] = (unsigned char) l;
414  if (*p == '\0')
415  break;
416  s = ++p;
417  }
418 
419  len = i;
420  family = AF_UNSPEC;
421  goto prefix;
422  }
423 
424  err = -NLE_NOADDR;
425  goto errout;
426 
427 prefix:
428  addr = nl_addr_alloc(len);
429  if (!addr) {
430  err = -NLE_NOMEM;
431  goto errout;
432  }
433 
434  nl_addr_set_family(addr, family);
435 
436  if (copy)
437  nl_addr_set_binary_addr(addr, buf, len);
438 
439  if (prefix) {
440  char *p;
441  long pl = strtol(++prefix, &p, 0);
442  if (p == prefix) {
443  addr_destroy(addr);
444  err = -NLE_INVAL;
445  goto errout;
446  }
447  nl_addr_set_prefixlen(addr, pl);
448  } else
449  nl_addr_set_prefixlen(addr, len * 8);
450 
451  *result = addr;
452  err = 0;
453 errout:
454  free(str);
455 
456  return err;
457 }
458 
459 /**
460  * Clone existing abstract address object
461  * @arg addr Abstract address object
462  *
463  * Allocates new abstract address representing an identical clone of an
464  * existing address.
465  *
466  * @see nl_addr_alloc()
467  * @see nl_addr_put()
468  *
469  * @return Allocated abstract address or NULL upon failure.
470  */
471 struct nl_addr *nl_addr_clone(const struct nl_addr *addr)
472 {
473  struct nl_addr *new;
474 
475  new = nl_addr_build(addr->a_family, addr->a_addr, addr->a_len);
476  if (new)
477  new->a_prefixlen = addr->a_prefixlen;
478 
479  return new;
480 }
481 
482 /** @} */
483 
484 /**
485  * @name Managing Usage References
486  * @{
487  */
488 
489 /**
490  * Increase the reference counter of an abstract address
491  * @arg addr Abstract address
492  *
493  * Increases the reference counter of the address and thus prevents the
494  * release of the memory resources until the reference is given back
495  * using the function nl_addr_put().
496  *
497  * @see nl_addr_put()
498  *
499  * @return Pointer to the existing abstract address
500  */
501 struct nl_addr *nl_addr_get(struct nl_addr *addr)
502 {
503  addr->a_refcnt++;
504 
505  return addr;
506 }
507 
508 /**
509  * Decrease the reference counter of an abstract address
510  * @arg addr Abstract addr
511  *
512  * @note The resources of the abstract address will be freed after the
513  * last reference to the address has been returned.
514  *
515  * @see nl_addr_get()
516  */
517 void nl_addr_put(struct nl_addr *addr)
518 {
519  if (!addr)
520  return;
521 
522  if (addr->a_refcnt == 1)
523  addr_destroy(addr);
524  else
525  addr->a_refcnt--;
526 }
527 
528 /**
529  * Check whether an abstract address is shared.
530  * @arg addr Abstract address object.
531  *
532  * @return Non-zero if the abstract address is shared, otherwise 0.
533  */
534 int nl_addr_shared(const struct nl_addr *addr)
535 {
536  return addr->a_refcnt > 1;
537 }
538 
539 /** @} */
540 
541 /**
542  * @name Miscellaneous
543  * @{
544  */
545 
546 /**
547  * Compare abstract addresses
548  * @arg a An abstract address
549  * @arg b Another abstract address
550  *
551  * Verifies whether the address family, address length, prefix length, and
552  * binary addresses of two abstract addresses matches.
553  *
554  * @note This function will *not* respect the prefix length in the sense
555  * that only the actual prefix will be compared. Please refer to the
556  * nl_addr_cmp_prefix() function if you require this functionality.
557  *
558  * @see nl_addr_cmp_prefix()
559  *
560  * @return Integer less than, equal to or greather than zero if the two
561  * addresses match.
562  */
563 int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
564 {
565  int d = a->a_family - b->a_family;
566 
567  if (d == 0) {
568  d = a->a_len - b->a_len;
569 
570  if (a->a_len && d == 0) {
571  d = memcmp(a->a_addr, b->a_addr, a->a_len);
572 
573  if (d == 0)
574  return (a->a_prefixlen - b->a_prefixlen);
575  }
576  }
577 
578  return d;
579 }
580 
581 /**
582  * Compare the prefix of two abstract addresses
583  * @arg a An abstract address
584  * @arg b Another abstract address
585  *
586  * Verifies whether the address family and the binary address covered by
587  * the smaller prefix length of the two abstract addresses matches.
588  *
589  * @see nl_addr_cmp()
590  *
591  * @return Integer less than, equal to or greather than zero if the two
592  * addresses match.
593  */
594 int nl_addr_cmp_prefix(const struct nl_addr *a, const struct nl_addr *b)
595 {
596  int d = a->a_family - b->a_family;
597 
598  if (d == 0) {
599  int len = min(a->a_prefixlen, b->a_prefixlen);
600  int bytes = len / 8;
601 
602  d = memcmp(a->a_addr, b->a_addr, bytes);
603  if (d == 0 && (len % 8) != 0) {
604  int mask = (0xFF00 >> (len % 8)) & 0xFF;
605 
606  d = (a->a_addr[bytes] & mask) -
607  (b->a_addr[bytes] & mask);
608  }
609  }
610 
611  return d;
612 }
613 
614 /**
615  * Returns true if the address consists of all zeros
616  * @arg addr Abstract address
617  *
618  * @return 1 if the binary address consists of all zeros, 0 otherwise.
619  */
620 int nl_addr_iszero(const struct nl_addr *addr)
621 {
622  unsigned int i;
623 
624  for (i = 0; i < addr->a_len; i++)
625  if (addr->a_addr[i])
626  return 0;
627 
628  return 1;
629 }
630 
631 /**
632  * Check if address string is parseable for a specific address family
633  * @arg addr Address represented as character string.
634  * @arg family Desired address family.
635  *
636  * @return 1 if the address is parseable assuming the specified address family,
637  * otherwise 0 is returned.
638  */
639 int nl_addr_valid(const char *addr, int family)
640 {
641  int ret;
642  char buf[32];
643 
644  switch (family) {
645  case AF_INET:
646  case AF_INET6:
647  ret = inet_pton(family, addr, buf);
648  if (ret <= 0)
649  return 0;
650  break;
651 
652  case AF_DECnet:
653  ret = dnet_pton(addr, buf);
654  if (ret <= 0)
655  return 0;
656  break;
657 
658  case AF_LLC:
659  if (sscanf(addr, "%*02x:%*02x:%*02x:%*02x:%*02x:%*02x") != 6)
660  return 0;
661  break;
662  }
663 
664  return 1;
665 }
666 
667 /**
668  * Guess address family of abstract address based on address size
669  * @arg addr Abstract address object.
670  *
671  * @return Numeric address family or AF_UNSPEC
672  */
673 int nl_addr_guess_family(const struct nl_addr *addr)
674 {
675  switch (addr->a_len) {
676  case 4:
677  return AF_INET;
678  case 6:
679  return AF_LLC;
680  case 16:
681  return AF_INET6;
682  default:
683  return AF_UNSPEC;
684  }
685 }
686 
687 /**
688  * Fill out sockaddr structure with values from abstract address object.
689  * @arg addr Abstract address object.
690  * @arg sa Destination sockaddr structure buffer.
691  * @arg salen Length of sockaddr structure buffer.
692  *
693  * Fills out the specified sockaddr structure with the data found in the
694  * specified abstract address. The salen argument needs to be set to the
695  * size of sa but will be modified to the actual size used during before
696  * the function exits.
697  *
698  * @return 0 on success or a negative error code
699  */
700 int nl_addr_fill_sockaddr(const struct nl_addr *addr, struct sockaddr *sa,
701  socklen_t *salen)
702 {
703  switch (addr->a_family) {
704  case AF_INET: {
705  struct sockaddr_in *sai = (struct sockaddr_in *) sa;
706 
707  if (*salen < sizeof(*sai))
708  return -NLE_INVAL;
709 
710  if (addr->a_len == 4)
711  memcpy(&sai->sin_addr, addr->a_addr, 4);
712  else if (addr->a_len != 0)
713  return -NLE_INVAL;
714  else
715  memset(&sai->sin_addr, 0, 4);
716 
717  sai->sin_family = addr->a_family;
718  *salen = sizeof(*sai);
719  }
720  break;
721 
722  case AF_INET6: {
723  struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
724 
725  if (*salen < sizeof(*sa6))
726  return -NLE_INVAL;
727 
728  if (addr->a_len == 16)
729  memcpy(&sa6->sin6_addr, addr->a_addr, 16);
730  else if (addr->a_len != 0)
731  return -NLE_INVAL;
732  else
733  memset(&sa6->sin6_addr, 0, 16);
734 
735  sa6->sin6_family = addr->a_family;
736  *salen = sizeof(*sa6);
737  }
738  break;
739 
740  default:
741  return -NLE_INVAL;
742  }
743 
744  return 0;
745 }
746 
747 
748 /** @} */
749 
750 /**
751  * @name Getting Information About Addresses
752  * @{
753  */
754 
755 /**
756  * Call getaddrinfo() for an abstract address object.
757  * @arg addr Abstract address object.
758  * @arg result Pointer to store resulting address list.
759  *
760  * Calls getaddrinfo() for the specified abstract address in AI_NUMERICHOST
761  * mode.
762  *
763  * @note The caller is responsible for freeing the linked list using the
764  * interface provided by getaddrinfo(3).
765  *
766  * @return 0 on success or a negative error code.
767  */
768 int nl_addr_info(const struct nl_addr *addr, struct addrinfo **result)
769 {
770  int err;
771  char buf[INET6_ADDRSTRLEN+5];
772  struct addrinfo hint = {
773  .ai_flags = AI_NUMERICHOST,
774  .ai_family = addr->a_family,
775  };
776 
777  nl_addr2str(addr, buf, sizeof(buf));
778 
779  err = getaddrinfo(buf, NULL, &hint, result);
780  if (err != 0) {
781  switch (err) {
782  case EAI_ADDRFAMILY: return -NLE_AF_NOSUPPORT;
783  case EAI_AGAIN: return -NLE_AGAIN;
784  case EAI_BADFLAGS: return -NLE_INVAL;
785  case EAI_FAIL: return -NLE_NOADDR;
786  case EAI_FAMILY: return -NLE_AF_NOSUPPORT;
787  case EAI_MEMORY: return -NLE_NOMEM;
788  case EAI_NODATA: return -NLE_NOADDR;
789  case EAI_NONAME: return -NLE_OBJ_NOTFOUND;
790  case EAI_SERVICE: return -NLE_OPNOTSUPP;
791  case EAI_SOCKTYPE: return -NLE_BAD_SOCK;
792  default: return -NLE_FAILURE;
793  }
794  }
795 
796  return 0;
797 }
798 
799 /**
800  * Resolve abstract address object to a name using getnameinfo().
801  * @arg addr Abstract address object.
802  * @arg host Destination buffer for host name.
803  * @arg hostlen Length of destination buffer.
804  *
805  * Resolves the abstract address to a name and writes the looked up result
806  * into the host buffer. getnameinfo() is used to perform the lookup and
807  * is put into NI_NAMEREQD mode so the function will fail if the lookup
808  * couldn't be performed.
809  *
810  * @return 0 on success or a negative error code.
811  */
812 int nl_addr_resolve(const struct nl_addr *addr, char *host, size_t hostlen)
813 {
814  int err;
815  struct sockaddr_in6 buf;
816  socklen_t salen = sizeof(buf);
817 
818  err = nl_addr_fill_sockaddr(addr, (struct sockaddr *) &buf, &salen);
819  if (err < 0)
820  return err;
821 
822  err = getnameinfo((struct sockaddr *) &buf, salen, host, hostlen,
823  NULL, 0, NI_NAMEREQD);
824  if (err < 0)
825  return nl_syserr2nlerr(err);
826 
827  return 0;
828 }
829 
830 /** @} */
831 
832 /**
833  * @name Attributes
834  * @{
835  */
836 
837 /**
838  * Set address family
839  * @arg addr Abstract address object
840  * @arg family Address family
841  *
842  * @see nl_addr_get_family()
843  */
844 void nl_addr_set_family(struct nl_addr *addr, int family)
845 {
846  addr->a_family = family;
847 }
848 
849 /**
850  * Return address family
851  * @arg addr Abstract address object
852  *
853  * @see nl_addr_set_family()
854  *
855  * @return The numeric address family or `AF_UNSPEC`
856  */
857 int nl_addr_get_family(const struct nl_addr *addr)
858 {
859  return addr->a_family;
860 }
861 
862 /**
863  * Set binary address of abstract address object.
864  * @arg addr Abstract address object.
865  * @arg buf Buffer containing binary address.
866  * @arg len Length of buffer containing binary address.
867  *
868  * Modifies the binary address portion of the abstract address. The
869  * abstract address must be capable of holding the required amount
870  * or this function will fail.
871  *
872  * @note This function will *not* modify the prefix length. It is within
873  * the responsibility of the caller to set the prefix length to the
874  * desirable length.
875  *
876  * @see nl_addr_alloc()
877  * @see nl_addr_get_binary_addr()
878  * @see nl_addr_get_len()
879  *
880  * @return 0 on success or a negative error code.
881  */
882 int nl_addr_set_binary_addr(struct nl_addr *addr, const void *buf, size_t len)
883 {
884  if (len > addr->a_maxsize)
885  return -NLE_RANGE;
886 
887  addr->a_len = len;
888  memset(addr->a_addr, 0, addr->a_maxsize);
889 
890  if (len)
891  memcpy(addr->a_addr, buf, len);
892 
893  return 0;
894 }
895 
896 /**
897  * Get binary address of abstract address object.
898  * @arg addr Abstract address object.
899  *
900  * @see nl_addr_set_binary_addr()
901  * @see nl_addr_get_len()
902  *
903  * @return Pointer to binary address of length nl_addr_get_len()
904  */
905 void *nl_addr_get_binary_addr(const struct nl_addr *addr)
906 {
907  return (void*)addr->a_addr;
908 }
909 
910 /**
911  * Get length of binary address of abstract address object.
912  * @arg addr Abstract address object.
913  *
914  * @see nl_addr_get_binary_addr()
915  * @see nl_addr_set_binary_addr()
916  */
917 unsigned int nl_addr_get_len(const struct nl_addr *addr)
918 {
919  return addr->a_len;
920 }
921 
922 /**
923  * Set the prefix length of an abstract address
924  * @arg addr Abstract address object
925  * @arg prefixlen New prefix length
926  *
927  * @see nl_addr_get_prefixlen()
928  */
929 void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen)
930 {
931  addr->a_prefixlen = prefixlen;
932 }
933 
934 /**
935  * Return prefix length of abstract address object.
936  * @arg addr Abstract address object
937  *
938  * @see nl_addr_set_prefixlen()
939  */
940 unsigned int nl_addr_get_prefixlen(const struct nl_addr *addr)
941 {
942  return addr->a_prefixlen;
943 }
944 
945 /** @} */
946 
947 /**
948  * @name Translations to Strings
949  * @{
950  */
951 
952 /**
953  * Convert abstract address object to character string.
954  * @arg addr Abstract address object.
955  * @arg buf Destination buffer.
956  * @arg size Size of destination buffer.
957  *
958  * Converts an abstract address to a character string and stores
959  * the result in the specified destination buffer.
960  *
961  * @return Address represented in ASCII stored in destination buffer.
962  */
963 char *nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
964 {
965  unsigned int i;
966  char tmp[16];
967 
968  if (!addr || !addr->a_len) {
969  snprintf(buf, size, "none");
970  if (addr)
971  goto prefix;
972  else
973  return buf;
974  }
975 
976  switch (addr->a_family) {
977  case AF_INET:
978  inet_ntop(AF_INET, addr->a_addr, buf, size);
979  break;
980 
981  case AF_INET6:
982  inet_ntop(AF_INET6, addr->a_addr, buf, size);
983  break;
984 
985  case AF_DECnet:
986  dnet_ntop(addr->a_addr, addr->a_len, buf, size);
987  break;
988 
989  case AF_LLC:
990  default:
991  snprintf(buf, size, "%02x",
992  (unsigned char) addr->a_addr[0]);
993  for (i = 1; i < addr->a_len; i++) {
994  snprintf(tmp, sizeof(tmp), ":%02x",
995  (unsigned char) addr->a_addr[i]);
996  strncat(buf, tmp, size - strlen(buf) - 1);
997  }
998  break;
999  }
1000 
1001 prefix:
1002  if (addr->a_prefixlen != (8 * addr->a_len)) {
1003  snprintf(tmp, sizeof(tmp), "/%u", addr->a_prefixlen);
1004  strncat(buf, tmp, size - strlen(buf) - 1);
1005  }
1006 
1007  return buf;
1008 }
1009 
1010 /** @} */
1011 
1012 /**
1013  * @name Address Family Transformations
1014  * @{
1015  */
1016 
1017 static const struct trans_tbl afs[] = {
1018  __ADD(AF_UNSPEC,unspec),
1019  __ADD(AF_UNIX,unix),
1020  __ADD(AF_INET,inet),
1021  __ADD(AF_AX25,ax25),
1022  __ADD(AF_IPX,ipx),
1023  __ADD(AF_APPLETALK,appletalk),
1024  __ADD(AF_NETROM,netrom),
1025  __ADD(AF_BRIDGE,bridge),
1026  __ADD(AF_ATMPVC,atmpvc),
1027  __ADD(AF_X25,x25),
1028  __ADD(AF_INET6,inet6),
1029  __ADD(AF_ROSE,rose),
1030  __ADD(AF_DECnet,decnet),
1031  __ADD(AF_NETBEUI,netbeui),
1032  __ADD(AF_SECURITY,security),
1033  __ADD(AF_KEY,key),
1034  __ADD(AF_NETLINK,netlink),
1035  __ADD(AF_PACKET,packet),
1036  __ADD(AF_ASH,ash),
1037  __ADD(AF_ECONET,econet),
1038  __ADD(AF_ATMSVC,atmsvc),
1039 #ifdef AF_RDS
1040  __ADD(AF_RDS,rds),
1041 #endif
1042  __ADD(AF_SNA,sna),
1043  __ADD(AF_IRDA,irda),
1044  __ADD(AF_PPPOX,pppox),
1045  __ADD(AF_WANPIPE,wanpipe),
1046  __ADD(AF_LLC,llc),
1047 #ifdef AF_CAN
1048  __ADD(AF_CAN,can),
1049 #endif
1050 #ifdef AF_TIPC
1051  __ADD(AF_TIPC,tipc),
1052 #endif
1053  __ADD(AF_BLUETOOTH,bluetooth),
1054 #ifdef AF_IUCV
1055  __ADD(AF_IUCV,iucv),
1056 #endif
1057 #ifdef AF_RXRPC
1058  __ADD(AF_RXRPC,rxrpc),
1059 #endif
1060 #ifdef AF_ISDN
1061  __ADD(AF_ISDN,isdn),
1062 #endif
1063 #ifdef AF_PHONET
1064  __ADD(AF_PHONET,phonet),
1065 #endif
1066 #ifdef AF_IEEE802154
1067  __ADD(AF_IEEE802154,ieee802154),
1068 #endif
1069 #ifdef AF_CAIF
1070  __ADD(AF_CAIF,caif),
1071 #endif
1072 #ifdef AF_ALG
1073  __ADD(AF_ALG,alg),
1074 #endif
1075 #ifdef AF_NFC
1076  __ADD(AF_NFC,nfc),
1077 #endif
1078 };
1079 
1080 char *nl_af2str(int family, char *buf, size_t size)
1081 {
1082  return __type2str(family, buf, size, afs, ARRAY_SIZE(afs));
1083 }
1084 
1085 int nl_str2af(const char *name)
1086 {
1087  int fam = __str2type(name, afs, ARRAY_SIZE(afs));
1088  return fam >= 0 ? fam : -EINVAL;
1089 }
1090 
1091 /** @} */
1092 
1093 /** @} */
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition: addr.c:471
struct nl_addr * nl_addr_alloc(size_t maxsize)
Allocate empty abstract address.
Definition: addr.c:185
int nl_addr_resolve(const struct nl_addr *addr, char *host, size_t hostlen)
Resolve abstract address object to a name using getnameinfo().
Definition: addr.c:812
void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen)
Set the prefix length of an abstract address.
Definition: addr.c:929
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
Definition: addr.c:563
int nl_addr_guess_family(const struct nl_addr *addr)
Guess address family of abstract address based on address size.
Definition: addr.c:673
unsigned int nl_addr_get_prefixlen(const struct nl_addr *addr)
Return prefix length of abstract address object.
Definition: addr.c:940
struct nl_addr * nl_addr_build(int family, const void *buf, size_t size)
Allocate abstract address based on a binary address.
Definition: addr.c:216
int nl_addr_parse(const char *addrstr, int hint, struct nl_addr **result)
Allocate abstract address based on character string.
Definition: addr.c:291
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition: addr.c:501
void nl_addr_set_family(struct nl_addr *addr, int family)
Set address family.
Definition: addr.c:844
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
Definition: addr.c:255
int nl_addr_iszero(const struct nl_addr *addr)
Returns true if the address consists of all zeros.
Definition: addr.c:620
int nl_addr_set_binary_addr(struct nl_addr *addr, const void *buf, size_t len)
Set binary address of abstract address object.
Definition: addr.c:882
int nl_addr_info(const struct nl_addr *addr, struct addrinfo **result)
Call getaddrinfo() for an abstract address object.
Definition: addr.c:768
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:120
int nla_len(const struct nlattr *nla)
Return length of the payload .
Definition: attr.c:131
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition: addr.c:517
int nl_addr_valid(const char *addr, int family)
Check if address string is parseable for a specific address family.
Definition: addr.c:639
int nl_addr_fill_sockaddr(const struct nl_addr *addr, struct sockaddr *sa, socklen_t *salen)
Fill out sockaddr structure with values from abstract address object.
Definition: addr.c:700
int nl_addr_cmp_prefix(const struct nl_addr *a, const struct nl_addr *b)
Compare the prefix of two abstract addresses.
Definition: addr.c:594
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:917
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:905
int nl_addr_shared(const struct nl_addr *addr)
Check whether an abstract address is shared.
Definition: addr.c:534
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:963
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
Definition: addr.c:857