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. */
33static 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
45static 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
63static 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
112static 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
131static 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
151static 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 */
180struct 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 */
211struct 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 && buf)
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 */
256struct 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 */
292int 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 len = 4;
329 goto prefix;
330
331 case AF_INET6:
332 family = AF_INET6;
333 len = 16;
334 goto prefix;
335
336 case AF_LLC:
337 family = AF_LLC;
338 len = 6;
339 goto prefix;
340
341 default:
342 err = -NLE_AF_NOSUPPORT;
343 goto errout;
344 }
345 }
346
347 copy = 1;
348
349 if (hint == AF_INET || hint == AF_UNSPEC) {
350 if (inet_pton(AF_INET, str, buf) > 0) {
351 family = AF_INET;
352 len = 4;
353 goto prefix;
354 }
355 if (hint == AF_INET) {
356 err = -NLE_NOADDR;
357 goto errout;
358 }
359 }
360
361 if (hint == AF_INET6 || hint == AF_UNSPEC) {
362 if (inet_pton(AF_INET6, str, buf) > 0) {
363 family = AF_INET6;
364 len = 16;
365 goto prefix;
366 }
367 if (hint == AF_INET6) {
368 err = -NLE_NOADDR;
369 goto errout;
370 }
371 }
372
373 if ((hint == AF_LLC || hint == AF_UNSPEC) && strchr(str, ':')) {
374 unsigned int a, b, c, d, e, f;
375
376 if (sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
377 &a, &b, &c, &d, &e, &f) == 6) {
378 family = AF_LLC;
379 len = 6;
380 buf[0] = (unsigned char) a;
381 buf[1] = (unsigned char) b;
382 buf[2] = (unsigned char) c;
383 buf[3] = (unsigned char) d;
384 buf[4] = (unsigned char) e;
385 buf[5] = (unsigned char) f;
386 goto prefix;
387 }
388
389 if (hint == AF_LLC) {
390 err = -NLE_NOADDR;
391 goto errout;
392 }
393 }
394
395 if ((hint == AF_DECnet || hint == AF_UNSPEC) &&
396 (strchr(str, '.') || strchr(str, ','))) {
397 if (dnet_pton(str, buf) > 0) {
398 family = AF_DECnet;
399 len = 2;
400 goto prefix;
401 }
402 if (hint == AF_DECnet) {
403 err = -NLE_NOADDR;
404 goto errout;
405 }
406 }
407
408 if (hint == AF_MPLS) {
409 len = mpls_pton(AF_MPLS, str, buf, sizeof(buf));
410 if (len <= 0) {
411 err = -NLE_INVAL;
412 goto errout;
413 }
414 family = AF_MPLS;
415 plen = 20;
416 goto prefix;
417 }
418
419 if (hint == AF_UNSPEC && strchr(str, ':')) {
420 size_t i = 0;
421 char *s = str, *p;
422 for (;;) {
423 long l = strtol(s, &p, 16);
424
425 if (s == p || l > 0xff || i >= sizeof(buf)) {
426 err = -NLE_INVAL;
427 goto errout;
428 }
429
430 buf[i++] = (unsigned char) l;
431 if (*p == '\0')
432 break;
433 s = ++p;
434 }
435
436 len = i;
437 family = AF_UNSPEC;
438 goto prefix;
439 }
440
441 err = -NLE_NOADDR;
442 goto errout;
443
444prefix:
445 addr = nl_addr_alloc(len);
446 if (!addr) {
447 err = -NLE_NOMEM;
448 goto errout;
449 }
450
451 nl_addr_set_family(addr, family);
452
453 if (copy)
454 nl_addr_set_binary_addr(addr, buf, len);
455 else
456 addr->a_len = len;
457
458 if (prefix) {
459 char *p;
460 long pl = strtol(++prefix, &p, 0);
461 if (p == prefix) {
462 addr_destroy(addr);
463 err = -NLE_INVAL;
464 goto errout;
465 }
466 nl_addr_set_prefixlen(addr, pl);
467 } else {
468 if (copy && !plen)
469 plen = len * 8;
470 nl_addr_set_prefixlen(addr, plen);
471 }
472 *result = addr;
473 err = 0;
474errout:
475 free(str);
476
477 return err;
478}
479
480/**
481 * Clone existing abstract address object
482 * @arg addr Abstract address object
483 *
484 * Allocates new abstract address representing an identical clone of an
485 * existing address.
486 *
487 * @see nl_addr_alloc()
488 * @see nl_addr_put()
489 *
490 * @return Allocated abstract address or NULL upon failure.
491 */
492struct nl_addr *nl_addr_clone(const struct nl_addr *addr)
493{
494 struct nl_addr *new;
495
496 new = nl_addr_build(addr->a_family, addr->a_addr, addr->a_len);
497 if (new)
498 new->a_prefixlen = addr->a_prefixlen;
499
500 return new;
501}
502
503/** @} */
504
505/**
506 * @name Managing Usage References
507 * @{
508 */
509
510/**
511 * Increase the reference counter of an abstract address
512 * @arg addr Abstract address
513 *
514 * Increases the reference counter of the address and thus prevents the
515 * release of the memory resources until the reference is given back
516 * using the function nl_addr_put().
517 *
518 * @see nl_addr_put()
519 *
520 * @return Pointer to the existing abstract address
521 */
522struct nl_addr *nl_addr_get(struct nl_addr *addr)
523{
524 addr->a_refcnt++;
525
526 return addr;
527}
528
529/**
530 * Decrease the reference counter of an abstract address
531 * @arg addr Abstract addr
532 *
533 * @note The resources of the abstract address will be freed after the
534 * last reference to the address has been returned.
535 *
536 * @see nl_addr_get()
537 */
538void nl_addr_put(struct nl_addr *addr)
539{
540 if (!addr)
541 return;
542
543 if (addr->a_refcnt == 1)
544 addr_destroy(addr);
545 else
546 addr->a_refcnt--;
547}
548
549/**
550 * Check whether an abstract address is shared.
551 * @arg addr Abstract address object.
552 *
553 * @return Non-zero if the abstract address is shared, otherwise 0.
554 */
555int nl_addr_shared(const struct nl_addr *addr)
556{
557 return addr->a_refcnt > 1;
558}
559
560/** @} */
561
562/**
563 * @name Miscellaneous
564 * @{
565 */
566
567/**
568 * Compare abstract addresses
569 * @arg a An abstract address
570 * @arg b Another abstract address
571 *
572 * Verifies whether the address family, address length, prefix length, and
573 * binary addresses of two abstract addresses matches.
574 *
575 * @note This function will *not* respect the prefix length in the sense
576 * that only the actual prefix will be compared. Please refer to the
577 * nl_addr_cmp_prefix() function if you require this functionality.
578 *
579 * @see nl_addr_cmp_prefix()
580 *
581 * @return Integer less than, equal to or greather than zero if the two
582 * addresses match.
583 */
584int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
585{
586 int d;
587
588 if (a == b)
589 return 0;
590 if (!a)
591 return -1;
592 if (!b)
593 return 1;
594
595 d = a->a_family - b->a_family;
596 if (d == 0) {
597 d = a->a_len - b->a_len;
598
599 if (a->a_len && d == 0) {
600 d = memcmp(a->a_addr, b->a_addr, a->a_len);
601
602 if (d == 0)
603 return (a->a_prefixlen - b->a_prefixlen);
604 }
605 }
606
607 return d;
608}
609
610/**
611 * Compare the prefix of two abstract addresses
612 * @arg a An abstract address
613 * @arg b Another abstract address
614 *
615 * Verifies whether the address family and the binary address covered by
616 * the smaller prefix length of the two abstract addresses matches.
617 *
618 * @see nl_addr_cmp()
619 *
620 * @return Integer less than, equal to or greather than zero if the two
621 * addresses match.
622 */
623int nl_addr_cmp_prefix(const struct nl_addr *a, const struct nl_addr *b)
624{
625 int d = a->a_family - b->a_family;
626
627 if (d == 0) {
628 int len = min(a->a_prefixlen, b->a_prefixlen);
629 int bytes = len / 8;
630
631 d = memcmp(a->a_addr, b->a_addr, bytes);
632 if (d == 0 && (len % 8) != 0) {
633 int mask = (0xFF00 >> (len % 8)) & 0xFF;
634
635 d = (a->a_addr[bytes] & mask) -
636 (b->a_addr[bytes] & mask);
637 }
638 }
639
640 return d;
641}
642
643/**
644 * Returns true if the address consists of all zeros
645 * @arg addr Abstract address
646 *
647 * @return 1 if the binary address consists of all zeros, 0 otherwise.
648 */
649int nl_addr_iszero(const struct nl_addr *addr)
650{
651 unsigned int i;
652
653 for (i = 0; i < addr->a_len; i++)
654 if (addr->a_addr[i])
655 return 0;
656
657 return 1;
658}
659
660/**
661 * Check if address string is parseable for a specific address family
662 * @arg addr Address represented as character string.
663 * @arg family Desired address family.
664 *
665 * @return 1 if the address is parseable assuming the specified address family,
666 * otherwise 0 is returned.
667 */
668int nl_addr_valid(const char *addr, int family)
669{
670 int ret;
671 char buf[256]; /* MPLS has N-labels at 4-bytes / label */
672
673 switch (family) {
674 case AF_INET:
675 case AF_INET6:
676 ret = inet_pton(family, addr, buf);
677 if (ret <= 0)
678 return 0;
679 break;
680
681 case AF_MPLS:
682 ret = mpls_pton(family, addr, buf, sizeof(buf));
683 if (ret <= 0)
684 return 0;
685 break;
686
687 case AF_DECnet:
688 ret = dnet_pton(addr, buf);
689 if (ret <= 0)
690 return 0;
691 break;
692
693 case AF_LLC:
694 if (sscanf(addr, "%*02x:%*02x:%*02x:%*02x:%*02x:%*02x") != 6)
695 return 0;
696 break;
697 }
698
699 return 1;
700}
701
702/**
703 * Guess address family of abstract address based on address size
704 * @arg addr Abstract address object.
705 *
706 * @return Numeric address family or AF_UNSPEC
707 */
708int nl_addr_guess_family(const struct nl_addr *addr)
709{
710 switch (addr->a_len) {
711 case 4:
712 return AF_INET;
713 case 6:
714 return AF_LLC;
715 case 16:
716 return AF_INET6;
717 default:
718 return AF_UNSPEC;
719 }
720}
721
722/**
723 * Fill out sockaddr structure with values from abstract address object.
724 * @arg addr Abstract address object.
725 * @arg sa Destination sockaddr structure buffer.
726 * @arg salen Length of sockaddr structure buffer.
727 *
728 * Fills out the specified sockaddr structure with the data found in the
729 * specified abstract address. The salen argument needs to be set to the
730 * size of sa but will be modified to the actual size used during before
731 * the function exits.
732 *
733 * @return 0 on success or a negative error code
734 */
735int nl_addr_fill_sockaddr(const struct nl_addr *addr, struct sockaddr *sa,
736 socklen_t *salen)
737{
738 switch (addr->a_family) {
739 case AF_INET: {
740 struct sockaddr_in *sai = (struct sockaddr_in *) sa;
741
742 if (*salen < sizeof(*sai))
743 return -NLE_INVAL;
744
745 if (addr->a_len == 4)
746 memcpy(&sai->sin_addr, addr->a_addr, 4);
747 else if (addr->a_len != 0)
748 return -NLE_INVAL;
749 else
750 memset(&sai->sin_addr, 0, 4);
751
752 sai->sin_family = addr->a_family;
753 *salen = sizeof(*sai);
754 }
755 break;
756
757 case AF_INET6: {
758 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
759
760 if (*salen < sizeof(*sa6))
761 return -NLE_INVAL;
762
763 if (addr->a_len == 16)
764 memcpy(&sa6->sin6_addr, addr->a_addr, 16);
765 else if (addr->a_len != 0)
766 return -NLE_INVAL;
767 else
768 memset(&sa6->sin6_addr, 0, 16);
769
770 sa6->sin6_family = addr->a_family;
771 *salen = sizeof(*sa6);
772 }
773 break;
774
775 default:
776 return -NLE_INVAL;
777 }
778
779 return 0;
780}
781
782
783/** @} */
784
785/**
786 * @name Getting Information About Addresses
787 * @{
788 */
789
790/**
791 * Call getaddrinfo() for an abstract address object.
792 * @arg addr Abstract address object.
793 * @arg result Pointer to store resulting address list.
794 *
795 * Calls getaddrinfo() for the specified abstract address in AI_NUMERICHOST
796 * mode.
797 *
798 * @note The caller is responsible for freeing the linked list using the
799 * interface provided by getaddrinfo(3).
800 *
801 * @return 0 on success or a negative error code.
802 */
803int nl_addr_info(const struct nl_addr *addr, struct addrinfo **result)
804{
805 int err;
806 char buf[INET6_ADDRSTRLEN+5];
807 struct addrinfo hint = {
808 .ai_flags = AI_NUMERICHOST,
809 .ai_family = addr->a_family,
810 };
811
812 nl_addr2str(addr, buf, sizeof(buf));
813
814 err = getaddrinfo(buf, NULL, &hint, result);
815 if (err != 0) {
816 switch (err) {
817 case EAI_ADDRFAMILY: return -NLE_AF_NOSUPPORT;
818 case EAI_AGAIN: return -NLE_AGAIN;
819 case EAI_BADFLAGS: return -NLE_INVAL;
820 case EAI_FAIL: return -NLE_NOADDR;
821 case EAI_FAMILY: return -NLE_AF_NOSUPPORT;
822 case EAI_MEMORY: return -NLE_NOMEM;
823 case EAI_NODATA: return -NLE_NOADDR;
824 case EAI_NONAME: return -NLE_OBJ_NOTFOUND;
825 case EAI_SERVICE: return -NLE_OPNOTSUPP;
826 case EAI_SOCKTYPE: return -NLE_BAD_SOCK;
827 default: return -NLE_FAILURE;
828 }
829 }
830
831 return 0;
832}
833
834/**
835 * Resolve abstract address object to a name using getnameinfo().
836 * @arg addr Abstract address object.
837 * @arg host Destination buffer for host name.
838 * @arg hostlen Length of destination buffer.
839 *
840 * Resolves the abstract address to a name and writes the looked up result
841 * into the host buffer. getnameinfo() is used to perform the lookup and
842 * is put into NI_NAMEREQD mode so the function will fail if the lookup
843 * couldn't be performed.
844 *
845 * @return 0 on success or a negative error code.
846 */
847int nl_addr_resolve(const struct nl_addr *addr, char *host, size_t hostlen)
848{
849 int err;
850 struct sockaddr_in6 buf;
851 socklen_t salen = sizeof(buf);
852
853 err = nl_addr_fill_sockaddr(addr, (struct sockaddr *) &buf, &salen);
854 if (err < 0)
855 return err;
856
857 err = getnameinfo((struct sockaddr *) &buf, salen, host, hostlen,
858 NULL, 0, NI_NAMEREQD);
859 if (err < 0)
860 return nl_syserr2nlerr(err);
861
862 return 0;
863}
864
865/** @} */
866
867/**
868 * @name Attributes
869 * @{
870 */
871
872/**
873 * Set address family
874 * @arg addr Abstract address object
875 * @arg family Address family
876 *
877 * @see nl_addr_get_family()
878 */
879void nl_addr_set_family(struct nl_addr *addr, int family)
880{
881 addr->a_family = family;
882}
883
884/**
885 * Return address family
886 * @arg addr Abstract address object
887 *
888 * @see nl_addr_set_family()
889 *
890 * @return The numeric address family or `AF_UNSPEC`
891 */
892int nl_addr_get_family(const struct nl_addr *addr)
893{
894 return addr->a_family;
895}
896
897/**
898 * Set binary address of abstract address object.
899 * @arg addr Abstract address object.
900 * @arg buf Buffer containing binary address.
901 * @arg len Length of buffer containing binary address.
902 *
903 * Modifies the binary address portion of the abstract address. The
904 * abstract address must be capable of holding the required amount
905 * or this function will fail.
906 *
907 * @note This function will *not* modify the prefix length. It is within
908 * the responsibility of the caller to set the prefix length to the
909 * desirable length.
910 *
911 * @see nl_addr_alloc()
912 * @see nl_addr_get_binary_addr()
913 * @see nl_addr_get_len()
914 *
915 * @return 0 on success or a negative error code.
916 */
917int nl_addr_set_binary_addr(struct nl_addr *addr, const void *buf, size_t len)
918{
919 if (len > addr->a_maxsize)
920 return -NLE_RANGE;
921
922 addr->a_len = len;
923 memset(addr->a_addr, 0, addr->a_maxsize);
924
925 if (len)
926 memcpy(addr->a_addr, buf, len);
927
928 return 0;
929}
930
931/**
932 * Get binary address of abstract address object.
933 * @arg addr Abstract address object.
934 *
935 * @see nl_addr_set_binary_addr()
936 * @see nl_addr_get_len()
937 *
938 * @return Pointer to binary address of length nl_addr_get_len()
939 */
940void *nl_addr_get_binary_addr(const struct nl_addr *addr)
941{
942 return (void*)addr->a_addr;
943}
944
945/**
946 * Get length of binary address of abstract address object.
947 * @arg addr Abstract address object.
948 *
949 * @see nl_addr_get_binary_addr()
950 * @see nl_addr_set_binary_addr()
951 */
952unsigned int nl_addr_get_len(const struct nl_addr *addr)
953{
954 return addr->a_len;
955}
956
957/**
958 * Set the prefix length of an abstract address
959 * @arg addr Abstract address object
960 * @arg prefixlen New prefix length
961 *
962 * @see nl_addr_get_prefixlen()
963 */
964void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen)
965{
966 addr->a_prefixlen = prefixlen;
967}
968
969/**
970 * Return prefix length of abstract address object.
971 * @arg addr Abstract address object
972 *
973 * @see nl_addr_set_prefixlen()
974 */
975unsigned int nl_addr_get_prefixlen(const struct nl_addr *addr)
976{
977 return addr->a_prefixlen;
978}
979
980/** @} */
981
982/**
983 * @name Translations to Strings
984 * @{
985 */
986
987/**
988 * Convert abstract address object to character string.
989 * @arg addr Abstract address object.
990 * @arg buf Destination buffer.
991 * @arg size Size of destination buffer.
992 *
993 * Converts an abstract address to a character string and stores
994 * the result in the specified destination buffer.
995 *
996 * @return Address represented in ASCII stored in destination buffer.
997 */
998char *nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
999{
1000 unsigned int i;
1001 char tmp[16];
1002
1003 if (!addr || !addr->a_len) {
1004 snprintf(buf, size, "none");
1005 if (addr)
1006 goto prefix;
1007 else
1008 return buf;
1009 }
1010
1011 switch (addr->a_family) {
1012 case AF_INET:
1013 inet_ntop(AF_INET, addr->a_addr, buf, size);
1014 break;
1015
1016 case AF_INET6:
1017 inet_ntop(AF_INET6, addr->a_addr, buf, size);
1018 break;
1019
1020 case AF_MPLS:
1021 mpls_ntop(AF_MPLS, addr->a_addr, buf, size);
1022 break;
1023
1024 case AF_DECnet:
1025 dnet_ntop(addr->a_addr, addr->a_len, buf, size);
1026 break;
1027
1028 case AF_LLC:
1029 default:
1030 snprintf(buf, size, "%02x",
1031 (unsigned char) addr->a_addr[0]);
1032 for (i = 1; i < addr->a_len; i++) {
1033 snprintf(tmp, sizeof(tmp), ":%02x",
1034 (unsigned char) addr->a_addr[i]);
1035 strncat(buf, tmp, size - strlen(buf) - 1);
1036 }
1037 break;
1038 }
1039
1040prefix:
1041 if (addr->a_family != AF_MPLS &&
1042 addr->a_prefixlen != (8 * addr->a_len)) {
1043 snprintf(tmp, sizeof(tmp), "/%u", addr->a_prefixlen);
1044 strncat(buf, tmp, size - strlen(buf) - 1);
1045 }
1046
1047 return buf;
1048}
1049
1050/** @} */
1051
1052/**
1053 * @name Address Family Transformations
1054 * @{
1055 */
1056
1057static const struct trans_tbl afs[] = {
1058 __ADD(AF_UNSPEC,unspec),
1059 __ADD(AF_UNIX,unix),
1060 __ADD(AF_INET,inet),
1061 __ADD(AF_AX25,ax25),
1062 __ADD(AF_IPX,ipx),
1063 __ADD(AF_APPLETALK,appletalk),
1064 __ADD(AF_NETROM,netrom),
1065 __ADD(AF_BRIDGE,bridge),
1066 __ADD(AF_ATMPVC,atmpvc),
1067 __ADD(AF_X25,x25),
1068 __ADD(AF_INET6,inet6),
1069 __ADD(AF_ROSE,rose),
1070 __ADD(AF_DECnet,decnet),
1071 __ADD(AF_NETBEUI,netbeui),
1072 __ADD(AF_SECURITY,security),
1073 __ADD(AF_KEY,key),
1074 __ADD(AF_NETLINK,netlink),
1075 __ADD(AF_PACKET,packet),
1076 __ADD(AF_ASH,ash),
1077 __ADD(AF_ECONET,econet),
1078 __ADD(AF_ATMSVC,atmsvc),
1079#ifdef AF_RDS
1080 __ADD(AF_RDS,rds),
1081#endif
1082 __ADD(AF_SNA,sna),
1083 __ADD(AF_IRDA,irda),
1084 __ADD(AF_PPPOX,pppox),
1085 __ADD(AF_WANPIPE,wanpipe),
1086 __ADD(AF_LLC,llc),
1087#ifdef AF_CAN
1088 __ADD(AF_CAN,can),
1089#endif
1090#ifdef AF_TIPC
1091 __ADD(AF_TIPC,tipc),
1092#endif
1093 __ADD(AF_BLUETOOTH,bluetooth),
1094#ifdef AF_IUCV
1095 __ADD(AF_IUCV,iucv),
1096#endif
1097#ifdef AF_RXRPC
1098 __ADD(AF_RXRPC,rxrpc),
1099#endif
1100#ifdef AF_ISDN
1101 __ADD(AF_ISDN,isdn),
1102#endif
1103#ifdef AF_PHONET
1104 __ADD(AF_PHONET,phonet),
1105#endif
1106#ifdef AF_IEEE802154
1107 __ADD(AF_IEEE802154,ieee802154),
1108#endif
1109#ifdef AF_CAIF
1110 __ADD(AF_CAIF,caif),
1111#endif
1112#ifdef AF_ALG
1113 __ADD(AF_ALG,alg),
1114#endif
1115#ifdef AF_NFC
1116 __ADD(AF_NFC,nfc),
1117#endif
1118#ifdef AF_VSOCK
1119 __ADD(AF_VSOCK,vsock),
1120#endif
1121 __ADD(AF_MPLS,mpls),
1122};
1123
1124char *nl_af2str(int family, char *buf, size_t size)
1125{
1126 return __type2str(family, buf, size, afs, ARRAY_SIZE(afs));
1127}
1128
1129int nl_str2af(const char *name)
1130{
1131 int fam = __str2type(name, afs, ARRAY_SIZE(afs));
1132 return fam >= 0 ? fam : -EINVAL;
1133}
1134
1135/** @} */
1136
1137/** @} */
int nl_addr_info(const struct nl_addr *addr, struct addrinfo **result)
Call getaddrinfo() for an abstract address object.
Definition: addr.c:803
int nl_addr_iszero(const struct nl_addr *addr)
Returns true if the address consists of all zeros.
Definition: addr.c:649
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:735
void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen)
Set the prefix length of an abstract address.
Definition: addr.c:964
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition: addr.c:522
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
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:847
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:940
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
Definition: addr.c:584
struct nl_addr * nl_addr_alloc(size_t maxsize)
Allocate empty abstract address.
Definition: addr.c:180
int nl_addr_parse(const char *addrstr, int hint, struct nl_addr **result)
Allocate abstract address based on character string.
Definition: addr.c:292
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition: addr.c:492
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:917
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
Definition: addr.c:892
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:623
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:998
int nl_addr_valid(const char *addr, int family)
Check if address string is parseable for a specific address family.
Definition: addr.c:668
unsigned int nl_addr_get_prefixlen(const struct nl_addr *addr)
Return prefix length of abstract address object.
Definition: addr.c:975
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:952
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition: addr.c:538
void nl_addr_set_family(struct nl_addr *addr, int family)
Set address family.
Definition: addr.c:879
int nl_addr_shared(const struct nl_addr *addr)
Check whether an abstract address is shared.
Definition: addr.c:555
int nl_addr_guess_family(const struct nl_addr *addr)
Guess address family of abstract address based on address size.
Definition: addr.c:708
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:114
int nla_len(const struct nlattr *nla)
Return length of the payload .
Definition: attr.c:125