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