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