avoid setting device presence for wifi interfaces via hotplug messages
[project/netifd.git] / utils.c
1 /*
2 * netifd - network interface daemon
3 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14 #include <string.h>
15 #include <stdlib.h>
16 #include "utils.h"
17
18 #include <arpa/inet.h>
19 #include <netinet/in.h>
20
21 void
22 __vlist_simple_init(struct vlist_simple_tree *tree, int offset)
23 {
24 INIT_LIST_HEAD(&tree->list);
25 tree->version = 1;
26 tree->head_offset = offset;
27 }
28
29 void
30 vlist_simple_delete(struct vlist_simple_tree *tree, struct vlist_simple_node *node)
31 {
32 char *ptr;
33
34 list_del(&node->list);
35 ptr = (char *) node - tree->head_offset;
36 free(ptr);
37 }
38
39 void
40 vlist_simple_flush(struct vlist_simple_tree *tree)
41 {
42 struct vlist_simple_node *n, *tmp;
43
44 list_for_each_entry_safe(n, tmp, &tree->list, list) {
45 if ((n->version == tree->version || n->version == -1) &&
46 tree->version != -1)
47 continue;
48
49 vlist_simple_delete(tree, n);
50 }
51 }
52
53 void
54 vlist_simple_replace(struct vlist_simple_tree *dest, struct vlist_simple_tree *old)
55 {
56 struct vlist_simple_node *n, *tmp;
57
58 vlist_simple_update(dest);
59 list_for_each_entry_safe(n, tmp, &old->list, list) {
60 list_del(&n->list);
61 vlist_simple_add(dest, n);
62 }
63 vlist_simple_flush(dest);
64 }
65
66 void
67 vlist_simple_flush_all(struct vlist_simple_tree *tree)
68 {
69 tree->version = -1;
70 vlist_simple_flush(tree);
71 }
72
73 unsigned int
74 parse_netmask_string(const char *str, bool v6)
75 {
76 struct in_addr addr;
77 unsigned int ret;
78 char *err = NULL;
79
80 if (!strchr(str, '.')) {
81 ret = strtoul(str, &err, 0);
82 if (err && *err)
83 goto error;
84
85 return ret;
86 }
87
88 if (v6)
89 goto error;
90
91 if (inet_aton(str, &addr) != 1)
92 goto error;
93
94 return 32 - fls(~(ntohl(addr.s_addr)));
95
96 error:
97 return ~0;
98 }
99
100 bool
101 split_netmask(char *str, unsigned int *netmask, bool v6)
102 {
103 char *delim = strchr(str, '/');
104
105 if (delim) {
106 *(delim++) = 0;
107
108 *netmask = parse_netmask_string(delim, v6);
109 }
110 return true;
111 }
112
113 int
114 parse_ip_and_netmask(int af, const char *str, void *addr, unsigned int *netmask)
115 {
116 char *astr = alloca(strlen(str) + 1);
117
118 strcpy(astr, str);
119 if (!split_netmask(astr, netmask, af == AF_INET6))
120 return 0;
121
122 if (af == AF_INET6) {
123 if (*netmask > 128)
124 return 0;
125 } else {
126 if (*netmask > 32)
127 return 0;
128 }
129
130 return inet_pton(af, astr, addr);
131 }