libnl 1.1.4
addr.c
1/*
2 * lib/addr.c Abstract 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-2006 Thomas Graf <tgraf@suug.ch>
10 */
11
12/**
13 * @ingroup utils
14 * @defgroup addr Abstract Address
15 *
16 * @par 1) Transform character string to abstract address
17 * @code
18 * struct nl_addr *a = nl_addr_parse("::1", AF_UNSPEC);
19 * printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a)));
20 * nl_addr_put(a);
21 * a = nl_addr_parse("11:22:33:44:55:66", AF_UNSPEC);
22 * printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a)));
23 * nl_addr_put(a);
24 * @endcode
25 * @{
26 */
27
28#include <netlink-local.h>
29#include <netlink/netlink.h>
30#include <netlink/utils.h>
31#include <netlink/addr.h>
32#include <linux/socket.h>
33
34/* All this DECnet stuff is stolen from iproute2, thanks to whoever wrote
35 * this, probably Alexey. */
36static inline uint16_t dn_ntohs(uint16_t addr)
37{
38 union {
39 uint8_t byte[2];
40 uint16_t word;
41 } u = {
42 .word = addr,
43 };
44
45 return ((uint16_t) u.byte[0]) | (((uint16_t) u.byte[1]) << 8);
46}
47
48static inline int do_digit(char *str, uint16_t *addr, uint16_t scale,
49 size_t *pos, size_t len, int *started)
50{
51 uint16_t tmp = *addr / scale;
52
53 if (*pos == len)
54 return 1;
55
56 if (((tmp) > 0) || *started || (scale == 1)) {
57 *str = tmp + '0';
58 *started = 1;
59 (*pos)++;
60 *addr -= (tmp * scale);
61 }
62
63 return 0;
64}
65
66static const char *dnet_ntop(char *addrbuf, size_t addrlen, char *str,
67 size_t len)
68{
69 uint16_t addr = dn_ntohs(*(uint16_t *)addrbuf);
70 uint16_t area = addr >> 10;
71 size_t pos = 0;
72 int started = 0;
73
74 if (addrlen != 2)
75 return NULL;
76
77 addr &= 0x03ff;
78
79 if (len == 0)
80 return str;
81
82 if (do_digit(str + pos, &area, 10, &pos, len, &started))
83 return str;
84
85 if (do_digit(str + pos, &area, 1, &pos, len, &started))
86 return str;
87
88 if (pos == len)
89 return str;
90
91 *(str + pos) = '.';
92 pos++;
93 started = 0;
94
95 if (do_digit(str + pos, &addr, 1000, &pos, len, &started))
96 return str;
97
98 if (do_digit(str + pos, &addr, 100, &pos, len, &started))
99 return str;
100
101 if (do_digit(str + pos, &addr, 10, &pos, len, &started))
102 return str;
103
104 if (do_digit(str + pos, &addr, 1, &pos, len, &started))
105 return str;
106
107 if (pos == len)
108 return str;
109
110 *(str + pos) = 0;
111
112 return str;
113}
114
115static int dnet_num(const char *src, uint16_t * dst)
116{
117 int rv = 0;
118 int tmp;
119 *dst = 0;
120
121 while ((tmp = *src++) != 0) {
122 tmp -= '0';
123 if ((tmp < 0) || (tmp > 9))
124 return rv;
125
126 rv++;
127 (*dst) *= 10;
128 (*dst) += tmp;
129 }
130
131 return rv;
132}
133
134static inline int dnet_pton(const char *src, char *addrbuf)
135{
136 uint16_t area = 0;
137 uint16_t node = 0;
138 int pos;
139
140 pos = dnet_num(src, &area);
141 if ((pos == 0) || (area > 63) ||
142 ((*(src + pos) != '.') && (*(src + pos) != ',')))
143 return -EINVAL;
144
145 pos = dnet_num(src + pos + 1, &node);
146 if ((pos == 0) || (node > 1023))
147 return -EINVAL;
148
149 *(uint16_t *)addrbuf = dn_ntohs((area << 10) | node);
150
151 return 1;
152}
153
154/**
155 * @name Creating Abstract Addresses
156 * @{
157 */
158
159/**
160 * Allocate new abstract address object.
161 * @arg maxsize Maximum size of the binary address.
162 * @return Newly allocated address object or NULL
163 */
164struct nl_addr *nl_addr_alloc(size_t maxsize)
165{
166 struct nl_addr *addr;
167
168 addr = calloc(1, sizeof(*addr) + maxsize);
169 if (!addr) {
170 nl_errno(ENOMEM);
171 return NULL;
172 }
173
174 addr->a_refcnt = 1;
175 addr->a_maxsize = maxsize;
176
177 return addr;
178}
179
180/**
181 * Allocate new abstract address object based on a binary address.
182 * @arg family Address family.
183 * @arg buf Buffer containing the binary address.
184 * @arg size Length of binary address buffer.
185 * @return Newly allocated address handle or NULL
186 */
187struct nl_addr *nl_addr_build(int family, void *buf, size_t size)
188{
189 struct nl_addr *addr;
190
191 addr = nl_addr_alloc(size);
192 if (!addr)
193 return NULL;
194
195 addr->a_family = family;
196 addr->a_len = size;
197 addr->a_prefixlen = size*8;
198
199 if (size)
200 memcpy(addr->a_addr, buf, size);
201
202 return addr;
203}
204
205/**
206 * Allocate abstract address object based on a character string
207 * @arg addrstr Address represented as character string.
208 * @arg hint Address family hint or AF_UNSPEC.
209 *
210 * Regognizes the following address formats:
211 *@code
212 * Format Len Family
213 * ----------------------------------------------------------------
214 * IPv6 address format 16 AF_INET6
215 * ddd.ddd.ddd.ddd 4 AF_INET
216 * HH:HH:HH:HH:HH:HH 6 AF_LLC
217 * AA{.|,}NNNN 2 AF_DECnet
218 * HH:HH:HH:... variable AF_UNSPEC
219 * @endcode
220 *
221 * Special values:
222 * - none: All bits and length set to 0.
223 * - {default|all|any}: All bits set to 0, length based on hint or
224 * AF_INET if no hint is given.
225 *
226 * The prefix length may be appened at the end prefixed with a
227 * slash, e.g. 10.0.0.0/8.
228 *
229 * @return Newly allocated abstract address object or NULL.
230 */
231struct nl_addr *nl_addr_parse(const char *addrstr, int hint)
232{
233 int err, copy = 0, len = 0, family = AF_UNSPEC;
234 char *str, *prefix, buf[32];
235 struct nl_addr *addr = NULL; /* gcc ain't that smart */
236
237 str = strdup(addrstr);
238 if (!str) {
239 err = nl_errno(ENOMEM);
240 goto errout;
241 }
242
243 prefix = strchr(str, '/');
244 if (prefix)
245 *prefix = '\0';
246
247 if (!strcasecmp(str, "none")) {
248 family = hint;
249 goto prefix;
250 }
251
252 if (!strcasecmp(str, "default") ||
253 !strcasecmp(str, "all") ||
254 !strcasecmp(str, "any")) {
255
256 switch (hint) {
257 case AF_INET:
258 case AF_UNSPEC:
259 /* Kind of a hack, we assume that if there is
260 * no hint given the user wants to have a IPv4
261 * address given back. */
262 family = AF_INET;
263 len = 4;
264 goto prefix;
265
266 case AF_INET6:
267 family = AF_INET6;
268 len = 16;
269 goto prefix;
270
271 case AF_LLC:
272 family = AF_LLC;
273 len = 6;
274 goto prefix;
275
276 default:
277 err = nl_error(EINVAL, "Unsuported address" \
278 "family for default address");
279 goto errout;
280 }
281 }
282
283 copy = 1;
284
285 if (hint == AF_INET || hint == AF_UNSPEC) {
286 if (inet_pton(AF_INET, str, buf) > 0) {
287 family = AF_INET;
288 len = 4;
289 goto prefix;
290 }
291 if (hint == AF_INET) {
292 err = nl_error(EINVAL, "Invalid IPv4 address");
293 goto errout;
294 }
295 }
296
297 if (hint == AF_INET6 || hint == AF_UNSPEC) {
298 if (inet_pton(AF_INET6, str, buf) > 0) {
299 family = AF_INET6;
300 len = 16;
301 goto prefix;
302 }
303 if (hint == AF_INET6) {
304 err = nl_error(EINVAL, "Invalid IPv6 address");
305 goto errout;
306 }
307 }
308
309 if ((hint == AF_LLC || hint == AF_UNSPEC) && strchr(str, ':')) {
310 unsigned int a, b, c, d, e, f;
311
312 if (sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
313 &a, &b, &c, &d, &e, &f) == 6) {
314 family = AF_LLC;
315 len = 6;
316 buf[0] = (unsigned char) a;
317 buf[1] = (unsigned char) b;
318 buf[2] = (unsigned char) c;
319 buf[3] = (unsigned char) d;
320 buf[4] = (unsigned char) e;
321 buf[5] = (unsigned char) f;
322 goto prefix;
323 }
324
325 if (hint == AF_LLC) {
326 err = nl_error(EINVAL, "Invalid link layer address");
327 goto errout;
328 }
329 }
330
331 if ((hint == AF_DECnet || hint == AF_UNSPEC) &&
332 (strchr(str, '.') || strchr(str, ','))) {
333 if (dnet_pton(str, buf) > 0) {
334 family = AF_DECnet;
335 len = 2;
336 goto prefix;
337 }
338 if (hint == AF_DECnet) {
339 err = nl_error(EINVAL, "Invalid DECnet address");
340 goto errout;
341 }
342 }
343
344 if (hint == AF_UNSPEC && strchr(str, ':')) {
345 int i = 0;
346 char *s = str, *p;
347 for (;;) {
348 long l = strtol(s, &p, 16);
349
350 if (s == p || l > 0xff || i >= sizeof(buf)) {
351 err = -EINVAL;
352 goto errout;
353 }
354
355 buf[i++] = (unsigned char) l;
356 if (*p == '\0')
357 break;
358 s = ++p;
359 }
360
361 len = i;
362 family = AF_UNSPEC;
363 goto prefix;
364 }
365
366 err = nl_error(EINVAL, "Invalid address");
367 goto errout;
368
369prefix:
370 addr = nl_addr_alloc(len);
371 if (!addr) {
372 err = nl_errno(ENOMEM);
373 goto errout;
374 }
375
376 nl_addr_set_family(addr, family);
377
378 if (copy)
379 nl_addr_set_binary_addr(addr, buf, len);
380
381 if (prefix) {
382 char *p;
383 long pl = strtol(++prefix, &p, 0);
384 if (p == prefix) {
385 nl_addr_destroy(addr);
386 err = -EINVAL;
387 goto errout;
388 }
389 nl_addr_set_prefixlen(addr, pl);
390 } else
391 nl_addr_set_prefixlen(addr, len * 8);
392
393 err = 0;
394errout:
395 free(str);
396
397 return err ? NULL : addr;
398}
399
400/**
401 * Clone existing abstract address object.
402 * @arg addr Abstract address object.
403 * @return Newly allocated abstract address object being a duplicate of the
404 * specified address object or NULL if a failure occured.
405 */
406struct nl_addr *nl_addr_clone(struct nl_addr *addr)
407{
408 struct nl_addr *new;
409
410 new = nl_addr_build(addr->a_family, addr->a_addr, addr->a_len);
411 if (new)
412 new->a_prefixlen = addr->a_prefixlen;
413
414 return new;
415}
416
417/** @} */
418
419/**
420 * @name Destroying Abstract Addresses
421 * @{
422 */
423
424/**
425 * Destroy abstract address object.
426 * @arg addr Abstract address object.
427 */
428void nl_addr_destroy(struct nl_addr *addr)
429{
430 if (!addr)
431 return;
432
433 if (addr->a_refcnt != 1)
434 BUG();
435
436 free(addr);
437}
438
439/** @} */
440
441/**
442 * @name Managing Usage References
443 * @{
444 */
445
446struct nl_addr *nl_addr_get(struct nl_addr *addr)
447{
448 addr->a_refcnt++;
449
450 return addr;
451}
452
453void nl_addr_put(struct nl_addr *addr)
454{
455 if (!addr)
456 return;
457
458 if (addr->a_refcnt == 1)
459 nl_addr_destroy(addr);
460 else
461 addr->a_refcnt--;
462}
463
464/**
465 * Check whether an abstract address object is shared.
466 * @arg addr Abstract address object.
467 * @return Non-zero if the abstract address object is shared, otherwise 0.
468 */
469int nl_addr_shared(struct nl_addr *addr)
470{
471 return addr->a_refcnt > 1;
472}
473
474/** @} */
475
476/**
477 * @name Miscellaneous
478 * @{
479 */
480
481/**
482 * Compares two abstract address objects.
483 * @arg a A abstract address object.
484 * @arg b Another abstract address object.
485 *
486 * @return Integer less than, equal to or greather than zero if \c is found,
487 * respectively to be less than, to, or be greater than \c b.
488 */
489int nl_addr_cmp(struct nl_addr *a, struct nl_addr *b)
490{
491 int d = a->a_family - b->a_family;
492
493 if (d == 0) {
494 d = a->a_len - b->a_len;
495
496 if (a->a_len && d == 0)
497 return memcmp(a->a_addr, b->a_addr, a->a_len);
498 }
499
500 return d;
501}
502
503/**
504 * Compares the prefix of two abstract address objects.
505 * @arg a A abstract address object.
506 * @arg b Another abstract address object.
507 *
508 * @return Integer less than, equal to or greather than zero if \c is found,
509 * respectively to be less than, to, or be greater than \c b.
510 */
511int nl_addr_cmp_prefix(struct nl_addr *a, struct nl_addr *b)
512{
513 int d = a->a_family - b->a_family;
514
515 if (d == 0) {
516 int len = min(a->a_prefixlen, b->a_prefixlen);
517 int bytes = len / 8;
518
519 d = memcmp(a->a_addr, b->a_addr, bytes);
520 if (d == 0) {
521 int mask = (1UL << (len % 8)) - 1UL;
522
523 d = (a->a_addr[bytes] & mask) -
524 (b->a_addr[bytes] & mask);
525 }
526 }
527
528 return d;
529}
530
531/**
532 * Returns true if the address consists of all zeros
533 * @arg addr Address to look at.
534 */
535int nl_addr_iszero(struct nl_addr *addr)
536{
537 int i;
538
539 for (i = 0; i < addr->a_len; i++)
540 if (addr->a_addr[i])
541 return 0;
542
543 return 1;
544}
545
546/**
547 * Check if an address matches a certain family.
548 * @arg addr Address represented as character string.
549 * @arg family Desired address family.
550 *
551 * @return 1 if the address is of the desired address family,
552 * otherwise 0 is returned.
553 */
554int nl_addr_valid(char *addr, int family)
555{
556 int ret;
557 char buf[32];
558
559 switch (family) {
560 case AF_INET:
561 case AF_INET6:
562 ret = inet_pton(family, addr, buf);
563 if (ret <= 0)
564 return 0;
565 break;
566
567 case AF_DECnet:
568 ret = dnet_pton(addr, buf);
569 if (ret <= 0)
570 return 0;
571 break;
572
573 case AF_LLC:
574 if (sscanf(addr, "%*02x:%*02x:%*02x:%*02x:%*02x:%*02x") != 6)
575 return 0;
576 break;
577 }
578
579 return 1;
580}
581
582/**
583 * Guess address family of an abstract address object based on address size.
584 * @arg addr Abstract address object.
585 * @return Address family or AF_UNSPEC if guessing wasn't successful.
586 */
587int nl_addr_guess_family(struct nl_addr *addr)
588{
589 switch (addr->a_len) {
590 case 4:
591 return AF_INET;
592 case 6:
593 return AF_LLC;
594 case 16:
595 return AF_INET6;
596 default:
597 return AF_UNSPEC;
598 }
599}
600
601/**
602 * Fill out sockaddr structure with values from abstract address object.
603 * @arg addr Abstract address object.
604 * @arg sa Destination sockaddr structure buffer.
605 * @arg salen Length of sockaddr structure buffer.
606 *
607 * Fills out the specified sockaddr structure with the data found in the
608 * specified abstract address. The salen argument needs to be set to the
609 * size of sa but will be modified to the actual size used during before
610 * the function exits.
611 *
612 * @return 0 on success or a negative error code
613 */
614int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa,
615 socklen_t *salen)
616{
617 switch (addr->a_family) {
618 case AF_INET: {
619 struct sockaddr_in *sai = (struct sockaddr_in *) sa;
620
621 if (*salen < sizeof(*sai))
622 return -EINVAL;
623
624 sai->sin_family = addr->a_family;
625 memcpy(&sai->sin_addr, addr->a_addr, 4);
626 *salen = sizeof(*sai);
627 }
628 break;
629
630 case AF_INET6: {
631 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
632
633 if (*salen < sizeof(*sa6))
634 return -EINVAL;
635
636 sa6->sin6_family = addr->a_family;
637 memcpy(&sa6->sin6_addr, addr->a_addr, 16);
638 *salen = sizeof(*sa6);
639 }
640 break;
641
642 default:
643 return -EINVAL;
644 }
645
646 return 0;
647}
648
649
650/** @} */
651
652/**
653 * @name Getting Information About Addresses
654 * @{
655 */
656
657/**
658 * Call getaddrinfo() for an abstract address object.
659 * @arg addr Abstract address object.
660 *
661 * Calls getaddrinfo() for the specified abstract address in AI_NUMERICHOST
662 * mode.
663 *
664 * @note The caller is responsible for freeing the linked list using the
665 * interface provided by getaddrinfo(3).
666 *
667 * @return A linked list of addrinfo handles or NULL with an error message
668 * associated.
669 */
670struct addrinfo *nl_addr_info(struct nl_addr *addr)
671{
672 int err;
673 struct addrinfo *res;
674 char buf[INET6_ADDRSTRLEN+5];
675 struct addrinfo hint = {
676 .ai_flags = AI_NUMERICHOST,
677 .ai_family = addr->a_family,
678 };
679
680 nl_addr2str(addr, buf, sizeof(buf));
681
682 err = getaddrinfo(buf, NULL, &hint, &res);
683 if (err != 0) {
684 nl_error(err, gai_strerror(err));
685 return NULL;
686 }
687
688 return res;
689}
690
691/**
692 * Resolve abstract address object to a name using getnameinfo().
693 * @arg addr Abstract address object.
694 * @arg host Destination buffer for host name.
695 * @arg hostlen Length of destination buffer.
696 *
697 * Resolves the abstract address to a name and writes the looked up result
698 * into the host buffer. getnameinfo() is used to perform the lookup and
699 * is put into NI_NAMEREQD mode so the function will fail if the lookup
700 * couldn't be performed.
701 *
702 * @return 0 on success or a negative error code.
703 */
704int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen)
705{
706 int err;
707 struct sockaddr_in6 buf;
708 socklen_t salen = sizeof(buf);
709
710 err = nl_addr_fill_sockaddr(addr, (struct sockaddr *) &buf, &salen);
711 if (err < 0)
712 return err;
713
714 return getnameinfo((struct sockaddr *) &buf, salen,
715 host, hostlen, NULL, 0, NI_NAMEREQD);
716}
717
718/** @} */
719
720/**
721 * @name Attributes
722 * @{
723 */
724
725void nl_addr_set_family(struct nl_addr *addr, int family)
726{
727 addr->a_family = family;
728}
729
730int nl_addr_get_family(struct nl_addr *addr)
731{
732 return addr->a_family;
733}
734
735/**
736 * Set binary address of abstract address object.
737 * @arg addr Abstract address object.
738 * @arg buf Buffer containing binary address.
739 * @arg len Length of buffer containing binary address.
740 */
741int nl_addr_set_binary_addr(struct nl_addr *addr, void *buf, size_t len)
742{
743 if (len > addr->a_maxsize)
744 return -ERANGE;
745
746 addr->a_len = len;
747 memcpy(addr->a_addr, buf, len);
748
749 return 0;
750}
751
752/**
753 * Get binary address of abstract address object.
754 * @arg addr Abstract address object.
755 */
756void *nl_addr_get_binary_addr(struct nl_addr *addr)
757{
758 return addr->a_addr;
759}
760
761/**
762 * Get length of binary address of abstract address object.
763 * @arg addr Abstract address object.
764 */
765unsigned int nl_addr_get_len(struct nl_addr *addr)
766{
767 return addr->a_len;
768}
769
770void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen)
771{
772 addr->a_prefixlen = prefixlen;
773}
774
775/**
776 * Get prefix length of abstract address object.
777 * @arg addr Abstract address object.
778 */
779unsigned int nl_addr_get_prefixlen(struct nl_addr *addr)
780{
781 return addr->a_prefixlen;
782}
783
784/** @} */
785
786/**
787 * @name Translations to Strings
788 * @{
789 */
790
791/**
792 * Convert abstract address object to character string.
793 * @arg addr Abstract address object.
794 * @arg buf Destination buffer.
795 * @arg size Size of destination buffer.
796 *
797 * Converts an abstract address to a character string and stores
798 * the result in the specified destination buffer.
799 *
800 * @return Address represented in ASCII stored in destination buffer.
801 */
802char *nl_addr2str(struct nl_addr *addr, char *buf, size_t size)
803{
804 int i;
805 char tmp[16];
806
807 if (!addr->a_len) {
808 snprintf(buf, size, "none");
809 goto prefix;
810 }
811
812 switch (addr->a_family) {
813 case AF_INET:
814 inet_ntop(AF_INET, addr->a_addr, buf, size);
815 break;
816
817 case AF_INET6:
818 inet_ntop(AF_INET6, addr->a_addr, buf, size);
819 break;
820
821 case AF_DECnet:
822 dnet_ntop(addr->a_addr, addr->a_len, buf, size);
823 break;
824
825 case AF_LLC:
826 default:
827 snprintf(buf, size, "%02x",
828 (unsigned char) addr->a_addr[0]);
829 for (i = 1; i < addr->a_len; i++) {
830 snprintf(tmp, sizeof(tmp), ":%02x",
831 (unsigned char) addr->a_addr[i]);
832 strncat(buf, tmp, size - strlen(buf) - 1);
833 }
834 break;
835 }
836
837prefix:
838 if (addr->a_prefixlen != (8 * addr->a_len)) {
839 snprintf(tmp, sizeof(tmp), "/%u", addr->a_prefixlen);
840 strncat(buf, tmp, size - strlen(buf) - 1);
841 }
842
843 return buf;
844}
845
846/** @} */
847
848/**
849 * @name Address Family Transformations
850 * @{
851 */
852
853static struct trans_tbl afs[] = {
854 __ADD(AF_UNSPEC,unspec)
855 __ADD(AF_UNIX,unix)
856 __ADD(AF_LOCAL,local)
857 __ADD(AF_INET,inet)
858 __ADD(AF_AX25,ax25)
859 __ADD(AF_IPX,ipx)
860 __ADD(AF_APPLETALK,appletalk)
861 __ADD(AF_NETROM,netrom)
862 __ADD(AF_BRIDGE,bridge)
863 __ADD(AF_ATMPVC,atmpvc)
864 __ADD(AF_X25,x25)
865 __ADD(AF_INET6,inet6)
866 __ADD(AF_ROSE,rose)
867 __ADD(AF_DECnet,decnet)
868 __ADD(AF_NETBEUI,netbeui)
869 __ADD(AF_SECURITY,security)
870 __ADD(AF_KEY,key)
871 __ADD(AF_NETLINK,netlink)
872 __ADD(AF_ROUTE,route)
873 __ADD(AF_PACKET,packet)
874 __ADD(AF_ASH,ash)
875 __ADD(AF_ECONET,econet)
876 __ADD(AF_ATMSVC,atmsvc)
877 __ADD(AF_SNA,sna)
878 __ADD(AF_IRDA,irda)
879 __ADD(AF_PPPOX,pppox)
880 __ADD(AF_WANPIPE,wanpipe)
881 __ADD(AF_LLC,llc)
882 __ADD(AF_BLUETOOTH,bluetooth)
883};
884
885char *nl_af2str(int family, char *buf, size_t size)
886{
887 return __type2str(family, buf, size, afs, ARRAY_SIZE(afs));
888}
889
890int nl_str2af(const char *name)
891{
892 int fam = __str2type(name, afs, ARRAY_SIZE(afs));
893 return fam >= 0 ? fam : AF_UNSPEC;
894}
895
896/** @} */
897
898/** @} */
char * nl_addr2str(struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:802
void nl_addr_destroy(struct nl_addr *addr)
Destroy abstract address object.
Definition: addr.c:428
int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa, socklen_t *salen)
Fill out sockaddr structure with values from abstract address object.
Definition: addr.c:614
struct addrinfo * nl_addr_info(struct nl_addr *addr)
Call getaddrinfo() for an abstract address object.
Definition: addr.c:670
int nl_addr_cmp(struct nl_addr *a, struct nl_addr *b)
Compares two abstract address objects.
Definition: addr.c:489
struct nl_addr * nl_addr_clone(struct nl_addr *addr)
Clone existing abstract address object.
Definition: addr.c:406
int nl_addr_iszero(struct nl_addr *addr)
Returns true if the address consists of all zeros.
Definition: addr.c:535
unsigned int nl_addr_get_len(struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:765
struct nl_addr * nl_addr_alloc(size_t maxsize)
Allocate new abstract address object.
Definition: addr.c:164
int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen)
Resolve abstract address object to a name using getnameinfo().
Definition: addr.c:704
int nl_addr_cmp_prefix(struct nl_addr *a, struct nl_addr *b)
Compares the prefix of two abstract address objects.
Definition: addr.c:511
void * nl_addr_get_binary_addr(struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:756
int nl_addr_set_binary_addr(struct nl_addr *addr, void *buf, size_t len)
Set binary address of abstract address object.
Definition: addr.c:741
struct nl_addr * nl_addr_build(int family, void *buf, size_t size)
Allocate new abstract address object based on a binary address.
Definition: addr.c:187
unsigned int nl_addr_get_prefixlen(struct nl_addr *addr)
Get prefix length of abstract address object.
Definition: addr.c:779
int nl_addr_shared(struct nl_addr *addr)
Check whether an abstract address object is shared.
Definition: addr.c:469
int nl_addr_valid(char *addr, int family)
Check if an address matches a certain family.
Definition: addr.c:554
struct nl_addr * nl_addr_parse(const char *addrstr, int hint)
Allocate abstract address object based on a character string.
Definition: addr.c:231
int nl_addr_guess_family(struct nl_addr *addr)
Guess address family of an abstract address object based on address size.
Definition: addr.c:587