BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file netmask.c
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * @section DESCRIPTION
30 *
31 * Synopsis:
32 * ipv4_prefix_to_mask(string prefix)
33 *
34 * Variables:
35 * string (empty) - prefix, converted to dotted decimal format without leading
36 * zeros
37 *
38 * Synopsis:
39 * ipv4_mask_to_prefix(string mask)
40 *
41 * Variables:
42 * string (empty) - mask, converted to prefix length
43 *
44 * Synopsis:
45 * ipv4_net_from_addr_and_prefix(string addr, string prefix)
46 *
47 * Variables:
48 * string (empty) - network part of the address, according to given prefix
49 * length, in dotted decimal format without leading zeros
50 */
51  
52 #include <stdlib.h>
53 #include <string.h>
54 #include <stdio.h>
55 #include <inttypes.h>
56  
57 #include <misc/ipaddr.h>
58 #include <misc/parse_number.h>
59  
60 #include <ncd/module_common.h>
61  
62 #include <generated/blog_channel_ncd_netmask.h>
63  
64 struct addr_instance {
65 NCDModuleInst *i;
66 uint32_t addr;
67 };
68  
69 struct prefix_instance {
70 NCDModuleInst *i;
71 int prefix;
72 };
73  
74 static void addr_func_init_templ (void *vo, NCDModuleInst *i, uint32_t addr)
75 {
76 struct addr_instance *o = vo;
77 o->i = i;
78  
79 // remember address
80 o->addr = addr;
81  
82 // signal up
83 NCDModuleInst_Backend_Up(i);
84 }
85  
86 static void prefix_to_mask_func_init (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
87 {
88 // read arguments
89 NCDValRef prefix_arg;
90 if (!NCDVal_ListRead(params->args, 1, &prefix_arg)) {
91 ModuleLog(i, BLOG_ERROR, "wrong arity");
92 goto fail0;
93 }
94 if (!NCDVal_IsString(prefix_arg)) {
95 ModuleLog(i, BLOG_ERROR, "wrong type");
96 goto fail0;
97 }
98  
99 // parse prefix
100 int prefix;
101 if (!ipaddr_parse_ipv4_prefix(NCDVal_StringMemRef(prefix_arg), &prefix)) {
102 ModuleLog(i, BLOG_ERROR, "bad prefix");
103 goto fail0;
104 }
105  
106 // make mask
107 uint32_t mask = ipaddr_ipv4_mask_from_prefix(prefix);
108  
109 addr_func_init_templ(vo, i, mask);
110 return;
111  
112 fail0:
113 NCDModuleInst_Backend_DeadError(i);
114 }
115  
116 static void ipv4_net_from_addr_and_prefix_func_init (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
117 {
118 // read arguments
119 NCDValRef addr_arg;
120 NCDValRef prefix_arg;
121 if (!NCDVal_ListRead(params->args, 2, &addr_arg, &prefix_arg)) {
122 ModuleLog(i, BLOG_ERROR, "wrong arity");
123 goto fail0;
124 }
125 if (!NCDVal_IsString(addr_arg) || !NCDVal_IsString(prefix_arg)) {
126 ModuleLog(i, BLOG_ERROR, "wrong type");
127 goto fail0;
128 }
129  
130 // parse addr
131 uint32_t addr;
132 if (!ipaddr_parse_ipv4_addr(NCDVal_StringMemRef(addr_arg), &addr)) {
133 ModuleLog(i, BLOG_ERROR, "bad addr");
134 goto fail0;
135 }
136  
137 // parse prefix
138 int prefix;
139 if (!ipaddr_parse_ipv4_prefix(NCDVal_StringMemRef(prefix_arg), &prefix)) {
140 ModuleLog(i, BLOG_ERROR, "bad prefix");
141 goto fail0;
142 }
143  
144 // make network
145 uint32_t network = (addr & ipaddr_ipv4_mask_from_prefix(prefix));
146  
147 addr_func_init_templ(vo, i, network);
148 return;
149  
150 fail0:
151 NCDModuleInst_Backend_DeadError(i);
152 }
153  
154 static void addr_func_die (void *vo)
155 {
156 struct addr_instance *o = vo;
157  
158 NCDModuleInst_Backend_Dead(o->i);
159 }
160  
161 static int addr_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out)
162 {
163 struct addr_instance *o = vo;
164  
165 if (name == NCD_STRING_EMPTY) {
166 char buf[IPADDR_PRINT_MAX];
167 ipaddr_print_addr(o->addr, buf);
168  
169 *out = NCDVal_NewString(mem, buf);
170 return 1;
171 }
172  
173 return 0;
174 }
175  
176 static void mask_to_prefix_func_init (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
177 {
178 struct prefix_instance *o = vo;
179 o->i = i;
180  
181 // read arguments
182 NCDValRef mask_arg;
183 if (!NCDVal_ListRead(params->args, 1, &mask_arg)) {
184 ModuleLog(i, BLOG_ERROR, "wrong arity");
185 goto fail0;
186 }
187 if (!NCDVal_IsString(mask_arg)) {
188 ModuleLog(i, BLOG_ERROR, "wrong type");
189 goto fail0;
190 }
191  
192 // parse mask
193 uint32_t mask;
194 if (!ipaddr_parse_ipv4_addr(NCDVal_StringMemRef(mask_arg), &mask)) {
195 ModuleLog(i, BLOG_ERROR, "bad mask");
196 goto fail0;
197 }
198  
199 // build prefix
200 if (!ipaddr_ipv4_prefix_from_mask(mask, &o->prefix)) {
201 ModuleLog(i, BLOG_ERROR, "bad mask");
202 goto fail0;
203 }
204  
205 // signal up
206 NCDModuleInst_Backend_Up(i);
207 return;
208  
209 fail0:
210 NCDModuleInst_Backend_DeadError(i);
211 }
212  
213 static void prefix_func_die (void *vo)
214 {
215 struct prefix_instance *o = vo;
216  
217 NCDModuleInst_Backend_Dead(o->i);
218 }
219  
220 static int prefix_func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValRef *out)
221 {
222 struct prefix_instance *o = vo;
223  
224 if (name == NCD_STRING_EMPTY) {
225 char buf[6];
226 sprintf(buf, "%d", o->prefix);
227  
228 *out = NCDVal_NewString(mem, buf);
229 return 1;
230 }
231  
232 return 0;
233 }
234  
235 static struct NCDModule modules[] = {
236 {
237 .type = "ipv4_prefix_to_mask",
238 .func_new2 = prefix_to_mask_func_init,
239 .func_die = addr_func_die,
240 .func_getvar2 = addr_func_getvar2,
241 .alloc_size = sizeof(struct addr_instance)
242 }, {
243 .type = "ipv4_mask_to_prefix",
244 .func_new2 = mask_to_prefix_func_init,
245 .func_die = prefix_func_die,
246 .func_getvar2 = prefix_func_getvar2,
247 .alloc_size = sizeof(struct prefix_instance)
248 }, {
249 .type = "ipv4_net_from_addr_and_prefix",
250 .func_new2 = ipv4_net_from_addr_and_prefix_func_init,
251 .func_die = addr_func_die,
252 .func_getvar2 = addr_func_getvar2,
253 .alloc_size = sizeof(struct addr_instance)
254 }, {
255 .type = NULL
256 }
257 };
258  
259 const struct NCDModuleGroup ncdmodule_netmask = {
260 .modules = modules
261 };