Merge "Implement MultiCloud proxyed Designate"
[demo.git] / vnfs / vCPE / vpp-radius-client-for-vbng / src / patches / Vpp-Integrate-FreeRADIUS-Client-for-vBNG.patch
1 diff --git a/build-root/build-vpp-native/vpp/vnet/dhcp/dhcp.api.h b/build-root/build-vpp-native/vpp/vnet/dhcp/dhcp.api.h
2 new file mode 100644
3 index 0000000..8f719f2
4 --- /dev/null
5 +++ b/build-root/build-vpp-native/vpp/vnet/dhcp/dhcp.api.h
6 @@ -0,0 +1,413 @@
7 +/*
8 + * VLIB API definitions Tue Oct 24 18:42:06 2017
9 + * Input file: vnet/dhcp/dhcp.api.h
10 + * Automatically generated: please edit the input file NOT this file!
11 + */
12 +
13 +#if defined(vl_msg_id)||defined(vl_union_id)||defined(vl_printfun) \
14 + ||defined(vl_endianfun)|| defined(vl_api_version)||defined(vl_typedefs) \
15 + ||defined(vl_msg_name)||defined(vl_msg_name_crc_list)
16 +/* ok, something was selected */
17 +#else
18 +#warning no content included from vnet/dhcp/dhcp.api.h
19 +#endif
20 +
21 +#define VL_API_PACKED(x) x __attribute__ ((packed))
22 +
23 +
24 +/****** Message ID / handler enum ******/
25 +
26 +#ifdef vl_msg_id
27 +vl_msg_id(VL_API_DHCP_PROXY_CONFIG, vl_api_dhcp_proxy_config_t_handler)
28 +vl_msg_id(VL_API_DHCP_PROXY_CONFIG_REPLY, vl_api_dhcp_proxy_config_reply_t_handler)
29 +vl_msg_id(VL_API_DHCP_PROXY_SET_VSS, vl_api_dhcp_proxy_set_vss_t_handler)
30 +vl_msg_id(VL_API_DHCP_PROXY_SET_VSS_REPLY, vl_api_dhcp_proxy_set_vss_reply_t_handler)
31 +vl_msg_id(VL_API_DHCP_CLIENT_CONFIG, vl_api_dhcp_client_config_t_handler)
32 +vl_msg_id(VL_API_DHCP_CLIENT_CONFIG_REPLY, vl_api_dhcp_client_config_reply_t_handler)
33 +vl_msg_id(VL_API_DHCP_COMPL_EVENT, vl_api_dhcp_compl_event_t_handler)
34 +vl_msg_id(VL_API_DHCP_PROXY_DUMP, vl_api_dhcp_proxy_dump_t_handler)
35 +/* typeonly: dhcp_server */
36 +vl_msg_id(VL_API_DHCP_PROXY_DETAILS, vl_api_dhcp_proxy_details_t_handler)
37 +#endif
38 +
39 +/****** Message names ******/
40 +
41 +#ifdef vl_msg_name
42 +vl_msg_name(vl_api_dhcp_proxy_config_t, 1)
43 +vl_msg_name(vl_api_dhcp_proxy_config_reply_t, 1)
44 +vl_msg_name(vl_api_dhcp_proxy_set_vss_t, 1)
45 +vl_msg_name(vl_api_dhcp_proxy_set_vss_reply_t, 1)
46 +vl_msg_name(vl_api_dhcp_client_config_t, 1)
47 +vl_msg_name(vl_api_dhcp_client_config_reply_t, 1)
48 +vl_msg_name(vl_api_dhcp_compl_event_t, 1)
49 +vl_msg_name(vl_api_dhcp_proxy_dump_t, 1)
50 +/* typeonly: dhcp_server */
51 +vl_msg_name(vl_api_dhcp_proxy_details_t, 1)
52 +#endif
53 +
54 +
55 +/****** Message name, crc list ******/
56 +
57 +#ifdef vl_msg_name_crc_list
58 +#define foreach_vl_msg_name_crc_dhcp \
59 +_(VL_API_DHCP_PROXY_CONFIG, dhcp_proxy_config, 3b4f2bc8) \
60 +_(VL_API_DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply, fe63196f) \
61 +_(VL_API_DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss, be54d194) \
62 +_(VL_API_DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply, 5bb4e754) \
63 +_(VL_API_DHCP_CLIENT_CONFIG, dhcp_client_config, 87920bb6) \
64 +_(VL_API_DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply, d947f4c8) \
65 +_(VL_API_DHCP_COMPL_EVENT, dhcp_compl_event, 5218db55) \
66 +_(VL_API_DHCP_PROXY_DUMP, dhcp_proxy_dump, 175bc073) \
67 +_(VL_API_DHCP_PROXY_DETAILS, dhcp_proxy_details, 9727dbdd) 
68 +#endif
69 +
70 +
71 +/****** Typedefs *****/
72 +
73 +#ifdef vl_typedefs
74 +
75 +typedef VL_API_PACKED(struct _vl_api_dhcp_proxy_config {
76 +    u16 _vl_msg_id;
77 +    u32 client_index;
78 +    u32 context;
79 +    u32 rx_vrf_id;
80 +    u32 server_vrf_id;
81 +    u8 is_ipv6;
82 +    u8 is_add;
83 +    u8 dhcp_server[16];
84 +    u8 dhcp_src_address[16];
85 +}) vl_api_dhcp_proxy_config_t;
86 +
87 +typedef VL_API_PACKED(struct _vl_api_dhcp_proxy_config_reply {
88 +    u16 _vl_msg_id;
89 +    u32 context;
90 +    i32 retval;
91 +}) vl_api_dhcp_proxy_config_reply_t;
92 +
93 +typedef VL_API_PACKED(struct _vl_api_dhcp_proxy_set_vss {
94 +    u16 _vl_msg_id;
95 +    u32 client_index;
96 +    u32 context;
97 +    u32 tbl_id;
98 +    u32 oui;
99 +    u32 fib_id;
100 +    u8 is_ipv6;
101 +    u8 is_add;
102 +}) vl_api_dhcp_proxy_set_vss_t;
103 +
104 +typedef VL_API_PACKED(struct _vl_api_dhcp_proxy_set_vss_reply {
105 +    u16 _vl_msg_id;
106 +    u32 context;
107 +    i32 retval;
108 +}) vl_api_dhcp_proxy_set_vss_reply_t;
109 +
110 +typedef VL_API_PACKED(struct _vl_api_dhcp_client_config {
111 +    u16 _vl_msg_id;
112 +    u32 client_index;
113 +    u32 context;
114 +    u32 sw_if_index;
115 +    u8 hostname[64];
116 +    u8 is_add;
117 +    u8 want_dhcp_event;
118 +    u32 pid;
119 +}) vl_api_dhcp_client_config_t;
120 +
121 +typedef VL_API_PACKED(struct _vl_api_dhcp_client_config_reply {
122 +    u16 _vl_msg_id;
123 +    u32 context;
124 +    i32 retval;
125 +}) vl_api_dhcp_client_config_reply_t;
126 +
127 +typedef VL_API_PACKED(struct _vl_api_dhcp_compl_event {
128 +    u16 _vl_msg_id;
129 +    u32 client_index;
130 +    u32 pid;
131 +    u8 hostname[64];
132 +    u8 is_ipv6;
133 +    u8 host_address[16];
134 +    u8 router_address[16];
135 +    u8 host_mac[6];
136 +}) vl_api_dhcp_compl_event_t;
137 +
138 +typedef VL_API_PACKED(struct _vl_api_dhcp_proxy_dump {
139 +    u16 _vl_msg_id;
140 +    u32 client_index;
141 +    u32 context;
142 +    u8 is_ip6;
143 +}) vl_api_dhcp_proxy_dump_t;
144 +
145 +typedef VL_API_PACKED(struct _vl_api_dhcp_server {
146 +    u32 server_vrf_id;
147 +    u8 dhcp_server[16];
148 +}) vl_api_dhcp_server_t;
149 +
150 +typedef VL_API_PACKED(struct _vl_api_dhcp_proxy_details {
151 +    u16 _vl_msg_id;
152 +    u32 context;
153 +    u32 rx_vrf_id;
154 +    u32 vss_oui;
155 +    u32 vss_fib_id;
156 +    u8 is_ipv6;
157 +    u8 dhcp_src_address[16];
158 +    u8 count;
159 +    vl_api_dhcp_server_t servers[0];
160 +}) vl_api_dhcp_proxy_details_t;
161 +
162 +#endif /* vl_typedefs */
163 +
164 +/****** Discriminated Union Definitions *****/
165 +
166 +#ifdef vl_union_id
167 +
168 +
169 +#endif /* vl_union_id */
170 +
171 +/****** Print functions *****/
172 +
173 +#ifdef vl_printfun
174 +
175 +#ifdef LP64
176 +#define _uword_fmt "%lld"
177 +#define _uword_cast (long long)
178 +#else
179 +#define _uword_fmt "%ld"
180 +#define _uword_cast long
181 +#endif
182 +
183 +static inline void *vl_api_dhcp_proxy_config_t_print (vl_api_dhcp_proxy_config_t *a,void *handle)
184 +{
185 +    vl_print(handle, "vl_api_dhcp_proxy_config_t:\n");
186 +    vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id);
187 +    vl_print(handle, "client_index: %u\n", (unsigned) a->client_index);
188 +    vl_print(handle, "context: %u\n", (unsigned) a->context);
189 +    vl_print(handle, "rx_vrf_id: %u\n", (unsigned) a->rx_vrf_id);
190 +    vl_print(handle, "server_vrf_id: %u\n", (unsigned) a->server_vrf_id);
191 +    vl_print(handle, "is_ipv6: %u\n", (unsigned) a->is_ipv6);
192 +    vl_print(handle, "is_add: %u\n", (unsigned) a->is_add);
193 +    {
194 +        int _i;
195 +        for (_i = 0; _i < 16; _i++) {
196 +            vl_print(handle, "dhcp_server[%d]: %u\n", _i, a->dhcp_server[_i]);
197 +        }
198 +    }
199 +    {
200 +        int _i;
201 +        for (_i = 0; _i < 16; _i++) {
202 +            vl_print(handle, "dhcp_src_address[%d]: %u\n", _i, a->dhcp_src_address[_i]);
203 +        }
204 +    }
205 +    return handle;
206 +}
207 +
208 +static inline void *vl_api_dhcp_proxy_config_reply_t_print (vl_api_dhcp_proxy_config_reply_t *a,void *handle)
209 +{
210 +    vl_print(handle, "vl_api_dhcp_proxy_config_reply_t:\n");
211 +    vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id);
212 +    vl_print(handle, "context: %u\n", (unsigned) a->context);
213 +    vl_print(handle, "retval: %ld\n", (long) a->retval);
214 +    return handle;
215 +}
216 +
217 +static inline void *vl_api_dhcp_proxy_set_vss_t_print (vl_api_dhcp_proxy_set_vss_t *a,void *handle)
218 +{
219 +    vl_print(handle, "vl_api_dhcp_proxy_set_vss_t:\n");
220 +    vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id);
221 +    vl_print(handle, "client_index: %u\n", (unsigned) a->client_index);
222 +    vl_print(handle, "context: %u\n", (unsigned) a->context);
223 +    vl_print(handle, "tbl_id: %u\n", (unsigned) a->tbl_id);
224 +    vl_print(handle, "oui: %u\n", (unsigned) a->oui);
225 +    vl_print(handle, "fib_id: %u\n", (unsigned) a->fib_id);
226 +    vl_print(handle, "is_ipv6: %u\n", (unsigned) a->is_ipv6);
227 +    vl_print(handle, "is_add: %u\n", (unsigned) a->is_add);
228 +    return handle;
229 +}
230 +
231 +static inline void *vl_api_dhcp_proxy_set_vss_reply_t_print (vl_api_dhcp_proxy_set_vss_reply_t *a,void *handle)
232 +{
233 +    vl_print(handle, "vl_api_dhcp_proxy_set_vss_reply_t:\n");
234 +    vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id);
235 +    vl_print(handle, "context: %u\n", (unsigned) a->context);
236 +    vl_print(handle, "retval: %ld\n", (long) a->retval);
237 +    return handle;
238 +}
239 +
240 +static inline void *vl_api_dhcp_client_config_t_print (vl_api_dhcp_client_config_t *a,void *handle)
241 +{
242 +    vl_print(handle, "vl_api_dhcp_client_config_t:\n");
243 +    vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id);
244 +    vl_print(handle, "client_index: %u\n", (unsigned) a->client_index);
245 +    vl_print(handle, "context: %u\n", (unsigned) a->context);
246 +    vl_print(handle, "sw_if_index: %u\n", (unsigned) a->sw_if_index);
247 +    {
248 +        int _i;
249 +        for (_i = 0; _i < 64; _i++) {
250 +            vl_print(handle, "hostname[%d]: %u\n", _i, a->hostname[_i]);
251 +        }
252 +    }
253 +    vl_print(handle, "is_add: %u\n", (unsigned) a->is_add);
254 +    vl_print(handle, "want_dhcp_event: %u\n", (unsigned) a->want_dhcp_event);
255 +    vl_print(handle, "pid: %u\n", (unsigned) a->pid);
256 +    return handle;
257 +}
258 +
259 +static inline void *vl_api_dhcp_client_config_reply_t_print (vl_api_dhcp_client_config_reply_t *a,void *handle)
260 +{
261 +    vl_print(handle, "vl_api_dhcp_client_config_reply_t:\n");
262 +    vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id);
263 +    vl_print(handle, "context: %u\n", (unsigned) a->context);
264 +    vl_print(handle, "retval: %ld\n", (long) a->retval);
265 +    return handle;
266 +}
267 +
268 +static inline void *vl_api_dhcp_compl_event_t_print (vl_api_dhcp_compl_event_t *a,void *handle)
269 +{
270 +    vl_print(handle, "vl_api_dhcp_compl_event_t:\n");
271 +    vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id);
272 +    vl_print(handle, "client_index: %u\n", (unsigned) a->client_index);
273 +    vl_print(handle, "pid: %u\n", (unsigned) a->pid);
274 +    {
275 +        int _i;
276 +        for (_i = 0; _i < 64; _i++) {
277 +            vl_print(handle, "hostname[%d]: %u\n", _i, a->hostname[_i]);
278 +        }
279 +    }
280 +    vl_print(handle, "is_ipv6: %u\n", (unsigned) a->is_ipv6);
281 +    {
282 +        int _i;
283 +        for (_i = 0; _i < 16; _i++) {
284 +            vl_print(handle, "host_address[%d]: %u\n", _i, a->host_address[_i]);
285 +        }
286 +    }
287 +    {
288 +        int _i;
289 +        for (_i = 0; _i < 16; _i++) {
290 +            vl_print(handle, "router_address[%d]: %u\n", _i, a->router_address[_i]);
291 +        }
292 +    }
293 +    {
294 +        int _i;
295 +        for (_i = 0; _i < 6; _i++) {
296 +            vl_print(handle, "host_mac[%d]: %u\n", _i, a->host_mac[_i]);
297 +        }
298 +    }
299 +    return handle;
300 +}
301 +
302 +static inline void *vl_api_dhcp_proxy_dump_t_print (vl_api_dhcp_proxy_dump_t *a,void *handle)
303 +{
304 +    vl_print(handle, "vl_api_dhcp_proxy_dump_t:\n");
305 +    vl_print(handle, "_vl_msg_id: %u\n", (unsigned) a->_vl_msg_id);
306 +    vl_print(handle, "client_index: %u\n", (unsigned) a->client_index);
307 +    vl_print(handle, "context: %u\n", (unsigned) a->context);
308 +    vl_print(handle, "is_ip6: %u\n", (unsigned) a->is_ip6);
309 +    return handle;
310 +}
311 +
312 +/***** manual: vl_api_dhcp_server_t_print  *****/
313 +
314 +/***** manual: vl_api_dhcp_proxy_details_t_print  *****/
315 +
316 +#endif /* vl_printfun */
317 +
318 +
319 +/****** Endian swap functions *****/
320 +
321 +#ifdef vl_endianfun
322 +
323 +#undef clib_net_to_host_uword
324 +#ifdef LP64
325 +#define clib_net_to_host_uword clib_net_to_host_u64
326 +#else
327 +#define clib_net_to_host_uword clib_net_to_host_u32
328 +#endif
329 +
330 +static inline void vl_api_dhcp_proxy_config_t_endian (vl_api_dhcp_proxy_config_t *a)
331 +{
332 +    a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id);
333 +    a->client_index = clib_net_to_host_u32(a->client_index);
334 +    a->context = clib_net_to_host_u32(a->context);
335 +    a->rx_vrf_id = clib_net_to_host_u32(a->rx_vrf_id);
336 +    a->server_vrf_id = clib_net_to_host_u32(a->server_vrf_id);
337 +    /* a->is_ipv6 = a->is_ipv6 (no-op) */
338 +    /* a->is_add = a->is_add (no-op) */
339 +    /* a->dhcp_server[0..15] = a->dhcp_server[0..15] (no-op) */
340 +    /* a->dhcp_src_address[0..15] = a->dhcp_src_address[0..15] (no-op) */
341 +}
342 +
343 +static inline void vl_api_dhcp_proxy_config_reply_t_endian (vl_api_dhcp_proxy_config_reply_t *a)
344 +{
345 +    a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id);
346 +    a->context = clib_net_to_host_u32(a->context);
347 +    a->retval = clib_net_to_host_u32(a->retval);
348 +}
349 +
350 +static inline void vl_api_dhcp_proxy_set_vss_t_endian (vl_api_dhcp_proxy_set_vss_t *a)
351 +{
352 +    a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id);
353 +    a->client_index = clib_net_to_host_u32(a->client_index);
354 +    a->context = clib_net_to_host_u32(a->context);
355 +    a->tbl_id = clib_net_to_host_u32(a->tbl_id);
356 +    a->oui = clib_net_to_host_u32(a->oui);
357 +    a->fib_id = clib_net_to_host_u32(a->fib_id);
358 +    /* a->is_ipv6 = a->is_ipv6 (no-op) */
359 +    /* a->is_add = a->is_add (no-op) */
360 +}
361 +
362 +static inline void vl_api_dhcp_proxy_set_vss_reply_t_endian (vl_api_dhcp_proxy_set_vss_reply_t *a)
363 +{
364 +    a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id);
365 +    a->context = clib_net_to_host_u32(a->context);
366 +    a->retval = clib_net_to_host_u32(a->retval);
367 +}
368 +
369 +static inline void vl_api_dhcp_client_config_t_endian (vl_api_dhcp_client_config_t *a)
370 +{
371 +    a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id);
372 +    a->client_index = clib_net_to_host_u32(a->client_index);
373 +    a->context = clib_net_to_host_u32(a->context);
374 +    a->sw_if_index = clib_net_to_host_u32(a->sw_if_index);
375 +    /* a->hostname[0..63] = a->hostname[0..63] (no-op) */
376 +    /* a->is_add = a->is_add (no-op) */
377 +    /* a->want_dhcp_event = a->want_dhcp_event (no-op) */
378 +    a->pid = clib_net_to_host_u32(a->pid);
379 +}
380 +
381 +static inline void vl_api_dhcp_client_config_reply_t_endian (vl_api_dhcp_client_config_reply_t *a)
382 +{
383 +    a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id);
384 +    a->context = clib_net_to_host_u32(a->context);
385 +    a->retval = clib_net_to_host_u32(a->retval);
386 +}
387 +
388 +static inline void vl_api_dhcp_compl_event_t_endian (vl_api_dhcp_compl_event_t *a)
389 +{
390 +    a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id);
391 +    a->client_index = clib_net_to_host_u32(a->client_index);
392 +    a->pid = clib_net_to_host_u32(a->pid);
393 +    /* a->hostname[0..63] = a->hostname[0..63] (no-op) */
394 +    /* a->is_ipv6 = a->is_ipv6 (no-op) */
395 +    /* a->host_address[0..15] = a->host_address[0..15] (no-op) */
396 +    /* a->router_address[0..15] = a->router_address[0..15] (no-op) */
397 +    /* a->host_mac[0..5] = a->host_mac[0..5] (no-op) */
398 +}
399 +
400 +static inline void vl_api_dhcp_proxy_dump_t_endian (vl_api_dhcp_proxy_dump_t *a)
401 +{
402 +    a->_vl_msg_id = clib_net_to_host_u16(a->_vl_msg_id);
403 +    a->client_index = clib_net_to_host_u32(a->client_index);
404 +    a->context = clib_net_to_host_u32(a->context);
405 +    /* a->is_ip6 = a->is_ip6 (no-op) */
406 +}
407 +
408 +/***** manual: vl_api_dhcp_server_t_endian  *****/
409 +
410 +/***** manual: vl_api_dhcp_proxy_details_t_endian  *****/
411 +
412 +#endif /* vl_endianfun */
413 +
414 +
415 +#ifdef vl_api_version
416 +vl_api_version(dhcp.api, 0x214119c5)
417 +
418 +#endif
419 +
420 diff --git a/src/configure.ac b/src/configure.ac
421 index fb2ead6..ef5537d 100644
422 --- a/src/configure.ac
423 +++ b/src/configure.ac
424 @@ -152,6 +152,7 @@ PLUGIN_ENABLED(ioam)
425  PLUGIN_ENABLED(ixge)
426  PLUGIN_ENABLED(lb)
427  PLUGIN_ENABLED(memif)
428 +PLUGIN_ENABLED(vbng)
429  PLUGIN_ENABLED(sixrd)
430  PLUGIN_ENABLED(snat)
431  
432 diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
433 index 623892e..d6f607f 100644
434 --- a/src/plugins/Makefile.am
435 +++ b/src/plugins/Makefile.am
436 @@ -61,6 +61,10 @@ if ENABLE_MEMIF_PLUGIN
437  include memif.am
438  endif
439  
440 +if ENABLE_VBNG_PLUGIN
441 +include vbng.am
442 +endif
443 +
444  if ENABLE_SIXRD_PLUGIN
445  include sixrd.am
446  endif
447 diff --git a/src/plugins/vbng.am b/src/plugins/vbng.am
448 new file mode 100644
449 index 0000000..99398f4
450 --- /dev/null
451 +++ b/src/plugins/vbng.am
452 @@ -0,0 +1,32 @@
453 +# Copyright (c) 2017 Intel and/or its affiliates.
454 +# Licensed under the Apache License, Version 2.0 (the "License");
455 +# you may not use this file except in compliance with the License.
456 +# You may obtain a copy of the License at:
457 +#
458 +#     http://www.apache.org/licenses/LICENSE-2.0
459 +#
460 +# Unless required by applicable law or agreed to in writing, software
461 +# distributed under the License is distributed on an "AS IS" BASIS,
462 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
463 +# See the License for the specific language governing permissions and
464 +# limitations under the License.
465 +
466 +vppplugins_LTLIBRARIES += vbng_plugin.la
467 +
468 +vbng_plugin_la_LDFLAGS = $(AM_LDFLAGS) -lfreeradiusclient
469 +
470 +vbng_plugin_la_SOURCES = vbng/vbng_dhcp4_node.c        \
471 +                        vbng/vbng_dhcp4.c      \
472 +                        vbng/vbng_api.c        \
473 +                        vbng/vbng_aaa.c
474 +
475 +BUILT_SOURCES += vbng/vbng.api.h               \
476 +                vbng/vbng.api.json
477 +
478 +API_FILES += vbng/vbng.api
479 +
480 +nobase_apiinclude_HEADERS += vbng/vbng_all_api_h.h     \
481 +                            vbng/vbng_msg_enum.h       \
482 +                            vbng/vbng.api.h
483 +
484 +# vi:syntax=automake
485 diff --git a/src/plugins/vbng/etc/dictionary b/src/plugins/vbng/etc/dictionary
486 new file mode 100644
487 index 0000000..45f4189
488 --- /dev/null
489 +++ b/src/plugins/vbng/etc/dictionary
490 @@ -0,0 +1,274 @@
491 +#
492 +# Updated 97/06/13 to livingston-radius-2.01 miquels@cistron.nl
493 +#
494 +#      This file contains dictionary translations for parsing
495 +#      requests and generating responses.  All transactions are
496 +#      composed of Attribute/Value Pairs.  The value of each attribute
497 +#      is specified as one of 4 data types.  Valid data types are:
498 +#
499 +#      string - 0-253 octets
500 +#      ipaddr - 4 octets in network byte order
501 +#      integer - 32 bit value in big endian order (high byte first)
502 +#      date - 32 bit value in big endian order - seconds since
503 +#                                      00:00:00 GMT,  Jan.  1,  1970
504 +#
505 +#      Enumerated values are stored in the user file with dictionary
506 +#      VALUE translations for easy administration.
507 +#
508 +#      Example:
509 +#
510 +#      ATTRIBUTE         VALUE
511 +#      ---------------   -----
512 +#      Framed-Protocol = PPP
513 +#      7               = 1     (integer encoding)
514 +#
515 +
516 +#
517 +#      Following are the proper new names. Use these.
518 +#
519 +ATTRIBUTE      User-Name               1       string
520 +ATTRIBUTE      Password                2       string
521 +ATTRIBUTE      CHAP-Password           3       string
522 +ATTRIBUTE      NAS-IP-Address          4       ipaddr
523 +ATTRIBUTE      NAS-Port-Id             5       integer
524 +ATTRIBUTE      Service-Type            6       integer
525 +ATTRIBUTE      Framed-Protocol         7       integer
526 +ATTRIBUTE      Framed-IP-Address       8       ipaddr
527 +ATTRIBUTE      Framed-IP-Netmask       9       ipaddr
528 +ATTRIBUTE      Framed-Routing          10      integer
529 +ATTRIBUTE      Filter-Id               11      string
530 +ATTRIBUTE      Framed-MTU              12      integer
531 +ATTRIBUTE      Framed-Compression      13      integer
532 +ATTRIBUTE      Login-IP-Host           14      ipaddr
533 +ATTRIBUTE      Login-Service           15      integer
534 +ATTRIBUTE      Login-TCP-Port          16      integer
535 +ATTRIBUTE      Reply-Message           18      string
536 +ATTRIBUTE      Callback-Number         19      string
537 +ATTRIBUTE      Callback-Id             20      string
538 +ATTRIBUTE      Framed-Route            22      string
539 +ATTRIBUTE      Framed-IPX-Network      23      ipaddr
540 +ATTRIBUTE      State                   24      string
541 +ATTRIBUTE      Class                   25      string
542 +ATTRIBUTE      Vendor-Specific         26      string
543 +ATTRIBUTE      Session-Timeout         27      integer
544 +ATTRIBUTE      Idle-Timeout            28      integer
545 +ATTRIBUTE      Termination-Action      29      integer
546 +ATTRIBUTE      Called-Station-Id       30      string
547 +ATTRIBUTE      Calling-Station-Id      31      string
548 +ATTRIBUTE      NAS-Identifier          32      string
549 +ATTRIBUTE      Proxy-State             33      string
550 +ATTRIBUTE      Login-LAT-Service       34      string
551 +ATTRIBUTE      Login-LAT-Node          35      string
552 +ATTRIBUTE      Login-LAT-Group         36      string
553 +ATTRIBUTE      Framed-AppleTalk-Link   37      integer
554 +ATTRIBUTE      Framed-AppleTalk-Network        38      integer
555 +ATTRIBUTE      Framed-AppleTalk-Zone   39      string
556 +ATTRIBUTE      Acct-Status-Type        40      integer
557 +ATTRIBUTE      Acct-Delay-Time         41      integer
558 +ATTRIBUTE      Acct-Input-Octets       42      integer
559 +ATTRIBUTE      Acct-Output-Octets      43      integer
560 +ATTRIBUTE      Acct-Session-Id         44      string
561 +ATTRIBUTE      Acct-Authentic          45      integer
562 +ATTRIBUTE      Acct-Session-Time       46      integer
563 +ATTRIBUTE      Acct-Input-Packets      47      integer
564 +ATTRIBUTE      Acct-Output-Packets     48      integer
565 +ATTRIBUTE      Acct-Terminate-Cause    49      integer
566 +ATTRIBUTE      Acct-Multi-Session-Id   50      string
567 +ATTRIBUTE      Acct-Link-Count         51      integer
568 +ATTRIBUTE      Acct-Input-Gigawords    52      integer
569 +ATTRIBUTE      Acct-Output-Gigawords   53      integer
570 +ATTRIBUTE      Event-Timestamp         55      integer
571 +ATTRIBUTE      CHAP-Challenge          60      string
572 +ATTRIBUTE      NAS-Port-Type           61      integer
573 +ATTRIBUTE      Port-Limit              62      integer
574 +ATTRIBUTE      Login-LAT-Port          63      integer
575 +ATTRIBUTE      Connect-Info            77      string
576 +
577 +#
578 +#      RFC3162 IPv6 attributes
579 +#
580 +ATTRIBUTE      NAS-IPv6-Address        95      string
581 +ATTRIBUTE      Framed-Interface-Id     96      string
582 +ATTRIBUTE      Framed-IPv6-Prefix      97      ipv6prefix
583 +ATTRIBUTE      Login-IPv6-Host         98      string
584 +ATTRIBUTE      Framed-IPv6-Route       99      string
585 +ATTRIBUTE      Framed-IPv6-Pool        100     string
586 +
587 +#
588 +#      RFC6911 IPv6 attributes
589 +#
590 +ATTRIBUTE      Framed-IPv6-Address     168     ipv6addr
591 +ATTRIBUTE      DNS-Server-IPv6-Address 169     ipv6addr
592 +ATTRIBUTE      Route-IPv6-Information  170     ipv6prefix
593 +
594 +#
595 +#      Experimental Non Protocol Attributes used by Cistron-Radiusd
596 +#
597 +ATTRIBUTE      Huntgroup-Name          221     string
598 +ATTRIBUTE      User-Category           1029    string
599 +ATTRIBUTE      Group-Name              1030    string
600 +ATTRIBUTE      Simultaneous-Use        1034    integer
601 +ATTRIBUTE      Strip-User-Name         1035    integer
602 +ATTRIBUTE      Fall-Through            1036    integer
603 +ATTRIBUTE      Add-Port-To-IP-Address  1037    integer
604 +ATTRIBUTE      Exec-Program            1038    string
605 +ATTRIBUTE      Exec-Program-Wait       1039    string
606 +ATTRIBUTE      Hint                    1040    string
607 +
608 +#
609 +#      Non-Protocol Attributes
610 +#      These attributes are used internally by the server
611 +#
612 +ATTRIBUTE      Expiration                21    date
613 +ATTRIBUTE      Auth-Type               1000    integer
614 +ATTRIBUTE      Menu                    1001    string
615 +ATTRIBUTE      Termination-Menu        1002    string
616 +ATTRIBUTE      Prefix                  1003    string
617 +ATTRIBUTE      Suffix                  1004    string
618 +ATTRIBUTE      Group                   1005    string
619 +ATTRIBUTE      Crypt-Password          1006    string
620 +ATTRIBUTE      Connect-Rate            1007    integer
621 +
622 +#
623 +#      Integer Translations
624 +#
625 +
626 +#      User Types
627 +
628 +VALUE          Service-Type            Login-User              1
629 +VALUE          Service-Type            Framed-User             2
630 +VALUE          Service-Type            Callback-Login-User     3
631 +VALUE          Service-Type            Callback-Framed-User    4
632 +VALUE          Service-Type            Outbound-User           5
633 +VALUE          Service-Type            Administrative-User     6
634 +VALUE          Service-Type            NAS-Prompt-User         7
635 +VALUE          Service-Type            Authenticate-Only       8
636 +VALUE          Service-Type            Callback-NAS-Prompt     9
637 +VALUE          Service-Type            Call-Check              10
638 +VALUE          Service-Type            Callback-Administrative 11
639 +
640 +#      Framed Protocols
641 +
642 +VALUE          Framed-Protocol         PPP                     1
643 +VALUE          Framed-Protocol         SLIP                    2
644 +VALUE          Framed-Protocol         ARAP                    3
645 +VALUE          Framed-Protocol         GANDALF-SLMLP           4
646 +VALUE          Framed-Protocol         XYLOGICS-IPX-SLIP       5
647 +VALUE          Framed-Protocol         X75                     6
648 +
649 +#      Framed Routing Values
650 +
651 +VALUE          Framed-Routing          None                    0
652 +VALUE          Framed-Routing          Broadcast               1
653 +VALUE          Framed-Routing          Listen                  2
654 +VALUE          Framed-Routing          Broadcast-Listen        3
655 +
656 +#      Framed Compression Types
657 +
658 +VALUE          Framed-Compression      None                    0
659 +VALUE          Framed-Compression      Van-Jacobson-TCP-IP     1
660 +VALUE          Framed-Compression      IPX-Header              2
661 +VALUE          Framed-Compression      Stac-LZS                3
662 +
663 +#      Login Services
664 +
665 +VALUE          Login-Service           Telnet                  0
666 +VALUE          Login-Service           Rlogin                  1
667 +VALUE          Login-Service           TCP-Clear               2
668 +VALUE          Login-Service           PortMaster              3
669 +VALUE          Login-Service           LAT                     4
670 +VALUE          Login-Service           X.25-PAD                5
671 +VALUE          Login-Service           X.25-T3POS              6
672 +VALUE          Login-Service           TCP-Clear-Quiet         8
673 +
674 +#      Status Types
675 +
676 +VALUE          Acct-Status-Type        Start                   1
677 +VALUE          Acct-Status-Type        Stop                    2
678 +VALUE          Acct-Status-Type        Alive                   3
679 +VALUE          Acct-Status-Type        Accounting-On           7
680 +VALUE          Acct-Status-Type        Accounting-Off          8
681 +
682 +#      Authentication Types
683 +
684 +VALUE          Acct-Authentic          RADIUS                  1
685 +VALUE          Acct-Authentic          Local                   2
686 +VALUE          Acct-Authentic          Remote                  3
687 +
688 +#      Termination Options
689 +
690 +VALUE          Termination-Action      Default                 0
691 +VALUE          Termination-Action      RADIUS-Request          1
692 +
693 +#      NAS Port Types, available in 3.3.1 and later
694 +
695 +VALUE          NAS-Port-Type           Async                   0
696 +VALUE          NAS-Port-Type           Sync                    1
697 +VALUE          NAS-Port-Type           ISDN                    2
698 +VALUE          NAS-Port-Type           ISDN-V120               3
699 +VALUE          NAS-Port-Type           ISDN-V110               4
700 +VALUE          NAS-Port-Type           Virtual                 5
701 +VALUE          NAS-Port-Type           PIAFS                   6
702 +VALUE          NAS-Port-Type           HDLC-Clear-Channel      7
703 +VALUE          NAS-Port-Type           X.25                    8
704 +VALUE          NAS-Port-Type           X.75                    9
705 +VALUE          NAS-Port-Type           G.3-Fax                 10
706 +VALUE          NAS-Port-Type           SDSL                    11
707 +VALUE          NAS-Port-Type           ADSL-CAP                12
708 +VALUE          NAS-Port-Type           ADSL-DMT                13
709 +VALUE          NAS-Port-Type           IDSL                    14
710 +VALUE          NAS-Port-Type           Ethernet                15
711 +
712 +#      Acct Terminate Causes, available in 3.3.2 and later
713 +
714 +VALUE           Acct-Terminate-Cause    User-Request            1
715 +VALUE           Acct-Terminate-Cause    Lost-Carrier            2
716 +VALUE           Acct-Terminate-Cause    Lost-Service            3
717 +VALUE           Acct-Terminate-Cause    Idle-Timeout            4
718 +VALUE           Acct-Terminate-Cause    Session-Timeout         5
719 +VALUE           Acct-Terminate-Cause    Admin-Reset             6
720 +VALUE           Acct-Terminate-Cause    Admin-Reboot            7
721 +VALUE           Acct-Terminate-Cause    Port-Error              8
722 +VALUE           Acct-Terminate-Cause    NAS-Error               9
723 +VALUE           Acct-Terminate-Cause    NAS-Request             10
724 +VALUE           Acct-Terminate-Cause    NAS-Reboot              11
725 +VALUE           Acct-Terminate-Cause    Port-Unneeded           12
726 +VALUE           Acct-Terminate-Cause    Port-Preempted          13
727 +VALUE           Acct-Terminate-Cause    Port-Suspended          14
728 +VALUE           Acct-Terminate-Cause    Service-Unavailable     15
729 +VALUE           Acct-Terminate-Cause    Callback                16
730 +VALUE           Acct-Terminate-Cause    User-Error              17
731 +VALUE           Acct-Terminate-Cause    Host-Request            18
732 +
733 +#
734 +#      Non-Protocol Integer Translations
735 +#
736 +
737 +VALUE          Auth-Type               Local                   0
738 +VALUE          Auth-Type               System                  1
739 +VALUE          Auth-Type               SecurID                 2
740 +VALUE          Auth-Type               Crypt-Local             3
741 +VALUE          Auth-Type               Reject                  4
742 +
743 +#
744 +#      Cistron extensions
745 +#
746 +VALUE          Auth-Type               Pam                     253
747 +VALUE          Auth-Type               Accept                  254
748 +
749 +#
750 +#      Experimental Non-Protocol Integer Translations for Cistron-Radiusd
751 +#
752 +VALUE          Fall-Through            No                      0
753 +VALUE          Fall-Through            Yes                     1
754 +VALUE          Add-Port-To-IP-Address  No                      0
755 +VALUE          Add-Port-To-IP-Address  Yes                     1
756 +
757 +#
758 +#      Configuration Values
759 +#      uncomment these two lines to turn account expiration on
760 +#
761 +
762 +#VALUE         Server-Config           Password-Expiration     30
763 +#VALUE         Server-Config           Password-Warning        5
764 +
765 diff --git a/src/plugins/vbng/etc/dictionary.ascend b/src/plugins/vbng/etc/dictionary.ascend
766 new file mode 100644
767 index 0000000..a02c207
768 --- /dev/null
769 +++ b/src/plugins/vbng/etc/dictionary.ascend
770 @@ -0,0 +1,297 @@
771 +#
772 +# Ascend dictionary.
773 +#
774 +#              Enable by putting the line "$INCLUDE dictionary.ascend" into
775 +#              the main dictionary file.
776 +#
777 +# Version:     1.00  21-Jul-1997  Jens Glaser <jens@regio.net>
778 +#
779 +
780 +
781 +#
782 +#      Ascend specific extensions
783 +#      Used by ASCEND MAX/Pipeline products
784 +#
785 +ATTRIBUTE      Ascend-FCP-Parameter            119     string
786 +ATTRIBUTE      Ascend-Modem-PortNo             120     integer
787 +ATTRIBUTE      Ascend-Modem-SlotNo             121     integer
788 +ATTRIBUTE      Ascend-Modem-ShelfNo            122     integer
789 +ATTRIBUTE      Ascend-Call-Attempt-Limit       123     integer
790 +ATTRIBUTE      Ascend-Call-Block-Duration      124     integer
791 +ATTRIBUTE      Ascend-Maximum-Call-Duration    125     integer
792 +ATTRIBUTE      Ascend-Temporary-Rtes           126     integer
793 +ATTRIBUTE       Tunneling-Protocol              127     integer
794 +ATTRIBUTE       Ascend-Shared-Profile-Enable    128     integer
795 +ATTRIBUTE      Ascend-Primary-Home-Agent       129     string
796 +ATTRIBUTE      Ascend-Secondary-Home-Agent     130     string
797 +ATTRIBUTE      Ascend-Dialout-Allowed          131     integer
798 +ATTRIBUTE      Ascend-Client-Gateway           132     ipaddr
799 +ATTRIBUTE      Ascend-BACP-Enable              133     integer
800 +ATTRIBUTE      Ascend-DHCP-Maximum-Leases      134     integer
801 +ATTRIBUTE      Ascend-Client-Primary-DNS       135     ipaddr
802 +ATTRIBUTE      Ascend-Client-Secondary-DNS     136     ipaddr
803 +ATTRIBUTE      Ascend-Client-Assign-DNS        137     integer
804 +ATTRIBUTE      Ascend-User-Acct-Type           138     integer
805 +ATTRIBUTE      Ascend-User-Acct-Host           139     ipaddr
806 +ATTRIBUTE      Ascend-User-Acct-Port           140     integer
807 +ATTRIBUTE      Ascend-User-Acct-Key            141     string
808 +ATTRIBUTE      Ascend-User-Acct-Base           142     integer
809 +ATTRIBUTE      Ascend-User-Acct-Time           143     integer
810 +ATTRIBUTE      Ascend-Assign-IP-Client         144     ipaddr
811 +ATTRIBUTE      Ascend-Assign-IP-Server         145     ipaddr
812 +ATTRIBUTE      Ascend-Assign-IP-Global-Pool    146     string
813 +ATTRIBUTE      Ascend-DHCP-Reply               147     integer
814 +ATTRIBUTE      Ascend-DHCP-Pool-Number         148     integer
815 +ATTRIBUTE      Ascend-Expect-Callback          149     integer
816 +ATTRIBUTE      Ascend-Event-Type               150     integer
817 +ATTRIBUTE      Ascend-Session-Svr-Key          151     string
818 +ATTRIBUTE      Ascend-Multicast-Rate-Limit     152     integer
819 +ATTRIBUTE      Ascend-IF-Netmask               153     ipaddr
820 +ATTRIBUTE      Ascend-Remote-Addr              154     ipaddr
821 +ATTRIBUTE      Ascend-Multicast-Client         155     integer
822 +ATTRIBUTE      Ascend-FR-Circuit-Name          156     string
823 +ATTRIBUTE      Ascend-FR-LinkUp                157     integer
824 +ATTRIBUTE      Ascend-FR-Nailed-Grp            158     integer
825 +ATTRIBUTE      Ascend-FR-Type                  159     integer
826 +ATTRIBUTE      Ascend-FR-Link-Mgt              160     integer
827 +ATTRIBUTE      Ascend-FR-N391                  161     integer
828 +ATTRIBUTE      Ascend-FR-DCE-N392              162     integer
829 +ATTRIBUTE      Ascend-FR-DTE-N392              163     integer
830 +ATTRIBUTE      Ascend-FR-DCE-N393              164     integer
831 +ATTRIBUTE      Ascend-FR-DTE-N393              165     integer
832 +ATTRIBUTE      Ascend-FR-T391                  166     integer
833 +ATTRIBUTE      Ascend-FR-T392                  167     integer
834 +ATTRIBUTE      Ascend-Bridge-Address           168     string
835 +ATTRIBUTE       Ascend-TS-Idle-Limit            169     integer
836 +ATTRIBUTE       Ascend-TS-Idle-Mode             170     integer
837 +ATTRIBUTE      Ascend-DBA-Monitor              171     integer
838 +ATTRIBUTE      Ascend-Base-Channel-Count       172     integer
839 +ATTRIBUTE      Ascend-Minimum-Channels         173     integer
840 +ATTRIBUTE      Ascend-IPX-Route                174     string
841 +ATTRIBUTE      Ascend-FT1-Caller               175     integer
842 +ATTRIBUTE      Ascend-Backup                   176     string
843 +ATTRIBUTE      Ascend-Call-Type                177     integer
844 +ATTRIBUTE      Ascend-Group                    178     string
845 +ATTRIBUTE      Ascend-FR-DLCI                  179     integer
846 +ATTRIBUTE      Ascend-FR-Profile-Name          180     string
847 +ATTRIBUTE      Ascend-Ara-PW                   181     string
848 +ATTRIBUTE      Ascend-IPX-Node-Addr            182     string
849 +ATTRIBUTE      Ascend-Home-Agent-IP-Addr       183     ipaddr
850 +ATTRIBUTE      Ascend-Home-Agent-Password      184     string
851 +ATTRIBUTE      Ascend-Home-Network-Name        185     string
852 +ATTRIBUTE      Ascend-Home-Agent-UDP-Port      186     integer
853 +ATTRIBUTE      Ascend-Multilink-ID             187     integer
854 +ATTRIBUTE      Ascend-Num-In-Multilink         188     integer
855 +ATTRIBUTE      Ascend-First-Dest               189     ipaddr
856 +ATTRIBUTE      Ascend-Pre-Input-Octets         190     integer
857 +ATTRIBUTE      Ascend-Pre-Output-Octets        191     integer
858 +ATTRIBUTE      Ascend-Pre-Input-Packets        192     integer
859 +ATTRIBUTE      Ascend-Pre-Output-Packets       193     integer
860 +ATTRIBUTE      Ascend-Maximum-Time             194     integer
861 +ATTRIBUTE      Ascend-Disconnect-Cause         195     integer
862 +ATTRIBUTE      Ascend-Connect-Progress         196     integer
863 +ATTRIBUTE      Ascend-Data-Rate                197     integer
864 +ATTRIBUTE      Ascend-PreSession-Time          198     integer
865 +ATTRIBUTE      Ascend-Token-Idle               199     integer
866 +ATTRIBUTE      Ascend-Token-Immediate          200     integer
867 +ATTRIBUTE      Ascend-Require-Auth             201     integer
868 +ATTRIBUTE      Ascend-Number-Sessions          202     string
869 +ATTRIBUTE      Ascend-Authen-Alias             203     string
870 +ATTRIBUTE      Ascend-Token-Expiry             204     integer
871 +ATTRIBUTE      Ascend-Menu-Selector            205     string
872 +ATTRIBUTE      Ascend-Menu-Item                206     string
873 +ATTRIBUTE      Ascend-PW-Warntime              207     integer
874 +ATTRIBUTE      Ascend-PW-Lifetime              208     integer
875 +ATTRIBUTE      Ascend-IP-Direct                209     ipaddr
876 +ATTRIBUTE      Ascend-PPP-VJ-Slot-Comp         210     integer
877 +ATTRIBUTE      Ascend-PPP-VJ-1172              211     integer
878 +ATTRIBUTE      Ascend-PPP-Async-Map            212     integer
879 +ATTRIBUTE      Ascend-Third-Prompt             213     string
880 +ATTRIBUTE      Ascend-Send-Secret              214     string
881 +ATTRIBUTE      Ascend-Receive-Secret           215     string
882 +ATTRIBUTE      Ascend-IPX-Peer-Mode            216     integer
883 +ATTRIBUTE      Ascend-IP-Pool-Definition       217     string
884 +ATTRIBUTE      Ascend-Assign-IP-Pool           218     integer
885 +ATTRIBUTE      Ascend-FR-Direct                219     integer
886 +ATTRIBUTE      Ascend-FR-Direct-Profile        220     string
887 +ATTRIBUTE      Ascend-FR-Direct-DLCI           221     integer
888 +ATTRIBUTE      Ascend-Handle-IPX               222     integer
889 +ATTRIBUTE      Ascend-Netware-timeout          223     integer
890 +ATTRIBUTE      Ascend-IPX-Alias                224     integer
891 +ATTRIBUTE      Ascend-Metric                   225     integer
892 +ATTRIBUTE      Ascend-PRI-Number-Type          226     integer
893 +ATTRIBUTE      Ascend-Dial-Number              227     string
894 +ATTRIBUTE      Ascend-Route-IP                 228     integer
895 +ATTRIBUTE      Ascend-Route-IPX                229     integer
896 +ATTRIBUTE      Ascend-Bridge                   230     integer
897 +ATTRIBUTE      Ascend-Send-Auth                231     integer
898 +ATTRIBUTE      Ascend-Send-Passwd              232     string
899 +ATTRIBUTE      Ascend-Link-Compression         233     integer
900 +ATTRIBUTE      Ascend-Target-Util              234     integer
901 +ATTRIBUTE      Ascend-Maximum-Channels         235     integer
902 +ATTRIBUTE      Ascend-Inc-Channel-Count        236     integer
903 +ATTRIBUTE      Ascend-Dec-Channel-Count        237     integer
904 +ATTRIBUTE      Ascend-Seconds-Of-History       238     integer
905 +ATTRIBUTE      Ascend-History-Weigh-Type       239     integer
906 +ATTRIBUTE      Ascend-Add-Seconds              240     integer
907 +ATTRIBUTE      Ascend-Remove-Seconds           241     integer
908 +ATTRIBUTE      Ascend-Idle-Limit               244     integer
909 +ATTRIBUTE      Ascend-Preempt-Limit            245     integer
910 +ATTRIBUTE      Ascend-Callback                 246     integer
911 +ATTRIBUTE      Ascend-Data-Svc                 247     integer
912 +ATTRIBUTE      Ascend-Force-56                 248     integer
913 +ATTRIBUTE      Ascend-Billing-Number           249     string
914 +ATTRIBUTE      Ascend-Call-By-Call             250     integer
915 +ATTRIBUTE      Ascend-Transit-Number           251     string
916 +ATTRIBUTE      Ascend-Host-Info                252     string
917 +ATTRIBUTE      Ascend-PPP-Address              253     ipaddr
918 +ATTRIBUTE      Ascend-MPP-Idle-Percent         254     integer
919 +ATTRIBUTE      Ascend-Xmit-Rate                255     integer
920 +
921 +
922 +
923 +# Ascend protocols
924 +VALUE          Service-Type            Dialout-Framed-User     5
925 +VALUE          Framed-Protocol         ARA                     255
926 +VALUE          Framed-Protocol         MPP                     256
927 +VALUE          Framed-Protocol         EURAW                   257
928 +VALUE          Framed-Protocol         EUUI                    258
929 +VALUE          Framed-Protocol         X25                     259
930 +VALUE          Framed-Protocol         COMB                    260
931 +VALUE          Framed-Protocol         FR                      261
932 +VALUE          Framed-Protocol         MP                      262
933 +VALUE          Framed-Protocol         FR-CIR                  263
934 +
935 +
936 +#
937 +#      Ascend specific extensions
938 +#      Used by ASCEND MAX/Pipeline products (see above)
939 +#
940 +
941 +VALUE          Ascend-FR-Direct        FR-Direct-No            0
942 +VALUE          Ascend-FR-Direct        FR-Direct-Yes           1
943 +VALUE          Ascend-Handle-IPX       Handle-IPX-None         0
944 +VALUE          Ascend-Handle-IPX       Handle-IPX-Client       1
945 +VALUE          Ascend-Handle-IPX       Handle-IPX-Server       2
946 +VALUE          Ascend-IPX-Peer-Mode    IPX-Peer-Router         0
947 +VALUE          Ascend-IPX-Peer-Mode    IPX-Peer-Dialin         1
948 +VALUE          Ascend-Call-Type        Nailed                  1
949 +VALUE          Ascend-Call-Type        Nailed/Mpp              2
950 +VALUE          Ascend-Call-Type        Perm/Switched           3
951 +VALUE          Ascend-FT1-Caller       FT1-No                  0
952 +VALUE          Ascend-FT1-Caller       FT1-Yes                 1
953 +VALUE          Ascend-PRI-Number-Type  Unknown-Number          0
954 +VALUE          Ascend-PRI-Number-Type  Intl-Number             1
955 +VALUE          Ascend-PRI-Number-Type  National-Number         2
956 +VALUE          Ascend-PRI-Number-Type  Local-Number            4
957 +VALUE          Ascend-PRI-Number-Type  Abbrev-Number           5
958 +VALUE          Ascend-Route-IPX        Route-IPX-No            0
959 +VALUE          Ascend-Route-IPX        Route-IPX-Yes           1
960 +VALUE          Ascend-Bridge           Bridge-No               0
961 +VALUE          Ascend-Bridge           Bridge-Yes              1
962 +VALUE                  Ascend-TS-Idle-Mode     TS-Idle-None            0
963 +VALUE          Ascend-TS-Idle-Mode     TS-Idle-Input           1
964 +VALUE                  Ascend-TS-Idle-Mode     TS-Idle-Input-Output    2
965 +VALUE          Ascend-Send-Auth        Send-Auth-None          0
966 +VALUE          Ascend-Send-Auth        Send-Auth-PAP           1
967 +VALUE          Ascend-Send-Auth        Send-Auth-CHAP          2
968 +VALUE          Ascend-Send-Auth        Send-Auth-MS-CHAP       3
969 +VALUE          Ascend-Link-Compression Link-Comp-None          0
970 +VALUE          Ascend-Link-Compression Link-Comp-Stac          1
971 +VALUE          Ascend-Link-Compression Link-Comp-Stac-Draft-9  2
972 +VALUE          Ascend-Link-Compression Link-Comp-MS-Stac       3
973 +VALUE          Ascend-History-Weigh-Type       History-Constant        0
974 +VALUE          Ascend-History-Weigh-Type       History-Linear          1
975 +VALUE          Ascend-History-Weigh-Type       History-Quadratic       2
976 +VALUE          Ascend-Callback         Callback-No             0
977 +VALUE          Ascend-Callback         Callback-Yes            1
978 +VALUE          Ascend-Expect-Callback  Expect-Callback-No      0
979 +VALUE          Ascend-Expect-Callback  Expect-Callback-Yes     1
980 +VALUE          Ascend-Data-Svc         Switched-Voice-Bearer   0
981 +VALUE          Ascend-Data-Svc         Switched-56KR           1
982 +VALUE          Ascend-Data-Svc         Switched-64K            2
983 +VALUE          Ascend-Data-Svc         Switched-64KR           3
984 +VALUE          Ascend-Data-Svc         Switched-56K            4
985 +VALUE          Ascend-Data-Svc         Switched-384KR          5
986 +VALUE          Ascend-Data-Svc         Switched-384K           6
987 +VALUE          Ascend-Data-Svc         Switched-1536K          7
988 +VALUE          Ascend-Data-Svc         Switched-1536KR         8
989 +VALUE          Ascend-Data-Svc         Switched-128K           9
990 +VALUE          Ascend-Data-Svc         Switched-192K           10
991 +VALUE          Ascend-Data-Svc         Switched-256K           11
992 +VALUE          Ascend-Data-Svc         Switched-320K           12
993 +VALUE          Ascend-Data-Svc         Switched-384K-MR        13
994 +VALUE          Ascend-Data-Svc         Switched-448K           14
995 +VALUE          Ascend-Data-Svc         Switched-512K           15
996 +VALUE          Ascend-Data-Svc         Switched-576K           16
997 +VALUE          Ascend-Data-Svc         Switched-640K           17
998 +VALUE          Ascend-Data-Svc         Switched-704K           18
999 +VALUE          Ascend-Data-Svc         Switched-768K           19
1000 +VALUE          Ascend-Data-Svc         Switched-832K           20
1001 +VALUE          Ascend-Data-Svc         Switched-896K           21
1002 +VALUE          Ascend-Data-Svc         Switched-960K           22
1003 +VALUE          Ascend-Data-Svc         Switched-1024K          23
1004 +VALUE          Ascend-Data-Svc         Switched-1088K          24
1005 +VALUE          Ascend-Data-Svc         Switched-1152K          25
1006 +VALUE          Ascend-Data-Svc         Switched-1216K          26
1007 +VALUE          Ascend-Data-Svc         Switched-1280K          27
1008 +VALUE          Ascend-Data-Svc         Switched-1344K          28
1009 +VALUE          Ascend-Data-Svc         Switched-1408K          29
1010 +VALUE          Ascend-Data-Svc         Switched-1472K          30
1011 +VALUE          Ascend-Data-Svc         Switched-1600K          31
1012 +VALUE          Ascend-Data-Svc         Switched-1664K          32
1013 +VALUE          Ascend-Data-Svc         Switched-1728K          33
1014 +VALUE          Ascend-Data-Svc         Switched-1792K          34
1015 +VALUE          Ascend-Data-Svc         Switched-1856K          35
1016 +VALUE          Ascend-Data-Svc         Switched-1920K          36
1017 +VALUE          Ascend-Data-Svc         Switched-inherited              37
1018 +VALUE          Ascend-Data-Svc         Switched-restricted-bearer-x30  38
1019 +VALUE          Ascend-Data-Svc         Switched-clear-bearer-v110      39
1020 +VALUE          Ascend-Data-Svc         Switched-restricted-64-x30      40
1021 +VALUE          Ascend-Data-Svc         Switched-clear-56-v110          41
1022 +VALUE          Ascend-Data-Svc         Switched-modem                  42
1023 +VALUE          Ascend-Data-Svc         Switched-atmodem                43
1024 +VALUE          Ascend-Data-Svc         Nailed-56KR             1
1025 +VALUE          Ascend-Data-Svc         Nailed-64K              2
1026 +VALUE          Ascend-Force-56         Force-56-No             0
1027 +VALUE          Ascend-Force-56         Force-56-Yes            1
1028 +VALUE          Ascend-PW-Lifetime      Lifetime-In-Days        0
1029 +VALUE          Ascend-PW-Warntime      Days-Of-Warning         0
1030 +VALUE          Ascend-PPP-VJ-1172      PPP-VJ-1172             1
1031 +VALUE          Ascend-PPP-VJ-Slot-Comp VJ-Slot-Comp-No         1
1032 +VALUE          Ascend-Require-Auth     Not-Require-Auth        0
1033 +VALUE          Ascend-Require-Auth     Require-Auth            1
1034 +VALUE          Ascend-Token-Immediate  Tok-Imm-No              0
1035 +VALUE          Ascend-Token-Immediate  Tok-Imm-Yes             1
1036 +VALUE          Ascend-DBA-Monitor              DBA-Transmit            0
1037 +VALUE          Ascend-DBA-Monitor      DBA-Transmit-Recv       1
1038 +VALUE          Ascend-DBA-Monitor      DBA-None                2
1039 +VALUE          Ascend-FR-Type          Ascend-FR-DTE           0
1040 +VALUE          Ascend-FR-Type          Ascend-FR-DCE           1
1041 +VALUE          Ascend-FR-Type          Ascend-FR-NNI           2
1042 +VALUE          Ascend-FR-Link-Mgt      Ascend-FR-No-Link-Mgt   0
1043 +VALUE          Ascend-FR-Link-Mgt      Ascend-FR-T1-617D       1
1044 +VALUE          Ascend-FR-Link-Mgt      Ascend-FR-Q-933A        2
1045 +VALUE          Ascend-FR-LinkUp        Ascend-LinkUp-Default   0
1046 +VALUE          Ascend-FR-LinkUp        Ascend-LinkUp-AlwaysUp  1
1047 +VALUE          Ascend-Multicast-Client Multicast-No            0
1048 +VALUE          Ascend-Multicast-Client Multicast-Yes           1
1049 +VALUE          Ascend-User-Acct-Type   Ascend-User-Acct-None   0
1050 +VALUE          Ascend-User-Acct-Type   Ascend-User-Acct-User   1
1051 +VALUE          Ascend-User-Acct-Type   Ascend-User-Acct-User-Default   2
1052 +VALUE          Ascend-User-Acct-Base   Base-10                 0
1053 +VALUE          Ascend-User-Acct-Base   Base-16                 1
1054 +VALUE          Ascend-DHCP-Reply       DHCP-Reply-No           0
1055 +VALUE          Ascend-DHCP-Reply       DHCP-Reply-Yes          1
1056 +VALUE          Ascend-Client-Assign-DNS        DNS-Assign-No           0
1057 +VALUE          Ascend-Client-Assign-DNS        DNS-Assign-Yes          1
1058 +VALUE          Ascend-Event-Type       Ascend-ColdStart        1
1059 +VALUE          Ascend-Event-Type       Ascend-Session-Event    2
1060 +VALUE          Ascend-BACP-Enable      BACP-No                 0
1061 +VALUE          Ascend-BACP-Enable      BACP-Yes                1
1062 +VALUE          Ascend-Dialout-Allowed  Dialout-Not-Allowed     0
1063 +VALUE          Ascend-Dialout-Allowed  Dialout-Allowed         1
1064 +VALUE          Ascend-Shared-Profile-Enable    Shared-Profile-No       0
1065 +VALUE          Ascend-Shared-Profile-Enable    Shared-Profile-Yes      1
1066 +VALUE          Ascend-Temporary-Rtes   Temp-Rtes-No            0
1067 +VALUE          Ascend-Temporary-Rtes   Temp-Rtes-Yes           1
1068 diff --git a/src/plugins/vbng/etc/dictionary.compat b/src/plugins/vbng/etc/dictionary.compat
1069 new file mode 100644
1070 index 0000000..4c85ea8
1071 --- /dev/null
1072 +++ b/src/plugins/vbng/etc/dictionary.compat
1073 @@ -0,0 +1,47 @@
1074 +#
1075 +#      Obsolete names for backwards compatibility with older users files.
1076 +#      Move the $INCLUDE in the main dictionary file to the end if you want
1077 +#      these names to be used in the "details" logfile.
1078 +#
1079 +ATTRIBUTE      Client-Id               4       ipaddr
1080 +ATTRIBUTE      Client-Port-Id          5       integer
1081 +ATTRIBUTE      User-Service-Type       6       integer
1082 +ATTRIBUTE      Framed-Address          8       ipaddr
1083 +ATTRIBUTE      Framed-Netmask          9       ipaddr
1084 +ATTRIBUTE      Framed-Filter-Id        11      string
1085 +ATTRIBUTE      Login-Host              14      ipaddr
1086 +ATTRIBUTE      Login-Port              16      integer
1087 +ATTRIBUTE      Old-Password            17      string
1088 +ATTRIBUTE      Port-Message            18      string
1089 +ATTRIBUTE      Dialback-No             19      string
1090 +ATTRIBUTE      Dialback-Name           20      string
1091 +ATTRIBUTE      Challenge-State         24      string
1092 +VALUE          Framed-Compression      Van-Jacobsen-TCP-IP     1
1093 +VALUE          Framed-Compression      VJ-TCP-IP               1
1094 +VALUE          Service-Type            Shell-User              6
1095 +VALUE          Auth-Type               Unix                    1
1096 +VALUE          Service-Type            Dialback-Login-User     3
1097 +VALUE          Service-Type            Dialback-Framed-User    4
1098 +
1099 +#
1100 +#      For compatibility with MERIT users files.
1101 +#
1102 +ATTRIBUTE      NAS-Port                5       integer
1103 +ATTRIBUTE      Login-Host              14      ipaddr
1104 +ATTRIBUTE      Login-Callback-Number   19      string
1105 +ATTRIBUTE      Framed-Callback-Id      20      string
1106 +ATTRIBUTE      Client-Port-DNIS        30      string
1107 +ATTRIBUTE      Caller-ID               31      string
1108 +VALUE          Service-Type            Login                   1
1109 +VALUE          Service-Type            Framed                  2
1110 +VALUE          Service-Type            Callback-Login          3
1111 +VALUE          Service-Type            Callback-Framed         4
1112 +VALUE          Service-Type            Exec-User               7
1113 +
1114 +#
1115 +#      For compatibility with ESVA RADIUS, Old Cistron RADIUS
1116 +#
1117 +ATTRIBUTE      Session                 1034    integer
1118 +ATTRIBUTE      User-Name-Is-Star       1035    integer
1119 +VALUE          User-Name-Is-Star       No                      0
1120 +VALUE          User-Name-Is-Star       Yes                     1
1121 diff --git a/src/plugins/vbng/etc/dictionary.dhcp b/src/plugins/vbng/etc/dictionary.dhcp
1122 new file mode 100644
1123 index 0000000..cf32934
1124 --- /dev/null
1125 +++ b/src/plugins/vbng/etc/dictionary.dhcp
1126 @@ -0,0 +1,440 @@
1127 +# -*- text -*-
1128 +# Copyright (C) 2011 The FreeRADIUS Server project and contributors
1129 +##############################################################################
1130 +#
1131 +#      DHCP to RADUS gateway dictionary.
1132 +#
1133 +#      http://www.iana.org/assignments/bootp-dhcp-parameters
1134 +#
1135 +#      Also http://www.networksorcery.com/enp/protocol/bootp/options.htm
1136 +#
1137 +#      http://www.bind9.net/rfc-dhcp
1138 +#
1139 +#      $Id: 73632c57d3860bb30749a1df4dad2320d5f79f31 $
1140 +#
1141 +##############################################################################
1142 +
1143 +#
1144 +
1145 +#      This is really Apollo's number, but since they're out of business,
1146 +#      I don't think they'll be needing this.
1147 +#
1148 +#      HP owns the Apollo assets, but let's not worry about that.
1149 +#
1150 +#      The vendor codes are 2 octets, because we need 256 numbers
1151 +#      for the base DHCP options, PLUS a few for the DHCP headers,
1152 +#      which aren't in option format.
1153 +#
1154 +#      On top of that, a number of options are really TLV's.
1155 +#      We need to be able to understand them, too.
1156 +#
1157 +VENDOR         DHCP                            54      format=2,1
1158 +
1159 +BEGIN-VENDOR   DHCP
1160 +
1161 +ATTRIBUTE      DHCP-Opcode                             256     byte
1162 +ATTRIBUTE      DHCP-Hardware-Type                      257     byte
1163 +ATTRIBUTE      DHCP-Hardware-Address-Length            258     byte
1164 +ATTRIBUTE      DHCP-Hop-Count                          259     byte
1165 +ATTRIBUTE      DHCP-Transaction-Id                     260     integer
1166 +ATTRIBUTE      DHCP-Number-of-Seconds                  261     short
1167 +ATTRIBUTE      DHCP-Flags                              262     short
1168 +ATTRIBUTE      DHCP-Client-IP-Address                  263     ipaddr
1169 +ATTRIBUTE      DHCP-Your-IP-Address                    264     ipaddr
1170 +ATTRIBUTE      DHCP-Server-IP-Address                  265     ipaddr
1171 +ATTRIBUTE      DHCP-Gateway-IP-Address                 266     ipaddr
1172 +ATTRIBUTE      DHCP-Client-Hardware-Address            267     ether     # 16 octets
1173 +ATTRIBUTE      DHCP-Server-Host-Name                   268     string    # 64 octets
1174 +ATTRIBUTE      DHCP-Boot-Filename                      269     string    # 128 octets
1175 +
1176 +ATTRIBUTE      DHCP-Relay-To-IP-Address                270     ipaddr
1177 +ATTRIBUTE      DHCP-Relay-Max-Hop-Count                271     integer
1178 +
1179 +# This is copied from the request packet, giaddr, and
1180 +# added to the reply packet by the server core.
1181 +ATTRIBUTE      DHCP-Relay-IP-Address                   272     ipaddr
1182 +
1183 +VALUE  DHCP-Flags                      Broadcast               0x8000
1184 +
1185 +VALUE  DHCP-Hardware-Type              Ethernet                1
1186 +VALUE  DHCP-Hardware-Type              Experiemental-Ethernet  2
1187 +VALUE  DHCP-Hardware-Type              AX.25                   3
1188 +VALUE  DHCP-Hardware-Type              Proteon-Token-Ring      4
1189 +VALUE  DHCP-Hardware-Type              Chaos                   5
1190 +VALUE  DHCP-Hardware-Type              IEEE-802                6
1191 +VALUE  DHCP-Hardware-Type              Arcnet                  7
1192 +VALUE  DHCP-Hardware-Type              Hyperchannel            8
1193 +VALUE  DHCP-Hardware-Type              Lanstar                 9
1194 +VALUE  DHCP-Hardware-Type              Autonet-Short-Address   10
1195 +VALUE  DHCP-Hardware-Type              LocalTalk               11
1196 +VALUE  DHCP-Hardware-Type              LocalNet                12
1197 +VALUE  DHCP-Hardware-Type              Ultra-Link              13
1198 +VALUE  DHCP-Hardware-Type              SMDS                    14
1199 +VALUE  DHCP-Hardware-Type              Frame-Relay             15
1200 +VALUE  DHCP-Hardware-Type              ATM-16                  16
1201 +VALUE  DHCP-Hardware-Type              HDLC                    17
1202 +VALUE  DHCP-Hardware-Type              Fibre-Channel           18
1203 +VALUE  DHCP-Hardware-Type              ATM-19                  19
1204 +VALUE  DHCP-Hardware-Type              Serial-Line             20
1205 +VALUE  DHCP-Hardware-Type              ATM-21                  21
1206 +VALUE  DHCP-Hardware-Type              MIL-STD-188-220         22
1207 +VALUE  DHCP-Hardware-Type              Metricom                23
1208 +VALUE  DHCP-Hardware-Type              IEEE-1394               24
1209 +VALUE  DHCP-Hardware-Type              MAPOS                   25
1210 +VALUE  DHCP-Hardware-Type              Twinaxial               26
1211 +VALUE  DHCP-Hardware-Type              EUI-64                  27
1212 +VALUE  DHCP-Hardware-Type              HIPARP                  28
1213 +VALUE  DHCP-Hardware-Type              IP-Over-ISO-7816-3      29
1214 +VALUE  DHCP-Hardware-Type              ARPSec                  30
1215 +VALUE  DHCP-Hardware-Type              IPSec-Tunnel            31
1216 +VALUE  DHCP-Hardware-Type              Infiniband              32
1217 +VALUE  DHCP-Hardware-Type              CAI-TIA-102             33
1218 +
1219 +##############################################################################
1220 +#
1221 +#      DHCP Options, with comments.  For now, many are "octets",
1222 +#      as FreeRADIUS doesn't handle complex data structures.
1223 +#
1224 +##############################################################################
1225 +
1226 +#ATTRIBUTE     DHCP-Pad                                0       octets
1227 +ATTRIBUTE      DHCP-Subnet-Mask                        1       ipaddr
1228 +# Time Offset in twos-complement notation.
1229 +ATTRIBUTE      DHCP-Time-Offset                        2       integer
1230 +ATTRIBUTE      DHCP-Router-Address                     3       ipaddr array
1231 +ATTRIBUTE      DHCP-Time-Server                        4       ipaddr array
1232 +ATTRIBUTE      DHCP-IEN-116-Name-Server                5       ipaddr array
1233 +ATTRIBUTE      DHCP-Domain-Name-Server                 6       ipaddr array
1234 +# Logging-Server addresses
1235 +ATTRIBUTE      DHCP-Log-Server                         7       ipaddr array
1236 +ATTRIBUTE      DHCP-Quotes-Server                      8       ipaddr array
1237 +ATTRIBUTE      DHCP-LPR-Server                         9       ipaddr array
1238 +ATTRIBUTE      DHCP-Impress-Server                     10      ipaddr array
1239 +ATTRIBUTE      DHCP-RLP-Server                         11      ipaddr array
1240 +# Hostname string
1241 +ATTRIBUTE      DHCP-Hostname                           12      string
1242 +# Size of boot file in 512 byte
1243 +ATTRIBUTE      DHCP-Boot-File-Size                     13      short
1244 +# Client to dump and name
1245 +ATTRIBUTE      DHCP-Merit-Dump-File                    14      octets
1246 +ATTRIBUTE      DHCP-Domain-Name                        15      string
1247 +ATTRIBUTE      DHCP-Swap-Server                        16      ipaddr
1248 +# Path name for root disk
1249 +ATTRIBUTE      DHCP-Root-Path                          17      string
1250 +ATTRIBUTE      DHCP-Bootp-Extensions-Path              18      string
1251 +ATTRIBUTE      DHCP-IP-Forward-Enable                  19      byte
1252 +ATTRIBUTE      DHCP-Source-Route-Enable                20      byte
1253 +# Routing Policy Filters
1254 +ATTRIBUTE      DHCP-Policy-Filter                      21      octets
1255 +ATTRIBUTE      DHCP-Max-Datagram-Reassembly-Sz         22      short
1256 +ATTRIBUTE      DHCP-Default-IP-TTL                     23      octets
1257 +ATTRIBUTE      DHCP-Path-MTU-Aging-Timeout             24      integer
1258 +ATTRIBUTE      DHCP-Path-MTU-Plateau-Table             25      short array
1259 +ATTRIBUTE      DHCP-Interface-MTU-Size                 26      short
1260 +ATTRIBUTE      DHCP-All-Subnets-Are-Local              27      byte
1261 +ATTRIBUTE      DHCP-Broadcast-Address                  28      ipaddr
1262 +ATTRIBUTE      DHCP-Perform-Mask-Discovery             29      byte
1263 +ATTRIBUTE      DHCP-Provide-Mask-To-Others             30      byte
1264 +ATTRIBUTE      DHCP-Perform-Router-Discovery           31      byte
1265 +ATTRIBUTE      DHCP-Router-Solicitation-Address        32      ipaddr
1266 +# first is destination address, second is router.
1267 +ATTRIBUTE      DHCP-Static-Routes                      33      ipaddr array
1268 +ATTRIBUTE      DHCP-Trailer-Encapsulation              34      byte
1269 +ATTRIBUTE      DHCP-ARP-Cache-Timeout                  35      integer
1270 +ATTRIBUTE      DHCP-Ethernet-Encapsulation             36      byte
1271 +ATTRIBUTE      DHCP-Default-TCP-TTL                    37      byte
1272 +ATTRIBUTE      DHCP-Keep-Alive-Interval                38      integer
1273 +ATTRIBUTE      DHCP-Keep-Alive-Garbage                 39      byte
1274 +ATTRIBUTE      DHCP-NIS-Domain-Name                    40      string
1275 +ATTRIBUTE      DHCP-NIS-Servers                        41      ipaddr array
1276 +ATTRIBUTE      DHCP-NTP-Servers                        42      ipaddr array
1277 +# N Vendor Specific Information
1278 +ATTRIBUTE      DHCP-Vendor                             43      octets # tlv
1279 +ATTRIBUTE      DHCP-NETBIOS-Name-Servers               44      ipaddr array
1280 +ATTRIBUTE      DHCP-NETBIOS-Dgm-Dist-Servers           45      ipaddr array
1281 +ATTRIBUTE      DHCP-NETBIOS-Node-Type                  46      byte
1282 +# N NETBIOS Scope
1283 +ATTRIBUTE      DHCP-NETBIOS                            47      octets
1284 +ATTRIBUTE      DHCP-X-Window-Font-Server               48      ipaddr array
1285 +ATTRIBUTE      DHCP-X-Window-Display-Mgr               49      ipaddr array
1286 +ATTRIBUTE      DHCP-Requested-IP-Address               50      ipaddr
1287 +ATTRIBUTE      DHCP-IP-Address-Lease-Time              51      integer
1288 +# Overload "sname" or "file"
1289 +ATTRIBUTE      DHCP-Overload                           52      byte
1290 +ATTRIBUTE      DHCP-Message-Type                       53      byte
1291 +ATTRIBUTE      DHCP-DHCP-Server-Identifier             54      ipaddr
1292 +
1293 +# Array of 1-byte numbers indicating which options the client
1294 +# would like to see in the response.
1295 +ATTRIBUTE      DHCP-Parameter-Request-List             55      byte array
1296 +ATTRIBUTE      DHCP-DHCP-Error-Message                 56      octets
1297 +ATTRIBUTE      DHCP-DHCP-Maximum-Msg-Size              57      short
1298 +ATTRIBUTE      DHCP-Renewal-Time                       58      integer
1299 +ATTRIBUTE      DHCP-Rebinding-Time                     59      integer
1300 +ATTRIBUTE      DHCP-Vendor-Class-Identifier            60      string
1301 +
1302 +# Client Identifier
1303 +# First octets is DHCP-Hardware-Type, rest are type-specific data,
1304 +# e.g. MAC address.
1305 +ATTRIBUTE      DHCP-Client-Identifier                  61      ether
1306 +ATTRIBUTE      DHCP-Netware-Domain-Name                62      octets
1307 +ATTRIBUTE      DHCP-Netware-Sub-Options                63      octets
1308 +ATTRIBUTE      DHCP-NIS-Client-Domain-Name             64      octets
1309 +ATTRIBUTE      DHCP-NIS-Server-Address                 65      ipaddr
1310 +ATTRIBUTE      DHCP-TFTP-Server-Name                   66      string
1311 +ATTRIBUTE      DHCP-Boot-File-Name                     67      string
1312 +# Home Agent Addresses
1313 +ATTRIBUTE      DHCP-Home-Agent-Address                 68      octets
1314 +ATTRIBUTE      DHCP-SMTP-Server-Address                69      ipaddr array
1315 +ATTRIBUTE      DHCP-POP3-Server-Address                70      ipaddr array
1316 +ATTRIBUTE      DHCP-NNTP-Server-Address                71      ipaddr array
1317 +ATTRIBUTE      DHCP-WWW-Server-Address                 72      ipaddr array
1318 +ATTRIBUTE      DHCP-Finger-Server-Address              73      ipaddr array
1319 +ATTRIBUTE      DHCP-IRC-Server-Address                 74      ipaddr array
1320 +ATTRIBUTE      DHCP-StreetTalk-Server-Address          75      ipaddr array
1321 +ATTRIBUTE      DHCP-STDA-Server-Address                76      ipaddr array
1322 +# User Class Information
1323 +ATTRIBUTE      DHCP-User-Class                         77      octets
1324 +# directory agent information
1325 +ATTRIBUTE      DHCP-Directory-Agent                    78      octets
1326 +# service location agent scope
1327 +ATTRIBUTE      DHCP-Service-Scope                      79      octets
1328 +# Rapid Commit
1329 +ATTRIBUTE      DHCP-Rapid-Commit                       80      octets
1330 +# Fully Qualified Domain Name
1331 +ATTRIBUTE      DHCP-Client-FQDN                        81      string
1332 +# Relay Agent Information
1333 +ATTRIBUTE      DHCP-Relay-Agent-Information            82      tlv
1334 +
1335 +ATTRIBUTE      DHCP-Agent-Circuit-Id                   82.1    octets
1336 +ATTRIBUTE      DHCP-Agent-Remote-Id                    82.2    octets
1337 +
1338 +ATTRIBUTE      DHCP-Relay-Circuit-Id                   82.1    octets
1339 +ATTRIBUTE      DHCP-Relay-Remote-Id                    82.2    octets
1340 +
1341 +# 3 is reserved and shouldn't be used for anything
1342 +ATTRIBUTE      DHCP-Docsis-Device-Class                82.4    integer
1343 +ATTRIBUTE      DHCP-Relay-Link-Selection               82.5    ipaddr
1344 +ATTRIBUTE      DHCP-Subscriber-Id                      82.6    string
1345 +
1346 +# AGH!  RADIUS inside of DHCP!
1347 +ATTRIBUTE      DHCP-RADIUS-Attributes                  82.7    octets
1348 +
1349 +# Horribly complicated
1350 +ATTRIBUTE      DHCP-Authentication-Information         82.8    octets
1351 +ATTRIBUTE      DHCP-Vendor-Specific-Information        82.9    octets
1352 +ATTRIBUTE      DHCP-Relay-Agent-Flags                  82.10   byte
1353 +ATTRIBUTE      DHCP-Server-Identifier-Override         82.11   ipaddr
1354 +
1355 +# Internet Storage Name Service
1356 +ATTRIBUTE      DHCP-iSNS                               83      octets
1357 +# Novell Directory Services
1358 +ATTRIBUTE      DHCP-NDS-Servers                        85      octets
1359 +# Novell Directory Services
1360 +ATTRIBUTE      DHCP-NDS-Tree-Name                      86      octets
1361 +# Novell Directory Services
1362 +ATTRIBUTE      DHCP-NDS-Context                        87      octets
1363 +# Authentication
1364 +ATTRIBUTE      DHCP-Authentication                     90      octets
1365 +
1366 +ATTRIBUTE      DHCP-Client-Last-Txn-Time               91      octets
1367 +
1368 +ATTRIBUTE      DHCP-associated-ip                      92      octets
1369 +# Client System Architecture
1370 +ATTRIBUTE      DHCP-Client-System                      93      octets
1371 +# Client Network Device Interface
1372 +ATTRIBUTE      DHCP-Client-NDI                         94      octets
1373 +# Lightweight Directory Access Protocol
1374 +ATTRIBUTE      DHCP-LDAP                               95      octets
1375 +# UUID/GUID-based Client Identifier
1376 +ATTRIBUTE      DHCP-UUID/GUID                          97      octets
1377 +# Open Group's User Authentication
1378 +ATTRIBUTE      DHCP-User-Auth                          98      octets
1379 +# NetInfo Parent-Server Address
1380 +ATTRIBUTE      DHCP-Netinfo-Address                    112     octets
1381 +# NetInfo Parent-Server Tag
1382 +ATTRIBUTE      DHCP-Netinfo-Tag                        113     octets
1383 +# URL
1384 +ATTRIBUTE      DHCP-URL                                114     octets
1385 +# DHCP Auto-Configuration
1386 +ATTRIBUTE      DHCP-Auto-Config                        116     byte
1387 +# Name Service Search
1388 +ATTRIBUTE      DHCP-Name-Service-Search                117     octets
1389 +# Subnet Selection Option
1390 +ATTRIBUTE      DHCP-Subnet-Selection-Option            118     octets
1391 +# DNS domain serach list
1392 +ATTRIBUTE      DHCP-Domain-Search                      119     octets
1393 +# SIP-Servers DHCP Option
1394 +ATTRIBUTE      DHCP-SIP-Servers-DHCP-Option            120     octets
1395 +# Classless Static Route Option
1396 +ATTRIBUTE      DHCP-Classless-Static-Route             121     octets
1397 +# CableLabs Client Configuration
1398 +ATTRIBUTE      DHCP-CCC                                122     octets
1399 +# 16 GeoConf Option
1400 +ATTRIBUTE      DHCP-GeoConf-Option                     123     octets
1401 +
1402 +# Vendor Class
1403 +#
1404 +# String name that defines the vendor space used for the TLV's
1405 +# in option 125.
1406 +#
1407 +ATTRIBUTE      DHCP-V-I-Vendor-Class                   124     octets
1408 +# Vendor-Specific
1409 +ATTRIBUTE      DHCP-V-I-Vendor-Specific                125     octets # tlv
1410 +ATTRIBUTE      DHCP-Etherboot                          128     ether
1411 +# (for IP Phone software load)
1412 +ATTRIBUTE      DHCP-TFTP-Server-IP-Address             128     octets
1413 +
1414 +ATTRIBUTE      DHCP-Call-Server-IP-address             129     octets
1415 +
1416 +ATTRIBUTE      DHCP-Ethernet-Interface                 130     octets
1417 +
1418 +ATTRIBUTE      DHCP-Vendor-Discrimination-Str          130     octets
1419 +
1420 +ATTRIBUTE      DHCP-Remote-Stats-Svr-IP-Address        131     octets
1421 +
1422 +ATTRIBUTE      DHCP-IEEE-802.1Q-L2-Priority            132     octets
1423 +
1424 +ATTRIBUTE      DHCP-IEEE-802.1P-VLAN-ID                133     octets
1425 +
1426 +ATTRIBUTE      DHCP-Diffserv-Code-Point                134     octets
1427 +
1428 +ATTRIBUTE      DHCP-HTTP-Proxy                         135     octets
1429 +
1430 +ATTRIBUTE      DHCP-Cisco-TFTP-Server-IP-Addresses     150     ipaddr array
1431 +
1432 +ATTRIBUTE      DHCP-End-Of-Options                     255     byte
1433 +
1434 +VALUE  DHCP-Opcode                     Client-Message          1
1435 +VALUE  DHCP-Opcode                     Server-Message          2
1436 +
1437 +VALUE  DHCP-Message-Type               DHCP-Do-Not-Respond     0
1438 +VALUE  DHCP-Message-Type               DHCP-Discover           1
1439 +VALUE  DHCP-Message-Type               DHCP-Offer              2
1440 +VALUE  DHCP-Message-Type               DHCP-Request            3
1441 +VALUE  DHCP-Message-Type               DHCP-Decline            4
1442 +VALUE  DHCP-Message-Type               DHCP-Ack                5
1443 +VALUE  DHCP-Message-Type               DHCP-NAK                6
1444 +VALUE  DHCP-Message-Type               DHCP-Release            7
1445 +VALUE  DHCP-Message-Type               DHCP-Inform             8
1446 +VALUE  DHCP-Message-Type               DHCP-Force-Renew        9
1447 +
1448 +VALUE  DHCP-Parameter-Request-List     DHCP-Subnet-Mask        1
1449 +VALUE  DHCP-Parameter-Request-List     DHCP-Time-Offset        2
1450 +VALUE  DHCP-Parameter-Request-List     DHCP-Router-Address     3
1451 +VALUE  DHCP-Parameter-Request-List     DHCP-Time-Server        4
1452 +VALUE  DHCP-Parameter-Request-List     DHCP-IEN-116-Name-Server 5
1453 +VALUE  DHCP-Parameter-Request-List     DHCP-Domain-Name-Server 6
1454 +VALUE  DHCP-Parameter-Request-List     DHCP-Log-Server         7
1455 +VALUE  DHCP-Parameter-Request-List     DHCP-Quotes-Server      8
1456 +VALUE  DHCP-Parameter-Request-List     DHCP-LPR-Server         9
1457 +VALUE  DHCP-Parameter-Request-List     DHCP-Impress-Server     10
1458 +VALUE  DHCP-Parameter-Request-List     DHCP-RLP-Server         11
1459 +VALUE  DHCP-Parameter-Request-List     DHCP-Hostname           12
1460 +VALUE  DHCP-Parameter-Request-List     DHCP-Boot-File-Size     13
1461 +VALUE  DHCP-Parameter-Request-List     DHCP-Merit-Dump-File    14
1462 +VALUE  DHCP-Parameter-Request-List     DHCP-Domain-Name        15
1463 +VALUE  DHCP-Parameter-Request-List     DHCP-Swap-Server        16
1464 +VALUE  DHCP-Parameter-Request-List     DHCP-Root-Path          17
1465 +VALUE  DHCP-Parameter-Request-List     DHCP-Bootp-Extensions-Path 18
1466 +VALUE  DHCP-Parameter-Request-List     DHCP-IP-Forward-Enable  19
1467 +VALUE  DHCP-Parameter-Request-List     DHCP-Source-Route-Enable 20
1468 +VALUE  DHCP-Parameter-Request-List     DHCP-Policy-Filter      21
1469 +VALUE  DHCP-Parameter-Request-List     DHCP-Max-Datagram-Reassembly-Sz 22
1470 +VALUE  DHCP-Parameter-Request-List     DHCP-Default-IP-TTL     23
1471 +VALUE  DHCP-Parameter-Request-List     DHCP-Path-MTU-Aging-Timeout 24
1472 +VALUE  DHCP-Parameter-Request-List     DHCP-Path-MTU-Plateau-Table 25
1473 +VALUE  DHCP-Parameter-Request-List     DHCP-Interface-MTU-Size 26
1474 +VALUE  DHCP-Parameter-Request-List     DHCP-All-Subnets-Are-Local 27
1475 +VALUE  DHCP-Parameter-Request-List     DHCP-Broadcast-Address  28
1476 +VALUE  DHCP-Parameter-Request-List     DHCP-Perform-Mask-Discovery 29
1477 +VALUE  DHCP-Parameter-Request-List     DHCP-Provide-Mask-To-Others 30
1478 +VALUE  DHCP-Parameter-Request-List     DHCP-Perform-Router-Discovery 31
1479 +VALUE  DHCP-Parameter-Request-List     DHCP-Router-Solicitation-Address 32
1480 +VALUE  DHCP-Parameter-Request-List     DHCP-Static-Routes      33
1481 +VALUE  DHCP-Parameter-Request-List     DHCP-Trailer-Encapsulation 34
1482 +VALUE  DHCP-Parameter-Request-List     DHCP-ARP-Cache-Timeout  35
1483 +VALUE  DHCP-Parameter-Request-List     DHCP-Ethernet-Encapsulation 36
1484 +VALUE  DHCP-Parameter-Request-List     DHCP-Default-TCP-TTL    37
1485 +VALUE  DHCP-Parameter-Request-List     DHCP-Keep-Alive-Interval 38
1486 +VALUE  DHCP-Parameter-Request-List     DHCP-Keep-Alive-Garbage 39
1487 +VALUE  DHCP-Parameter-Request-List     DHCP-NIS-Domain-Name    40
1488 +VALUE  DHCP-Parameter-Request-List     DHCP-NIS-Servers        41
1489 +VALUE  DHCP-Parameter-Request-List     DHCP-NTP-Servers        42
1490 +VALUE  DHCP-Parameter-Request-List     DHCP-Vendor             43
1491 +VALUE  DHCP-Parameter-Request-List     DHCP-NETBIOS-Name-Servers 44
1492 +VALUE  DHCP-Parameter-Request-List     DHCP-NETBIOS-Dgm-Dist-Servers 45
1493 +VALUE  DHCP-Parameter-Request-List     DHCP-NETBIOS-Node-Type  46
1494 +VALUE  DHCP-Parameter-Request-List     DHCP-NETBIOS            47
1495 +VALUE  DHCP-Parameter-Request-List     DHCP-X-Window-Font-Server 48
1496 +VALUE  DHCP-Parameter-Request-List     DHCP-X-Window-Display-Mgr 49
1497 +VALUE  DHCP-Parameter-Request-List     DHCP-Requested-IP-Address 50
1498 +VALUE  DHCP-Parameter-Request-List     DHCP-IP-Address-Lease-Time 51
1499 +VALUE  DHCP-Parameter-Request-List     DHCP-Overload           52
1500 +VALUE  DHCP-Parameter-Request-List     DHCP-Message-Type       53
1501 +VALUE  DHCP-Parameter-Request-List     DHCP-DHCP-Server-Identifier 54
1502 +VALUE  DHCP-Parameter-Request-List     DHCP-Parameter-Request-List 55
1503 +VALUE  DHCP-Parameter-Request-List     DHCP-DHCP-Error-Message 56
1504 +VALUE  DHCP-Parameter-Request-List     DHCP-DHCP-Maximum-Msg-Size 57
1505 +VALUE  DHCP-Parameter-Request-List     DHCP-Renewal-Time       58
1506 +VALUE  DHCP-Parameter-Request-List     DHCP-Rebinding-Time     59
1507 +VALUE  DHCP-Parameter-Request-List     DHCP-Class-Identifier   60
1508 +VALUE  DHCP-Parameter-Request-List     DHCP-Client-Identifier  61
1509 +VALUE  DHCP-Parameter-Request-List     DHCP-Netware-Domain-Name 62
1510 +VALUE  DHCP-Parameter-Request-List     DHCP-Netware-Sub-Options 63
1511 +VALUE  DHCP-Parameter-Request-List     DHCP-NIS-Client-Domain-Name 64
1512 +VALUE  DHCP-Parameter-Request-List     DHCP-NIS-Server-Address 65
1513 +VALUE  DHCP-Parameter-Request-List     DHCP-TFTP-Server-Name   66
1514 +VALUE  DHCP-Parameter-Request-List     DHCP-Boot-File-Name     67
1515 +VALUE  DHCP-Parameter-Request-List     DHCP-Home-Agent-Address 68
1516 +VALUE  DHCP-Parameter-Request-List     DHCP-SMTP-Server-Address 69
1517 +VALUE  DHCP-Parameter-Request-List     DHCP-POP3-Server-Address 70
1518 +VALUE  DHCP-Parameter-Request-List     DHCP-NNTP-Server-Address 71
1519 +VALUE  DHCP-Parameter-Request-List     DHCP-WWW-Server-Address 72
1520 +VALUE  DHCP-Parameter-Request-List     DHCP-Finger-Server-Address 73
1521 +VALUE  DHCP-Parameter-Request-List     DHCP-IRC-Server-Address 74
1522 +VALUE  DHCP-Parameter-Request-List     DHCP-StreetTalk-Server-Address 75
1523 +VALUE  DHCP-Parameter-Request-List     DHCP-STDA-Server-Address 76
1524 +VALUE  DHCP-Parameter-Request-List     DHCP-User-Class         77
1525 +VALUE  DHCP-Parameter-Request-List     DHCP-Directory-Agent    78
1526 +VALUE  DHCP-Parameter-Request-List     DHCP-Service-Scope      79
1527 +VALUE  DHCP-Parameter-Request-List     DHCP-Rapid-Commit       80
1528 +VALUE  DHCP-Parameter-Request-List     DHCP-Client-FQDN        81
1529 +VALUE  DHCP-Parameter-Request-List     DHCP-Relay-Agent-Information 82
1530 +VALUE  DHCP-Parameter-Request-List     DHCP-iSNS               83
1531 +VALUE  DHCP-Parameter-Request-List     DHCP-NDS-Servers        85
1532 +VALUE  DHCP-Parameter-Request-List     DHCP-NDS-Tree-Name      86
1533 +VALUE  DHCP-Parameter-Request-List     DHCP-NDS-Context        87
1534 +VALUE  DHCP-Parameter-Request-List     DHCP-Authentication     90
1535 +VALUE  DHCP-Parameter-Request-List     DHCP-Client-Last-Txn-Time 91
1536 +VALUE  DHCP-Parameter-Request-List     DHCP-associated-ip      92
1537 +VALUE  DHCP-Parameter-Request-List     DHCP-Client-System      93
1538 +VALUE  DHCP-Parameter-Request-List     DHCP-Client-NDI         94
1539 +VALUE  DHCP-Parameter-Request-List     DHCP-LDAP               95
1540 +VALUE  DHCP-Parameter-Request-List     DHCP-UUID/GUID          97
1541 +VALUE  DHCP-Parameter-Request-List     DHCP-User-Auth          98
1542 +VALUE  DHCP-Parameter-Request-List     DHCP-Netinfo-Address    112
1543 +VALUE  DHCP-Parameter-Request-List     DHCP-Netinfo-Tag        113
1544 +VALUE  DHCP-Parameter-Request-List     DHCP-URL                114
1545 +VALUE  DHCP-Parameter-Request-List     DHCP-Auto-Config        116
1546 +VALUE  DHCP-Parameter-Request-List     DHCP-Name-Service-Search 117
1547 +VALUE  DHCP-Parameter-Request-List     DHCP-Subnet-Selection-Option 118
1548 +VALUE  DHCP-Parameter-Request-List     DHCP-Domain-Search      119
1549 +VALUE  DHCP-Parameter-Request-List     DHCP-SIP-Servers-DHCP-Option 120
1550 +VALUE  DHCP-Parameter-Request-List     DHCP-Classless-Static-Route 121
1551 +VALUE  DHCP-Parameter-Request-List     DHCP-CCC                122
1552 +VALUE  DHCP-Parameter-Request-List     DHCP-GeoConf-Option     123
1553 +VALUE  DHCP-Parameter-Request-List     DHCP-V-I-Vendor-Class   124
1554 +VALUE  DHCP-Parameter-Request-List     DHCP-V-I-Vendor-Specific 125
1555 +VALUE  DHCP-Parameter-Request-List     DHCP-Etherboot          128
1556 +VALUE  DHCP-Parameter-Request-List     DHCP-TFTP-Server-IP-Address 128
1557 +VALUE  DHCP-Parameter-Request-List     DHCP-Call-Server-IP-address 129
1558 +VALUE  DHCP-Parameter-Request-List     DHCP-Ethernet-Interface 130
1559 +VALUE  DHCP-Parameter-Request-List     DHCP-Vendor-Discrimination-Str 130
1560 +VALUE  DHCP-Parameter-Request-List     DHCP-Remote-Stats-Svr-IP-Address 131
1561 +VALUE  DHCP-Parameter-Request-List     DHCP-IEEE-802.1P-VLAN-ID 132
1562 +VALUE  DHCP-Parameter-Request-List     DHCP-IEEE-802.1Q-L2-Priority 133
1563 +VALUE  DHCP-Parameter-Request-List     DHCP-Diffserv-Code-Point 134
1564 +VALUE  DHCP-Parameter-Request-List     DHCP-HTTP-Proxy         135
1565 +
1566 +END-VENDOR     DHCP
1567 diff --git a/src/plugins/vbng/etc/dictionary.merit b/src/plugins/vbng/etc/dictionary.merit
1568 new file mode 100644
1569 index 0000000..7d675e5
1570 --- /dev/null
1571 +++ b/src/plugins/vbng/etc/dictionary.merit
1572 @@ -0,0 +1,17 @@
1573 +#
1574 +#      Experimental extensions, configuration only (for check-items)
1575 +#      Names/numbers as per the MERIT extensions (if possible).
1576 +#
1577 +ATTRIBUTE      NAS-Identifier          32      string
1578 +ATTRIBUTE      Proxy-State             33      string
1579 +ATTRIBUTE      Login-LAT-Service       34      string
1580 +ATTRIBUTE      Login-LAT-Node          35      string
1581 +ATTRIBUTE      Login-LAT-Group         36      string
1582 +ATTRIBUTE      Framed-AppleTalk-Link   37      integer
1583 +ATTRIBUTE      Framed-AppleTalk-Network 38     integer
1584 +ATTRIBUTE      Framed-AppleTalk-Zone   39      string
1585 +ATTRIBUTE       Acct-Input-Packets     47      integer
1586 +ATTRIBUTE       Acct-Output-Packets    48      integer
1587 +# 8 is a MERIT extension.
1588 +VALUE          Service-Type            Authenticate-Only       8
1589 +
1590 diff --git a/src/plugins/vbng/etc/dictionary.sip b/src/plugins/vbng/etc/dictionary.sip
1591 new file mode 100644
1592 index 0000000..149fa4c
1593 --- /dev/null
1594 +++ b/src/plugins/vbng/etc/dictionary.sip
1595 @@ -0,0 +1,77 @@
1596 +#
1597 +# Updated 97/06/13 to livingston-radius-2.01 miquels@cistron.nl
1598 +#
1599 +#      This file contains dictionary translations for parsing
1600 +#      requests and generating responses.  All transactions are
1601 +#      composed of Attribute/Value Pairs.  The value of each attribute
1602 +#      is specified as one of 4 data types.  Valid data types are:
1603 +#
1604 +#      string - 0-253 octets
1605 +#      ipaddr - 4 octets in network byte order
1606 +#      integer - 32 bit value in big endian order (high byte first)
1607 +#      date - 32 bit value in big endian order - seconds since
1608 +#                                      00:00:00 GMT,  Jan.  1,  1970
1609 +#
1610 +#      Enumerated values are stored in the user file with dictionary
1611 +#      VALUE translations for easy administration.
1612 +#
1613 +#      Example:
1614 +#
1615 +#      ATTRIBUTE         VALUE
1616 +#      ---------------   -----
1617 +#      Framed-Protocol = PPP
1618 +#      7               = 1     (integer encoding)
1619 +#
1620 +
1621 +#
1622 +#      Experimental SIP Attributes/Values (draft-sterman-aaa-sip-00.txt etc)
1623 +#
1624 +ATTRIBUTE      Sip-Method              101     integer
1625 +ATTRIBUTE      Sip-Response-Code       102     integer
1626 +ATTRIBUTE      Sip-CSeq                103     string
1627 +ATTRIBUTE      Sip-To-Tag              104     string
1628 +ATTRIBUTE      Sip-From-Tag            105     string
1629 +ATTRIBUTE      Sip-Branch-ID           106     string
1630 +ATTRIBUTE      Sip-Translated-Request-URI      107     string
1631 +ATTRIBUTE      Sip-Source-IP-Address   108     ipaddr
1632 +ATTRIBUTE      Sip-Source-Port         109     integer
1633 +ATTRIBUTE      Sip-User-ID             110     string
1634 +ATTRIBUTE      Sip-User-Realm          111     string
1635 +ATTRIBUTE      Sip-User-Nonce          112     string
1636 +ATTRIBUTE      Sip-User-Method         113     string
1637 +ATTRIBUTE      Sip-User-Digest-URI     114     string
1638 +ATTRIBUTE      Sip-User-Nonce-Count    115     string
1639 +ATTRIBUTE      Sip-User-QOP            116     string
1640 +ATTRIBUTE      Sip-User-Opaque         117     string
1641 +ATTRIBUTE      Sip-User-Response       118     string
1642 +ATTRIBUTE      Sip-User-CNonce         119     string
1643 +ATTRIBUTE      Sip-URI-User            208     string
1644 +ATTRIBUTE      Sip-Req-URI             210     string
1645 +ATTRIBUTE      Sip-CC                  212     string
1646 +ATTRIBUTE      Sip-RPId                213     string
1647 +ATTRIBUTE      Digest-Response         206     string
1648 +ATTRIBUTE      Digest-Attributes       207     string
1649 +ATTRIBUTE      Digest-Realm            1063    string
1650 +ATTRIBUTE      Digest-Nonce            1064    string
1651 +ATTRIBUTE      Digest-Method           1065    string
1652 +ATTRIBUTE      Digest-URI              1066    string
1653 +ATTRIBUTE      Digest-QOP              1067    string
1654 +ATTRIBUTE      Digest-Algorithm        1068    string
1655 +ATTRIBUTE      Digest-Body-Digest      1069    string
1656 +ATTRIBUTE      Digest-CNonce           1070    string
1657 +ATTRIBUTE      Digest-Nonce-Count      1071    string
1658 +ATTRIBUTE      Digest-User-Name        1072    string
1659 +
1660 +VALUE          Service-Type            SIP                     15
1661 +
1662 +VALUE          Sip-Method              Other                   0
1663 +VALUE          Sip-Method              Invite                  1
1664 +VALUE          Sip-Method              Cancel                  2
1665 +VALUE          Sip-Method              Ack                     3
1666 +VALUE          Sip-Method              Bye                     4
1667 +
1668 +VALUE          Sip-Response-Code       Other                   0
1669 +VALUE          Sip-Response-Code       Invite                  1
1670 +VALUE          Sip-Response-Code       Cancel                  2
1671 +VALUE          Sip-Response-Code       Ack                     3
1672 +VALUE          Sip-Response-Code       Bye                     4
1673 diff --git a/src/plugins/vbng/etc/issue b/src/plugins/vbng/etc/issue
1674 new file mode 100644
1675 index 0000000..6254487
1676 --- /dev/null
1677 +++ b/src/plugins/vbng/etc/issue
1678 @@ -0,0 +1,5 @@
1679 +(\I)
1680 +-----------------------------------------------------
1681 +\S \R (\N) (port \L)
1682 +-----------------------------------------------------
1683 +
1684 diff --git a/src/plugins/vbng/etc/port-id-map b/src/plugins/vbng/etc/port-id-map
1685 new file mode 100644
1686 index 0000000..9088a0b
1687 --- /dev/null
1688 +++ b/src/plugins/vbng/etc/port-id-map
1689 @@ -0,0 +1,24 @@
1690 +#
1691 +# port-id-map
1692 +#
1693 +# This file describes the ttyname to port id mapping. The port id
1694 +# is reported as part of a RADIUS authentication or accouting request.
1695 +#
1696 +#ttyname (as returned by ttyname(3))   port-id
1697 +/dev/tty1      1
1698 +/dev/tty2      2
1699 +/dev/tty3      3
1700 +/dev/tty4      4
1701 +/dev/tty5      5
1702 +/dev/tty6      6
1703 +/dev/tty7      7
1704 +/dev/tty8      8
1705 +/dev/ttyS0     9
1706 +/dev/ttyS1     10
1707 +/dev/ttyS2     11
1708 +/dev/ttyS3     12
1709 +/dev/ttyS4     13
1710 +/dev/ttyS5     14
1711 +/dev/ttyS6     15
1712 +/dev/ttyS7     16
1713
1714 \ No newline at end of file
1715 diff --git a/src/plugins/vbng/etc/radiusclient.conf b/src/plugins/vbng/etc/radiusclient.conf
1716 new file mode 100644
1717 index 0000000..3a315b4
1718 --- /dev/null
1719 +++ b/src/plugins/vbng/etc/radiusclient.conf
1720 @@ -0,0 +1,92 @@
1721 +# General settings
1722 +
1723 +# specify which authentication comes first respectively which
1724 +# authentication is used. possible values are: "radius" and "local".
1725 +# if you specify "radius,local" then the RADIUS server is asked
1726 +# first then the local one. if only one keyword is specified only
1727 +# this server is asked.
1728 +auth_order     radius,local
1729 +
1730 +# maximum login tries a user has
1731 +login_tries    4
1732 +
1733 +# timeout for all login tries
1734 +# if this time is exceeded the user is kicked out
1735 +login_timeout  60
1736 +
1737 +# name of the nologin file which when it exists disables logins.
1738 +# it may be extended by the ttyname which will result in
1739 +# a terminal specific lock (e.g. /etc/nologin.ttyS2 will disable
1740 +# logins on /dev/ttyS2)
1741 +nologin /etc/nologin
1742 +
1743 +# name of the issue file. it's only display when no username is passed
1744 +# on the radlogin command line
1745 +issue  /usr/local/etc/radiusclient/issue
1746 +
1747 +# RADIUS settings
1748 +
1749 +# RADIUS server to use for authentication requests. this config
1750 +# item can appear more then one time. if multiple servers are
1751 +# defined they are tried in a round robin fashion if one
1752 +# server is not answering.
1753 +# optionally you can specify a the port number on which is remote
1754 +# RADIUS listens separated by a colon from the hostname. if
1755 +# no port is specified /etc/services is consulted of the radius
1756 +# service. if this fails also a compiled in default is used.
1757 +authserver     localhost
1758 +
1759 +# RADIUS server to use for accouting requests. All that I
1760 +# said for authserver applies, too. 
1761 +#
1762 +acctserver     localhost
1763 +
1764 +# file holding shared secrets used for the communication
1765 +# between the RADIUS client and server
1766 +servers                /usr/local/etc/radiusclient/servers
1767 +
1768 +# dictionary of allowed attributes and values
1769 +# just like in the normal RADIUS distributions
1770 +dictionary     /usr/local/etc/radiusclient/dictionary
1771 +
1772 +# program to call for a RADIUS authenticated login
1773 +login_radius   /usr/local/sbin/login.radius
1774 +
1775 +# file which holds sequence number for communication with the
1776 +# RADIUS server
1777 +seqfile                /var/run/radius.seq
1778 +
1779 +# file which specifies mapping between ttyname and NAS-Port attribute
1780 +mapfile                /usr/local/etc/radiusclient/port-id-map
1781 +
1782 +# default authentication realm to append to all usernames if no
1783 +# realm was explicitly specified by the user
1784 +# the radiusd directly form Livingston doesnt use any realms, so leave
1785 +# it blank then
1786 +default_realm
1787 +
1788 +# time to wait for a reply from the RADIUS server
1789 +radius_timeout 10
1790 +
1791 +# resend request this many times before trying the next server
1792 +radius_retries 3
1793 +
1794 +# The length of time in seconds that we skip a nonresponsive RADIUS
1795 +# server for transaction requests.  Server(s) being in the "dead" state
1796 +# are tried only after all other non-dead servers have been tried and
1797 +# failed or timeouted.  The deadtime interval starts when the server
1798 +# does not respond to an authentication/accounting request transmissions. 
1799 +# When the interval expires, the "dead" server would be re-tried again,
1800 +# and if it's still down then it will be considered "dead" for another
1801 +# such interval and so on. This option is no-op if there is only one
1802 +# server in the list. Set to 0 in order to disable the feature.
1803 +radius_deadtime        0
1804 +
1805 +# local address from which radius packets have to be sent
1806 +bindaddr *
1807 +
1808 +# LOCAL settings
1809 +
1810 +# program to execute for local login
1811 +# it must support the -f flag for preauthenticated login
1812 +login_local    /bin/login
1813 diff --git a/src/plugins/vbng/etc/radiusclient.conf.in b/src/plugins/vbng/etc/radiusclient.conf.in
1814 new file mode 100644
1815 index 0000000..fdf62e6
1816 --- /dev/null
1817 +++ b/src/plugins/vbng/etc/radiusclient.conf.in
1818 @@ -0,0 +1,92 @@
1819 +# General settings
1820 +
1821 +# specify which authentication comes first respectively which
1822 +# authentication is used. possible values are: "radius" and "local".
1823 +# if you specify "radius,local" then the RADIUS server is asked
1824 +# first then the local one. if only one keyword is specified only
1825 +# this server is asked.
1826 +auth_order     radius,local
1827 +
1828 +# maximum login tries a user has
1829 +login_tries    4
1830 +
1831 +# timeout for all login tries
1832 +# if this time is exceeded the user is kicked out
1833 +login_timeout  60
1834 +
1835 +# name of the nologin file which when it exists disables logins.
1836 +# it may be extended by the ttyname which will result in
1837 +# a terminal specific lock (e.g. /etc/nologin.ttyS2 will disable
1838 +# logins on /dev/ttyS2)
1839 +nologin /etc/nologin
1840 +
1841 +# name of the issue file. it's only display when no username is passed
1842 +# on the radlogin command line
1843 +issue  @pkgsysconfdir@/issue
1844 +
1845 +# RADIUS settings
1846 +
1847 +# RADIUS server to use for authentication requests. this config
1848 +# item can appear more then one time. if multiple servers are
1849 +# defined they are tried in a round robin fashion if one
1850 +# server is not answering.
1851 +# optionally you can specify a the port number on which is remote
1852 +# RADIUS listens separated by a colon from the hostname. if
1853 +# no port is specified /etc/services is consulted of the radius
1854 +# service. if this fails also a compiled in default is used.
1855 +authserver     localhost
1856 +
1857 +# RADIUS server to use for accouting requests. All that I
1858 +# said for authserver applies, too. 
1859 +#
1860 +acctserver     localhost
1861 +
1862 +# file holding shared secrets used for the communication
1863 +# between the RADIUS client and server
1864 +servers                @pkgsysconfdir@/servers
1865 +
1866 +# dictionary of allowed attributes and values
1867 +# just like in the normal RADIUS distributions
1868 +dictionary     @pkgsysconfdir@/dictionary
1869 +
1870 +# program to call for a RADIUS authenticated login
1871 +login_radius   @sbindir@/login.radius
1872 +
1873 +# file which holds sequence number for communication with the
1874 +# RADIUS server
1875 +seqfile                /var/run/radius.seq
1876 +
1877 +# file which specifies mapping between ttyname and NAS-Port attribute
1878 +mapfile                @pkgsysconfdir@/port-id-map
1879 +
1880 +# default authentication realm to append to all usernames if no
1881 +# realm was explicitly specified by the user
1882 +# the radiusd directly form Livingston doesnt use any realms, so leave
1883 +# it blank then
1884 +default_realm
1885 +
1886 +# time to wait for a reply from the RADIUS server
1887 +radius_timeout 10
1888 +
1889 +# resend request this many times before trying the next server
1890 +radius_retries 3
1891 +
1892 +# The length of time in seconds that we skip a nonresponsive RADIUS
1893 +# server for transaction requests.  Server(s) being in the "dead" state
1894 +# are tried only after all other non-dead servers have been tried and
1895 +# failed or timeouted.  The deadtime interval starts when the server
1896 +# does not respond to an authentication/accounting request transmissions. 
1897 +# When the interval expires, the "dead" server would be re-tried again,
1898 +# and if it's still down then it will be considered "dead" for another
1899 +# such interval and so on. This option is no-op if there is only one
1900 +# server in the list. Set to 0 in order to disable the feature.
1901 +radius_deadtime        0
1902 +
1903 +# local address from which radius packets have to be sent
1904 +bindaddr *
1905 +
1906 +# LOCAL settings
1907 +
1908 +# program to execute for local login
1909 +# it must support the -f flag for preauthenticated login
1910 +login_local    /bin/login
1911 diff --git a/src/plugins/vbng/etc/servers b/src/plugins/vbng/etc/servers
1912 new file mode 100644
1913 index 0000000..50eddd3
1914 --- /dev/null
1915 +++ b/src/plugins/vbng/etc/servers
1916 @@ -0,0 +1,10 @@
1917 +## Server Name or Client/Server pair           Key             
1918 +## ----------------                            ---------------
1919 +#
1920 +#portmaster.elemental.net                      hardlyasecret
1921 +#portmaster2.elemental.net                     donttellanyone
1922 +#
1923 +## uncomment the following line for simple testing of radlogin
1924 +## with freeradius-server
1925 +#
1926 +#localhost/localhost                           testing123
1927 diff --git a/src/plugins/vbng/include/freeradius-client.h b/src/plugins/vbng/include/freeradius-client.h
1928 new file mode 100644
1929 index 0000000..96c7546
1930 --- /dev/null
1931 +++ b/src/plugins/vbng/include/freeradius-client.h
1932 @@ -0,0 +1,528 @@
1933 +/*
1934 + * $Id: freeradius-client.h,v 1.18 2010/06/15 09:22:51 aland Exp $
1935 + *
1936 + * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg
1937 + *
1938 + * Copyright 1992 Livingston Enterprises, Inc.
1939 + *
1940 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
1941 + * and Merit Network, Inc. All Rights Reserved
1942 + *
1943 + * See the file COPYRIGHT for the respective terms and conditions.
1944 + * If the file is missing contact me at lf@elemental.net
1945 + * and I'll send you a copy.
1946 + *
1947 + */
1948 +
1949 +#ifndef FREERADIUS_CLIENT_H
1950 +#define FREERADIUS_CLIENT_H
1951 +
1952 +#ifdef CP_DEBUG
1953 +#define                DEBUG(args, ...)        rc_log(## args)
1954 +#else
1955 +#define                DEBUG(args, ...)        ;
1956 +#endif
1957 +
1958 +#include       <sys/types.h>
1959 +/*
1960 + * Include for C99 uintX_t defines is stdint.h on most systems.  Solaris uses
1961 + * inttypes.h instead.  Comment out the stdint include if you get an error,
1962 + * and uncomment the inttypes.h include.
1963 + */
1964 +#include       <stdint.h>
1965 +/* #include    <inttypes.h> */
1966 +#include       <stdio.h>
1967 +#include       <time.h>
1968 +
1969 +#undef __BEGIN_DECLS
1970 +#undef __END_DECLS
1971 +#ifdef __cplusplus
1972 +# define __BEGIN_DECLS extern "C" {
1973 +# define __END_DECLS }
1974 +#else
1975 +# define __BEGIN_DECLS /* empty */
1976 +# define __END_DECLS /* empty */
1977 +#endif
1978 +
1979 +#define AUTH_VECTOR_LEN                16
1980 +#define AUTH_PASS_LEN          (3 * 16) /* multiple of 16 */
1981 +#define AUTH_ID_LEN            64
1982 +#define AUTH_STRING_LEN                253      /* maximum of 253 */
1983 +
1984 +#define        BUFFER_LEN              8192
1985 +
1986 +#define NAME_LENGTH            32
1987 +#define        GETSTR_LENGTH           128     /* must be bigger than AUTH_PASS_LEN */
1988 +
1989 +#define        MAX_SECRET_LENGTH       (3 * 16) /* MUST be multiple of 16 */
1990 +
1991 +#define        VENDOR(x)               (((x) >> 16) & 0xffff)
1992 +#define        ATTRID(x)               ((x) & 0xffff)
1993 +
1994 +#define PW_MAX_MSG_SIZE                4096
1995 +
1996 +/* codes for radius_buildreq, radius_getport, etc. */
1997 +#define AUTH                   0
1998 +#define ACCT                   1
1999 +
2000 +/* defines for config.c */
2001 +
2002 +#define SERVER_MAX 8
2003 +
2004 +#define AUTH_LOCAL_FST (1<<0)
2005 +#define AUTH_RADIUS_FST (1<<1)
2006 +#define AUTH_LOCAL_SND  (1<<2)
2007 +#define AUTH_RADIUS_SND (1<<3)
2008 +
2009 +typedef struct server {
2010 +       int max;
2011 +       char *name[SERVER_MAX];
2012 +       uint16_t port[SERVER_MAX];
2013 +       char *secret[SERVER_MAX];
2014 +       double deadtime_ends[SERVER_MAX];
2015 +} SERVER;
2016 +
2017 +typedef struct pw_auth_hdr
2018 +{
2019 +       uint8_t          code;
2020 +       uint8_t          id;
2021 +       uint16_t         length;
2022 +       uint8_t          vector[AUTH_VECTOR_LEN];
2023 +       uint8_t          data[2];
2024 +} AUTH_HDR;
2025 +
2026 +struct rc_conf
2027 +{
2028 +       struct _option          *config_options;
2029 +       uint32_t                        this_host_ipaddr;
2030 +       uint32_t                        *this_host_bind_ipaddr;
2031 +       struct map2id_s         *map2id_list;
2032 +       struct dict_attr        *dictionary_attributes;
2033 +       struct dict_value       *dictionary_values;
2034 +       struct dict_vendor      *dictionary_vendors;
2035 +       char                    buf[GETSTR_LENGTH];
2036 +       char                    buf1[14];
2037 +       char                    ifname[512];
2038 +};
2039 +
2040 +typedef struct rc_conf rc_handle;
2041 +
2042 +#define AUTH_HDR_LEN                   20
2043 +#define CHAP_VALUE_LENGTH              16
2044 +
2045 +#define PW_AUTH_UDP_PORT               1645
2046 +#define PW_ACCT_UDP_PORT               1646
2047 +
2048 +#define PW_TYPE_STRING                 0
2049 +#define PW_TYPE_INTEGER                        1
2050 +#define PW_TYPE_IPADDR                 2
2051 +#define PW_TYPE_DATE                   3
2052 +#define PW_TYPE_IPV6ADDR               4
2053 +#define PW_TYPE_IPV6PREFIX             5
2054 +
2055 +/* standard RADIUS codes */
2056 +
2057 +#define        PW_ACCESS_REQUEST               1
2058 +#define        PW_ACCESS_ACCEPT                2
2059 +#define        PW_ACCESS_REJECT                3
2060 +#define        PW_ACCOUNTING_REQUEST           4
2061 +#define        PW_ACCOUNTING_RESPONSE          5
2062 +#define        PW_ACCOUNTING_STATUS            6
2063 +#define        PW_PASSWORD_REQUEST             7
2064 +#define        PW_PASSWORD_ACK                 8
2065 +#define        PW_PASSWORD_REJECT              9
2066 +#define        PW_ACCOUNTING_MESSAGE           10
2067 +#define        PW_ACCESS_CHALLENGE             11
2068 +#define        PW_STATUS_SERVER                12
2069 +#define        PW_STATUS_CLIENT                13
2070 +
2071 +
2072 +/* standard RADIUS attribute-value pairs */
2073 +
2074 +#define        PW_USER_NAME                    1       /* string */
2075 +#define        PW_USER_PASSWORD                2       /* string */
2076 +#define        PW_CHAP_PASSWORD                3       /* string */
2077 +#define        PW_NAS_IP_ADDRESS               4       /* ipaddr */
2078 +#define        PW_NAS_PORT                     5       /* integer */
2079 +#define        PW_SERVICE_TYPE                 6       /* integer */
2080 +#define        PW_FRAMED_PROTOCOL              7       /* integer */
2081 +#define        PW_FRAMED_IP_ADDRESS            8       /* ipaddr */
2082 +#define        PW_FRAMED_IP_NETMASK            9       /* ipaddr */
2083 +#define        PW_FRAMED_ROUTING               10      /* integer */
2084 +#define        PW_FILTER_ID                    11      /* string */
2085 +#define        PW_FRAMED_MTU                   12      /* integer */
2086 +#define        PW_FRAMED_COMPRESSION           13      /* integer */
2087 +#define        PW_LOGIN_IP_HOST                14      /* ipaddr */
2088 +#define        PW_LOGIN_SERVICE                15      /* integer */
2089 +#define        PW_LOGIN_PORT                   16      /* integer */
2090 +#define        PW_OLD_PASSWORD                 17      /* string */ /* deprecated */
2091 +#define        PW_REPLY_MESSAGE                18      /* string */
2092 +#define        PW_LOGIN_CALLBACK_NUMBER        19      /* string */
2093 +#define        PW_FRAMED_CALLBACK_ID           20      /* string */
2094 +#define        PW_EXPIRATION                   21      /* date */ /* deprecated */
2095 +#define        PW_FRAMED_ROUTE                 22      /* string */
2096 +#define        PW_FRAMED_IPX_NETWORK           23      /* integer */
2097 +#define        PW_STATE                        24      /* string */
2098 +#define        PW_CLASS                        25      /* string */
2099 +#define        PW_VENDOR_SPECIFIC              26      /* string */
2100 +#define        PW_SESSION_TIMEOUT              27      /* integer */
2101 +#define        PW_IDLE_TIMEOUT                 28      /* integer */
2102 +#define        PW_TERMINATION_ACTION           29      /* integer */
2103 +#define        PW_CALLED_STATION_ID            30      /* string */
2104 +#define        PW_CALLING_STATION_ID           31      /* string */
2105 +#define        PW_NAS_IDENTIFIER               32      /* string */
2106 +#define        PW_PROXY_STATE                  33      /* string */
2107 +#define        PW_LOGIN_LAT_SERVICE            34      /* string */
2108 +#define        PW_LOGIN_LAT_NODE               35      /* string */
2109 +#define        PW_LOGIN_LAT_GROUP              36      /* string */
2110 +#define        PW_FRAMED_APPLETALK_LINK        37      /* integer */
2111 +#define        PW_FRAMED_APPLETALK_NETWORK     38      /* integer */
2112 +#define        PW_FRAMED_APPLETALK_ZONE        39      /* string */
2113 +#define        PW_EVENT_TIMESTAMP              55      /* integer */
2114 +#define        PW_CHAP_CHALLENGE               60      /* string */
2115 +#define        PW_NAS_PORT_TYPE                61      /* integer */
2116 +#define        PW_PORT_LIMIT                   62      /* integer */
2117 +#define PW_LOGIN_LAT_PORT               63      /* string */
2118 +#define PW_CONNECT_INFO                 77      /* string */
2119 +#define PW_MESSAGE_AUTHENTICATOR        80      /* string */
2120 +
2121 +/* RFC3162 IPv6 attributes */
2122 +
2123 +#define PW_NAS_IPV6_ADDRESS             95      /* string */
2124 +#define PW_FRAMED_INTERFACE_ID          96      /* string */
2125 +#define PW_FRAMED_IPV6_PREFIX           97      /* string */
2126 +#define PW_LOGIN_IPV6_HOST              98      /* string */
2127 +#define PW_FRAMED_IPV6_ROUTE            99      /* string */
2128 +#define PW_FRAMED_IPV6_POOL             100     /* string */
2129 +
2130 +/* RFC6911 IPv6 attributes */
2131 +#define PW_FRAMED_IPV6_ADDRESS         168     /* ipaddr6 */
2132 +#define PW_DNS_SERVER_IPV6_ADDRESS     169     /* ipaddr6 */
2133 +#define PW_ROUTE_IPV6_INFORMATION      170     /* ipv6prefix */
2134 +
2135 +/*     Accounting */
2136 +
2137 +#define        PW_ACCT_STATUS_TYPE             40      /* integer */
2138 +#define        PW_ACCT_DELAY_TIME              41      /* integer */
2139 +#define        PW_ACCT_INPUT_OCTETS            42      /* integer */
2140 +#define        PW_ACCT_OUTPUT_OCTETS           43      /* integer */
2141 +#define        PW_ACCT_SESSION_ID              44      /* string */
2142 +#define        PW_ACCT_AUTHENTIC               45      /* integer */
2143 +#define        PW_ACCT_SESSION_TIME            46      /* integer */
2144 +#define        PW_ACCT_INPUT_PACKETS           47      /* integer */
2145 +#define        PW_ACCT_OUTPUT_PACKETS          48      /* integer */
2146 +#define PW_ACCT_TERMINATE_CAUSE                49      /* integer */
2147 +#define PW_ACCT_MULTI_SESSION_ID       50      /* string */
2148 +#define PW_ACCT_LINK_COUNT             51      /* integer */
2149 +#define PW_ACCT_INPUT_GIGAWORDS                52      /* integer */
2150 +#define PW_ACCT_OUTPUT_GIGAWORDS       53      /* integer */
2151 +
2152 +/*     Experimental SIP-specific attributes (draft-sterman-aaa-sip-00.txt etc) */
2153 +
2154 +#define        PW_DIGEST_RESPONSE              206     /* string */
2155 +#define        PW_DIGEST_ATTRIBUTES            207     /* string */
2156 +#define        PW_DIGEST_REALM                 1063    /* string */
2157 +#define        PW_DIGEST_NONCE                 1064    /* string */
2158 +#define        PW_DIGEST_METHOD                1065    /* string */
2159 +#define        PW_DIGEST_URI                   1066    /* string */
2160 +#define        PW_DIGEST_QOP                   1067    /* string */
2161 +#define        PW_DIGEST_ALGORITHM             1068    /* string */
2162 +#define        PW_DIGEST_BODY_DIGEST           1069    /* string */
2163 +#define        PW_DIGEST_CNONCE                1070    /* string */
2164 +#define        PW_DIGEST_NONCE_COUNT           1071    /* string */
2165 +#define        PW_DIGEST_USER_NAME             1072    /* string */
2166 +
2167 +/*     Merit Experimental Extensions */
2168 +
2169 +#define PW_USER_ID                      222     /* string */
2170 +#define PW_USER_REALM                   223     /* string */
2171 +
2172 +/*     Integer Translations */
2173 +
2174 +/*     SERVICE TYPES   */
2175 +
2176 +#define        PW_LOGIN                        1
2177 +#define        PW_FRAMED                       2
2178 +#define        PW_CALLBACK_LOGIN               3
2179 +#define        PW_CALLBACK_FRAMED              4
2180 +#define        PW_OUTBOUND                     5
2181 +#define        PW_ADMINISTRATIVE               6
2182 +#define PW_NAS_PROMPT                   7
2183 +#define PW_AUTHENTICATE_ONLY           8
2184 +#define PW_CALLBACK_NAS_PROMPT          9
2185 +
2186 +/*     FRAMED PROTOCOLS        */
2187 +
2188 +#define        PW_PPP                          1
2189 +#define        PW_SLIP                         2
2190 +#define PW_ARA                          3
2191 +#define PW_GANDALF                      4
2192 +#define PW_XYLOGICS                     5
2193 +
2194 +/*     FRAMED ROUTING VALUES   */
2195 +
2196 +#define        PW_NONE                         0
2197 +#define        PW_BROADCAST                    1
2198 +#define        PW_LISTEN                       2
2199 +#define        PW_BROADCAST_LISTEN             3
2200 +
2201 +/*     FRAMED COMPRESSION TYPES        */
2202 +
2203 +#define        PW_VAN_JACOBSON_TCP_IP          1
2204 +#define        PW_IPX_HEADER_COMPRESSION       2
2205 +
2206 +/*     LOGIN SERVICES  */
2207 +
2208 +#define PW_TELNET                       0
2209 +#define PW_RLOGIN                       1
2210 +#define PW_TCP_CLEAR                    2
2211 +#define PW_PORTMASTER                   3
2212 +#define PW_LAT                          4
2213 +#define PW_X25_PAD                      5
2214 +#define PW_X25_T3POS                    6
2215 +
2216 +/*     TERMINATION ACTIONS     */
2217 +
2218 +#define        PW_DEFAULT                      0
2219 +#define        PW_RADIUS_REQUEST               1
2220 +
2221 +/*     PROHIBIT PROTOCOL  */
2222 +
2223 +#define PW_DUMB                0       /* 1 and 2 are defined in FRAMED PROTOCOLS */
2224 +#define PW_AUTH_ONLY   3
2225 +#define PW_ALL         255
2226 +
2227 +/*     ACCOUNTING STATUS TYPES    */
2228 +
2229 +#define PW_STATUS_START                1
2230 +#define PW_STATUS_STOP         2
2231 +#define PW_STATUS_ALIVE                3
2232 +#define PW_STATUS_MODEM_START  4
2233 +#define PW_STATUS_MODEM_STOP   5
2234 +#define PW_STATUS_CANCEL       6
2235 +#define PW_ACCOUNTING_ON       7
2236 +#define PW_ACCOUNTING_OFF      8
2237 +
2238 +/*      ACCOUNTING TERMINATION CAUSES   */
2239 +
2240 +#define PW_USER_REQUEST         1
2241 +#define PW_LOST_CARRIER         2
2242 +#define PW_LOST_SERVICE         3
2243 +#define PW_ACCT_IDLE_TIMEOUT    4
2244 +#define PW_ACCT_SESSION_TIMEOUT 5
2245 +#define PW_ADMIN_RESET          6
2246 +#define PW_ADMIN_REBOOT         7
2247 +#define PW_PORT_ERROR           8
2248 +#define PW_NAS_ERROR            9
2249 +#define PW_NAS_REQUEST          10
2250 +#define PW_NAS_REBOOT           11
2251 +#define PW_PORT_UNNEEDED        12
2252 +#define PW_PORT_PREEMPTED       13
2253 +#define PW_PORT_SUSPENDED       14
2254 +#define PW_SERVICE_UNAVAILABLE  15
2255 +#define PW_CALLBACK             16
2256 +#define PW_USER_ERROR           17
2257 +#define PW_HOST_REQUEST         18
2258 +
2259 +/*     NAS PORT TYPES    */
2260 +
2261 +#define PW_ASYNC               0
2262 +#define PW_SYNC                        1
2263 +#define PW_ISDN_SYNC           2
2264 +#define PW_ISDN_SYNC_V120      3
2265 +#define PW_ISDN_SYNC_V110      4
2266 +#define PW_VIRTUAL             5
2267 +
2268 +/*        AUTHENTIC TYPES */
2269 +#define PW_RADIUS      1
2270 +#define PW_LOCAL       2
2271 +#define PW_REMOTE      3
2272 +
2273 +/* Server data structures */
2274 +
2275 +typedef struct dict_attr
2276 +{
2277 +       char              name[NAME_LENGTH + 1];        /* attribute name */
2278 +       int               value;                        /* attribute index */
2279 +       int               type;                         /* string, int, etc. */
2280 +       struct dict_attr *next;
2281 +} DICT_ATTR;
2282 +
2283 +typedef struct dict_value
2284 +{
2285 +       char               attrname[NAME_LENGTH +1];
2286 +       char               name[NAME_LENGTH + 1];
2287 +       int                value;
2288 +       struct dict_value *next;
2289 +} DICT_VALUE;
2290 +
2291 +typedef struct dict_vendor
2292 +{
2293 +       char               vendorname[NAME_LENGTH +1];
2294 +       int                vendorpec;
2295 +       struct dict_vendor *next;
2296 +} DICT_VENDOR;
2297 +
2298 +typedef struct value_pair
2299 +{
2300 +       char               name[NAME_LENGTH + 1];
2301 +       int                attribute;
2302 +       int                type;
2303 +       uint32_t           lvalue;
2304 +       char               strvalue[AUTH_STRING_LEN + 1];
2305 +       struct value_pair *next;
2306 +} VALUE_PAIR;
2307 +
2308 +/* don't change this, as it has to be the same as in the Merit radiusd code */
2309 +#define MGMT_POLL_SECRET       "Hardlyasecret"
2310 +
2311 +/*     Define return codes from "SendServer" utility */
2312 +
2313 +#define BADRESP_RC     -2
2314 +#define ERROR_RC       -1
2315 +#define OK_RC          0
2316 +#define TIMEOUT_RC     1
2317 +#define REJECT_RC      2
2318 +
2319 +typedef struct send_data /* Used to pass information to sendserver() function */
2320 +{
2321 +       uint8_t        code;            /* RADIUS packet code */
2322 +       uint8_t        seq_nbr;         /* Packet sequence number */
2323 +       char           *server;         /* Name/addrress of RADIUS server */
2324 +       int            svc_port;        /* RADIUS protocol destination port */
2325 +       char           *secret;         /* Shared secret of RADIUS server */
2326 +       int            timeout;         /* Session timeout in seconds */
2327 +       int            retries;
2328 +       VALUE_PAIR     *send_pairs;     /* More a/v pairs to send */
2329 +       VALUE_PAIR     *receive_pairs;  /* Where to place received a/v pairs */
2330 +} SEND_DATA;
2331 +
2332 +#ifndef MIN
2333 +#define MIN(a, b)     ((a) < (b) ? (a) : (b))
2334 +#endif
2335 +#ifndef MAX
2336 +#define MAX(a, b)     ((a) > (b) ? (a) : (b))
2337 +#endif
2338 +
2339 +#ifndef PATH_MAX
2340 +#define PATH_MAX       1024
2341 +#endif
2342 +
2343 +typedef struct env
2344 +{
2345 +       int maxsize, size;
2346 +       char **env;
2347 +} ENV;
2348 +
2349 +#define ENV_SIZE       128
2350 +
2351 +__BEGIN_DECLS
2352 +
2353 +/*     Function prototypes     */
2354 +
2355 +/*     avpair.c                */
2356 +
2357 +VALUE_PAIR *rc_avpair_add(rc_handle const *, VALUE_PAIR **, int, void const *, int, int);
2358 +int rc_avpair_assign(VALUE_PAIR *, void const *, int);
2359 +VALUE_PAIR *rc_avpair_new(rc_handle const *, int, void const *, int, int);
2360 +VALUE_PAIR *rc_avpair_gen(rc_handle const *, VALUE_PAIR *, unsigned char const *, int, int);
2361 +VALUE_PAIR *rc_avpair_get(VALUE_PAIR *, int, int);
2362 +void rc_avpair_insert(VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *);
2363 +void rc_avpair_free(VALUE_PAIR *);
2364 +int rc_avpair_parse(rc_handle const *, char const *, VALUE_PAIR **);
2365 +int rc_avpair_tostr(rc_handle const *, VALUE_PAIR *, char *, int, char *, int);
2366 +char *rc_avpair_log(rc_handle const *, VALUE_PAIR *, char *buf, size_t buf_len);
2367 +VALUE_PAIR *rc_avpair_readin(rc_handle const *, FILE *);
2368 +
2369 +/*     buildreq.c              */
2370 +
2371 +void rc_buildreq(rc_handle const *, SEND_DATA *, int, char *, unsigned short, char *, int, int);
2372 +unsigned char rc_get_id();
2373 +int rc_auth(rc_handle *, uint32_t, VALUE_PAIR *, VALUE_PAIR **, char *);
2374 +int rc_auth_proxy(rc_handle *, VALUE_PAIR *, VALUE_PAIR **, char *);
2375 +int rc_acct(rc_handle *, uint32_t, VALUE_PAIR *);
2376 +int rc_acct_proxy(rc_handle *, VALUE_PAIR *);
2377 +int rc_check(rc_handle *, char *, char *, unsigned short, char *);
2378 +
2379 +int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
2380 +    char *msg, int add_nas_port, int request_type);
2381 +
2382 +/*     clientid.c              */
2383 +
2384 +int rc_read_mapfile(rc_handle *, char const *);
2385 +uint32_t rc_map2id(rc_handle const *, char const *);
2386 +void rc_map2id_free(rc_handle *);
2387 +
2388 +/*     config.c                */
2389 +
2390 +rc_handle *rc_read_config(char const *);
2391 +char *rc_conf_str(rc_handle const *, char const *);
2392 +int rc_conf_int(rc_handle const *, char const *);
2393 +SERVER *rc_conf_srv(rc_handle const *, char const *);
2394 +int rc_find_server(rc_handle const *, char const *, uint32_t *, char *);
2395 +void rc_config_free(rc_handle *);
2396 +int rc_add_config(rc_handle *, char const *, char const *, char const *, int);
2397 +rc_handle *rc_config_init(rc_handle *);
2398 +int test_config(rc_handle const *, char const *);
2399 +
2400 +/*     dict.c                  */
2401 +
2402 +int rc_read_dictionary(rc_handle *, char const *);
2403 +DICT_ATTR *rc_dict_getattr(rc_handle const *, int);
2404 +DICT_ATTR *rc_dict_findattr(rc_handle const *, char const *);
2405 +DICT_VALUE *rc_dict_findval(rc_handle const *, char const *);
2406 +DICT_VENDOR *rc_dict_findvend(rc_handle const *, char const *);
2407 +DICT_VENDOR *rc_dict_getvend(rc_handle const *, int);
2408 +DICT_VALUE * rc_dict_getval(rc_handle const *, uint32_t, char const *);
2409 +void rc_dict_free(rc_handle *);
2410 +
2411 +/*     ip_util.c               */
2412 +
2413 +struct hostent *rc_gethostbyname(char const *);
2414 +struct hostent *rc_gethostbyaddr(char const *, size_t, int);
2415 +uint32_t rc_get_ipaddr(char const *);
2416 +int rc_good_ipaddr(char const *);
2417 +char const *rc_ip_hostname(uint32_t);
2418 +unsigned short rc_getport(int);
2419 +int rc_own_hostname(char *, int);
2420 +uint32_t rc_own_ipaddress(rc_handle *);
2421 +uint32_t rc_own_bind_ipaddress(rc_handle *);
2422 +struct sockaddr;
2423 +int rc_get_srcaddr(struct sockaddr *, struct sockaddr *);
2424 +
2425 +
2426 +/*     log.c                   */
2427 +
2428 +void rc_openlog(char const *);
2429 +void rc_log(int, char const *, ...);
2430 +
2431 +/*     sendserver.c            */
2432 +
2433 +int rc_send_server(rc_handle *, SEND_DATA *, char *);
2434 +
2435 +/*     util.c                  */
2436 +
2437 +void rc_str2tm(char const *, struct tm *);
2438 +char *rc_getifname(rc_handle *, char const *);
2439 +char *rc_getstr(rc_handle *, char const *, int);
2440 +void rc_mdelay(int);
2441 +char *rc_mksid(rc_handle *);
2442 +rc_handle *rc_new(void);
2443 +void rc_destroy(rc_handle *);
2444 +char *rc_fgetln(FILE *, size_t *);
2445 +double rc_getctime(void);
2446 +
2447 +/*     env.c                   */
2448 +
2449 +struct env *rc_new_env(int);
2450 +void rc_free_env(struct env *);
2451 +int rc_add_env(struct env *, char const *, char const *);
2452 +int rc_import_env(struct env *, char const **);
2453 +
2454 +/* md5.c                       */
2455 +
2456 +void rc_md5_calc(unsigned char *, unsigned char const *, unsigned int);
2457 +
2458 +__END_DECLS
2459 +
2460 +#endif /* FREERADIUS_CLIENT_H */
2461 diff --git a/src/plugins/vbng/include/includes.h b/src/plugins/vbng/include/includes.h
2462 new file mode 100644
2463 index 0000000..908f0e7
2464 --- /dev/null
2465 +++ b/src/plugins/vbng/include/includes.h
2466 @@ -0,0 +1,182 @@
2467 +/*
2468 + * $Id: includes.h,v 1.6 2007/06/21 18:07:22 cparker Exp $
2469 + *
2470 + * Copyright (C) 1997 Lars Fenneberg
2471 + *
2472 + * Copyright 1992 Livingston Enterprises, Inc.
2473 + *
2474 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
2475 + * and Merit Network, Inc. All Rights Reserved
2476 + *
2477 + * See the file COPYRIGHT for the respective terms and conditions.
2478 + * If the file is missing contact me at lf@elemental.net
2479 + * and I'll send you a copy.
2480 + *
2481 + */
2482 +
2483 +#include "config.h"
2484 +
2485 +/* AIX requires this to be the first thing in the file.  */
2486 +#ifndef __GNUC__
2487 +# if HAVE_ALLOCA_H
2488 +#  include <alloca.h>
2489 +# else
2490 +#  ifdef _AIX
2491 +#   pragma alloca
2492 +#  else
2493 +#   ifndef alloca /* predefined by HP cc +Olibcalls */
2494 +     char *alloca ();
2495 +#   endif
2496 +#  endif
2497 +# endif
2498 +#endif
2499 +
2500 +#include <sys/types.h>
2501 +
2502 +#include <ctype.h>
2503 +#include <stdio.h>
2504 +#include <errno.h>
2505 +
2506 +#ifdef HAVE_NETDB_H
2507 +#include <netdb.h>
2508 +#endif
2509 +
2510 +#ifdef HAVE_SYSLOG_H
2511 +#include <syslog.h>
2512 +#endif
2513 +
2514 +#ifdef STDC_HEADERS
2515 +# include <stdlib.h>
2516 +# include <string.h>
2517 +# include <stdarg.h>
2518 +#else
2519 +# include <stdarg.h>
2520 +# ifndef HAVE_STRCHR
2521 +#  define strchr index
2522 +#  define strrchr rindex
2523 +# endif
2524 +#endif
2525 +
2526 +/* I realize that this is ugly and unsafe.. :( */
2527 +#ifndef HAVE_SNPRINTF
2528 +# define snprintf(buf, len, format, ...) sprintf(buf, format, __VA_ARGS__)
2529 +#endif
2530 +#ifndef HAVE_VSNPRINTF
2531 +# define vsnprintf(buf, len, format, ap) vsprintf(buf, format, ap)
2532 +#endif
2533 +
2534 +#ifdef HAVE_UNISTD_H
2535 +# include <unistd.h>
2536 +#endif /* HAVE_UNISTD_H */
2537 +
2538 +#ifdef HAVE_FCNTL_H
2539 +# include <fcntl.h>
2540 +#endif
2541 +
2542 +#ifdef HAVE_SYS_FCNTL_H
2543 +# include <sys/fcntl.h>
2544 +#endif
2545 +
2546 +#ifdef HAVE_SYS_FILE_H
2547 +# include <sys/file.h>
2548 +#endif
2549 +
2550 +#ifdef HAVE_SYS_STAT_H
2551 +# include <sys/stat.h>
2552 +#endif
2553 +
2554 +#ifdef HAVE_SYS_UTSNAME_H
2555 +# include <sys/utsname.h>
2556 +#endif
2557 +
2558 +#ifdef HAVE_SYS_IOCTL_H
2559 +# include <sys/ioctl.h>
2560 +#endif
2561 +
2562 +#ifdef HAVE_CRYPT_H
2563 +# include <crypt.h>
2564 +#endif
2565 +
2566 +#ifdef HAVE_LIMITS_H
2567 +# include <limits.h>
2568 +#endif
2569 +
2570 +#ifdef HAVE_TERMIOS_H
2571 +# include <termios.h>
2572 +#endif
2573 +
2574 +#ifndef PATH_MAX
2575 +#define PATH_MAX        1024
2576 +#endif
2577 +
2578 +#ifndef UCHAR_MAX
2579 +# ifdef  __STDC__
2580 +#  define UCHAR_MAX       255U
2581 +# else
2582 +#  define UCHAR_MAX       255
2583 +# endif
2584 +#endif
2585 +
2586 +#ifdef HAVE_PWD_H
2587 +#include <pwd.h>
2588 +#endif
2589 +
2590 +#ifdef HAVE_SYS_SOCKET_H
2591 +#include <sys/socket.h>
2592 +#endif
2593 +
2594 +#ifdef HAVE_NETINET_IN_H
2595 +#include <netinet/in.h>
2596 +#endif
2597 +
2598 +#ifdef HAVE_ARPA_INET_H
2599 +#include <arpa/inet.h>
2600 +#endif
2601 +
2602 +#if defined(HAVE_SIGNAL_H)
2603 +# include <signal.h>
2604 +#endif
2605 +#if defined(HAVE_SYS_SIGNAL_H)
2606 +# include <sys/signal.h>
2607 +#endif
2608 +
2609 +#ifdef NEED_SIG_PROTOTYPES
2610 +int sigemptyset(sigset_t *);
2611 +int sigaddset(sigset_t *, int);
2612 +int sigprocmask (int, sigset_t *, sigset_t *);
2613 +#endif
2614 +
2615 +#if HAVE_GETOPT_H
2616 +# include <getopt.h>
2617 +#endif
2618 +
2619 +#if defined(HAVE_SHADOW_H) && defined(HAVE_SHADOW_PASSWORDS)
2620 +# include <shadow.h>
2621 +#endif
2622 +
2623 +#if TIME_WITH_SYS_TIME
2624 +# include <sys/time.h>
2625 +# include <time.h>
2626 +#else
2627 +# if HAVE_SYS_TIME_H
2628 +#  include <sys/time.h>
2629 +# else
2630 +#  include <time.h>
2631 +# endif
2632 +#endif
2633 +
2634 +/*
2635 + * prefer srandom/random over srand/rand as there generator has a
2636 + * better distribution of the numbers on certain systems.
2637 + * on Linux both generators are identical.
2638 + */
2639 +#ifndef HAVE_RANDOM
2640 +# ifdef HAVE_RAND
2641 +# define srandom        srand
2642 +# define random         rand
2643 +# endif
2644 +#endif
2645 +
2646 +/* rlib/lock.c */
2647 +int do_lock_exclusive(FILE *);
2648 +int do_unlock(FILE *);
2649 diff --git a/src/plugins/vbng/include/messages.h b/src/plugins/vbng/include/messages.h
2650 new file mode 100644
2651 index 0000000..9a5f0e8
2652 --- /dev/null
2653 +++ b/src/plugins/vbng/include/messages.h
2654 @@ -0,0 +1,53 @@
2655 +/*
2656 + * $Id: messages.h,v 1.2 2004/02/23 20:10:39 sobomax Exp $
2657 + *
2658 + * Copyright (C) 1995,1996 Lars Fenneberg
2659 + *
2660 + * Copyright 1992 Livingston Enterprises, Inc.
2661 + *
2662 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
2663 + * and Merit Network, Inc. All Rights Reserved
2664 + *
2665 + * See the file COPYRIGHT for the respective terms and conditions.
2666 + * If the file is missing contact me at lf@elemental.net
2667 + * and I'll send you a copy.
2668 + *
2669 + */
2670 +
2671 +/*
2672 + * Only messages that the user gets under normal use are in here.
2673 + * Error messages and such are still in the source code.
2674 + */
2675 +
2676 +#ifndef MESSAGES_H
2677 +#define MESSAGES_H
2678 +
2679 +/* radlogin.c */
2680 +
2681 +#define SC_LOGIN        "login: "
2682 +#define SC_PASSWORD     "Password: "
2683 +
2684 +#define SC_TIMEOUT      "\r\nlogin timed out after %d seconds. Bye.\r\n"
2685 +#define SC_EXCEEDED     "Maximum login tries exceeded. Go away!\r\n"
2686 +
2687 +#define SC_RADIUS_OK    "RADIUS: Authentication OK\r\n"
2688 +#define SC_RADIUS_FAILED "RADIUS: Authentication failure\r\n"
2689 +
2690 +#define SC_LOCAL_OK     "local: Authentication OK\r\n"
2691 +#define SC_LOCAL_FAILED         "local: Authentication failure\r\n"
2692 +#define SC_NOLOGIN      "\r\nSystem closed for maintenance. Try again later...\r\n"
2693 +
2694 +#define SC_SERVER_REPLY         "RADIUS: %s"
2695 +
2696 +#define SC_DEFAULT_ISSUE "(\\I)\r\n\r\n\\S \\R (\\N) (port \\L)\r\n\r\n"
2697 +
2698 +/* radacct.c */
2699 +
2700 +#define SC_ACCT_OK      "RADIUS accounting OK\r\n"
2701 +#define SC_ACCT_FAILED  "RADIUS accounting failed (RC=%i)\r\n"
2702 +
2703 +/* radstatus.c */
2704 +
2705 +#define SC_STATUS_FAILED       "RADIUS: Status failure\r\n"
2706 +
2707 +#endif /* MESSAGES_H */
2708 diff --git a/src/plugins/vbng/include/pathnames.h b/src/plugins/vbng/include/pathnames.h
2709 new file mode 100644
2710 index 0000000..0256d47
2711 --- /dev/null
2712 +++ b/src/plugins/vbng/include/pathnames.h
2713 @@ -0,0 +1,28 @@
2714 +/*
2715 + * $Id: pathnames.h,v 1.2 2004/02/23 20:10:39 sobomax Exp $
2716 + *
2717 + * Copyright (C) 1995,1996 Lars Fenneberg
2718 + *
2719 + * Copyright 1992 Livingston Enterprises, Inc.
2720 + *
2721 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
2722 + * and Merit Network, Inc. All Rights Reserved
2723 + *
2724 + * See the file COPYRIGHT for the respective terms and conditions.
2725 + * If the file is missing contact me at lf@elemental.net
2726 + * and I'll send you a copy.
2727 + *
2728 + */
2729 +
2730 +#ifndef PATHNAMES_H
2731 +#define PATHNAMES_H
2732 +
2733 +#define _PATH_DEV_URANDOM      "/dev/urandom"          /* Linux only */
2734 +#define _PATH_ETC_ISSUE                "/etc/issue"
2735 +
2736 +/* normally defined in the Makefile */
2737 +#ifndef _PATH_ETC_RADIUSCLIENT_CONF
2738 +#define _PATH_ETC_RADIUSCLIENT_CONF       "/etc/radiusclient.conf"
2739 +#endif
2740 +
2741 +#endif /* PATHNAMES_H */
2742 diff --git a/src/plugins/vbng/lib/avpair.c b/src/plugins/vbng/lib/avpair.c
2743 new file mode 100644
2744 index 0000000..8ce2a8e
2745 --- /dev/null
2746 +++ b/src/plugins/vbng/lib/avpair.c
2747 @@ -0,0 +1,874 @@
2748 +/*
2749 + * $Id: avpair.c,v 1.26 2010/06/15 09:22:52 aland Exp $
2750 + *
2751 + * Copyright (C) 1995 Lars Fenneberg
2752 + *
2753 + * Copyright 1992 Livingston Enterprises, Inc.
2754 + *
2755 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
2756 + * and Merit Network, Inc. All Rights Reserved
2757 + *
2758 + * See the file COPYRIGHT for the respective terms and conditions.
2759 + * If the file is missing contact me at lf@elemental.net
2760 + * and I'll send you a copy.
2761 + *
2762 + */
2763 +
2764 +#include <config.h>
2765 +#include <includes.h>
2766 +#include <freeradius-client.h>
2767 +
2768 +/*
2769 + * Function: rc_avpair_add
2770 + *
2771 + * Purpose: add an attribute-value pair to the given list.
2772 + *
2773 + * Returns: pointer to added a/v pair upon success, NULL pointer upon failure.
2774 + *
2775 + * Remarks: Always appends the new pair to the end of the list.
2776 + *
2777 + */
2778 +
2779 +VALUE_PAIR *rc_avpair_add (rc_handle const *rh, VALUE_PAIR **list, int attrid, void const *pval, int len, int vendorpec)
2780 +{
2781 +       VALUE_PAIR     *vp;
2782 +
2783 +       vp = rc_avpair_new (rh, attrid, pval, len, vendorpec);
2784 +
2785 +       if (vp != NULL)
2786 +       {
2787 +               rc_avpair_insert (list, NULL, vp);
2788 +       }
2789 +
2790 +       return vp;
2791 +
2792 +}
2793 +
2794 +/*
2795 + * Function: rc_avpair_assign
2796 + *
2797 + * Purpose: assign the given value to an attribute-value pair.
2798 + *
2799 + * Returns:  0 on success,
2800 + *         -1 on failure.
2801 + *
2802 + */
2803 +
2804 +int rc_avpair_assign (VALUE_PAIR *vp, void const *pval, int len)
2805 +{
2806 +
2807 +       switch (vp->type)
2808 +       {
2809 +               case PW_TYPE_STRING:
2810 +                       if (len == -1)
2811 +                               len = (uint32_t)strlen((char const *)pval);
2812 +                       if (len > AUTH_STRING_LEN) {
2813 +                               rc_log(LOG_ERR, "rc_avpair_assign: bad attribute length");
2814 +                               return -1;
2815 +                       }
2816 +                       memcpy(vp->strvalue, (char const *)pval, len);
2817 +                       vp->strvalue[len] = '\0';
2818 +                       vp->lvalue = len;
2819 +                       break;
2820 +
2821 +               case PW_TYPE_DATE:
2822 +               case PW_TYPE_INTEGER:
2823 +               case PW_TYPE_IPADDR:
2824 +                       vp->lvalue = * (uint32_t *) pval;
2825 +                       break;
2826 +               case PW_TYPE_IPV6ADDR:
2827 +                       if (len != 16) {
2828 +                               rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 length");
2829 +                               return -1;
2830 +                       }
2831 +                       memcpy(vp->strvalue, (char const *)pval, len);
2832 +                       vp->lvalue = len;
2833 +                       break;
2834 +
2835 +               case PW_TYPE_IPV6PREFIX:
2836 +                       if (len < 2 || len > 18) {
2837 +                               rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 prefix length");
2838 +                               return -1;
2839 +                       }
2840 +                       memcpy(vp->strvalue, (char const *)pval, len);
2841 +                       vp->lvalue = len;
2842 +                       break;
2843 +
2844 +               default:
2845 +                       rc_log(LOG_ERR, "rc_avpair_assign: unknown attribute %d", vp->type);
2846 +                       return -1;
2847 +       }
2848 +       return 0;
2849 +}
2850 +
2851 +/*
2852 + * Function: rc_avpair_new
2853 + *
2854 + * Purpose: make a new attribute-value pair with given parameters.
2855 + *
2856 + * Returns: pointer to generated a/v pair when successful, NULL when failure.
2857 + *
2858 + */
2859 +
2860 +VALUE_PAIR *rc_avpair_new (rc_handle const *rh, int attrid, void const *pval, int len, int vendorpec)
2861 +{
2862 +       VALUE_PAIR     *vp = NULL;
2863 +       DICT_ATTR      *pda;
2864 +
2865 +       attrid = attrid | (vendorpec << 16);
2866 +       if ((pda = rc_dict_getattr (rh, attrid)) == NULL)
2867 +       {
2868 +               rc_log(LOG_ERR,"rc_avpair_new: unknown attribute %d", attrid);
2869 +               return NULL;
2870 +       }
2871 +       if (vendorpec != 0 && rc_dict_getvend(rh, vendorpec) == NULL)
2872 +       {
2873 +               rc_log(LOG_ERR,"rc_avpair_new: unknown Vendor-Id %d", vendorpec);
2874 +               return NULL;
2875 +       }
2876 +       if ((vp = malloc (sizeof (VALUE_PAIR))) != NULL)
2877 +       {
2878 +               strncpy (vp->name, pda->name, sizeof (vp->name));
2879 +               vp->attribute = attrid;
2880 +               vp->next = NULL;
2881 +               vp->type = pda->type;
2882 +               if (rc_avpair_assign (vp, pval, len) == 0)
2883 +               {
2884 +                       /* XXX: Fix up Digest-Attributes */
2885 +                       switch (vp->attribute) {
2886 +                       case PW_DIGEST_REALM:
2887 +                       case PW_DIGEST_NONCE:
2888 +                       case PW_DIGEST_METHOD:
2889 +                       case PW_DIGEST_URI:
2890 +                       case PW_DIGEST_QOP:
2891 +                       case PW_DIGEST_ALGORITHM:
2892 +                       case PW_DIGEST_BODY_DIGEST:
2893 +                       case PW_DIGEST_CNONCE:
2894 +                       case PW_DIGEST_NONCE_COUNT:
2895 +                       case PW_DIGEST_USER_NAME:
2896 +                               /* overlapping! */
2897 +                               if (vp->lvalue > AUTH_STRING_LEN - 2)
2898 +                                       vp->lvalue = AUTH_STRING_LEN - 2;
2899 +                               memmove(&vp->strvalue[2], &vp->strvalue[0], vp->lvalue);
2900 +                               vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
2901 +                               vp->lvalue += 2;
2902 +                               vp->strvalue[1] = vp->lvalue;
2903 +                               vp->strvalue[vp->lvalue] = '\0';
2904 +                               vp->attribute = PW_DIGEST_ATTRIBUTES;
2905 +                       default:
2906 +                               break;
2907 +                       }
2908 +                       return vp;
2909 +               }
2910 +               free (vp);
2911 +               vp = NULL;
2912 +       }
2913 +       else
2914 +       {
2915 +               rc_log(LOG_CRIT,"rc_avpair_new: out of memory");
2916 +       }
2917 +
2918 +       return vp;
2919 +}
2920 +
2921 +/*
2922 + *
2923 + * Function: rc_avpair_gen
2924 + *
2925 + * Purpose: takes attribute/value pairs from buffer and builds a
2926 + *         value_pair list using allocated memory. Uses recursion.
2927 + *
2928 + * Returns: value_pair list or NULL on failure
2929 + */
2930 +
2931 +VALUE_PAIR *
2932 +rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr,
2933 +    int length, int vendorpec)
2934 +{
2935 +       int attribute, attrlen, x_len;
2936 +       unsigned char const *x_ptr;
2937 +       uint32_t lvalue;
2938 +       DICT_ATTR *attr;
2939 +       VALUE_PAIR *rpair;
2940 +       char buffer[(AUTH_STRING_LEN * 2) + 1];
2941 +       /* For hex string conversion. */
2942 +       char hex[3];
2943 +
2944 +       if (length < 2) {
2945 +               rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
2946 +                   "invalid length");
2947 +               goto shithappens;
2948 +       }
2949 +       attrlen = ptr[1];
2950 +       if (length < attrlen || attrlen < 2) {
2951 +               rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
2952 +                   "invalid length");
2953 +               goto shithappens;
2954 +       }
2955 +
2956 +       /* Advance to the next attribute and process recursively */
2957 +       if (length != attrlen) {
2958 +               pair = rc_avpair_gen(rh, pair, ptr + attrlen, length - attrlen,
2959 +                   vendorpec);
2960 +               if (pair == NULL)
2961 +                       return NULL;
2962 +       }
2963 +
2964 +       /* Actual processing */
2965 +       attribute = ptr[0] | (vendorpec << 16);
2966 +       ptr += 2;
2967 +       attrlen -= 2;
2968 +
2969 +       /* VSA */
2970 +       if (attribute == PW_VENDOR_SPECIFIC) {
2971 +               if (attrlen < 4) {
2972 +                       rc_log(LOG_ERR, "rc_avpair_gen: received VSA "
2973 +                           "attribute with invalid length");
2974 +                       goto shithappens;
2975 +               }
2976 +               memcpy(&lvalue, ptr, 4);
2977 +               vendorpec = ntohl(lvalue);
2978 +               if (rc_dict_getvend(rh, vendorpec) == NULL) {
2979 +                       /* Warn and skip over the unknown VSA */
2980 +                       rc_log(LOG_WARNING, "rc_avpair_gen: received VSA "
2981 +                           "attribute with unknown Vendor-Id %d", vendorpec);
2982 +                       return pair;
2983 +               }
2984 +               /* Process recursively */
2985 +               return rc_avpair_gen(rh, pair, ptr + 4, attrlen - 4,
2986 +                   vendorpec);
2987 +       }
2988 +
2989 +       /* Normal */
2990 +       attr = rc_dict_getattr(rh, attribute);
2991 +       if (attr == NULL) {
2992 +               buffer[0] = '\0';       /* Initial length. */
2993 +               x_ptr = ptr;
2994 +               for (x_len = attrlen; x_len > 0; x_len--, x_ptr++) {
2995 +                       snprintf(hex, sizeof(hex), "%2.2X", x_ptr[0]);
2996 +                       strcat(buffer, hex);
2997 +               }
2998 +               if (vendorpec == 0) {
2999 +                       rc_log(LOG_WARNING, "rc_avpair_gen: received "
3000 +                           "unknown attribute %d of length %d: 0x%s",
3001 +                           attribute, attrlen + 2, buffer);
3002 +               } else {
3003 +                       rc_log(LOG_WARNING, "rc_avpair_gen: received "
3004 +                           "unknown VSA attribute %d, vendor %d of "
3005 +                           "length %d: 0x%s", attribute & 0xffff,
3006 +                           VENDOR(attribute), attrlen + 2, buffer);
3007 +               }
3008 +               goto shithappens;
3009 +       }
3010 +
3011 +       rpair = malloc(sizeof(*rpair));
3012 +       if (rpair == NULL) {
3013 +               rc_log(LOG_CRIT, "rc_avpair_gen: out of memory");
3014 +               goto shithappens;
3015 +       }
3016 +       memset(rpair, '\0', sizeof(*rpair));
3017 +
3018 +       /* Insert this new pair at the beginning of the list */
3019 +       rpair->next = pair;
3020 +       pair = rpair;
3021 +       strcpy(pair->name, attr->name);
3022 +       pair->attribute = attr->value;
3023 +       pair->type = attr->type;
3024 +
3025 +       switch (attr->type) {
3026 +       case PW_TYPE_STRING:
3027 +               memcpy(pair->strvalue, (char *)ptr, (size_t)attrlen);
3028 +               pair->strvalue[attrlen] = '\0';
3029 +               pair->lvalue = attrlen;
3030 +               break;
3031 +
3032 +       case PW_TYPE_INTEGER:
3033 +               if (attrlen != 4) {
3034 +                       rc_log(LOG_ERR, "rc_avpair_gen: received INT "
3035 +                           "attribute with invalid length");
3036 +                       goto shithappens;
3037 +               }
3038 +       case PW_TYPE_IPADDR:
3039 +               if (attrlen != 4) {
3040 +                       rc_log(LOG_ERR, "rc_avpair_gen: received IPADDR"
3041 +                           " attribute with invalid length");
3042 +                       goto shithappens;
3043 +               }
3044 +               memcpy((char *)&lvalue, (char *)ptr, 4);
3045 +               pair->lvalue = ntohl(lvalue);
3046 +               break;
3047 +       case PW_TYPE_IPV6ADDR:
3048 +               if (attrlen != 16) {
3049 +                       rc_log(LOG_ERR, "rc_avpair_gen: received IPV6ADDR"
3050 +                           " attribute with invalid length");
3051 +                       goto shithappens;
3052 +               }
3053 +               memcpy(pair->strvalue, (char *)ptr, 16);
3054 +               pair->lvalue = attrlen;
3055 +               break;
3056 +       case PW_TYPE_IPV6PREFIX:
3057 +               if (attrlen > 18 || attrlen < 2) {
3058 +                       rc_log(LOG_ERR, "rc_avpair_gen: received IPV6PREFIX"
3059 +                           " attribute with invalid length: %d", attrlen);
3060 +                       goto shithappens;
3061 +               }
3062 +               memcpy(pair->strvalue, (char *)ptr, attrlen);
3063 +               pair->lvalue = attrlen;
3064 +               break;
3065 +       case PW_TYPE_DATE:
3066 +               if (attrlen != 4) {
3067 +                       rc_log(LOG_ERR, "rc_avpair_gen: received DATE "
3068 +                           "attribute with invalid length");
3069 +                       goto shithappens;
3070 +               }
3071 +
3072 +       default:
3073 +               rc_log(LOG_WARNING, "rc_avpair_gen: %s has unknown type",
3074 +                   attr->name);
3075 +               goto shithappens;
3076 +       }
3077 +       return pair;
3078 +
3079 +shithappens:
3080 +       while (pair != NULL) {
3081 +               rpair = pair->next;
3082 +               free(pair);
3083 +               pair = rpair;
3084 +       }
3085 +       return NULL;
3086 +}
3087 +
3088 +/*
3089 + * Function: rc_avpair_get
3090 + *
3091 + * Purpose: Find the first attribute value-pair (which matches the given
3092 + *          attribute) from the specified value-pair list.
3093 + *
3094 + * Returns: found value_pair
3095 + *
3096 + */
3097 +
3098 +VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, int attrid, int vendorpec)
3099 +{
3100 +       for (; vp != NULL && !(ATTRID(vp->attribute) == ATTRID(attrid) &&
3101 +           VENDOR(vp->attribute) == vendorpec); vp = vp->next)
3102 +       {
3103 +               continue;
3104 +       }
3105 +       return vp;
3106 +}
3107 +
3108 +/*
3109 + * Function: rc_avpair_insert
3110 + *
3111 + * Purpose: Given the address of an existing list "a" and a pointer
3112 + *         to an entry "p" in that list, add the value pair "b" to
3113 + *         the "a" list after the "p" entry.  If "p" is NULL, add
3114 + *         the value pair "b" to the end of "a".
3115 + *
3116 + */
3117 +
3118 +void rc_avpair_insert (VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
3119 +{
3120 +       VALUE_PAIR     *this_node = NULL;
3121 +       VALUE_PAIR     *vp;
3122 +
3123 +       if (b->next != NULL)
3124 +       {
3125 +               rc_log(LOG_CRIT, "rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
3126 +               abort ();
3127 +       }
3128 +
3129 +       if (*a == NULL)
3130 +       {
3131 +               *a = b;
3132 +               return;
3133 +       }
3134 +
3135 +       vp = *a;
3136 +
3137 +       if ( p == NULL) /* run to end of "a" list */
3138 +       {
3139 +               while (vp != NULL)
3140 +               {
3141 +                       this_node = vp;
3142 +                       vp = vp->next;
3143 +               }
3144 +       }
3145 +       else /* look for the "p" entry in the "a" list */
3146 +       {
3147 +               this_node = *a;
3148 +               while (this_node != NULL)
3149 +               {
3150 +                       if (this_node == p)
3151 +                       {
3152 +                               break;
3153 +                       }
3154 +                       this_node = this_node->next;
3155 +               }
3156 +       }
3157 +
3158 +       b->next = this_node->next;
3159 +       this_node->next = b;
3160 +
3161 +       return;
3162 +}
3163 +
3164 +/*
3165 + * Function: rc_avpair_free
3166 + *
3167 + * Purpose: frees all value_pairs in the list
3168 + *
3169 + */
3170 +
3171 +void rc_avpair_free (VALUE_PAIR *pair)
3172 +{
3173 +       VALUE_PAIR     *next;
3174 +
3175 +       while (pair != NULL)
3176 +       {
3177 +               next = pair->next;
3178 +               free (pair);
3179 +               pair = next;
3180 +       }
3181 +}
3182 +
3183 +/*
3184 + * Function: rc_fieldcpy
3185 + *
3186 + * Purpose: Copy a data field from the buffer.  Advance the buffer
3187 + *          past the data field. Ensure that no more than len - 1
3188 + *          bytes are copied and that resulting string is terminated
3189 + *          with '\0'.
3190 + *
3191 + */
3192 +
3193 +static void
3194 +rc_fieldcpy(char *string, char const **uptr, char const *stopat, size_t len)
3195 +{
3196 +       char const *ptr, *estring;
3197 +
3198 +       ptr = *uptr;
3199 +       estring = string + len - 1;
3200 +       if (*ptr == '"')
3201 +       {
3202 +               ptr++;
3203 +               while (*ptr != '"' && *ptr != '\0' && *ptr != '\n')
3204 +               {
3205 +                       if (string < estring)
3206 +                               *string++ = *ptr;
3207 +                       ptr++;
3208 +               }
3209 +               if (*ptr == '"')
3210 +               {
3211 +                       ptr++;
3212 +               }
3213 +               *string = '\0';
3214 +               *uptr = ptr;
3215 +               return;
3216 +       }
3217 +
3218 +       while (*ptr != '\0' && strchr(stopat, *ptr) == NULL)
3219 +       {
3220 +               if (string < estring)
3221 +                       *string++ = *ptr;
3222 +               ptr++;
3223 +       }
3224 +       *string = '\0';
3225 +       *uptr = ptr;
3226 +       return;
3227 +}
3228 +
3229 +
3230 +/*
3231 + * Function: rc_avpair_parse
3232 + *
3233 + * Purpose: parses the buffer to extract the attribute-value pairs.
3234 + *
3235 + * Returns: 0 = successful parse of attribute-value pair,
3236 + *        -1 = syntax (or other) error detected.
3237 + *
3238 + */
3239 +
3240 +#define PARSE_MODE_NAME                0
3241 +#define PARSE_MODE_EQUAL       1
3242 +#define PARSE_MODE_VALUE       2
3243 +#define PARSE_MODE_INVALID     3
3244 +
3245 +int rc_avpair_parse (rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
3246 +{
3247 +       int             mode;
3248 +       char            attrstr[AUTH_ID_LEN];
3249 +       char            valstr[AUTH_STRING_LEN + 1], *p;
3250 +       DICT_ATTR      *attr = NULL;
3251 +       DICT_VALUE     *dval;
3252 +       VALUE_PAIR     *pair;
3253 +       VALUE_PAIR     *link;
3254 +       struct tm      *tm;
3255 +       time_t          timeval;
3256 +
3257 +       mode = PARSE_MODE_NAME;
3258 +       while (*buffer != '\n' && *buffer != '\0')
3259 +       {
3260 +               if (*buffer == ' ' || *buffer == '\t')
3261 +               {
3262 +                       buffer++;
3263 +                       continue;
3264 +               }
3265 +
3266 +               switch (mode)
3267 +               {
3268 +                   case PARSE_MODE_NAME:               /* Attribute Name */
3269 +                       rc_fieldcpy (attrstr, &buffer, " \t\n=,", sizeof(attrstr));
3270 +                       if ((attr =
3271 +                               rc_dict_findattr (rh, attrstr)) == NULL)
3272 +                       {
3273 +                               rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute");
3274 +                               if (*first_pair) {
3275 +                                       rc_avpair_free(*first_pair);
3276 +                                       *first_pair = NULL;
3277 +                               }
3278 +                               return -1;
3279 +                       }
3280 +                       mode = PARSE_MODE_EQUAL;
3281 +                       break;
3282 +
3283 +                   case PARSE_MODE_EQUAL:              /* Equal sign */
3284 +                       if (*buffer == '=')
3285 +                       {
3286 +                               mode = PARSE_MODE_VALUE;
3287 +                               buffer++;
3288 +                       }
3289 +                       else
3290 +                       {
3291 +                               rc_log(LOG_ERR, "rc_avpair_parse: missing or misplaced equal sign");
3292 +                               if (*first_pair) {
3293 +                                       rc_avpair_free(*first_pair);
3294 +                                       *first_pair = NULL;
3295 +                               }
3296 +                               return -1;
3297 +                       }
3298 +                       break;
3299 +
3300 +                   case PARSE_MODE_VALUE:              /* Value */
3301 +                       rc_fieldcpy (valstr, &buffer, " \t\n,", sizeof(valstr));
3302 +
3303 +                       if ((pair = malloc (sizeof (VALUE_PAIR))) == NULL)
3304 +                       {
3305 +                               rc_log(LOG_CRIT, "rc_avpair_parse: out of memory");
3306 +                               if (*first_pair) {
3307 +                                       rc_avpair_free(*first_pair);
3308 +                                       *first_pair = NULL;
3309 +                               }
3310 +                               return -1;
3311 +                       }
3312 +                       strcpy (pair->name, attr->name);
3313 +                       pair->attribute = attr->value;
3314 +                       pair->type = attr->type;
3315 +
3316 +                       switch (pair->type)
3317 +                       {
3318 +
3319 +                           case PW_TYPE_STRING:
3320 +                               strcpy (pair->strvalue, valstr);
3321 +                               pair->lvalue = (uint32_t)strlen(valstr);
3322 +                               break;
3323 +
3324 +                           case PW_TYPE_INTEGER:
3325 +                               if (isdigit (*valstr))
3326 +                               {
3327 +                                       pair->lvalue = atoi (valstr);
3328 +                               }
3329 +                               else
3330 +                               {
3331 +                                       if ((dval = rc_dict_findval (rh, valstr))
3332 +                                                       == NULL)
3333 +                                       {
3334 +                                               rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute value: %s", valstr);
3335 +                                               if (*first_pair) {
3336 +                                                       rc_avpair_free(*first_pair);
3337 +                                                       *first_pair = NULL;
3338 +                                               }
3339 +                                               free (pair);
3340 +                                               return -1;
3341 +                                       }
3342 +                                       else
3343 +                                       {
3344 +                                               pair->lvalue = dval->value;
3345 +                                       }
3346 +                               }
3347 +                               break;
3348 +
3349 +                           case PW_TYPE_IPADDR:
3350 +                                pair->lvalue = rc_get_ipaddr(valstr);
3351 +                               break;
3352 +
3353 +                           case PW_TYPE_IPV6ADDR:
3354 +                               if (inet_pton(AF_INET6, valstr, pair->strvalue) == 0) {
3355 +                                       rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 address %s", valstr);
3356 +                                       free(pair);
3357 +                                       return -1;
3358 +                               }
3359 +                               pair->lvalue = 16;
3360 +                               break;
3361 +
3362 +                           case PW_TYPE_IPV6PREFIX:
3363 +                               p = strchr(valstr, '/');
3364 +                               if (p == NULL) {
3365 +                                       rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
3366 +                                       free(pair);
3367 +                                       return -1;
3368 +                               }
3369 +                               *p = 0;
3370 +                               p++;
3371 +                               pair->strvalue[0] = 0;
3372 +                               pair->strvalue[1] = atoi(p);
3373 +
3374 +                               if (inet_pton(AF_INET6, valstr, pair->strvalue+2) == 0) {
3375 +                                       rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
3376 +                                       free(pair);
3377 +                                       return -1;
3378 +                               }
3379 +                               pair->lvalue = 2+16;
3380 +                               break;
3381 +
3382 +                           case PW_TYPE_DATE:
3383 +                               timeval = time (0);
3384 +                               tm = localtime (&timeval);
3385 +                               tm->tm_hour = 0;
3386 +                               tm->tm_min = 0;
3387 +                               tm->tm_sec = 0;
3388 +                               rc_str2tm (valstr, tm);
3389 +#ifdef TIMELOCAL
3390 +                               pair->lvalue = (uint32_t) timelocal (tm);
3391 +#else  /* TIMELOCAL */
3392 +                               pair->lvalue = (uint32_t) mktime (tm);
3393 +#endif /* TIMELOCAL */
3394 +                               break;
3395 +
3396 +                           default:
3397 +                               rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute type %d", pair->type);
3398 +                               if (*first_pair) {
3399 +                                       rc_avpair_free(*first_pair);
3400 +                                       *first_pair = NULL;
3401 +                               }
3402 +                               free (pair);
3403 +                               return -1;
3404 +                       }
3405 +
3406 +                       /* XXX: Fix up Digest-Attributes */
3407 +                       switch (pair->attribute) {
3408 +                       case PW_DIGEST_REALM:
3409 +                       case PW_DIGEST_NONCE:
3410 +                       case PW_DIGEST_METHOD:
3411 +                       case PW_DIGEST_URI:
3412 +                       case PW_DIGEST_QOP:
3413 +                       case PW_DIGEST_ALGORITHM:
3414 +                       case PW_DIGEST_BODY_DIGEST:
3415 +                       case PW_DIGEST_CNONCE:
3416 +                       case PW_DIGEST_NONCE_COUNT:
3417 +                       case PW_DIGEST_USER_NAME:
3418 +                               /* overlapping! */
3419 +                               if (pair->lvalue > AUTH_STRING_LEN - 2)
3420 +                                       pair->lvalue = AUTH_STRING_LEN - 2;
3421 +                               memmove(&pair->strvalue[2], &pair->strvalue[0], pair->lvalue);
3422 +                               pair->strvalue[0] = pair->attribute - PW_DIGEST_REALM + 1;
3423 +                               pair->lvalue += 2;
3424 +                               pair->strvalue[1] = pair->lvalue;
3425 +                               pair->strvalue[pair->lvalue] = '\0';
3426 +                               pair->attribute = PW_DIGEST_ATTRIBUTES;
3427 +                       }
3428 +
3429 +                       pair->next = NULL;
3430 +
3431 +                       if (*first_pair == NULL)
3432 +                       {
3433 +                               *first_pair = pair;
3434 +                       }
3435 +                       else
3436 +                       {
3437 +                               link = *first_pair;
3438 +                               while (link->next != NULL)
3439 +                               {
3440 +                                       link = link->next;
3441 +                               }
3442 +                               link->next = pair;
3443 +                       }
3444 +
3445 +                       mode = PARSE_MODE_NAME;
3446 +                       break;
3447 +
3448 +                   default:
3449 +                       mode = PARSE_MODE_NAME;
3450 +                       break;
3451 +               }
3452 +       }
3453 +       return 0;
3454 +}
3455 +
3456 +/*
3457 + * Function: rc_avpair_tostr
3458 + *
3459 + * Purpose: Translate an av_pair into two strings
3460 + *
3461 + * Returns: 0 on success, -1 on failure
3462 + *
3463 + */
3464 +
3465 +int rc_avpair_tostr (rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
3466 +{
3467 +       DICT_VALUE     *dval;
3468 +       char            buffer[32];
3469 +       struct in_addr  inad;
3470 +       unsigned char         *ptr;
3471 +
3472 +       *name = *value = '\0';
3473 +
3474 +       if (!pair || pair->name[0] == '\0') {
3475 +               rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty");
3476 +               return -1;
3477 +       }
3478 +
3479 +       strncpy(name, pair->name, (size_t) ln);
3480 +
3481 +       switch (pair->type)
3482 +       {
3483 +           case PW_TYPE_STRING:
3484 +               lv--;
3485 +               ptr = (unsigned char *) pair->strvalue;
3486 +               if (pair->attribute == PW_DIGEST_ATTRIBUTES) {
3487 +                       pair->strvalue[*(ptr + 1)] = '\0';
3488 +                       ptr += 2;
3489 +               }
3490 +               while (*ptr != '\0')
3491 +               {
3492 +                       if (!(isprint (*ptr)))
3493 +                       {
3494 +                               snprintf (buffer, sizeof(buffer), "\\%03o", *ptr);
3495 +                               strncat(value, buffer, (size_t) lv);
3496 +                               lv -= 4;
3497 +                               if (lv < 0) break;
3498 +                       }
3499 +                       else
3500 +                       {
3501 +                               strncat(value, (char *)ptr, 1);
3502 +                               lv--;
3503 +                               if (lv <= 0) break;
3504 +                       }
3505 +                       ptr++;
3506 +               }
3507 +               break;
3508 +
3509 +           case PW_TYPE_INTEGER:
3510 +               dval = rc_dict_getval (rh, pair->lvalue, pair->name);
3511 +               if (dval != NULL)
3512 +               {
3513 +                       strncpy(value, dval->name, (size_t) lv-1);
3514 +               }
3515 +               else
3516 +               {
3517 +                       snprintf(buffer, sizeof(buffer), "%ld", (long int)pair->lvalue);
3518 +                       strncpy(value, buffer, (size_t) lv);
3519 +               }
3520 +               break;
3521 +
3522 +           case PW_TYPE_IPADDR:
3523 +               inad.s_addr = htonl(pair->lvalue);
3524 +               strncpy (value, inet_ntoa (inad), (size_t) lv-1);
3525 +               break;
3526 +
3527 +           case PW_TYPE_IPV6ADDR:
3528 +               if (inet_ntop(AF_INET6, pair->strvalue, value, lv-1) == NULL)
3529 +                       return -1;
3530 +               break;
3531 +
3532 +           case PW_TYPE_IPV6PREFIX: {
3533 +               uint8_t ip[16];
3534 +               uint8_t txt[48];
3535 +               if (pair->lvalue < 2)
3536 +                       return -1;
3537 +
3538 +               memset(ip, 0, sizeof(ip));
3539 +               memcpy(ip, pair->strvalue+2, pair->lvalue-2);
3540 +
3541 +               if (inet_ntop(AF_INET6, ip, txt, sizeof(txt)) == NULL)
3542 +                       return -1;
3543 +               snprintf(value, lv-1, "%s/%u", txt, (unsigned)pair->strvalue[1]);
3544 +
3545 +               break;
3546 +           }
3547 +           case PW_TYPE_DATE:
3548 +               strftime (buffer, sizeof (buffer), "%m/%d/%y %H:%M:%S",
3549 +                         gmtime ((time_t *) & pair->lvalue));
3550 +               strncpy(value, buffer, lv-1);
3551 +               break;
3552 +
3553 +           default:
3554 +               rc_log(LOG_ERR, "rc_avpair_tostr: unknown attribute type %d", pair->type);
3555 +               return -1;
3556 +               break;
3557 +       }
3558 +
3559 +       return 0;
3560 +}
3561 +
3562 +/*
3563 + * Function: rc_avpair_log
3564 + *
3565 + * Purpose: format sequence of attribute value pairs into printable
3566 + * string. The caller should provide a storage buffer and the buffer length.
3567 + * Returns pointer to provided storage buffer.
3568 + *
3569 + */
3570 +char *
3571 +rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
3572 +{
3573 +       size_t len, nlen;
3574 +       VALUE_PAIR *vp;
3575 +       char name[33], value[256];
3576 +
3577 +       len = 0;
3578 +       for (vp = pair; vp != NULL; vp = vp->next) {
3579 +               if (rc_avpair_tostr(rh, vp, name, sizeof(name), value,
3580 +                   sizeof(value)) == -1)
3581 +                       return NULL;
3582 +               nlen = len + 32 + 3 + strlen(value) + 2 + 2;
3583 +               if(nlen<buf_len-1) {
3584 +                       sprintf(buf + len, "%-32s = '%s'\n", name, value);
3585 +               } else return buf;
3586 +               len = nlen - 1;
3587 +       }
3588 +       return buf;
3589 +}
3590 +
3591 +/*
3592 + * Function: rc_avpair_readin
3593 + *
3594 + * Purpose: get a sequence of attribute value pairs from the file input
3595 + *         and make them into a list of value_pairs
3596 + *
3597 + */
3598 +
3599 +VALUE_PAIR *rc_avpair_readin(rc_handle const *rh, FILE *input)
3600 +{
3601 +       VALUE_PAIR *vp = NULL;
3602 +       char buffer[1024], *q;
3603 +
3604 +       while (fgets(buffer, sizeof(buffer), input) != NULL)
3605 +       {
3606 +               q = buffer;
3607 +
3608 +               while(*q && isspace(*q)) q++;
3609 +
3610 +               if ((*q == '\n') || (*q == '#') || (*q == '\0'))
3611 +                       continue;
3612 +
3613 +               if (rc_avpair_parse(rh, q, &vp) < 0) {
3614 +                       rc_log(LOG_ERR, "rc_avpair_readin: malformed attribute: %s", buffer);
3615 +                       rc_avpair_free(vp);
3616 +                       return NULL;
3617 +               }
3618 +       }
3619 +
3620 +       return vp;
3621 +}
3622 diff --git a/src/plugins/vbng/lib/buildreq.c b/src/plugins/vbng/lib/buildreq.c
3623 new file mode 100644
3624 index 0000000..a71b1f9
3625 --- /dev/null
3626 +++ b/src/plugins/vbng/lib/buildreq.c
3627 @@ -0,0 +1,276 @@
3628 +/*
3629 + * $Id: buildreq.c,v 1.17 2010/02/04 10:27:09 aland Exp $
3630 + *
3631 + * Copyright (C) 1995,1997 Lars Fenneberg
3632 + *
3633 + * See the file COPYRIGHT for the respective terms and conditions.
3634 + * If the file is missing contact me at lf@elemental.net
3635 + * and I'll send you a copy.
3636 + *
3637 + */
3638 +
3639 +#include <config.h>
3640 +#include <includes.h>
3641 +#include <freeradius-client.h>
3642 +
3643 +unsigned char rc_get_id();
3644 +
3645 +/*
3646 + * Function: rc_buildreq
3647 + *
3648 + * Purpose: builds a skeleton RADIUS request using information from the
3649 + *         config file.
3650 + *
3651 + */
3652 +
3653 +void rc_buildreq(rc_handle const *rh, SEND_DATA *data, int code, char *server, unsigned short port,
3654 +                char *secret, int timeout, int retries)
3655 +{
3656 +       data->server = server;
3657 +       data->secret = secret;
3658 +       data->svc_port = port;
3659 +       data->seq_nbr = rc_get_id();
3660 +       data->timeout = timeout;
3661 +       data->retries = retries;
3662 +       data->code = code;
3663 +}
3664 +
3665 +/*
3666 + * Function: rc_get_id
3667 + *
3668 + * Purpose: generate random id
3669 + *
3670 + */
3671 +
3672 +unsigned char rc_get_id()
3673 +{
3674 +       return (unsigned char)(random() & UCHAR_MAX);
3675 +}
3676 +
3677 +/*
3678 + * Function: rc_aaa
3679 + *
3680 + * Purpose: Builds an authentication/accounting request for port id client_port
3681 + *         with the value_pairs send and submits it to a server
3682 + *
3683 + * Returns: received value_pairs in received, messages from the server in msg
3684 + *         and 0 on success, negative on failure as return value
3685 + *
3686 + */
3687 +
3688 +int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
3689 +    char *msg, int add_nas_port, int request_type)
3690 +{
3691 +       SEND_DATA       data;
3692 +       VALUE_PAIR      *adt_vp = NULL;
3693 +       int             result;
3694 +       int             i, skip_count;
3695 +       SERVER          *aaaserver;
3696 +       int             timeout = rc_conf_int(rh, "radius_timeout");
3697 +       int             retries = rc_conf_int(rh, "radius_retries");
3698 +       int             radius_deadtime = rc_conf_int(rh, "radius_deadtime");
3699 +       double          start_time = 0;
3700 +       double          now = 0;
3701 +       time_t          dtime;
3702 +
3703 +       if (request_type != PW_ACCOUNTING_REQUEST) {
3704 +               aaaserver = rc_conf_srv(rh, "authserver");
3705 +       } else {
3706 +               aaaserver = rc_conf_srv(rh, "acctserver");
3707 +       }
3708 +       if (aaaserver == NULL)
3709 +               return ERROR_RC;
3710 +
3711 +       data.send_pairs = send;
3712 +       data.receive_pairs = NULL;
3713 +
3714 +       if (add_nas_port != 0) {
3715 +               /*
3716 +                * Fill in NAS-Port
3717 +                */
3718 +               if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
3719 +                   &client_port, 0, 0) == NULL)
3720 +                       return ERROR_RC;
3721 +       }
3722 +
3723 +       if (request_type == PW_ACCOUNTING_REQUEST) {
3724 +               /*
3725 +                * Fill in Acct-Delay-Time
3726 +                */
3727 +               dtime = 0;
3728 +               now = rc_getctime();
3729 +               adt_vp = rc_avpair_get(data.send_pairs, PW_ACCT_DELAY_TIME, 0);
3730 +               if (adt_vp == NULL) {
3731 +                       adt_vp = rc_avpair_add(rh, &(data.send_pairs),
3732 +                           PW_ACCT_DELAY_TIME, &dtime, 0, 0);
3733 +                       if (adt_vp == NULL)
3734 +                               return ERROR_RC;
3735 +                       start_time = now;
3736 +               } else {
3737 +                       start_time = now - adt_vp->lvalue;
3738 +               }
3739 +       }
3740 +
3741 +       skip_count = 0;
3742 +       result = ERROR_RC;
3743 +       for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != BADRESP_RC)
3744 +           ; i++, now = rc_getctime())
3745 +       {
3746 +               if (aaaserver->deadtime_ends[i] != -1 &&
3747 +                   aaaserver->deadtime_ends[i] > start_time) {
3748 +                       skip_count++;
3749 +                       continue;
3750 +               }
3751 +               if (data.receive_pairs != NULL) {
3752 +                       rc_avpair_free(data.receive_pairs);
3753 +                       data.receive_pairs = NULL;
3754 +               }
3755 +               rc_buildreq(rh, &data, request_type, aaaserver->name[i],
3756 +                   aaaserver->port[i], aaaserver->secret[i], timeout, retries);
3757 +
3758 +               if (request_type == PW_ACCOUNTING_REQUEST) {
3759 +                       dtime = now - start_time;
3760 +                       rc_avpair_assign(adt_vp, &dtime, 0);
3761 +               }
3762 +
3763 +               result = rc_send_server (rh, &data, msg);
3764 +               if (result == TIMEOUT_RC && radius_deadtime > 0)
3765 +                       aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime;
3766 +       }
3767 +       if (result == OK_RC || result == BADRESP_RC || skip_count == 0)
3768 +               goto exit;
3769 +
3770 +       result = ERROR_RC;
3771 +       for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != BADRESP_RC)
3772 +           ; i++)
3773 +       {
3774 +               if (aaaserver->deadtime_ends[i] == -1 ||
3775 +                   aaaserver->deadtime_ends[i] <= start_time) {
3776 +                       continue;
3777 +               }
3778 +               if (data.receive_pairs != NULL) {
3779 +                       rc_avpair_free(data.receive_pairs);
3780 +                       data.receive_pairs = NULL;
3781 +               }
3782 +               rc_buildreq(rh, &data, request_type, aaaserver->name[i],
3783 +                   aaaserver->port[i], aaaserver->secret[i], timeout, retries);
3784 +
3785 +               if (request_type == PW_ACCOUNTING_REQUEST) {
3786 +                       dtime = rc_getctime() - start_time;
3787 +                       rc_avpair_assign(adt_vp, &dtime, 0);
3788 +               }
3789 +
3790 +               result = rc_send_server (rh, &data, msg);
3791 +               if (result != TIMEOUT_RC)
3792 +                       aaaserver->deadtime_ends[i] = -1;
3793 +       }
3794 +
3795 +exit:
3796 +       if (request_type != PW_ACCOUNTING_REQUEST) {
3797 +               *received = data.receive_pairs;
3798 +       } else {
3799 +               rc_avpair_free(data.receive_pairs);
3800 +       }
3801 +
3802 +       return result;
3803 +}
3804 +
3805 +/*
3806 + * Function: rc_auth
3807 + *
3808 + * Purpose: Builds an authentication request for port id client_port
3809 + *          with the value_pairs send and submits it to a server
3810 + *
3811 + * Returns: received value_pairs in received, messages from the server in msg (if non-NULL),
3812 + *          and 0 on success, negative on failure as return value
3813 + *
3814 + */
3815 +
3816 +int rc_auth(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
3817 +    char *msg)
3818 +{
3819 +
3820 +       return rc_aaa(rh, client_port, send, received, msg, 1, PW_ACCESS_REQUEST);
3821 +}
3822 +
3823 +/*
3824 + * Function: rc_auth_proxy
3825 + *
3826 + * Purpose: Builds an authentication request
3827 + *         with the value_pairs send and submits it to a server.
3828 + *         Works for a proxy; does not add IP address, and does
3829 + *         does not rely on config file.
3830 + *
3831 + * Returns: received value_pairs in received, messages from the server in msg (if non-NULL)
3832 + *         and 0 on success, negative on failure as return value
3833 + *
3834 + */
3835 +
3836 +int rc_auth_proxy(rc_handle *rh, VALUE_PAIR *send, VALUE_PAIR **received, char *msg)
3837 +{
3838 +
3839 +       return rc_aaa(rh, 0, send, received, msg, 0, PW_ACCESS_REQUEST);
3840 +}
3841 +
3842 +
3843 +/*
3844 + * Function: rc_acct
3845 + *
3846 + * Purpose: Builds an accounting request for port id client_port
3847 + *         with the value_pairs send
3848 + *
3849 + * Remarks: NAS-IP-Address, NAS-Port and Acct-Delay-Time get filled
3850 + *         in by this function, the rest has to be supplied.
3851 + */
3852 +
3853 +int rc_acct(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send)
3854 +{
3855 +
3856 +       return rc_aaa(rh, client_port, send, NULL, NULL, 1, PW_ACCOUNTING_REQUEST);
3857 +}
3858 +
3859 +/*
3860 + * Function: rc_acct_proxy
3861 + *
3862 + * Purpose: Builds an accounting request with the value_pairs send
3863 + *
3864 + */
3865 +
3866 +int rc_acct_proxy(rc_handle *rh, VALUE_PAIR *send)
3867 +{
3868 +
3869 +       return rc_aaa(rh, 0, send, NULL, NULL, 0, PW_ACCOUNTING_REQUEST);
3870 +}
3871 +
3872 +/*
3873 + * Function: rc_check
3874 + *
3875 + * Purpose: ask the server hostname on the specified port for a
3876 + *         status message
3877 + *
3878 + */
3879 +
3880 +int rc_check(rc_handle *rh, char *host, char *secret, unsigned short port, char *msg)
3881 +{
3882 +       SEND_DATA       data;
3883 +       int             result;
3884 +       uint32_t                service_type;
3885 +       int             timeout = rc_conf_int(rh, "radius_timeout");
3886 +       int             retries = rc_conf_int(rh, "radius_retries");
3887 +
3888 +       data.send_pairs = data.receive_pairs = NULL;
3889 +
3890 +       /*
3891 +        * Fill in Service-Type
3892 +        */
3893 +
3894 +       service_type = PW_ADMINISTRATIVE;
3895 +       rc_avpair_add(rh, &(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, 0);
3896 +
3897 +       rc_buildreq(rh, &data, PW_STATUS_SERVER, host, port, secret, timeout, retries);
3898 +       result = rc_send_server (rh, &data, msg);
3899 +
3900 +       rc_avpair_free(data.receive_pairs);
3901 +
3902 +       return result;
3903 +}
3904 diff --git a/src/plugins/vbng/lib/clientid.c b/src/plugins/vbng/lib/clientid.c
3905 new file mode 100644
3906 index 0000000..6901a04
3907 --- /dev/null
3908 +++ b/src/plugins/vbng/lib/clientid.c
3909 @@ -0,0 +1,146 @@
3910 +/*
3911 + * $Id: clientid.c,v 1.7 2007/07/11 17:29:29 cparker Exp $
3912 + *
3913 + * Copyright (C) 1995,1996,1997 Lars Fenneberg
3914 + *
3915 + * See the file COPYRIGHT for the respective terms and conditions.
3916 + * If the file is missing contact me at lf@elemental.net
3917 + * and I'll send you a copy.
3918 + *
3919 + */
3920 +
3921 +#include <config.h>
3922 +#include <includes.h>
3923 +#include <freeradius-client.h>
3924 +
3925 +struct map2id_s {
3926 +       char *name;
3927 +       uint32_t id;
3928 +
3929 +       struct map2id_s *next;
3930 +};
3931 +
3932 +/*
3933 + * Function: rc_read_mapfile
3934 + *
3935 + * Purpose: Read in the ttyname to port id map file
3936 + *
3937 + * Arguments: the file name of the map file
3938 + *
3939 + * Returns: zero on success, negative integer on failure
3940 + */
3941 +
3942 +int rc_read_mapfile(rc_handle *rh, char const *filename)
3943 +{
3944 +       char buffer[1024];
3945 +       FILE *mapfd;
3946 +       char *c, *name, *id, *q;
3947 +       struct map2id_s *p;
3948 +       int lnr = 0;
3949 +
3950 +        if ((mapfd = fopen(filename,"r")) == NULL)
3951 +        {
3952 +               rc_log(LOG_ERR,"rc_read_mapfile: can't read %s: %s", filename, strerror(errno));
3953 +               return -1;
3954 +       }
3955 +
3956 +#define SKIP(p) while(*p && isspace(*p)) p++;
3957 +
3958 +        while (fgets(buffer, sizeof(buffer), mapfd) != NULL)
3959 +        {
3960 +               lnr++;
3961 +
3962 +               q = buffer;
3963 +
3964 +                SKIP(q);
3965 +
3966 +                if ((*q == '\n') || (*q == '#') || (*q == '\0'))
3967 +                       continue;
3968 +
3969 +               if (( c = strchr(q, ' ')) || (c = strchr(q,'\t'))) {
3970 +
3971 +                       *c = '\0'; c++;
3972 +                       SKIP(c);
3973 +
3974 +                       name = q;
3975 +                       id = c;
3976 +
3977 +                       if ((p = (struct map2id_s *)malloc(sizeof(*p))) == NULL) {
3978 +                               rc_log(LOG_CRIT,"rc_read_mapfile: out of memory");
3979 +                               fclose(mapfd);
3980 +                               return -1;
3981 +                       }
3982 +
3983 +                       p->name = strdup(name);
3984 +                       p->id = atoi(id);
3985 +                       p->next = rh->map2id_list;
3986 +                       rh->map2id_list = p;
3987 +
3988 +               } else {
3989 +
3990 +                       rc_log(LOG_ERR, "rc_read_mapfile: malformed line in %s, line %d", filename, lnr);
3991 +                       fclose(mapfd);
3992 +                       return -1;
3993 +
3994 +               }
3995 +       }
3996 +
3997 +#undef SKIP
3998 +
3999 +       fclose(mapfd);
4000 +
4001 +       return 0;
4002 +}
4003 +
4004 +/*
4005 + * Function: rc_map2id
4006 + *
4007 + * Purpose: Map ttyname to port id
4008 + *
4009 + * Arguments: full pathname of the tty
4010 + *
4011 + * Returns: port id, zero if no entry found
4012 + */
4013 +
4014 +uint32_t rc_map2id(rc_handle const *rh, char const *name)
4015 +{
4016 +       struct map2id_s *p;
4017 +       char ttyname[PATH_MAX];
4018 +
4019 +       *ttyname = '\0';
4020 +       if (*name != '/')
4021 +               strcpy(ttyname, "/dev/");
4022 +
4023 +       strncat(ttyname, name, sizeof(ttyname)-strlen(ttyname)-1);
4024 +
4025 +       for(p = rh->map2id_list; p; p = p->next)
4026 +               if (!strcmp(ttyname, p->name)) return p->id;
4027 +
4028 +       rc_log(LOG_WARNING,"rc_map2id: can't find tty %s in map database", ttyname);
4029 +
4030 +       return 0;
4031 +}
4032 +
4033 +/*
4034 + * Function: rc_map2id_free
4035 + *
4036 + * Purpose: Free allocated map2id list
4037 + *
4038 + * Arguments: Radius Client handle
4039 + */
4040 +
4041 +void
4042 +rc_map2id_free(rc_handle *rh)
4043 +{
4044 +       struct map2id_s *p, *np;
4045 +
4046 +       if (rh->map2id_list == NULL)
4047 +               return;
4048 +
4049 +       for(p = rh->map2id_list; p != NULL; p = np) {
4050 +               np = p->next;
4051 +               free(p->name);
4052 +               free(p);
4053 +       }
4054 +       rh->map2id_list = NULL;
4055 +}
4056 diff --git a/src/plugins/vbng/lib/config.c b/src/plugins/vbng/lib/config.c
4057 new file mode 100644
4058 index 0000000..1db7860
4059 --- /dev/null
4060 +++ b/src/plugins/vbng/lib/config.c
4061 @@ -0,0 +1,925 @@
4062 +/*
4063 + * $Id: config.c,v 1.23 2010/04/28 14:26:15 aland Exp $
4064 + *
4065 + * Copyright (C) 1995,1996,1997 Lars Fenneberg
4066 + *
4067 + * Copyright 1992 Livingston Enterprises, Inc.
4068 + *
4069 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
4070 + * and Merit Network, Inc. All Rights Reserved
4071 + *
4072 + * See the file COPYRIGHT for the respective terms and conditions.
4073 + * If the file is missing contact me at lf@elemental.net
4074 + * and I'll send you a copy.
4075 + *
4076 + */
4077 +
4078 +#include <config.h>
4079 +#include <includes.h>
4080 +#include <freeradius-client.h>
4081 +#include <options.h>
4082 +
4083 +/*
4084 + * Function: find_option
4085 + *
4086 + * Purpose: find an option in the option list
4087 + *
4088 + * Returns: pointer to option on success, NULL otherwise
4089 + */
4090 +
4091 +static OPTION *find_option(rc_handle const *rh, char const *optname, unsigned int type)
4092 +{
4093 +       int     i;
4094 +
4095 +       /* there're so few options that a binary search seems not necessary */
4096 +       for (i = 0; i < NUM_OPTIONS; i++) {
4097 +               if (!strcmp(rh->config_options[i].name, optname) &&
4098 +                   (rh->config_options[i].type & type))
4099 +               {
4100 +                       return &rh->config_options[i];
4101 +               }
4102 +       }
4103 +
4104 +       return NULL;
4105 +}
4106 +
4107 +/*
4108 + * Function: set_option_...
4109 + *
4110 + * Purpose: set a specific option doing type conversions
4111 + *
4112 + * Returns: 0 on success, -1 on failure
4113 + */
4114 +
4115 +static int set_option_str(char const *filename, int line, OPTION *option, char const *p)
4116 +{
4117 +       if (p) {
4118 +               option->val = (void *) strdup(p);
4119 +               if (option->val == NULL) {
4120 +                       rc_log(LOG_CRIT, "read_config: out of memory");
4121 +                       return -1;
4122 +               }
4123 +       } else {
4124 +               option->val = NULL;
4125 +       }
4126 +
4127 +       return 0;
4128 +}
4129 +
4130 +static int set_option_int(char const *filename, int line, OPTION *option, char const *p)
4131 +{
4132 +       int *iptr;
4133 +
4134 +       if (p == NULL) {
4135 +               rc_log(LOG_ERR, "%s: line %d: bogus option value", filename, line);
4136 +               return -1;
4137 +       }
4138 +
4139 +       if ((iptr = malloc(sizeof(*iptr))) == NULL) {
4140 +               rc_log(LOG_CRIT, "read_config: out of memory");
4141 +               return -1;
4142 +       }
4143 +
4144 +       *iptr = atoi(p);
4145 +       option->val = (void *) iptr;
4146 +
4147 +       return 0;
4148 +}
4149 +
4150 +static int set_option_srv(char const *filename, int line, OPTION *option, char const *p)
4151 +{
4152 +       SERVER *serv;
4153 +       char *p_pointer;
4154 +       char *p_dupe;
4155 +       char *p_save;
4156 +       char *q;
4157 +       char *s;
4158 +       struct servent *svp;
4159 +
4160 +       p_dupe = strdup(p);
4161 +
4162 +       if (p_dupe == NULL) {
4163 +               rc_log(LOG_ERR, "%s: line %d: Invalid option or memory failure", filename, line);
4164 +               return -1;
4165 +       }
4166 +
4167 +       serv = (SERVER *) option->val;
4168 +       if (serv == NULL) {
4169 +               DEBUG(LOG_ERR, "option->val / server is NULL, allocating memory");
4170 +               serv = malloc(sizeof(*serv));
4171 +               if (serv == NULL) {
4172 +                       rc_log(LOG_CRIT, "read_config: out of memory");
4173 +                       free(p_dupe);
4174 +                       return -1;
4175 +               }
4176 +               memset(serv, 0, sizeof(*serv));
4177 +               serv->max = 0;
4178 +       }
4179 +
4180 +       p_pointer = strtok_r(p_dupe, ", \t", &p_save);
4181 +
4182 +       /* Check to see if we have 'servername:port' syntax */
4183 +       if ((q = strchr(p_pointer,':')) != NULL) {
4184 +               *q = '\0';
4185 +               q++;
4186 +
4187 +               /* Check to see if we have 'servername:port:secret' syntax */
4188 +               if((s = strchr(q,':')) != NULL) {
4189 +                       *s = '\0';
4190 +                       s++;
4191 +                       serv->secret[serv->max] = strdup(s);
4192 +                       if (serv->secret[serv->max] == NULL) {
4193 +                               rc_log(LOG_CRIT, "read_config: out of memory");
4194 +                               if (option->val == NULL) {
4195 +                                       free(p_dupe);
4196 +                                       free(serv);
4197 +                               }
4198 +                               return -1;
4199 +                       }
4200 +               }
4201 +       }
4202 +       if(q && strlen(q) > 0) {
4203 +               serv->port[serv->max] = atoi(q);
4204 +       } else {
4205 +               if (!strcmp(option->name,"authserver"))
4206 +                       if ((svp = getservbyname ("radius", "udp")) == NULL)
4207 +                               serv->port[serv->max] = PW_AUTH_UDP_PORT;
4208 +                       else
4209 +                               serv->port[serv->max] = ntohs ((unsigned int) svp->s_port);
4210 +               else if (!strcmp(option->name, "acctserver"))
4211 +                       if ((svp = getservbyname ("radacct", "udp")) == NULL)
4212 +                               serv->port[serv->max] = PW_ACCT_UDP_PORT;
4213 +                       else
4214 +                               serv->port[serv->max] = ntohs ((unsigned int) svp->s_port);
4215 +               else {
4216 +                       rc_log(LOG_ERR, "%s: line %d: no default port for %s", filename, line, option->name);
4217 +                       if (option->val == NULL) {
4218 +                               free(p_dupe);
4219 +                               free(serv);
4220 +                       }
4221 +                       return -1;
4222 +               }
4223 +       }
4224 +
4225 +       serv->name[serv->max] = strdup(p_pointer);
4226 +       if (serv->name[serv->max] == NULL) {
4227 +               rc_log(LOG_CRIT, "read_config: out of memory");
4228 +               if (option->val == NULL) {
4229 +                       free(p_dupe);
4230 +                       free(serv);
4231 +               }
4232 +               return -1;
4233 +       }
4234 +       free(p_dupe);
4235 +
4236 +       serv->deadtime_ends[serv->max] = -1;
4237 +       serv->max++;
4238 +
4239 +       if (option->val == NULL)
4240 +               option->val = (void *)serv;
4241 +
4242 +       return 0;
4243 +}
4244 +
4245 +static int set_option_auo(char const *filename, int line, OPTION *option, char const *p)
4246 +{
4247 +       int *iptr;
4248 +       char *p_dupe = NULL;
4249 +       char *p_pointer = NULL;
4250 +       char *p_save = NULL;
4251 +
4252 +       p_dupe = strdup(p);
4253 +
4254 +       if (p_dupe == NULL) {
4255 +               rc_log(LOG_WARNING, "%s: line %d: bogus option value", filename, line);
4256 +               return -1;
4257 +       }
4258 +
4259 +       if ((iptr = malloc(sizeof(iptr))) == NULL) {
4260 +                       rc_log(LOG_CRIT, "read_config: out of memory");
4261 +                       free(p_dupe);
4262 +                       return -1;
4263 +       }
4264 +
4265 +       *iptr = 0;
4266 +       /*if(strstr(p_dupe,", \t") != NULL) {*/
4267 +               p_pointer = strtok_r(p_dupe, ", \t", &p_save);
4268 +       /*}*/
4269 +
4270 +       if (!strncmp(p_pointer, "local", 5))
4271 +                       *iptr = AUTH_LOCAL_FST;
4272 +       else if (!strncmp(p_pointer, "radius", 6))
4273 +                       *iptr = AUTH_RADIUS_FST;
4274 +       else {
4275 +               rc_log(LOG_ERR,"%s: auth_order: unknown keyword: %s", filename, p);
4276 +               free(iptr);
4277 +               free(p_dupe);
4278 +               return -1;
4279 +       }
4280 +
4281 +       p_pointer = strtok_r(NULL, ", \t", &p_save);
4282 +
4283 +       if (p_pointer && (*p_pointer != '\0')) {
4284 +               if ((*iptr & AUTH_RADIUS_FST) && !strcmp(p_pointer, "local"))
4285 +                       *iptr = (*iptr) | AUTH_LOCAL_SND;
4286 +               else if ((*iptr & AUTH_LOCAL_FST) && !strcmp(p_pointer, "radius"))
4287 +                       *iptr = (*iptr) | AUTH_RADIUS_SND;
4288 +               else {
4289 +                       rc_log(LOG_ERR,"%s: auth_order: unknown or unexpected keyword: %s", filename, p);
4290 +                       free(iptr);
4291 +                       free(p_dupe);
4292 +                       return -1;
4293 +               }
4294 +       }
4295 +
4296 +       option->val = (void *) iptr;
4297 +
4298 +       free(p_dupe);
4299 +       return 0;
4300 +}
4301 +
4302 +
4303 +/* Function: rc_add_config
4304 + *
4305 + * Purpose: allow a config option to be added to rc_handle from inside a program
4306 + *
4307 + * Returns: 0 on success, -1 on failure
4308 + */
4309 +
4310 +int rc_add_config(rc_handle *rh, char const *option_name, char const *option_val, char const *source, int line)
4311 +{
4312 +       OPTION *option;
4313 +
4314 +       if ((option = find_option(rh, option_name, OT_ANY)) == NULL)
4315 +       {
4316 +               rc_log(LOG_ERR, "ERROR: unrecognized option: %s", option_name);
4317 +               return -1;
4318 +       }
4319 +
4320 +       if (option->status != ST_UNDEF)
4321 +       {
4322 +               rc_log(LOG_ERR, "ERROR: duplicate option: %s", option_name);
4323 +               return -1;
4324 +       }
4325 +
4326 +       switch (option->type) {
4327 +               case OT_STR:
4328 +                       if (set_option_str(source, line, option, option_val) < 0) {
4329 +                               return -1;
4330 +                       }
4331 +                       break;
4332 +               case OT_INT:
4333 +                       if (set_option_int(source, line, option, option_val) < 0) {
4334 +                               return -1;
4335 +                       }
4336 +                       break;
4337 +               case OT_SRV:
4338 +                       if (set_option_srv(source, line, option, option_val) < 0) {
4339 +                               return -1;
4340 +                       }
4341 +                       break;
4342 +               case OT_AUO:
4343 +                       if (set_option_auo(source, line, option, option_val) < 0) {
4344 +                               return -1;
4345 +                       }
4346 +                       break;
4347 +               default:
4348 +                       rc_log(LOG_CRIT, "rc_add_config: impossible case branch!");
4349 +                       abort();
4350 +       }
4351 +       return 0;
4352 +}
4353 +
4354 +/*
4355 + * Function: rc_config_init
4356 + *
4357 + * Purpose: initialize the configuration structure from an external program.  For use when not
4358 + * running a standalone client that reads from a config file.
4359 + *
4360 + * Returns: rc_handle on success, NULL on failure
4361 + */
4362 +
4363 +rc_handle *
4364 +rc_config_init(rc_handle *rh)
4365 +{
4366 +       int i;
4367 +       SERVER *authservers;
4368 +       SERVER *acctservers;
4369 +       OPTION *acct;
4370 +       OPTION *auth;
4371 +
4372 +        rh->config_options = malloc(sizeof(config_options_default));
4373 +        if (rh->config_options == NULL)
4374 +       {
4375 +                rc_log(LOG_CRIT, "rc_config_init: out of memory");
4376 +               rc_destroy(rh);
4377 +                return NULL;
4378 +        }
4379 +        memcpy(rh->config_options, &config_options_default, sizeof(config_options_default));
4380 +
4381 +       acct = find_option(rh, "acctserver", OT_ANY);
4382 +       auth = find_option(rh, "authserver", OT_ANY);
4383 +       authservers = malloc(sizeof(SERVER));
4384 +       acctservers = malloc(sizeof(SERVER));
4385 +
4386 +       if(authservers == NULL || acctservers == NULL)
4387 +       {
4388 +                rc_log(LOG_CRIT, "rc_config_init: error initializing server structs");
4389 +               rc_destroy(rh);
4390 +               if(authservers) free(authservers);
4391 +               if(acctservers) free(acctservers);
4392 +                return NULL;
4393 +       }
4394 +
4395 +
4396 +       authservers->max = 0;
4397 +       acctservers->max = 0;
4398 +
4399 +       for(i=0; i < SERVER_MAX; i++)
4400 +       {
4401 +               authservers->name[i] = NULL;
4402 +               authservers->secret[i] = NULL;
4403 +               acctservers->name[i] = NULL;
4404 +               acctservers->secret[i] = NULL;
4405 +       }
4406 +       acct->val = acctservers;
4407 +       auth->val = authservers;
4408 +       return rh;
4409 +}
4410 +
4411 +
4412 +/*
4413 + * Function: rc_read_config
4414 + *
4415 + * Purpose: read the global config file
4416 + *
4417 + * Returns: new rc_handle on success, NULL when failure
4418 + */
4419 +
4420 +rc_handle *
4421 +rc_read_config(char const *filename)
4422 +{
4423 +       FILE *configfd;
4424 +       char buffer[512], *p;
4425 +       OPTION *option;
4426 +       int line;
4427 +       size_t pos;
4428 +       rc_handle *rh;
4429 +
4430 +       srandom((unsigned int)(time(NULL)+getpid()));
4431 +
4432 +       rh = rc_new();
4433 +       if (rh == NULL)
4434 +               return NULL;
4435 +
4436 +        rh->config_options = malloc(sizeof(config_options_default));
4437 +        if (rh->config_options == NULL) {
4438 +                rc_log(LOG_CRIT, "rc_read_config: out of memory");
4439 +               rc_destroy(rh);
4440 +                return NULL;
4441 +        }
4442 +        memcpy(rh->config_options, &config_options_default, sizeof(config_options_default));
4443 +
4444 +       if ((configfd = fopen(filename,"r")) == NULL)
4445 +       {
4446 +               rc_log(LOG_ERR,"rc_read_config: can't open %s: %s", filename, strerror(errno));
4447 +               rc_destroy(rh);
4448 +               return NULL;
4449 +       }
4450 +
4451 +       line = 0;
4452 +       while ((fgets(buffer, sizeof(buffer), configfd) != NULL))
4453 +       {
4454 +               line++;
4455 +               p = buffer;
4456 +
4457 +               if ((*p == '\n') || (*p == '#') || (*p == '\0'))
4458 +                       continue;
4459 +
4460 +               p[strlen(p)-1] = '\0';
4461 +
4462 +
4463 +               if ((pos = strcspn(p, "\t ")) == 0) {
4464 +                       rc_log(LOG_ERR, "%s: line %d: bogus format: %s", filename, line, p);
4465 +                       fclose(configfd);
4466 +                       rc_destroy(rh);
4467 +                       return NULL;
4468 +               }
4469 +
4470 +               p[pos] = '\0';
4471 +
4472 +               if ((option = find_option(rh, p, OT_ANY)) == NULL) {
4473 +                       rc_log(LOG_ERR, "%s: line %d: unrecognized keyword: %s", filename, line, p);
4474 +                       fclose(configfd);
4475 +                       rc_destroy(rh);
4476 +                       return NULL;
4477 +               }
4478 +
4479 +               if (option->status != ST_UNDEF) {
4480 +                       rc_log(LOG_ERR, "%s: line %d: duplicate option line: %s", filename, line, p);
4481 +                       fclose(configfd);
4482 +                       rc_destroy(rh);
4483 +                       return NULL;
4484 +               }
4485 +
4486 +               p += pos+1;
4487 +               while (isspace(*p))
4488 +                       p++;
4489 +               pos = strlen(p) - 1;
4490 +               while(pos != 0 && isspace(p[pos]))
4491 +                       pos--;
4492 +               p[pos + 1] = '\0';
4493 +
4494 +               switch (option->type) {
4495 +                       case OT_STR:
4496 +                               if (set_option_str(filename, line, option, p) < 0) {
4497 +                                       fclose(configfd);
4498 +                                       rc_destroy(rh);
4499 +                                       return NULL;
4500 +                               }
4501 +                               break;
4502 +                       case OT_INT:
4503 +                               if (set_option_int(filename, line, option, p) < 0) {
4504 +                                       fclose(configfd);
4505 +                                       rc_destroy(rh);
4506 +                                       return NULL;
4507 +                               }
4508 +                               break;
4509 +                       case OT_SRV:
4510 +                               if (set_option_srv(filename, line, option, p) < 0) {
4511 +                                       fclose(configfd);
4512 +                                       rc_destroy(rh);
4513 +                                       return NULL;
4514 +                               }
4515 +                               break;
4516 +                       case OT_AUO:
4517 +                               if (set_option_auo(filename, line, option, p) < 0) {
4518 +                                       fclose(configfd);
4519 +                                       rc_destroy(rh);
4520 +                                       return NULL;
4521 +                               }
4522 +                               break;
4523 +                       default:
4524 +                               rc_log(LOG_CRIT, "rc_read_config: impossible case branch!");
4525 +                               abort();
4526 +               }
4527 +       }
4528 +       fclose(configfd);
4529 +
4530 +       if (test_config(rh, filename) == -1) {
4531 +               rc_destroy(rh);
4532 +               return NULL;
4533 +       }
4534 +       return rh;
4535 +}
4536 +
4537 +/*
4538 + * Function: rc_conf_str, rc_conf_int, rc_conf_src
4539 + *
4540 + * Purpose: get the value of a config option
4541 + *
4542 + * Returns: config option value
4543 + */
4544 +
4545 +char *rc_conf_str(rc_handle const *rh, char const *optname)
4546 +{
4547 +       OPTION *option;
4548 +
4549 +       option = find_option(rh, optname, OT_STR);
4550 +
4551 +       if (option != NULL) {
4552 +               return (char *)option->val;
4553 +       } else {
4554 +               rc_log(LOG_CRIT, "rc_conf_str: unkown config option requested: %s", optname);
4555 +               abort();
4556 +               return NULL;
4557 +       }
4558 +}
4559 +
4560 +int rc_conf_int(rc_handle const *rh, char const *optname)
4561 +{
4562 +       OPTION *option;
4563 +
4564 +       option = find_option(rh, optname, OT_INT|OT_AUO);
4565 +
4566 +       if (option != NULL) {
4567 +               if (option->val) {
4568 +                       return *((int *)option->val);
4569 +               } else {
4570 +                       rc_log(LOG_ERR, "rc_conf_int: config option %s was not set", optname);
4571 +                       return 0;
4572 +               }
4573 +       } else {
4574 +               rc_log(LOG_CRIT, "rc_conf_int: unkown config option requested: %s", optname);
4575 +               abort();
4576 +               return 0;
4577 +       }
4578 +}
4579 +
4580 +SERVER *rc_conf_srv(rc_handle const *rh, char const *optname)
4581 +{
4582 +       OPTION *option;
4583 +
4584 +       option = find_option(rh, optname, OT_SRV);
4585 +
4586 +       if (option != NULL) {
4587 +               return (SERVER *)option->val;
4588 +       } else {
4589 +               rc_log(LOG_CRIT, "rc_conf_srv: unkown config option requested: %s", optname);
4590 +               abort();
4591 +               return NULL;
4592 +       }
4593 +}
4594 +
4595 +/*
4596 + * Function: test_config
4597 + *
4598 + * Purpose: test the configuration the user supplied
4599 + *
4600 + * Returns: 0 on success, -1 when failure
4601 + */
4602 +
4603 +int test_config(rc_handle const *rh, char const *filename)
4604 +{
4605 +#if 0
4606 +       struct stat st;
4607 +       char        *file;
4608 +#endif
4609 +
4610 +       if (!(rc_conf_srv(rh, "authserver")->max))
4611 +       {
4612 +               rc_log(LOG_ERR,"%s: no authserver specified", filename);
4613 +               return -1;
4614 +       }
4615 +       if (!(rc_conf_srv(rh, "acctserver")->max))
4616 +       {
4617 +               rc_log(LOG_ERR,"%s: no acctserver specified", filename);
4618 +               return -1;
4619 +       }
4620 +       if (!rc_conf_str(rh, "servers"))
4621 +       {
4622 +               rc_log(LOG_ERR,"%s: no servers file specified", filename);
4623 +               return -1;
4624 +       }
4625 +       if (!rc_conf_str(rh, "dictionary"))
4626 +       {
4627 +               rc_log(LOG_ERR,"%s: no dictionary specified", filename);
4628 +               return -1;
4629 +       }
4630 +
4631 +       if (rc_conf_int(rh, "radius_timeout") <= 0)
4632 +       {
4633 +               rc_log(LOG_ERR,"%s: radius_timeout <= 0 is illegal", filename);
4634 +               return -1;
4635 +       }
4636 +       if (rc_conf_int(rh, "radius_retries") <= 0)
4637 +       {
4638 +               rc_log(LOG_ERR,"%s: radius_retries <= 0 is illegal", filename);
4639 +               return -1;
4640 +       }
4641 +       if (rc_conf_int(rh, "radius_deadtime") < 0)
4642 +       {
4643 +               rc_log(LOG_ERR,"%s: radius_deadtime is illegal", filename);
4644 +               return -1;
4645 +       }
4646 +#if 0
4647 +       file = rc_conf_str(rh, "login_local");
4648 +       if (stat(file, &st) == 0)
4649 +       {
4650 +               if (!S_ISREG(st.st_mode)) {
4651 +                       rc_log(LOG_ERR,"%s: not a regular file: %s", filename, file);
4652 +                       return -1;
4653 +               }
4654 +       } else {
4655 +               rc_log(LOG_ERR,"%s: file not found: %s", filename, file);
4656 +               return -1;
4657 +       }
4658 +       file = rc_conf_str(rh, "login_radius");
4659 +       if (stat(file, &st) == 0)
4660 +       {
4661 +               if (!S_ISREG(st.st_mode)) {
4662 +                       rc_log(LOG_ERR,"%s: not a regular file: %s", filename, file);
4663 +                       return -1;
4664 +               }
4665 +       } else {
4666 +               rc_log(LOG_ERR,"%s: file not found: %s", filename, file);
4667 +               return -1;
4668 +       }
4669 +#endif
4670 +
4671 +       if (rc_conf_int(rh, "login_tries") <= 0)
4672 +       {
4673 +               rc_log(LOG_ERR,"%s: login_tries <= 0 is illegal", filename);
4674 +               return -1;
4675 +       }
4676 +       if (rc_conf_str(rh, "seqfile") == NULL)
4677 +       {
4678 +               rc_log(LOG_ERR,"%s: seqfile not specified", filename);
4679 +               return -1;
4680 +       }
4681 +       if (rc_conf_int(rh, "login_timeout") <= 0)
4682 +       {
4683 +               rc_log(LOG_ERR,"%s: login_timeout <= 0 is illegal", filename);
4684 +               return -1;
4685 +       }
4686 +       if (rc_conf_str(rh, "mapfile") == NULL)
4687 +       {
4688 +               rc_log(LOG_ERR,"%s: mapfile not specified", filename);
4689 +               return -1;
4690 +       }
4691 +       if (rc_conf_str(rh, "nologin") == NULL)
4692 +       {
4693 +               rc_log(LOG_ERR,"%s: nologin not specified", filename);
4694 +               return -1;
4695 +       }
4696 +
4697 +       return 0;
4698 +}
4699 +
4700 +/*
4701 + * Function: rc_find_match
4702 + *
4703 + * Purpose: see if ip_addr is one of the ip addresses of hostname
4704 + *
4705 + * Returns: 0 on success, -1 when failure
4706 + *
4707 + */
4708 +
4709 +static int find_match (uint32_t *ip_addr, char const *hostname)
4710 +{
4711 +
4712 +       uint32_t           addr;
4713 +       char          **paddr;
4714 +       struct hostent *hp;
4715 +
4716 +       if (rc_good_ipaddr (hostname) == 0)
4717 +       {
4718 +               if (*ip_addr == ntohl(inet_addr (hostname)))
4719 +               {
4720 +                       return 0;
4721 +               }
4722 +               return -1;
4723 +       }
4724 +
4725 +       if ((hp = rc_gethostbyname(hostname)) == NULL)
4726 +       {
4727 +               return -1;
4728 +       }
4729 +
4730 +       for (paddr = hp->h_addr_list; *paddr; paddr++)
4731 +       {
4732 +               addr = ** (uint32_t **) paddr;
4733 +               if (ntohl(addr) == *ip_addr)
4734 +               {
4735 +                       return 0;
4736 +               }
4737 +       }
4738 +       return -1;
4739 +}
4740 +
4741 +/*
4742 + * Function: rc_ipaddr_local
4743 + *
4744 + * Purpose: checks if provided address is local address
4745 + *
4746 + * Returns: 0 if local, 1 if not local, -1 on failure
4747 + *
4748 + */
4749 +
4750 +static int
4751 +rc_ipaddr_local(uint32_t ip_addr)
4752 +{
4753 +       int temp_sock, res, serrno;
4754 +       struct sockaddr_in sin;
4755 +
4756 +       temp_sock = socket(AF_INET, SOCK_DGRAM, 0);
4757 +       if (temp_sock == -1)
4758 +               return -1;
4759 +       memset(&sin, '\0', sizeof(sin));
4760 +       sin.sin_family = AF_INET;
4761 +       sin.sin_addr.s_addr = htonl(ip_addr);
4762 +       sin.sin_port = htons(0);
4763 +       res = bind(temp_sock, (struct sockaddr *)&sin, sizeof(sin));
4764 +       serrno = errno;
4765 +       close(temp_sock);
4766 +       if (res == 0)
4767 +               return 0;
4768 +       if (serrno == EADDRNOTAVAIL)
4769 +               return 1;
4770 +       return -1;
4771 +}
4772 +
4773 +/*
4774 + * Function: rc_is_myname
4775 + *
4776 + * Purpose: check if provided name refers to ourselves
4777 + *
4778 + * Returns: 0 if yes, 1 if no and -1 on failure
4779 + *
4780 + */
4781 +
4782 +static int
4783 +rc_is_myname(char const *hostname)
4784 +{
4785 +       uint32_t        addr;
4786 +       char    **paddr;
4787 +       struct  hostent *hp;
4788 +       int     res;
4789 +
4790 +       if (rc_good_ipaddr(hostname) == 0)
4791 +               return rc_ipaddr_local(ntohl(inet_addr(hostname)));
4792 +
4793 +       if ((hp = rc_gethostbyname(hostname)) == NULL)
4794 +               return -1;
4795 +       for (paddr = hp->h_addr_list; *paddr; paddr++) {
4796 +               addr = **(uint32_t **)paddr;
4797 +               res = rc_ipaddr_local(ntohl(addr));
4798 +               if (res == 0 || res == -1)
4799 +                       return res;
4800 +       }
4801 +       return 1;
4802 +}
4803 +
4804 +/*
4805 + * Function: rc_find_server
4806 + *
4807 + * Purpose: locate a server in the rh config or if not found, check for a servers file
4808 + *
4809 + * Returns: 0 on success, -1 on failure
4810 + *
4811 + */
4812 +
4813 +int rc_find_server (rc_handle const *rh, char const *server_name, uint32_t *ip_addr, char *secret)
4814 +{
4815 +       int             i;
4816 +       size_t          len;
4817 +       int             result = 0;
4818 +       FILE           *clientfd;
4819 +       char           *h;
4820 +       char           *s;
4821 +       char            buffer[128];
4822 +       char            hostnm[AUTH_ID_LEN + 1];
4823 +       char           *buffer_save;
4824 +       char           *hostnm_save;
4825 +       SERVER         *authservers;
4826 +       SERVER         *acctservers;
4827 +
4828 +       /* Lookup the IP address of the radius server */
4829 +       if ((*ip_addr = rc_get_ipaddr (server_name)) == (uint32_t) 0)
4830 +               return -1;
4831 +
4832 +       /* Check to see if the server secret is defined in the rh config */
4833 +       if( (authservers = rc_conf_srv(rh, "authserver")) != NULL )
4834 +       {
4835 +               for( i = 0; i < authservers->max; i++ )
4836 +               {
4837 +                       if( (strncmp(server_name, authservers->name[i], strlen(server_name)) == 0) &&
4838 +                           (authservers->secret[i] != NULL) )
4839 +                       {
4840 +                               memset (secret, '\0', MAX_SECRET_LENGTH);
4841 +                               len = strlen (authservers->secret[i]);
4842 +                               if (len > MAX_SECRET_LENGTH)
4843 +                               {
4844 +                                       len = MAX_SECRET_LENGTH;
4845 +                               }
4846 +                               strncpy (secret, authservers->secret[i], (size_t) len);
4847 +                               secret[MAX_SECRET_LENGTH] = '\0';
4848 +                               return 0;
4849 +                       }
4850 +               }
4851 +       }
4852 +
4853 +       if( (acctservers = rc_conf_srv(rh, "acctserver")) != NULL )
4854 +       {
4855 +               for( i = 0; i < acctservers->max; i++ )
4856 +               {
4857 +                       if( (strncmp(server_name, acctservers->name[i], strlen(server_name)) == 0) &&
4858 +                           (acctservers->secret[i] != NULL) )
4859 +                       {
4860 +                               memset (secret, '\0', MAX_SECRET_LENGTH);
4861 +                               len = strlen (acctservers->secret[i]);
4862 +                               if (len > MAX_SECRET_LENGTH)
4863 +                               {
4864 +                                       len = MAX_SECRET_LENGTH;
4865 +                               }
4866 +                               strncpy (secret, acctservers->secret[i], (size_t) len);
4867 +                               secret[MAX_SECRET_LENGTH] = '\0';
4868 +                               return 0;
4869 +                       }
4870 +               }
4871 +       }
4872 +
4873 +       /* We didn't find it in the rh_config or the servername is too long so look for a
4874 +        * servers file to define the secret(s)
4875 +        */
4876 +
4877 +       if ((clientfd = fopen (rc_conf_str(rh, "servers"), "r")) == NULL)
4878 +       {
4879 +               rc_log(LOG_ERR, "rc_find_server: couldn't open file: %s: %s", strerror(errno), rc_conf_str(rh, "servers"));
4880 +               return -1;
4881 +       }
4882 +
4883 +       while (fgets (buffer, sizeof (buffer), clientfd) != NULL)
4884 +       {
4885 +               if (*buffer == '#')
4886 +                       continue;
4887 +
4888 +               if ((h = strtok_r(buffer, " \t\n", &buffer_save)) == NULL) /* first hostname */
4889 +                       continue;
4890 +
4891 +               memset (hostnm, '\0', AUTH_ID_LEN);
4892 +               len = strlen (h);
4893 +               if (len > AUTH_ID_LEN)
4894 +               {
4895 +                       len = AUTH_ID_LEN;
4896 +               }
4897 +               strncpy (hostnm, h, (size_t) len);
4898 +               hostnm[AUTH_ID_LEN] = '\0';
4899 +
4900 +               if ((s = strtok_r (NULL, " \t\n", &buffer_save)) == NULL) /* and secret field */
4901 +                       continue;
4902 +
4903 +               memset (secret, '\0', MAX_SECRET_LENGTH);
4904 +               len = strlen (s);
4905 +               if (len > MAX_SECRET_LENGTH)
4906 +               {
4907 +                       len = MAX_SECRET_LENGTH;
4908 +               }
4909 +               strncpy (secret, s, (size_t) len);
4910 +               secret[MAX_SECRET_LENGTH] = '\0';
4911 +
4912 +               if (!strchr (hostnm, '/')) /* If single name form */
4913 +               {
4914 +                       if (find_match (ip_addr, hostnm) == 0)
4915 +                       {
4916 +                               result++;
4917 +                               break;
4918 +                       }
4919 +               }
4920 +               else /* <name1>/<name2> "paired" form */
4921 +               {
4922 +                       strtok_r(hostnm, "/", &hostnm_save);
4923 +                       if (rc_is_myname(hostnm) == 0)
4924 +                       {            /* If we're the 1st name, target is 2nd */
4925 +                               if (find_match (ip_addr, hostnm_save) == 0)
4926 +                               {
4927 +                                       result++;
4928 +                                       break;
4929 +                               }
4930 +                       }
4931 +                       else    /* If we were 2nd name, target is 1st name */
4932 +                       {
4933 +                               if (find_match (ip_addr, hostnm) == 0)
4934 +                               {
4935 +                                       result++;
4936 +                                       break;
4937 +                               }
4938 +                       }
4939 +               }
4940 +       }
4941 +       fclose (clientfd);
4942 +       if (result == 0)
4943 +       {
4944 +               memset (buffer, '\0', sizeof (buffer));
4945 +               memset (secret, '\0', MAX_SECRET_LENGTH);
4946 +               rc_log(LOG_ERR, "rc_find_server: couldn't find RADIUS server %s in %s",
4947 +                        server_name, rc_conf_str(rh, "servers"));
4948 +               return -1;
4949 +       }
4950 +       return 0;
4951 +}
4952 +
4953 +/*
4954 + * Function: rc_config_free
4955 + *
4956 + * Purpose: Free allocated config values
4957 + *
4958 + * Arguments: Radius Client handle
4959 + */
4960 +
4961 +void
4962 +rc_config_free(rc_handle *rh)
4963 +{
4964 +       int i, j;
4965 +       SERVER *serv;
4966 +
4967 +       if (rh->config_options == NULL)
4968 +               return;
4969 +
4970 +       for (i = 0; i < NUM_OPTIONS; i++) {
4971 +               if (rh->config_options[i].val == NULL)
4972 +                       continue;
4973 +               if (rh->config_options[i].type == OT_SRV) {
4974 +                       serv = (SERVER *)rh->config_options[i].val;
4975 +                       for (j = 0; j < serv->max; j++){
4976 +                               free(serv->name[j]);
4977 +                               if(serv->secret[j]) free(serv->secret[j]);
4978 +                       }
4979 +                       free(serv);
4980 +               } else {
4981 +                       free(rh->config_options[i].val);
4982 +               }
4983 +       }
4984 +       free(rh->config_options);
4985 +       rh->config_options = NULL;
4986 +}
4987 diff --git a/src/plugins/vbng/lib/dict.c b/src/plugins/vbng/lib/dict.c
4988 new file mode 100644
4989 index 0000000..84dbba0
4990 --- /dev/null
4991 +++ b/src/plugins/vbng/lib/dict.c
4992 @@ -0,0 +1,519 @@
4993 +/*
4994 + * $Id: dict.c,v 1.10 2007/07/11 17:29:29 cparker Exp $
4995 + *
4996 + * Copyright (C) 1995,1996,1997 Lars Fenneberg
4997 + *
4998 + * Copyright 1992 Livingston Enterprises, Inc.
4999 + *
5000 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
5001 + * and Merit Network, Inc. All Rights Reserved
5002 + *
5003 + * See the file COPYRIGHT for the respective terms and conditions.
5004 + * If the file is missing contact me at lf@elemental.net
5005 + * and I'll send you a copy.
5006 + *
5007 + */
5008 +
5009 +#include <config.h>
5010 +#include <includes.h>
5011 +#include <freeradius-client.h>
5012 +
5013 +/*
5014 + * Function: rc_read_dictionary
5015 + *
5016 + * Purpose: Initialize the dictionary.  Read all ATTRIBUTES into
5017 + *         the dictionary_attributes list.  Read all VALUES into
5018 + *         the dictionary_values list.
5019 + *
5020 + */
5021 +
5022 +int rc_read_dictionary (rc_handle *rh, char const *filename)
5023 +{
5024 +       FILE           *dictfd;
5025 +       char            dummystr[AUTH_ID_LEN];
5026 +       char            namestr[AUTH_ID_LEN];
5027 +       char            valstr[AUTH_ID_LEN];
5028 +       char            attrstr[AUTH_ID_LEN];
5029 +       char            typestr[AUTH_ID_LEN];
5030 +       char            optstr[AUTH_ID_LEN];
5031 +       char            *cp, *ifilename;
5032 +       int             line_no;
5033 +       DICT_ATTR      *attr;
5034 +       DICT_VALUE     *dval;
5035 +       DICT_VENDOR    *dvend;
5036 +       char            buffer[256];
5037 +       int             value;
5038 +       int             type;
5039 +       unsigned attr_vendorspec = 0;
5040 +
5041 +       if ((dictfd = fopen (filename, "r")) == NULL)
5042 +       {
5043 +               rc_log(LOG_ERR, "rc_read_dictionary: couldn't open dictionary %s: %s",
5044 +                               filename, strerror(errno));
5045 +               return -1;
5046 +       }
5047 +
5048 +       line_no = 0;
5049 +       while (fgets (buffer, sizeof (buffer), dictfd) != NULL)
5050 +       {
5051 +               line_no++;
5052 +
5053 +               /* Skip empty space */
5054 +               if (*buffer == '#' || *buffer == '\0' || *buffer == '\n' || \
5055 +                   *buffer == '\r')
5056 +               {
5057 +                       continue;
5058 +               }
5059 +
5060 +               /* Strip out comments */
5061 +               cp = strchr(buffer, '#');
5062 +               if (cp != NULL)
5063 +               {
5064 +                       *cp = '\0';
5065 +               }
5066 +
5067 +               if (strncmp (buffer, "ATTRIBUTE", 9) == 0)
5068 +               {
5069 +                       optstr[0] = '\0';
5070 +                       /* Read the ATTRIBUTE line */
5071 +                       if (sscanf (buffer, "%63s%63s%63s%63s%63s", dummystr, namestr,
5072 +                                   valstr, typestr, optstr) < 4)
5073 +                       {
5074 +                               rc_log(LOG_ERR, "rc_read_dictionary: invalid attribute on line %d of dictionary %s",
5075 +                                        line_no, filename);
5076 +                               fclose(dictfd);
5077 +                               return -1;
5078 +                       }
5079 +
5080 +                       /*
5081 +                        * Validate all entries
5082 +                        */
5083 +                       if (strlen (namestr) > NAME_LENGTH)
5084 +                       {
5085 +                               rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
5086 +                                        line_no, filename);
5087 +                               fclose(dictfd);
5088 +                               return -1;
5089 +                       }
5090 +
5091 +                       if (!isdigit (*valstr))
5092 +                       {
5093 +                               rc_log(LOG_ERR,
5094 +                                "rc_read_dictionary: invalid value on line %d of dictionary %s",
5095 +                                        line_no, filename);
5096 +                               fclose(dictfd);
5097 +                               return -1;
5098 +                       }
5099 +                       value = atoi (valstr);
5100 +
5101 +                       if (strcmp (typestr, "string") == 0)
5102 +                       {
5103 +                               type = PW_TYPE_STRING;
5104 +                       }
5105 +                       else if (strcmp (typestr, "integer") == 0)
5106 +                       {
5107 +                               type = PW_TYPE_INTEGER;
5108 +                       }
5109 +                       else if (strcmp (typestr, "ipaddr") == 0)
5110 +                       {
5111 +                               type = PW_TYPE_IPADDR;
5112 +                       }
5113 +                       else if (strcmp (typestr, "ipv6addr") == 0)
5114 +                       {
5115 +                               type = PW_TYPE_IPV6ADDR;
5116 +                       }
5117 +                       else if (strcmp (typestr, "ipv6prefix") == 0)
5118 +                       {
5119 +                               type = PW_TYPE_IPV6PREFIX;
5120 +                       }
5121 +                       else if (strcmp (typestr, "date") == 0)
5122 +                       {
5123 +                               type = PW_TYPE_DATE;
5124 +                       }
5125 +                       else
5126 +                       {
5127 +                               rc_log(LOG_ERR,
5128 +                                 "rc_read_dictionary: invalid type on line %d of dictionary %s",
5129 +                                        line_no, filename);
5130 +                               fclose(dictfd);
5131 +                               return -1;
5132 +                       }
5133 +
5134 +                       dvend = NULL;
5135 +                       if (optstr[0] != '\0') {
5136 +                               char *cp1;
5137 +                               for (cp1 = optstr; cp1 != NULL; cp1 = cp) {
5138 +                                       cp = strchr(cp1, ',');
5139 +                                       if (cp != NULL) {
5140 +                                               *cp = '\0';
5141 +                                               cp++;
5142 +                                       }
5143 +                                       if (strncmp(cp1, "vendor=", 7) == 0)
5144 +                                               cp1 += 7;
5145 +                                       dvend = rc_dict_findvend(rh, cp1);
5146 +                                       if (dvend == NULL) {
5147 +                                               rc_log(LOG_ERR,
5148 +                                                "rc_read_dictionary: unknown Vendor-Id %s on line %d of dictionary %s",
5149 +                                                        cp1, line_no, filename);
5150 +                                               fclose(dictfd);
5151 +                                               return -1;
5152 +                                       }
5153 +                               }
5154 +                       }
5155 +
5156 +                       /* Create a new attribute for the list */
5157 +                       if ((attr = malloc (sizeof (DICT_ATTR))) == NULL)
5158 +                       {
5159 +                               rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
5160 +                               fclose(dictfd);
5161 +                               return -1;
5162 +                       }
5163 +                       strcpy (attr->name, namestr);
5164 +                       attr->value = value | (attr_vendorspec << 16);
5165 +                       attr->type = type;
5166 +
5167 +                       if (dvend != NULL) {
5168 +                               attr->value = value | (dvend->vendorpec << 16);
5169 +                       } else {
5170 +                               attr->value = value | (attr_vendorspec << 16);
5171 +                       }
5172 +
5173 +                       /* Insert it into the list */
5174 +                       attr->next = rh->dictionary_attributes;
5175 +                       rh->dictionary_attributes = attr;
5176 +               }
5177 +               else if (strncmp (buffer, "VALUE", 5) == 0)
5178 +               {
5179 +                       /* Read the VALUE line */
5180 +                       if (sscanf (buffer, "%63s%63s%63s%63s", dummystr, attrstr,
5181 +                                   namestr, valstr) != 4)
5182 +                       {
5183 +                               rc_log(LOG_ERR,
5184 +                          "rc_read_dictionary: invalid value entry on line %d of dictionary %s",
5185 +                                        line_no, filename);
5186 +                               fclose(dictfd);
5187 +                               return -1;
5188 +                       }
5189 +
5190 +                       /*
5191 +                        * Validate all entries
5192 +                        */
5193 +                       if (strlen (attrstr) > NAME_LENGTH)
5194 +                       {
5195 +                               rc_log(LOG_ERR,
5196 +                     "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
5197 +                                        line_no, filename);
5198 +                               fclose(dictfd);
5199 +                               return -1;
5200 +                       }
5201 +
5202 +                       if (strlen (namestr) > NAME_LENGTH)
5203 +                       {
5204 +                               rc_log(LOG_ERR,
5205 +                          "rc_read_dictionary: invalid name length on line %d of dictionary %s",
5206 +                                        line_no, filename);
5207 +                               fclose(dictfd);
5208 +                               return -1;
5209 +                       }
5210 +
5211 +                       if (!isdigit (*valstr))
5212 +                       {
5213 +                               rc_log(LOG_ERR,
5214 +                                "rc_read_dictionary: invalid value on line %d of dictionary %s",
5215 +                                        line_no, filename);
5216 +                               fclose(dictfd);
5217 +                               return -1;
5218 +                       }
5219 +                       value = atoi (valstr);
5220 +
5221 +                       /* Create a new VALUE entry for the list */
5222 +                       if ((dval = malloc (sizeof (DICT_VALUE))) == NULL)
5223 +                       {
5224 +                               rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
5225 +                               fclose(dictfd);
5226 +                               return -1;
5227 +                       }
5228 +                       strcpy (dval->attrname, attrstr);
5229 +                       strcpy (dval->name, namestr);
5230 +                       dval->value = value;
5231 +
5232 +                       /* Insert it into the list */
5233 +                       dval->next = rh->dictionary_values;
5234 +                       rh->dictionary_values = dval;
5235 +               }
5236 +                else if (strncmp (buffer, "$INCLUDE", 8) == 0)
5237 +                {
5238 +                       /* Read the $INCLUDE line */
5239 +                       if (sscanf (buffer, "%63s%63s", dummystr, namestr) != 2)
5240 +                       {
5241 +                               rc_log(LOG_ERR,
5242 +                                "rc_read_dictionary: invalid include entry on line %d of dictionary %s",
5243 +                                        line_no, filename);
5244 +                               fclose(dictfd);
5245 +                               return -1;
5246 +                       }
5247 +                       ifilename = namestr;
5248 +                       /* Append directory if necessary */
5249 +                       if (namestr[0] != '/') {
5250 +                               cp = strrchr(filename, '/');
5251 +                               if (cp != NULL) {
5252 +                                       ifilename = alloca(AUTH_ID_LEN);
5253 +                                       *cp = '\0';
5254 +                                       snprintf(ifilename, AUTH_ID_LEN, "%s/%s", filename, namestr);
5255 +                                       *cp = '/';
5256 +                               }
5257 +                       }
5258 +                       if (rc_read_dictionary(rh, ifilename) < 0)
5259 +                       {
5260 +                               fclose(dictfd);
5261 +                               return -1;
5262 +                       }
5263 +               }
5264 +               else if (strncmp (buffer, "END-VENDOR", 10) == 0)
5265 +               {
5266 +                       attr_vendorspec = 0;
5267 +               }
5268 +               else if (strncmp (buffer, "BEGIN-VENDOR", 12) == 0)
5269 +               {
5270 +                       DICT_VENDOR *v;
5271 +                       /* Read the vendor name */
5272 +                       if (sscanf (buffer+12, "%63s", dummystr) != 1)
5273 +                       {
5274 +                               rc_log(LOG_ERR,
5275 +                                "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
5276 +                                        line_no, filename);
5277 +                               fclose(dictfd);
5278 +                               return -1;
5279 +                       }
5280 +
5281 +                       v = rc_dict_findvend(rh, dummystr);
5282 +                       if (v == NULL) {
5283 +                               rc_log(LOG_ERR,
5284 +                                "rc_read_dictionary: unknown Vendor %s on line %d of dictionary %s",
5285 +                                        dummystr, line_no, filename);
5286 +                               fclose(dictfd);
5287 +                               return -1;
5288 +                       }
5289 +
5290 +                       attr_vendorspec = v->vendorpec;
5291 +               }
5292 +               else if (strncmp (buffer, "VENDOR", 6) == 0)
5293 +               {
5294 +                       /* Read the VALUE line */
5295 +                       if (sscanf (buffer, "%63s%63s%63s", dummystr, attrstr, valstr) != 3)
5296 +                       {
5297 +                               rc_log(LOG_ERR,
5298 +                                "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
5299 +                                        line_no, filename);
5300 +                               fclose(dictfd);
5301 +                               return -1;
5302 +                       }
5303 +
5304 +                       /* Validate all entries */
5305 +                       if (strlen (attrstr) > NAME_LENGTH)
5306 +                       {
5307 +                               rc_log(LOG_ERR,
5308 +                                "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
5309 +                                        line_no, filename);
5310 +                               fclose(dictfd);
5311 +                               return -1;
5312 +                       }
5313 +
5314 +                       if (!isdigit (*valstr))
5315 +                       {
5316 +                               rc_log(LOG_ERR,
5317 +                                "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
5318 +                                        line_no, filename);
5319 +                               fclose(dictfd);
5320 +                               return -1;
5321 +                       }
5322 +                       value = atoi (valstr);
5323 +
5324 +                       /* Create a new VENDOR entry for the list */
5325 +                       dvend = malloc(sizeof(DICT_VENDOR));
5326 +                       if (dvend == NULL)
5327 +                       {
5328 +                               rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
5329 +                               fclose(dictfd);
5330 +                               return -1;
5331 +                       }
5332 +                       strcpy (dvend->vendorname, attrstr);
5333 +                       dvend->vendorpec = value;
5334 +
5335 +                       /* Insert it into the list */
5336 +                       dvend->next = rh->dictionary_vendors;
5337 +                       rh->dictionary_vendors = dvend;
5338 +                }
5339 +       }
5340 +       fclose (dictfd);
5341 +       return 0;
5342 +}
5343 +
5344 +/*
5345 + * Function: rc_dict_getattr
5346 + *
5347 + * Purpose: Return the full attribute structure based on the
5348 + *         attribute id number.
5349 + *
5350 + */
5351 +
5352 +DICT_ATTR *rc_dict_getattr (rc_handle const *rh, int attribute)
5353 +{
5354 +       DICT_ATTR      *attr;
5355 +
5356 +       attr = rh->dictionary_attributes;
5357 +       while (attr != NULL)
5358 +       {
5359 +               if (attr->value == attribute)
5360 +               {
5361 +                       return attr;
5362 +               }
5363 +               attr = attr->next;
5364 +       }
5365 +       return NULL;
5366 +}
5367 +
5368 +/*
5369 + * Function: rc_dict_findattr
5370 + *
5371 + * Purpose: Return the full attribute structure based on the
5372 + *         attribute name.
5373 + *
5374 + */
5375 +
5376 +DICT_ATTR *rc_dict_findattr (rc_handle const *rh, char const *attrname)
5377 +{
5378 +       DICT_ATTR      *attr;
5379 +
5380 +       attr = rh->dictionary_attributes;
5381 +       while (attr != NULL)
5382 +       {
5383 +               if (strcasecmp (attr->name, attrname) == 0)
5384 +               {
5385 +                       return attr;
5386 +               }
5387 +               attr = attr->next;
5388 +       }
5389 +       return NULL;
5390 +}
5391 +
5392 +
5393 +/*
5394 + * Function: rc_dict_findval
5395 + *
5396 + * Purpose: Return the full value structure based on the
5397 + *         value name.
5398 + *
5399 + */
5400 +
5401 +DICT_VALUE *rc_dict_findval (rc_handle const *rh, char const *valname)
5402 +{
5403 +       DICT_VALUE     *val;
5404 +
5405 +       val = rh->dictionary_values;
5406 +       while (val != NULL)
5407 +       {
5408 +               if (strcasecmp (val->name, valname) == 0)
5409 +               {
5410 +                       return val;
5411 +               }
5412 +               val = val->next;
5413 +       }
5414 +       return NULL;
5415 +}
5416 +
5417 +/*
5418 + * Function: rc_dict_findvend
5419 + *
5420 + * Purpose: Return the full vendor structure based on the
5421 + *          vendor name.
5422 + *
5423 + */
5424 +
5425 +DICT_VENDOR *
5426 +rc_dict_findvend(rc_handle const *rh, char const *vendorname)
5427 +{
5428 +       DICT_VENDOR     *vend;
5429 +
5430 +       for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
5431 +               if (strcasecmp(vend->vendorname, vendorname) == 0)
5432 +                       return vend;
5433 +       return NULL;
5434 +}
5435 +
5436 +/*
5437 + * Function: rc_dict_getvend
5438 + *
5439 + * Purpose: Return the full vendor structure based on the
5440 + *          vendor id number.
5441 + *
5442 + */
5443 +
5444 +DICT_VENDOR *
5445 +rc_dict_getvend (rc_handle const *rh, int vendorpec)
5446 +{
5447 +        DICT_VENDOR      *vend;
5448 +
5449 +       for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
5450 +               if (vend->vendorpec == vendorpec)
5451 +                       return vend;
5452 +       return NULL;
5453 +}
5454 +
5455 +/*
5456 + * Function: dict_getval
5457 + *
5458 + * Purpose: Return the full value structure based on the
5459 + *          actual value and the associated attribute name.
5460 + *
5461 + */
5462 +
5463 +DICT_VALUE *
5464 +rc_dict_getval (rc_handle const *rh, uint32_t value, char const *attrname)
5465 +{
5466 +       DICT_VALUE     *val;
5467 +
5468 +       val = rh->dictionary_values;
5469 +       while (val != NULL)
5470 +       {
5471 +               if (strcmp (val->attrname, attrname) == 0 &&
5472 +                               val->value == value)
5473 +               {
5474 +                       return val;
5475 +               }
5476 +               val = val->next;
5477 +       }
5478 +       return NULL;
5479 +}
5480 +
5481 +/*
5482 + * Function: rc_dict_free
5483 + *
5484 + * Purpose: Free allocated av lists
5485 + *
5486 + * Arguments: Radius Client handle
5487 + */
5488 +
5489 +void
5490 +rc_dict_free(rc_handle *rh)
5491 +{
5492 +       DICT_ATTR       *attr, *nattr;
5493 +       DICT_VALUE      *val, *nval;
5494 +       DICT_VENDOR     *vend, *nvend;
5495 +
5496 +       for (attr = rh->dictionary_attributes; attr != NULL; attr = nattr) {
5497 +               nattr = attr->next;
5498 +               free(attr);
5499 +       }
5500 +       for (val = rh->dictionary_values; val != NULL; val = nval) {
5501 +               nval = val->next;
5502 +               free(val);
5503 +       }
5504 +       for (vend = rh->dictionary_vendors; vend != NULL; vend = nvend) {
5505 +               nvend = vend->next;
5506 +               free(vend);
5507 +       }
5508 +       rh->dictionary_attributes = NULL;
5509 +       rh->dictionary_values = NULL;
5510 +       rh->dictionary_vendors = NULL;
5511 +}
5512 diff --git a/src/plugins/vbng/lib/env.c b/src/plugins/vbng/lib/env.c
5513 new file mode 100644
5514 index 0000000..03dccf9
5515 --- /dev/null
5516 +++ b/src/plugins/vbng/lib/env.c
5517 @@ -0,0 +1,147 @@
5518 +/*
5519 + * $Id: env.c,v 1.6 2007/06/21 18:07:23 cparker Exp $
5520 + *
5521 + * Copyright (C) 1995,1996,1997 Lars Fenneberg
5522 + *
5523 + * See the file COPYRIGHT for the respective terms and conditions.
5524 + * If the file is missing contact me at lf@elemental.net
5525 + * and I'll send you a copy.
5526 + *
5527 + */
5528 +
5529 +#include <config.h>
5530 +#include <includes.h>
5531 +#include <freeradius-client.h>
5532 +
5533 +/*
5534 + * Function: rc_new_env
5535 + *
5536 + * Purpose: allocate space for a new environment
5537 + *
5538 + */
5539 +
5540 +ENV *rc_new_env(int size)
5541 +{
5542 +       ENV *p;
5543 +
5544 +       if (size < 1)
5545 +               return NULL;
5546 +
5547 +       if ((p = malloc(sizeof(*p))) == NULL)
5548 +               return NULL;
5549 +
5550 +       if ((p->env = malloc(size * sizeof(char *))) == NULL)
5551 +       {
5552 +               rc_log(LOG_CRIT, "rc_new_env: out of memory");
5553 +               free(p);
5554 +               return NULL;
5555 +       }
5556 +
5557 +       p->env[0] = NULL;
5558 +
5559 +       p->size = 0;
5560 +       p->maxsize = size;
5561 +
5562 +       return p;
5563 +}
5564 +
5565 +/*
5566 + * Function: rc_free_env
5567 + *
5568 + * Purpose: free the space used by an env structure
5569 + *
5570 + */
5571 +
5572 +void rc_free_env(ENV *env)
5573 +{
5574 +       free(env->env);
5575 +       free(env);
5576 +}
5577 +
5578 +/*
5579 + * Function: rc_add_env
5580 + *
5581 + * Purpose: add an environment entry
5582 + *
5583 + */
5584 +
5585 +int rc_add_env(ENV *env, char const *name, char const *value)
5586 +{
5587 +       int i;
5588 +       size_t len;
5589 +       char *new_env;
5590 +
5591 +       for (i = 0; env->env[i] != NULL; i++)
5592 +       {
5593 +               if (strncmp(env->env[i], name, MAX(strchr(env->env[i], '=') - env->env[i], (int)strlen(name))) == 0)
5594 +                       break;
5595 +       }
5596 +
5597 +       if (env->env[i])
5598 +       {
5599 +               len = strlen(name)+strlen(value)+2;
5600 +               if ((new_env = realloc(env->env[i], len)) == NULL)
5601 +                       return -1;
5602 +
5603 +               env->env[i] = new_env;
5604 +
5605 +               snprintf(env->env[i], len, "%s=%s", name, value);
5606 +       } else {
5607 +               if (env->size == (env->maxsize-1)) {
5608 +                       rc_log(LOG_CRIT, "rc_add_env: not enough space for environment (increase ENV_SIZE)");
5609 +                       return -1;
5610 +               }
5611 +
5612 +               len = strlen(name)+strlen(value)+2;
5613 +               if ((env->env[env->size] = malloc(len)) == NULL) {
5614 +                       rc_log(LOG_CRIT, "rc_add_env: out of memory");
5615 +                       return -1;
5616 +               }
5617 +
5618 +               snprintf(env->env[env->size], len, "%s=%s", name, value);
5619 +
5620 +               env->size++;
5621 +
5622 +               env->env[env->size] = NULL;
5623 +       }
5624 +
5625 +       return 0;
5626 +}
5627 +
5628 +/*
5629 + * Function: rc_import_env
5630 + *
5631 + * Purpose: imports an array of null-terminated strings
5632 + *
5633 + */
5634 +
5635 +int rc_import_env(ENV *env, char const **import)
5636 +{
5637 +       char *es;
5638 +
5639 +       while (*import)
5640 +       {
5641 +               es = strchr(*import, '=');
5642 +
5643 +               if (!es)
5644 +               {
5645 +                       import++;
5646 +                       continue;
5647 +               }
5648 +
5649 +               /* ok, i grant thats not very clean... */
5650 +               *es = '\0';
5651 +
5652 +               if (rc_add_env(env, *import, es+1) < 0)
5653 +               {
5654 +                       *es = '=';
5655 +                       return -1;
5656 +               }
5657 +
5658 +               *es = '=';
5659 +
5660 +               import++;
5661 +       }
5662 +
5663 +       return 0;
5664 +}
5665 diff --git a/src/plugins/vbng/lib/ip_util.c b/src/plugins/vbng/lib/ip_util.c
5666 new file mode 100644
5667 index 0000000..d686a59
5668 --- /dev/null
5669 +++ b/src/plugins/vbng/lib/ip_util.c
5670 @@ -0,0 +1,390 @@
5671 +/*
5672 + * $Id: ip_util.c,v 1.14 2010/03/17 18:57:01 aland Exp $
5673 + *
5674 + * Copyright (C) 1995,1996,1997 Lars Fenneberg
5675 + *
5676 + * Copyright 1992 Livingston Enterprises, Inc.
5677 + *
5678 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
5679 + * and Merit Network, Inc. All Rights Reserved
5680 + *
5681 + * See the file COPYRIGHT for the respective terms and conditions.
5682 + * If the file is missing contact me at lf@elemental.net
5683 + * and I'll send you a copy.
5684 + *
5685 + */
5686 +
5687 +#include <config.h>
5688 +#include <includes.h>
5689 +#include <freeradius-client.h>
5690 +
5691 +#define HOSTBUF_SIZE 1024
5692 +
5693 +#if !defined(SA_LEN)
5694 +#define SA_LEN(sa) \
5695 +  (((sa)->sa_family == AF_INET) ? \
5696 +    sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
5697 +#endif
5698 +
5699 +
5700 +static __thread size_t hostbuflen=HOSTBUF_SIZE;
5701 +static __thread        char    *tmphostbuf=NULL;
5702 +
5703 +/*
5704 + * Function: rc_gethostbyname
5705 + *
5706 + * Purpose: threadsafe replacement for gethostbyname.
5707 + *
5708 + * Returns: NULL on failure, hostent pointer on success
5709 + */
5710 +
5711 +struct hostent *rc_gethostbyname(char const *hostname)
5712 +{
5713 +       struct  hostent *hp;
5714 +#ifdef GETHOSTBYNAME_R
5715 +#if defined (GETHOSTBYNAMERSTYLE_SYSV) || defined (GETHOSTBYNAMERSTYLE_GNU)
5716 +       struct  hostent hostbuf;
5717 +       int     res;
5718 +       int     herr;
5719 +       
5720 +       if(!tmphostbuf) tmphostbuf = malloc(hostbuflen);
5721 +#endif
5722 +#endif
5723 +
5724 +#ifdef GETHOSTBYNAME_R
5725 +#if defined (GETHOSTBYNAMERSTYLE_GNU)
5726 +       while ((res = gethostbyname_r(hostname, &hostbuf, tmphostbuf, hostbuflen, &hp, &herr)) == ERANGE)
5727 +       {
5728 +               /* Enlarge the buffer */
5729 +               hostbuflen *= 2;
5730 +               tmphostbuf = realloc(tmphostbuf, hostbuflen);
5731 +       }
5732 +       if(res) return NULL;
5733 +#elif defined (GETHOSTBYNAMERSTYLE_SYSV)
5734 +       hp = gethostbyname_r(hostname, &hostbuf, tmphostbuf, hostbuflen, &herr);
5735 +#else
5736 +       hp = gethostbyname(hostname);
5737 +#endif
5738 +#else
5739 +       hp = gethostbyname(hostname);
5740 +#endif
5741 +
5742 +       if (hp == NULL) {
5743 +               return NULL;
5744 +       }
5745 +       return hp;
5746 +} 
5747 +
5748 +/*
5749 + * Function: rc_gethostbyname
5750 + *
5751 + * Purpose: threadsafe replacement for gethostbyname.
5752 + *
5753 + * Returns: NULL on failure, hostent pointer on success
5754 + */
5755 +
5756 +struct hostent *rc_gethostbyaddr(char const *addr, size_t length, int format)
5757 +{
5758 +       struct  hostent *hp;
5759 +#ifdef GETHOSTBYADDR_R
5760 +#if defined (GETHOSTBYADDRRSTYLE_SYSV) || defined (GETHOSTBYADDRRSTYLE_GNU)
5761 +       struct  hostent hostbuf;
5762 +       int     res;
5763 +       int     herr;
5764 +       
5765 +       if(!tmphostbuf) tmphostbuf = malloc(hostbuflen);
5766 +#endif
5767 +#endif
5768 +
5769 +#ifdef GETHOSTBYADDR_R
5770 +#if defined (GETHOSTBYADDRRSTYLE_GNU)
5771 +       while ((res = gethostbyaddr_r(addr, length, format, &hostbuf, tmphostbuf, hostbuflen, 
5772 +                                       &hp, &herr)) == ERANGE)
5773 +       {
5774 +               /* Enlarge the buffer */
5775 +               hostbuflen *= 2;
5776 +               tmphostbuf = realloc(tmphostbuf, hostbuflen);
5777 +       }
5778 +       if(res) return NULL;
5779 +#elif GETHOSTBYADDRSTYLE_SYSV
5780 +       hp = gethostbyaddr_r(addr, length, format, &hostbuf, tmphostbuf, hostbuflen, &herr);
5781 +#else
5782 +       hp = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
5783 +#endif
5784 +#else
5785 +       hp = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
5786 +#endif
5787 +
5788 +       if (hp == NULL) {
5789 +               return NULL;
5790 +       }
5791 +       return hp;
5792 +} 
5793 +
5794 +/*
5795 + * Function: rc_get_ipaddr
5796 + *
5797 + * Purpose: return an IP address in host long notation from a host
5798 + *          name or address in dot notation.
5799 + *
5800 + * Returns: 0 on failure
5801 + */
5802 +
5803 +uint32_t rc_get_ipaddr (char const *host)
5804 +{
5805 +       struct  hostent *hp;
5806 +
5807 +       if (rc_good_ipaddr (host) == 0)
5808 +       {
5809 +               return ntohl(inet_addr (host));
5810 +       }
5811 +       else if ((hp = rc_gethostbyname(host)) == NULL)
5812 +       {
5813 +               rc_log(LOG_ERR,"rc_get_ipaddr: couldn't resolve hostname: %s", host);
5814 +               return (uint32_t)0;
5815 +       }
5816 +       return ntohl((*(uint32_t *) hp->h_addr));
5817 +}
5818 +
5819 +/*
5820 + * Function: rc_good_ipaddr
5821 + *
5822 + * Purpose: check for valid IP address in standard dot notation.
5823 + *
5824 + * Returns: 0 on success, -1 when failure
5825 + *
5826 + */
5827 +
5828 +int rc_good_ipaddr (char const *addr)
5829 +{
5830 +       int             dot_count;
5831 +       int             digit_count;
5832 +
5833 +       if (addr == NULL)
5834 +               return -1;
5835 +
5836 +       dot_count = 0;
5837 +       digit_count = 0;
5838 +       while (*addr != '\0' && *addr != ' ')
5839 +       {
5840 +               if (*addr == '.')
5841 +               {
5842 +                       dot_count++;
5843 +                       digit_count = 0;
5844 +               }
5845 +               else if (!isdigit (*addr))
5846 +               {
5847 +                       dot_count = 5;
5848 +               }
5849 +               else
5850 +               {
5851 +                       digit_count++;
5852 +                       if (digit_count > 3)
5853 +                       {
5854 +                               dot_count = 5;
5855 +                       }
5856 +               }
5857 +               addr++;
5858 +       }
5859 +       if (dot_count != 3)
5860 +       {
5861 +               return -1;
5862 +       }
5863 +       else
5864 +       {
5865 +               return 0;
5866 +       }
5867 +}
5868 +
5869 +/*
5870 + * Function: rc_ip_hostname
5871 + *
5872 + * Purpose: Return a printable host name (or IP address in dot notation)
5873 + *         for the supplied IP address.
5874 + *
5875 + */
5876 +
5877 +char const *rc_ip_hostname (uint32_t h_ipaddr)
5878 +{
5879 +       struct hostent  *hp;
5880 +       uint32_t           n_ipaddr = htonl (h_ipaddr);
5881 +
5882 +       if ((hp = rc_gethostbyaddr ((char *) &n_ipaddr, sizeof (struct in_addr),
5883 +                           AF_INET)) == NULL) {
5884 +               rc_log(LOG_ERR,"rc_ip_hostname: couldn't look up host by addr: %08lX", h_ipaddr);
5885 +       }
5886 +
5887 +       return (hp == NULL) ? "unknown" : hp->h_name;
5888 +}
5889 +
5890 +/*
5891 + * Function: rc_getport
5892 + *
5893 + * Purpose: get the port number for the supplied request type
5894 + *
5895 + */
5896 +
5897 +unsigned short rc_getport(int type)
5898 +{
5899 +       struct servent *svp;
5900 +
5901 +       if ((svp = getservbyname ((type==AUTH)?"radius":"radacct", "udp")) == NULL)
5902 +       {
5903 +               return (type==AUTH) ? PW_AUTH_UDP_PORT : PW_ACCT_UDP_PORT;
5904 +       } else {
5905 +               return ntohs ((unsigned short) svp->s_port);
5906 +       }
5907 +}
5908 +
5909 +/*
5910 + * Function: rc_own_hostname
5911 + *
5912 + * Purpose: get the hostname of this machine
5913 + *
5914 + * Returns  -1 on failure, 0 on success
5915 + *
5916 + */
5917 +
5918 +int
5919 +rc_own_hostname(char *hostname, int len)
5920 +{
5921 +#ifdef HAVE_UNAME
5922 +       struct  utsname uts;
5923 +#endif
5924 +
5925 +#if defined(HAVE_UNAME)
5926 +       if (uname(&uts) < 0)
5927 +       {
5928 +               rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname");
5929 +               return -1;
5930 +       }
5931 +       strncpy(hostname, uts.nodename, len);
5932 +#elif defined(HAVE_GETHOSTNAME)
5933 +       if (gethostname(hostname, len) < 0)
5934 +       {
5935 +               rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname");
5936 +               return -1;
5937 +       }
5938 +#elif defined(HAVE_SYSINFO)
5939 +       if (sysinfo(SI_HOSTNAME, hostname, len) < 0)
5940 +       {
5941 +               rc_log(LOG_ERR,"rc_own_hostname: couldn't get own hostname");
5942 +               return -1;
5943 +       }
5944 +#else
5945 +       return -1;
5946 +#endif
5947 +
5948 +       return 0;
5949 +}
5950 +
5951 +/*
5952 + * Function: rc_own_ipaddress
5953 + *
5954 + * Purpose: get the IP address of this host in host order
5955 + *
5956 + * Returns: IP address on success, 0 on failure
5957 + *
5958 + */
5959 +
5960 +uint32_t rc_own_ipaddress(rc_handle *rh)
5961 +{
5962 +       char hostname[256];
5963 +
5964 +       if (!rh->this_host_ipaddr) {
5965 +               if (rc_conf_str(rh, "bindaddr") == NULL ||
5966 +                   strcmp(rc_conf_str(rh, "bindaddr"), "*") == 0) {
5967 +                       if (rc_own_hostname(hostname, sizeof(hostname)) < 0)
5968 +                               return 0;
5969 +               } else {
5970 +                       strncpy(hostname, rc_conf_str(rh, "bindaddr"), sizeof(hostname));
5971 +                       hostname[sizeof(hostname) - 1] = '\0';
5972 +               }
5973 +               if ((rh->this_host_ipaddr = rc_get_ipaddr (hostname)) == 0) {
5974 +                       rc_log(LOG_ERR, "rc_own_ipaddress: couldn't get own IP address");
5975 +                       return 0;
5976 +               }
5977 +       }
5978 +
5979 +       return rh->this_host_ipaddr;
5980 +}
5981 +
5982 +/*
5983 + * Function: rc_own_bind_ipaddress
5984 + *
5985 + * Purpose: get the IP address to be used as a source address
5986 + *          for sending requests in host order
5987 + *
5988 + * Returns: IP address
5989 + *
5990 + */
5991 +
5992 +uint32_t rc_own_bind_ipaddress(rc_handle *rh)
5993 +{
5994 +       char hostname[256];
5995 +       uint32_t rval;
5996 +
5997 +       if (rh->this_host_bind_ipaddr != NULL)
5998 +               return *rh->this_host_bind_ipaddr;
5999 +
6000 +       rh->this_host_bind_ipaddr = malloc(sizeof(*rh->this_host_bind_ipaddr));
6001 +       if (rh->this_host_bind_ipaddr == NULL)
6002 +               rc_log(LOG_CRIT, "rc_own_bind_ipaddress: out of memory");
6003 +       if (rc_conf_str(rh, "bindaddr") == NULL ||
6004 +           strcmp(rc_conf_str(rh, "bindaddr"), "*") == 0) {
6005 +               rval = INADDR_ANY;
6006 +       } else {
6007 +               strncpy(hostname, rc_conf_str(rh, "bindaddr"), sizeof(hostname));
6008 +               hostname[sizeof(hostname) - 1] = '\0';
6009 +               if ((rval = rc_get_ipaddr (hostname)) == 0) {
6010 +                       rc_log(LOG_ERR, "rc_own_ipaddress: couldn't get IP address from bindaddr");
6011 +                       rval = INADDR_ANY;
6012 +               }
6013 +       }
6014 +       if (rh->this_host_bind_ipaddr != NULL)
6015 +               *rh->this_host_bind_ipaddr = rval;
6016 +
6017 +       return rval;
6018 +}
6019 +
6020 +/*
6021 + * Function: rc_get_srcaddr
6022 + *
6023 + * Purpose: given remote address find local address which the
6024 + *          system will use as a source address for sending
6025 + *          datagrams to that remote address
6026 + *
6027 + * Returns: 0 in success, -1 on failure, address is filled into
6028 + *          the first argument.
6029 + *
6030 + */
6031 +int
6032 +rc_get_srcaddr(struct sockaddr *lia, struct sockaddr *ria)
6033 +{
6034 +       int temp_sock;
6035 +       socklen_t namelen;
6036 +
6037 +       temp_sock = socket(ria->sa_family, SOCK_DGRAM, 0);
6038 +       if (temp_sock == -1) {
6039 +               rc_log(LOG_ERR, "rc_get_srcaddr: socket: %s", strerror(errno));
6040 +               return -1;
6041 +       }
6042 +
6043 +       if (connect(temp_sock, ria, SA_LEN(ria)) != 0) {
6044 +               rc_log(LOG_ERR, "rc_get_srcaddr: connect: %s",
6045 +                   strerror(errno));
6046 +               close(temp_sock);
6047 +               return -1;
6048 +       }
6049 +
6050 +       namelen = SA_LEN(ria);
6051 +       if (getsockname(temp_sock, lia, &namelen) != 0) {
6052 +               rc_log(LOG_ERR, "rc_get_srcaddr: getsockname: %s",
6053 +                   strerror(errno));
6054 +               close(temp_sock);
6055 +               return -1;
6056 +       }
6057 +
6058 +       close(temp_sock);
6059 +       return 0;
6060 +}
6061 diff --git a/src/plugins/vbng/lib/log.c b/src/plugins/vbng/lib/log.c
6062 new file mode 100644
6063 index 0000000..09b01a2
6064 --- /dev/null
6065 +++ b/src/plugins/vbng/lib/log.c
6066 @@ -0,0 +1,57 @@
6067 +/*
6068 + * $Id: log.c,v 1.5 2007/06/21 18:07:23 cparker Exp $
6069 + *
6070 + * Copyright (C) 1995,1996,1997 Lars Fenneberg
6071 + *
6072 + * See the file COPYRIGHT for the respective terms and conditions.
6073 + * If the file is missing contact me at lf@elemental.net
6074 + * and I'll send you a copy.
6075 + *
6076 + */
6077 +
6078 +#include <config.h>
6079 +#include <includes.h>
6080 +#include <freeradius-client.h>
6081 +
6082 +/*
6083 + * Function: rc_openlog
6084 + *
6085 + * Purpose: open log
6086 + *
6087 + * Arguments: identification string
6088 + *
6089 + * Returns: nothing
6090 + *
6091 + */
6092 +
6093 +void rc_openlog(char const *ident)
6094 +{
6095 +#ifndef _MSC_VER /* TODO: Fix me */
6096 +       openlog(ident, LOG_PID, RC_LOG_FACILITY);
6097 +#endif
6098 +}
6099 +
6100 +/*
6101 + * Function: rc_log
6102 + *
6103 + * Purpose: log information
6104 + *
6105 + * Arguments: priority (just like syslog), rest like printf
6106 + *
6107 + * Returns: nothing
6108 + *
6109 + */
6110 +
6111 +void rc_log(int prio, char const *format, ...)
6112 +{
6113 +       char buff[1024];
6114 +       va_list ap;
6115 +
6116 +       va_start(ap,format);
6117 +    vsnprintf(buff, sizeof(buff), format, ap);
6118 +    va_end(ap);
6119 +
6120 +#ifndef _MSC_VER /* TODO: Fix me */
6121 +       syslog(prio, "%s", buff);
6122 +#endif
6123 +}
6124 diff --git a/src/plugins/vbng/lib/md5.c b/src/plugins/vbng/lib/md5.c
6125 new file mode 100644
6126 index 0000000..2344fb9
6127 --- /dev/null
6128 +++ b/src/plugins/vbng/lib/md5.c
6129 @@ -0,0 +1,251 @@
6130 +#include "md5.h"
6131 +
6132 +/*     The below was retrieved from
6133 + *     http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/crypto/md5.c?rev=1.1
6134 + *     with the following changes:
6135 + *     #includes commented out.
6136 + *     Support context->count as uint32_t[2] instead of uint64_t
6137 + *     u_int* to uint*
6138 + */
6139 +
6140 +/*
6141 + * This code implements the MD5 message-digest algorithm.
6142 + * The algorithm is due to Ron Rivest. This code was
6143 + * written by Colin Plumb in 1993, no copyright is claimed.
6144 + * This code is in the public domain; do with it what you wish.
6145 + *
6146 + * Equivalent code is available from RSA Data Security, Inc.
6147 + * This code has been tested against that, and is equivalent,
6148 + * except that you don't need to include two pages of legalese
6149 + * with every copy.
6150 + *
6151 + * To compute the message digest of a chunk of bytes, declare an
6152 + * MD5Context structure, pass it to MD5Init, call MD5Update as
6153 + * needed on buffers full of bytes, and then call MD5Final, which
6154 + * will fill a supplied 16-byte array with the digest.
6155 + */
6156 +
6157 +/*#include <sys/param.h>*/
6158 +/*#include <sys/systm.h>*/
6159 +/*#include <crypto/md5.h>*/
6160 +
6161 +#define PUT_64BIT_LE(cp, value) do {                           \
6162 +       (cp)[7] = (value)[1] >> 24;                                     \
6163 +       (cp)[6] = (value)[1] >> 16;                                     \
6164 +       (cp)[5] = (value)[1] >> 8;                                      \
6165 +       (cp)[4] = (value)[1];                                           \
6166 +       (cp)[3] = (value)[0] >> 24;                                     \
6167 +       (cp)[2] = (value)[0] >> 16;                                     \
6168 +       (cp)[1] = (value)[0] >> 8;                                      \
6169 +       (cp)[0] = (value)[0]; } while (0)
6170 +
6171 +#define PUT_32BIT_LE(cp, value) do {                                   \
6172 +       (cp)[3] = (value) >> 24;                                        \
6173 +       (cp)[2] = (value) >> 16;                                        \
6174 +       (cp)[1] = (value) >> 8;                                         \
6175 +       (cp)[0] = (value); } while (0)
6176 +
6177 +static uint8_t PADDING[MD5_BLOCK_LENGTH] = {
6178 +       0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6179 +       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6180 +       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
6181 +};
6182 +
6183 +/*
6184 + * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
6185 + * initialization constants.
6186 + */
6187 +void
6188 +MD5Init(MD5_CTX *ctx)
6189 +{
6190 +       ctx->count[0] = 0;
6191 +       ctx->count[1] = 0;
6192 +       ctx->state[0] = 0x67452301;
6193 +       ctx->state[1] = 0xefcdab89;
6194 +       ctx->state[2] = 0x98badcfe;
6195 +       ctx->state[3] = 0x10325476;
6196 +}
6197 +
6198 +/*
6199 + * Update context to reflect the concatenation of another buffer full
6200 + * of bytes.
6201 + */
6202 +void
6203 +MD5Update(MD5_CTX *ctx, uint8_t const *input, size_t len)
6204 +{
6205 +       size_t have, need;
6206 +
6207 +       /* Check how many bytes we already have and how many more we need. */
6208 +       have = (size_t)((ctx->count[0] >> 3) & (MD5_BLOCK_LENGTH - 1));
6209 +       need = MD5_BLOCK_LENGTH - have;
6210 +
6211 +       /* Update bitcount */
6212 +/*     ctx->count += (uint64_t)len << 3;*/
6213 +       if ((ctx->count[0] += ((uint32_t)len << 3)) < (uint32_t)len) {
6214 +       /* Overflowed ctx->count[0] */
6215 +               ctx->count[1]++;
6216 +       }
6217 +       ctx->count[1] += ((uint32_t)len >> 29);
6218 +
6219 +
6220 +
6221 +       if (len >= need) {
6222 +               if (have != 0) {
6223 +                       memcpy(ctx->buffer + have, input, need);
6224 +                       MD5Transform(ctx->state, ctx->buffer);
6225 +                       input += need;
6226 +                       len -= need;
6227 +                       have = 0;
6228 +               }
6229 +
6230 +               /* Process data in MD5_BLOCK_LENGTH-byte chunks. */
6231 +               while (len >= MD5_BLOCK_LENGTH) {
6232 +                       MD5Transform(ctx->state, input);
6233 +                       input += MD5_BLOCK_LENGTH;
6234 +                       len -= MD5_BLOCK_LENGTH;
6235 +               }
6236 +       }
6237 +
6238 +       /* Handle any remaining bytes of data. */
6239 +       if (len != 0)
6240 +               memcpy(ctx->buffer + have, input, len);
6241 +}
6242 +
6243 +/*
6244 + * Final wrapup - pad to 64-byte boundary with the bit pattern
6245 + * 1 0* (64-bit count of bits processed, MSB-first)
6246 + */
6247 +void
6248 +MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
6249 +{
6250 +       uint8_t count[8];
6251 +       size_t padlen;
6252 +       int i;
6253 +
6254 +       /* Convert count to 8 bytes in little endian order. */
6255 +       PUT_64BIT_LE(count, ctx->count);
6256 +
6257 +       /* Pad out to 56 mod 64. */
6258 +       padlen = MD5_BLOCK_LENGTH -
6259 +           ((ctx->count[0] >> 3) & (MD5_BLOCK_LENGTH - 1));
6260 +       if (padlen < 1 + 8)
6261 +               padlen += MD5_BLOCK_LENGTH;
6262 +       MD5Update(ctx, PADDING, padlen - 8);            /* padlen - 8 <= 64 */
6263 +       MD5Update(ctx, count, 8);
6264 +
6265 +       if (digest != NULL) {
6266 +               for (i = 0; i < 4; i++)
6267 +                       PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
6268 +       }
6269 +       memset(ctx, 0, sizeof(*ctx));   /* in case it's sensitive */
6270 +}
6271 +
6272 +
6273 +/* The four core functions - F1 is optimized somewhat */
6274 +
6275 +/* #define F1(x, y, z) (x & y | ~x & z) */
6276 +#define F1(x, y, z) (z ^ (x & (y ^ z)))
6277 +#define F2(x, y, z) F1(z, x, y)
6278 +#define F3(x, y, z) (x ^ y ^ z)
6279 +#define F4(x, y, z) (y ^ (x | ~z))
6280 +
6281 +/* This is the central step in the MD5 algorithm. */
6282 +#define MD5STEP(f, w, x, y, z, data, s) \
6283 +       ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
6284 +
6285 +/*
6286 + * The core of the MD5 algorithm, this alters an existing MD5 hash to
6287 + * reflect the addition of 16 longwords of new data.  MD5Update blocks
6288 + * the data and converts bytes into longwords for this routine.
6289 + */
6290 +void
6291 +MD5Transform(uint32_t state[4], uint8_t const block[MD5_BLOCK_LENGTH])
6292 +{
6293 +       uint32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
6294 +
6295 +       for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
6296 +               in[a] = (uint32_t)(
6297 +                   (uint32_t)(block[a * 4 + 0]) |
6298 +                   (uint32_t)(block[a * 4 + 1]) <<  8 |
6299 +                   (uint32_t)(block[a * 4 + 2]) << 16 |
6300 +                   (uint32_t)(block[a * 4 + 3]) << 24);
6301 +       }
6302 +
6303 +       a = state[0];
6304 +       b = state[1];
6305 +       c = state[2];
6306 +       d = state[3];
6307 +
6308 +       MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
6309 +       MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
6310 +       MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
6311 +       MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
6312 +       MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
6313 +       MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
6314 +       MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
6315 +       MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
6316 +       MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
6317 +       MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
6318 +       MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
6319 +       MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
6320 +       MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
6321 +       MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
6322 +       MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
6323 +       MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
6324 +
6325 +       MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
6326 +       MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
6327 +       MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
6328 +       MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
6329 +       MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
6330 +       MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
6331 +       MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
6332 +       MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
6333 +       MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
6334 +       MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
6335 +       MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
6336 +       MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
6337 +       MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
6338 +       MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
6339 +       MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
6340 +       MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
6341 +
6342 +       MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
6343 +       MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
6344 +       MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
6345 +       MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
6346 +       MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
6347 +       MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
6348 +       MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
6349 +       MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
6350 +       MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
6351 +       MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
6352 +       MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
6353 +       MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
6354 +       MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
6355 +       MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
6356 +       MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
6357 +       MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
6358 +
6359 +       MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
6360 +       MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
6361 +       MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
6362 +       MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
6363 +       MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
6364 +       MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
6365 +       MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
6366 +       MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
6367 +       MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
6368 +       MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
6369 +       MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
6370 +       MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
6371 +       MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
6372 +       MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
6373 +       MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
6374 +       MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
6375 +
6376 +       state[0] += a;
6377 +       state[1] += b;
6378 +       state[2] += c;
6379 +       state[3] += d;
6380 +}
6381 diff --git a/src/plugins/vbng/lib/md5.h b/src/plugins/vbng/lib/md5.h
6382 new file mode 100644
6383 index 0000000..fcbaf91
6384 --- /dev/null
6385 +++ b/src/plugins/vbng/lib/md5.h
6386 @@ -0,0 +1,86 @@
6387 +/*
6388 + * md5.h        Structures and prototypes for md5.
6389 + *
6390 + * Version:     $Id: md5.h,v 1.2 2007/06/21 18:07:24 cparker Exp $
6391 + * License:    BSD, but largely derived from a public domain source.
6392 + *
6393 + */
6394 +
6395 +#ifndef _RCRAD_MD5_H
6396 +#define _RCRAD_MD5_H
6397 +
6398 +#include "config.h"
6399 +
6400 +#ifdef HAVE_NETTLE
6401 +
6402 +#include <nettle/md5-compat.h>
6403 +
6404 +#else
6405 +
6406 +#ifdef HAVE_INTTYPES_H
6407 +#include <inttypes.h>
6408 +#endif
6409 +
6410 +#ifdef HAVE_SYS_TYPES_H
6411 +#include <sys/types.h>
6412 +#endif
6413 +
6414 +#ifdef HAVE_STDINT_H
6415 +#include <stdint.h>
6416 +#endif
6417 +
6418 +#include <string.h>
6419 +/*
6420 + *  FreeRADIUS Client defines to ensure globally unique MD5 function names,
6421 + *  so that we don't pick up vendor-specific broken MD5 libraries.
6422 + */
6423 +#define MD5_CTX                librad_MD5_CTX
6424 +#define MD5Init                librad_MD5Init
6425 +#define MD5Update      librad_MD5Update
6426 +#define MD5Final       librad_MD5Final
6427 +#define MD5Transform   librad_MD5Transform
6428 +
6429 +/*  The below was retrieved from
6430 + *  http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/crypto/md5.h?rev=1.1
6431 + *  With the following changes: uint64_t => uint32_t[2]
6432 + *  Commented out #include <sys/cdefs.h>
6433 + *  Commented out the __BEGIN and __END _DECLS, and the __attributes.
6434 + */
6435 +
6436 +/*
6437 + * This code implements the MD5 message-digest algorithm.
6438 + * The algorithm is due to Ron Rivest.  This code was
6439 + * written by Colin Plumb in 1993, no copyright is claimed.
6440 + * This code is in the public domain; do with it what you wish.
6441 + *
6442 + * Equivalent code is available from RSA Data Security, Inc.
6443 + * This code has been tested against that, and is equivalent,
6444 + * except that you don't need to include two pages of legalese
6445 + * with every copy.
6446 + */
6447 +
6448 +#define        MD5_BLOCK_LENGTH                64
6449 +#define        MD5_DIGEST_LENGTH               16
6450 +
6451 +typedef struct MD5Context {
6452 +       uint32_t state[4];                      /* state */
6453 +       uint32_t count[2];                      /* number of bits, mod 2^64 */
6454 +       uint8_t buffer[MD5_BLOCK_LENGTH];       /* input buffer */
6455 +} MD5_CTX;
6456 +
6457 +/* include <sys/cdefs.h> */
6458 +
6459 +/* __BEGIN_DECLS */
6460 +void    MD5Init(MD5_CTX *);
6461 +void    MD5Update(MD5_CTX *, uint8_t const *, size_t)
6462 +/*             __attribute__((__bounded__(__string__,2,3)))*/;
6463 +void    MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *)
6464 +/*             __attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH)))*/;
6465 +void    MD5Transform(uint32_t [4], uint8_t const [MD5_BLOCK_LENGTH])
6466 +/*             __attribute__((__bounded__(__minbytes__,1,4)))*/
6467 +/*             __attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH)))*/;
6468 +/* __END_DECLS */
6469 +
6470 +#endif /* HAVE_NETTLE */
6471 +
6472 +#endif /* _RCRAD_MD5_H */
6473 diff --git a/src/plugins/vbng/lib/options.h b/src/plugins/vbng/lib/options.h
6474 new file mode 100644
6475 index 0000000..05b66df
6476 --- /dev/null
6477 +++ b/src/plugins/vbng/lib/options.h
6478 @@ -0,0 +1,57 @@
6479 +/*
6480 + * $Id: options.h,v 1.6 2008/03/05 16:35:20 cparker Exp $
6481 + *
6482 + * Copyright (C) 1996 Lars Fenneberg
6483 + *
6484 + * See the file COPYRIGHT for the respective terms and conditions.
6485 + * If the file is missing contact me at lf@elemental.net
6486 + * and I'll send you a copy.
6487 + *
6488 + */
6489 +
6490 +#define OPTION_LEN     64
6491 +
6492 +/* ids for different option types */
6493 +#define OT_STR         (1<<0)    /* string */
6494 +#define OT_INT         (1<<1)    /* integer */
6495 +#define OT_SRV         (1<<2)    /* server list */
6496 +#define OT_AUO         (1<<3)    /* authentication order */
6497 +
6498 +#define OT_ANY         ((unsigned int)~0) /* used internally */
6499 +
6500 +/* status types */
6501 +#define ST_UNDEF       (1<<0)    /* option is undefined */
6502 +
6503 +typedef struct _option {
6504 +       char name[OPTION_LEN];    /* name of the option */
6505 +       int type, status;         /* type and status    */
6506 +       void *val;                /* pointer to option value */
6507 +} OPTION;
6508 +
6509 +static OPTION config_options_default[] = {
6510 +/* internally used options */
6511 +{"config_file",                OT_STR, ST_UNDEF, NULL},
6512 +/* General options */
6513 +{"auth_order",         OT_AUO, ST_UNDEF, NULL},
6514 +{"login_tries",                OT_INT, ST_UNDEF, NULL},
6515 +{"login_timeout",      OT_INT, ST_UNDEF, NULL},
6516 +{"nologin",            OT_STR, ST_UNDEF, NULL},
6517 +{"issue",              OT_STR, ST_UNDEF, NULL},
6518 +/* RADIUS specific options */
6519 +{"authserver",         OT_SRV, ST_UNDEF, NULL},
6520 +{"acctserver",         OT_SRV, ST_UNDEF, NULL},
6521 +{"servers",            OT_STR, ST_UNDEF, NULL},
6522 +{"dictionary",         OT_STR, ST_UNDEF, NULL},
6523 +{"login_radius",       OT_STR, ST_UNDEF, NULL},
6524 +{"seqfile",            OT_STR, ST_UNDEF, NULL},
6525 +{"mapfile",            OT_STR, ST_UNDEF, NULL},
6526 +{"default_realm",      OT_STR, ST_UNDEF, NULL},
6527 +{"radius_timeout",     OT_INT, ST_UNDEF, NULL},
6528 +{"radius_retries",     OT_INT, ST_UNDEF, NULL},
6529 +{"radius_deadtime",    OT_INT, ST_UNDEF, NULL},
6530 +{"bindaddr",           OT_STR, ST_UNDEF, NULL},
6531 +/* local options */
6532 +{"login_local",                OT_STR, ST_UNDEF, NULL},
6533 +};
6534 +
6535 +#define        NUM_OPTIONS     ((sizeof(config_options_default))/(sizeof(config_options_default[0])))
6536 diff --git a/src/plugins/vbng/lib/rc-md5.c b/src/plugins/vbng/lib/rc-md5.c
6537 new file mode 100644
6538 index 0000000..be9fbcb
6539 --- /dev/null
6540 +++ b/src/plugins/vbng/lib/rc-md5.c
6541 @@ -0,0 +1,24 @@
6542 +/* MD5 message-digest algorithm */
6543 +
6544 +/* This file is licensed under the BSD License, but is largely derived from
6545 + * public domain source code
6546 + */
6547 +
6548 +/*
6549 + *  FORCE MD5 TO USE OUR MD5 HEADER FILE!
6550 + *
6551 + *  If we don't do this, it might pick up the systems broken MD5.
6552 + *  - Alan DeKok <aland@ox.org>
6553 + */
6554 +#include "rc-md5.h"
6555 +
6556 +void rc_md5_calc(unsigned char *output, unsigned char const *input,
6557 +                    size_t inlen)
6558 +{
6559 +       MD5_CTX context;
6560 +
6561 +       MD5Init(&context);
6562 +       MD5Update(&context, input, inlen);
6563 +       MD5Final(output, &context);
6564 +}
6565 +
6566 diff --git a/src/plugins/vbng/lib/rc-md5.h b/src/plugins/vbng/lib/rc-md5.h
6567 new file mode 100644
6568 index 0000000..a30f16d
6569 --- /dev/null
6570 +++ b/src/plugins/vbng/lib/rc-md5.h
6571 @@ -0,0 +1,27 @@
6572 +/*
6573 + * md5.h        Structures and prototypes for md5.
6574 + *
6575 + * Version:     $Id: md5.h,v 1.2 2007/06/21 18:07:24 cparker Exp $
6576 + * License:    BSD
6577 + *
6578 + */
6579 +
6580 +#ifndef _RC_MD5_H
6581 +#define _RC_MD5_H
6582 +
6583 +#include "config.h"
6584 +
6585 +#ifdef HAVE_NETTLE
6586 +
6587 +#include <nettle/md5-compat.h>
6588 +
6589 +#else
6590 +
6591 +#include "md5.h"
6592 +
6593 +#endif /* HAVE_NETTLE */
6594 +
6595 +void rc_md5_calc(unsigned char *output, unsigned char const *input,
6596 +                    size_t inputlen);
6597 +
6598 +#endif /* _RC_MD5_H */
6599 diff --git a/src/plugins/vbng/lib/sendserver.c b/src/plugins/vbng/lib/sendserver.c
6600 new file mode 100644
6601 index 0000000..bfdd9a2
6602 --- /dev/null
6603 +++ b/src/plugins/vbng/lib/sendserver.c
6604 @@ -0,0 +1,631 @@
6605 +/*
6606 + * $Id: sendserver.c,v 1.30 2010/06/15 09:22:52 aland Exp $
6607 + *
6608 + * Copyright (C) 1995,1996,1997 Lars Fenneberg
6609 + *
6610 + * Copyright 1992 Livingston Enterprises, Inc.
6611 + *
6612 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
6613 + * and Merit Network, Inc. All Rights Reserved
6614 + *
6615 + * See the file COPYRIGHT for the respective terms and conditions.
6616 + * If the file is missing contact me at lf@elemental.net
6617 + * and I'll send you a copy.
6618 + *
6619 + */
6620 +
6621 +#include <poll.h>
6622 +
6623 +#include <config.h>
6624 +#include <includes.h>
6625 +#include <freeradius-client.h>
6626 +#include <pathnames.h>
6627 +
6628 +#define        SA(p)   ((struct sockaddr *)(p))
6629 +
6630 +static void rc_random_vector (unsigned char *);
6631 +static int rc_check_reply (AUTH_HDR *, int, char const *, unsigned char const *, unsigned char);
6632 +
6633 +/*
6634 + * Function: rc_pack_list
6635 + *
6636 + * Purpose: Packs an attribute value pair list into a buffer.
6637 + *
6638 + * Returns: Number of octets packed.
6639 + *
6640 + */
6641 +
6642 +static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth)
6643 +{
6644 +       int             length, i, pc, padded_length;
6645 +       int             total_length = 0;
6646 +       size_t                  secretlen;
6647 +       uint32_t           lvalue, vendor;
6648 +       unsigned char   passbuf[MAX(AUTH_PASS_LEN, CHAP_VALUE_LENGTH)];
6649 +       unsigned char   md5buf[256];
6650 +       unsigned char   *buf, *vector, *vsa_length_ptr;
6651 +
6652 +       buf = auth->data;
6653 +
6654 +       while (vp != NULL)
6655 +       {
6656 +               vsa_length_ptr = NULL;
6657 +               if (VENDOR(vp->attribute) != 0) {
6658 +                       *buf++ = PW_VENDOR_SPECIFIC;
6659 +                       vsa_length_ptr = buf;
6660 +                       *buf++ = 6;
6661 +                       vendor = htonl(VENDOR(vp->attribute));
6662 +                       memcpy(buf, &vendor, sizeof(uint32_t));
6663 +                       buf += 4;
6664 +                       total_length += 6;
6665 +               }
6666 +               *buf++ = (vp->attribute & 0xff);
6667 +
6668 +               switch (vp->attribute)
6669 +               {
6670 +                case PW_USER_PASSWORD:
6671 +
6672 +                 /* Encrypt the password */
6673 +
6674 +                 /* Chop off password at AUTH_PASS_LEN */
6675 +                 length = vp->lvalue;
6676 +                 if (length > AUTH_PASS_LEN)
6677 +                       length = AUTH_PASS_LEN;
6678 +
6679 +                 /* Calculate the padded length */
6680 +                 padded_length = (length+(AUTH_VECTOR_LEN-1)) & ~(AUTH_VECTOR_LEN-1);
6681 +
6682 +                 /* Record the attribute length */
6683 +                 *buf++ = padded_length + 2;
6684 +                 if (vsa_length_ptr != NULL) *vsa_length_ptr += padded_length + 2;
6685 +
6686 +                 /* Pad the password with zeros */
6687 +                 memset ((char *) passbuf, '\0', AUTH_PASS_LEN);
6688 +                 memcpy ((char *) passbuf, vp->strvalue, (size_t) length);
6689 +
6690 +                 secretlen = strlen (secret);
6691 +                 vector = (unsigned char *)auth->vector;
6692 +                 for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN)
6693 +                 {
6694 +                       /* Calculate the MD5 digest*/
6695 +                       strcpy ((char *) md5buf, secret);
6696 +                       memcpy ((char *) md5buf + secretlen, vector,
6697 +                                 AUTH_VECTOR_LEN);
6698 +                       rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN);
6699 +
6700 +                       /* Remeber the start of the digest */
6701 +                       vector = buf;
6702 +
6703 +                       /* Xor the password into the MD5 digest */
6704 +                       for (pc = i; pc < (i + AUTH_VECTOR_LEN); pc++)
6705 +                       {
6706 +                               *buf++ ^= passbuf[pc];
6707 +                       }
6708 +                 }
6709 +
6710 +                 total_length += padded_length + 2;
6711 +
6712 +                 break;
6713 +#if 0
6714 +                case PW_CHAP_PASSWORD:
6715 +
6716 +                 *buf++ = CHAP_VALUE_LENGTH + 2;
6717 +                 if (vsa_length_ptr != NULL) *vsa_length_ptr += CHAP_VALUE_LENGTH + 2;
6718 +
6719 +                 /* Encrypt the Password */
6720 +                 length = vp->lvalue;
6721 +                 if (length > CHAP_VALUE_LENGTH)
6722 +                 {
6723 +                       length = CHAP_VALUE_LENGTH;
6724 +                 }
6725 +                 memset ((char *) passbuf, '\0', CHAP_VALUE_LENGTH);
6726 +                 memcpy ((char *) passbuf, vp->strvalue, (size_t) length);
6727 +
6728 +                 /* Calculate the MD5 Digest */
6729 +                 secretlen = strlen (secret);
6730 +                 strcpy ((char *) md5buf, secret);
6731 +                 memcpy ((char *) md5buf + secretlen, (char *) auth->vector,
6732 +                         AUTH_VECTOR_LEN);
6733 +                 rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN);
6734 +
6735 +                 /* Xor the password into the MD5 digest */
6736 +                 for (i = 0; i < CHAP_VALUE_LENGTH; i++)
6737 +                 {
6738 +                       *buf++ ^= passbuf[i];
6739 +                 }
6740 +                 total_length += CHAP_VALUE_LENGTH + 2;
6741 +
6742 +                 break;
6743 +#endif
6744 +                default:
6745 +                 switch (vp->type)
6746 +                 {
6747 +                   case PW_TYPE_STRING:
6748 +                       length = vp->lvalue;
6749 +                       *buf++ = length + 2;
6750 +                       if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
6751 +                       memcpy (buf, vp->strvalue, (size_t) length);
6752 +                       buf += length;
6753 +                       total_length += length + 2;
6754 +                       break;
6755 +
6756 +                   case PW_TYPE_IPV6ADDR:
6757 +                       length = 16;
6758 +                       if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
6759 +                       memcpy (buf, vp->strvalue, (size_t) length);
6760 +                       buf += length;
6761 +                       total_length += length + 2;
6762 +                       break;
6763 +
6764 +                   case PW_TYPE_IPV6PREFIX:
6765 +                       length = vp->lvalue;
6766 +                       if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
6767 +                       memcpy (buf, vp->strvalue, (size_t) length);
6768 +                       buf += length;
6769 +                       total_length += length + 2;
6770 +                       break;
6771 +
6772 +                   case PW_TYPE_INTEGER:
6773 +                   case PW_TYPE_IPADDR:
6774 +                   case PW_TYPE_DATE:
6775 +                       *buf++ = sizeof (uint32_t) + 2;
6776 +                       if (vsa_length_ptr != NULL) *vsa_length_ptr += sizeof(uint32_t) + 2;
6777 +                       lvalue = htonl (vp->lvalue);
6778 +                       memcpy (buf, (char *) &lvalue, sizeof (uint32_t));
6779 +                       buf += sizeof (uint32_t);
6780 +                       total_length += sizeof (uint32_t) + 2;
6781 +                       break;
6782 +
6783 +                   default:
6784 +                       break;
6785 +                 }
6786 +                 break;
6787 +               }
6788 +               vp = vp->next;
6789 +       }
6790 +       return total_length;
6791 +}
6792 +
6793 +/* Function strappend
6794 + *
6795 + * Purpose: appends a string to the provided buffer
6796 + */
6797 +static void strappend(char *dest, unsigned max_size, int *pos, const char *src)
6798 +{
6799 +       unsigned len = strlen(src) + 1;
6800 +
6801 +       if (*pos == -1)
6802 +               return;
6803 +
6804 +       if (len + *pos > max_size) {
6805 +               *pos = -1;
6806 +               return;
6807 +       }
6808 +
6809 +       memcpy(&dest[*pos], src, len);
6810 +       *pos += len-1;
6811 +       return;
6812 +}
6813 +
6814 +/*
6815 + * Function: rc_send_server
6816 + *
6817 + * Purpose: send a request to a RADIUS server and wait for the reply
6818 + *
6819 + */
6820 +
6821 +int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg)
6822 +{
6823 +       int             sockfd;
6824 +       struct sockaddr_in sinlocal;
6825 +       struct sockaddr_in sinremote;
6826 +       AUTH_HDR       *auth, *recv_auth;
6827 +       uint32_t           auth_ipaddr, nas_ipaddr;
6828 +       char           *server_name;    /* Name of server to query */
6829 +       socklen_t       salen;
6830 +       int             result = 0;
6831 +       int             total_length;
6832 +       int             length, pos;
6833 +       int             retry_max;
6834 +       size_t                  secretlen;
6835 +       char            secret[MAX_SECRET_LENGTH + 1];
6836 +       unsigned char   vector[AUTH_VECTOR_LEN];
6837 +       char            recv_buffer[BUFFER_LEN];
6838 +       char            send_buffer[BUFFER_LEN];
6839 +       int             retries;
6840 +       VALUE_PAIR      *vp;
6841 +       struct pollfd   pfd;
6842 +       double          start_time, timeout;
6843 +
6844 +       server_name = data->server;
6845 +       if (server_name == NULL || server_name[0] == '\0')
6846 +               return ERROR_RC;
6847 +
6848 +       if ((vp = rc_avpair_get(data->send_pairs, PW_SERVICE_TYPE, 0)) && \
6849 +           (vp->lvalue == PW_ADMINISTRATIVE))
6850 +       {
6851 +               strcpy(secret, MGMT_POLL_SECRET);
6852 +               if ((auth_ipaddr = rc_get_ipaddr(server_name)) == 0)
6853 +                       return ERROR_RC;
6854 +       }
6855 +       else
6856 +       {
6857 +               if(data->secret != NULL)
6858 +               {
6859 +                       strncpy(secret, data->secret, MAX_SECRET_LENGTH);
6860 +               }
6861 +               /*
6862 +               else
6863 +               {
6864 +               */
6865 +               if (rc_find_server (rh, server_name, &auth_ipaddr, secret) != 0)
6866 +               {
6867 +                       rc_log(LOG_ERR, "rc_send_server: unable to find server: %s", server_name);
6868 +                       return ERROR_RC;
6869 +               }
6870 +               /*}*/
6871 +       }
6872 +
6873 +       DEBUG(LOG_ERR, "DEBUG: rc_send_server: creating socket to: %s", server_name);
6874 +
6875 +       sockfd = socket (AF_INET, SOCK_DGRAM, 0);
6876 +       if (sockfd < 0)
6877 +       {
6878 +               memset (secret, '\0', sizeof (secret));
6879 +               rc_log(LOG_ERR, "rc_send_server: socket: %s", strerror(errno));
6880 +               return ERROR_RC;
6881 +       }
6882 +
6883 +       memset((char *)&sinlocal, '\0', sizeof(sinlocal));
6884 +       sinlocal.sin_family = AF_INET;
6885 +       sinlocal.sin_addr.s_addr = htonl(rc_own_bind_ipaddress(rh));
6886 +       sinlocal.sin_port = htons((unsigned short) 0);
6887 +       if (bind(sockfd, SA(&sinlocal), sizeof(sinlocal)) < 0)
6888 +       {
6889 +               close (sockfd);
6890 +               memset (secret, '\0', sizeof (secret));
6891 +               rc_log(LOG_ERR, "rc_send_server: bind: %s: %s", server_name, strerror(errno));
6892 +               return ERROR_RC;
6893 +       }
6894 +
6895 +       retry_max = data->retries;      /* Max. numbers to try for reply */
6896 +       retries = 0;                    /* Init retry cnt for blocking call */
6897 +
6898 +       memset ((char *)&sinremote, '\0', sizeof(sinremote));
6899 +       sinremote.sin_family = AF_INET;
6900 +       sinremote.sin_addr.s_addr = htonl (auth_ipaddr);
6901 +       sinremote.sin_port = htons ((unsigned short) data->svc_port);
6902 +
6903 +       /*
6904 +        * Fill in NAS-IP-Address (if needed)
6905 +        */
6906 +       if (rc_avpair_get(data->send_pairs, PW_NAS_IP_ADDRESS, 0) == NULL) {
6907 +               if (sinlocal.sin_addr.s_addr == htonl(INADDR_ANY)) {
6908 +                       if (rc_get_srcaddr(SA(&sinlocal), SA(&sinremote)) != 0) {
6909 +                               close (sockfd);
6910 +                               memset (secret, '\0', sizeof (secret));
6911 +                               return ERROR_RC;
6912 +                       }
6913 +               }
6914 +               nas_ipaddr = ntohl(sinlocal.sin_addr.s_addr);
6915 +               rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IP_ADDRESS,
6916 +                   &nas_ipaddr, 0, 0);
6917 +       }
6918 +
6919 +       /* Build a request */
6920 +       auth = (AUTH_HDR *) send_buffer;
6921 +       auth->code = data->code;
6922 +       auth->id = data->seq_nbr;
6923 +
6924 +       if (data->code == PW_ACCOUNTING_REQUEST)
6925 +       {
6926 +               total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
6927 +
6928 +               auth->length = htons ((unsigned short) total_length);
6929 +
6930 +               memset((char *) auth->vector, 0, AUTH_VECTOR_LEN);
6931 +               secretlen = strlen (secret);
6932 +               memcpy ((char *) auth + total_length, secret, secretlen);
6933 +               rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen);
6934 +               memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
6935 +       }
6936 +       else
6937 +       {
6938 +               rc_random_vector (vector);
6939 +               memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
6940 +
6941 +               total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
6942 +
6943 +               auth->length = htons ((unsigned short) total_length);
6944 +       }
6945 +
6946 +       DEBUG(LOG_ERR, "DEBUG: local %s : 0, remote %s : %u\n", 
6947 +               inet_ntoa(sinlocal.sin_addr),
6948 +               inet_ntoa(sinremote.sin_addr), data->svc_port);
6949 +
6950 +       for (;;)
6951 +       {
6952 +               sendto (sockfd, (char *) auth, (unsigned int) total_length, (int) 0,
6953 +                       SA(&sinremote), sizeof (struct sockaddr_in));
6954 +
6955 +               pfd.fd = sockfd;
6956 +               pfd.events = POLLIN;
6957 +               pfd.revents = 0;
6958 +               start_time = rc_getctime();
6959 +               for (timeout = data->timeout; timeout > 0;
6960 +                   timeout -= rc_getctime() - start_time) {
6961 +                       result = poll(&pfd, 1, timeout * 1000);
6962 +                       if (result != -1 || errno != EINTR)
6963 +                               break;
6964 +               }
6965 +               if (result == -1)
6966 +               {
6967 +                       rc_log(LOG_ERR, "rc_send_server: poll: %s", strerror(errno));
6968 +                       memset (secret, '\0', sizeof (secret));
6969 +                       close (sockfd);
6970 +                       return ERROR_RC;
6971 +               }
6972 +               if (result == 1 && (pfd.revents & POLLIN) != 0)
6973 +                       break;
6974 +
6975 +               /*
6976 +                * Timed out waiting for response.  Retry "retry_max" times
6977 +                * before giving up.  If retry_max = 0, don't retry at all.
6978 +                */
6979 +               if (retries++ >= retry_max)
6980 +               {
6981 +                       rc_log(LOG_ERR,
6982 +                               "rc_send_server: no reply from RADIUS server %s:%u, %s",
6983 +                                rc_ip_hostname (auth_ipaddr), data->svc_port, inet_ntoa(sinremote.sin_addr));
6984 +                       close (sockfd);
6985 +                       memset (secret, '\0', sizeof (secret));
6986 +                       return TIMEOUT_RC;
6987 +               }
6988 +       }
6989 +       salen = sizeof(sinremote);
6990 +       length = recvfrom (sockfd, (char *) recv_buffer,
6991 +                          (int) sizeof (recv_buffer),
6992 +                          (int) 0, SA(&sinremote), &salen);
6993 +
6994 +       if (length <= 0)
6995 +       {
6996 +               rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: %s", server_name,\
6997 +                        data->svc_port, strerror(errno));
6998 +               close (sockfd);
6999 +               memset (secret, '\0', sizeof (secret));
7000 +               return ERROR_RC;
7001 +       }
7002 +
7003 +       recv_auth = (AUTH_HDR *)recv_buffer;
7004 +
7005 +       if (length < AUTH_HDR_LEN || length < ntohs(recv_auth->length)) {
7006 +               rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: reply is too short",
7007 +                   server_name, data->svc_port);
7008 +               close(sockfd);
7009 +               memset(secret, '\0', sizeof(secret));
7010 +               return ERROR_RC;
7011 +       }
7012 +
7013 +       result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr);
7014 +
7015 +       length = ntohs(recv_auth->length)  - AUTH_HDR_LEN;
7016 +       if (length > 0) {
7017 +               data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data,
7018 +                   length, 0);
7019 +       } else {
7020 +               data->receive_pairs = NULL;
7021 +       }
7022 +
7023 +       close (sockfd);
7024 +       memset (secret, '\0', sizeof (secret));
7025 +
7026 +       if (result != OK_RC) return result;
7027 +
7028 +       if (msg) {
7029 +               *msg = '\0';
7030 +               pos = 0;
7031 +               vp = data->receive_pairs;
7032 +               while (vp)
7033 +               {
7034 +                       if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0)))
7035 +                       {
7036 +                               strappend(msg, PW_MAX_MSG_SIZE, &pos, vp->strvalue);
7037 +                               strappend(msg, PW_MAX_MSG_SIZE, &pos, "\n");
7038 +                               vp = vp->next;
7039 +                       }
7040 +               }
7041 +       }
7042 +
7043 +       if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
7044 +               (recv_auth->code == PW_PASSWORD_ACK) ||
7045 +               (recv_auth->code == PW_ACCOUNTING_RESPONSE))
7046 +       {
7047 +               result = OK_RC;
7048 +       }
7049 +       else if ((recv_auth->code == PW_ACCESS_REJECT) ||
7050 +               (recv_auth->code == PW_PASSWORD_REJECT))
7051 +       {
7052 +               result = REJECT_RC;
7053 +       }
7054 +       else
7055 +       {
7056 +               result = BADRESP_RC;
7057 +       }
7058 +
7059 +       return result;
7060 +}
7061 +
7062 +/*
7063 + * Function: rc_check_reply
7064 + *
7065 + * Purpose: verify items in returned packet.
7066 + *
7067 + * Returns:    OK_RC       -- upon success,
7068 + *             BADRESP_RC  -- if anything looks funny.
7069 + *
7070 + */
7071 +
7072 +static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char const *secret, unsigned char const *vector, uint8_t seq_nbr)
7073 +{
7074 +       int             secretlen;
7075 +       int             totallen;
7076 +       unsigned char   calc_digest[AUTH_VECTOR_LEN];
7077 +       unsigned char   reply_digest[AUTH_VECTOR_LEN];
7078 +#ifdef DIGEST_DEBUG
7079 +       uint8_t         *ptr;
7080 +#endif
7081 +
7082 +       totallen = ntohs (auth->length);
7083 +       secretlen = (int)strlen (secret);
7084 +
7085 +       /* Do sanity checks on packet length */
7086 +       if ((totallen < 20) || (totallen > 4096))
7087 +       {
7088 +               rc_log(LOG_ERR, "rc_check_reply: received RADIUS server response with invalid length");
7089 +               return BADRESP_RC;
7090 +       }
7091 +
7092 +       /* Verify buffer space, should never trigger with current buffer size and check above */
7093 +       if ((totallen + secretlen) > bufferlen)
7094 +       {
7095 +               rc_log(LOG_ERR, "rc_check_reply: not enough buffer space to verify RADIUS server response");
7096 +               return BADRESP_RC;
7097 +       }
7098 +
7099 +       /* Verify that id (seq. number) matches what we sent */
7100 +       if (auth->id != seq_nbr)
7101 +       {
7102 +               rc_log(LOG_ERR, "rc_check_reply: received non-matching id in RADIUS server response");
7103 +               return BADRESP_RC;
7104 +       }
7105 +
7106 +       /* Verify the reply digest */
7107 +       memcpy ((char *) reply_digest, (char *) auth->vector, AUTH_VECTOR_LEN);
7108 +       memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
7109 +       memcpy ((char *) auth + totallen, secret, secretlen);
7110 +#ifdef DIGEST_DEBUG
7111 +        rc_log(LOG_ERR, "Calculating digest on:");
7112 +        for (ptr = (u_char *)auth; ptr < ((u_char *)auth) + totallen + secretlen; ptr += 32) {
7113 +                char buf[65];
7114 +                int i;
7115 +
7116 +                buf[0] = '\0';
7117 +                for (i = 0; i < 32; i++) {
7118 +                        if (ptr + i >= ((u_char *)auth) + totallen + secretlen)
7119 +                                break;
7120 +                        sprintf(buf + i * 2, "%.2X", ptr[i]);
7121 +                }
7122 +                rc_log(LOG_ERR, "  %s", buf);
7123 +        }
7124 +#endif
7125 +       rc_md5_calc (calc_digest, (unsigned char *) auth, totallen + secretlen);
7126 +#ifdef DIGEST_DEBUG
7127 +       rc_log(LOG_ERR, "Calculated digest is:");
7128 +        for (ptr = (u_char *)calc_digest; ptr < ((u_char *)calc_digest) + 16; ptr += 32) {
7129 +                char buf[65];
7130 +                int i;
7131 +
7132 +                buf[0] = '\0';
7133 +                for (i = 0; i < 32; i++) {
7134 +                        if (ptr + i >= ((u_char *)calc_digest) + 16)
7135 +                                break;
7136 +                        sprintf(buf + i * 2, "%.2X", ptr[i]);
7137 +                }
7138 +                rc_log(LOG_ERR, "  %s", buf);
7139 +        }
7140 +       rc_log(LOG_ERR, "Reply digest is:");
7141 +        for (ptr = (u_char *)reply_digest; ptr < ((u_char *)reply_digest) + 16; ptr += 32) {
7142 +                char buf[65];
7143 +                int i;
7144 +
7145 +                buf[0] = '\0';
7146 +                for (i = 0; i < 32; i++) {
7147 +                        if (ptr + i >= ((u_char *)reply_digest) + 16)
7148 +                                break;
7149 +                        sprintf(buf + i * 2, "%.2X", ptr[i]);
7150 +                }
7151 +                rc_log(LOG_ERR, "  %s", buf);
7152 +        }
7153 +#endif
7154 +
7155 +       if (memcmp ((char *) reply_digest, (char *) calc_digest,
7156 +                   AUTH_VECTOR_LEN) != 0)
7157 +       {
7158 +#ifdef RADIUS_116
7159 +               /* the original Livingston radiusd v1.16 seems to have
7160 +                  a bug in digest calculation with accounting requests,
7161 +                  authentication request are ok. i looked at the code
7162 +                  but couldn't find any bugs. any help to get this
7163 +                  kludge out are welcome. preferably i want to
7164 +                  reproduce the calculation bug here to be compatible
7165 +                  to stock Livingston radiusd v1.16.   -lf, 03/14/96
7166 +                */
7167 +               if (auth->code == PW_ACCOUNTING_RESPONSE)
7168 +                       return OK_RC;
7169 +#endif
7170 +               rc_log(LOG_ERR, "rc_check_reply: received invalid reply digest from RADIUS server");
7171 +               return BADRESP_RC;
7172 +       }
7173 +
7174 +       return OK_RC;
7175 +
7176 +}
7177 +
7178 +/*
7179 + * Function: rc_random_vector
7180 + *
7181 + * Purpose: generates a random vector of AUTH_VECTOR_LEN octets.
7182 + *
7183 + * Returns: the vector (call by reference)
7184 + *
7185 + */
7186 +
7187 +static void rc_random_vector (unsigned char *vector)
7188 +{
7189 +       int             randno;
7190 +       int             i;
7191 +#if defined(HAVE_GETENTROPY)
7192 +       if (getentropy(vector, AUTH_VECTOR_LEN) >= 0) {
7193 +               return;
7194 +       } /* else fall through */
7195 +#elif defined(HAVE_DEV_URANDOM)
7196 +       int             fd;
7197 +
7198 +/* well, I added this to increase the security for user passwords.
7199 +   we use /dev/urandom here, as /dev/random might block and we don't
7200 +   need that much randomness. BTW, great idea, Ted!     -lf, 03/18/95  */
7201 +
7202 +       if ((fd = open(_PATH_DEV_URANDOM, O_RDONLY)) >= 0)
7203 +       {
7204 +               unsigned char *pos;
7205 +               int readcount;
7206 +
7207 +               i = AUTH_VECTOR_LEN;
7208 +               pos = vector;
7209 +               while (i > 0)
7210 +               {
7211 +                       readcount = read(fd, (char *)pos, i);
7212 +                       if (readcount >= 0) {
7213 +                               pos += readcount;
7214 +                               i -= readcount;
7215 +                       } else {
7216 +                               if (errno != EINTR && errno != EAGAIN)
7217 +                                       goto fallback;
7218 +                       }
7219 +               }
7220 +
7221 +               close(fd);
7222 +               return;
7223 +       } /* else fall through */
7224 +#endif
7225 + fallback:
7226 +       for (i = 0; i < AUTH_VECTOR_LEN;)
7227 +       {
7228 +               randno = random ();
7229 +               memcpy ((char *) vector, (char *) &randno, sizeof (int));
7230 +               vector += sizeof (int);
7231 +               i += sizeof (int);
7232 +       }
7233 +
7234 +       return;
7235 +}
7236 diff --git a/src/plugins/vbng/lib/util.c b/src/plugins/vbng/lib/util.c
7237 new file mode 100644
7238 index 0000000..aa7c057
7239 --- /dev/null
7240 +++ b/src/plugins/vbng/lib/util.c
7241 @@ -0,0 +1,347 @@
7242 +/*
7243 + * $Id: util.c,v 1.10 2010/02/04 10:31:41 aland Exp $
7244 + *
7245 + * Copyright (c) 1998 The NetBSD Foundation, Inc.
7246 + *
7247 + * Copyright (C) 1995,1996,1997 Lars Fenneberg
7248 + *
7249 + * Copyright 1992 Livingston Enterprises, Inc.
7250 + *
7251 + * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
7252 + * and Merit Network, Inc. All Rights Reserved
7253 + *
7254 + * See the file COPYRIGHT for the respective terms and conditions.
7255 + * If the file is missing contact me at lf@elemental.net
7256 + * and I'll send you a copy.
7257 + *
7258 + */
7259 +
7260 +#include <sys/time.h>
7261 +
7262 +#include <config.h>
7263 +#include <includes.h>
7264 +#include <freeradius-client.h>
7265 +
7266 +#define        RC_BUFSIZ       1024
7267 +
7268 +/*
7269 + * Function: rc_str2tm
7270 + *
7271 + * Purpose: Turns printable string into correct tm struct entries.
7272 + *
7273 + */
7274 +
7275 +static char const * months[] =
7276 +               {
7277 +                       "Jan", "Feb", "Mar", "Apr", "May", "Jun",
7278 +                       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
7279 +               };
7280 +
7281 +void rc_str2tm (char const *valstr, struct tm *tm)
7282 +{
7283 +       int             i;
7284 +
7285 +       /* Get the month */
7286 +       for (i = 0; i < 12; i++)
7287 +       {
7288 +               if (strncmp (months[i], valstr, 3) == 0)
7289 +               {
7290 +                       tm->tm_mon = i;
7291 +                       i = 13;
7292 +               }
7293 +       }
7294 +
7295 +       /* Get the Day */
7296 +       tm->tm_mday = atoi (&valstr[4]);
7297 +
7298 +       /* Now the year */
7299 +       tm->tm_year = atoi (&valstr[7]) - 1900;
7300 +}
7301 +
7302 +/*
7303 + * Function: rc_getifname
7304 + *
7305 + * Purpose: get the network interface name associated with this tty
7306 + *
7307 + */
7308 +
7309 +char *rc_getifname(rc_handle *rh, char const *tty)
7310 +{
7311 +#if defined(BSD4_4) || defined(linux)
7312 +       int             fd;
7313 +
7314 +       if ((fd = open(tty, O_RDWR|O_NDELAY)) < 0) {
7315 +               rc_log(LOG_ERR, "rc_getifname: can't open %s: %s", tty, strerror(errno));
7316 +               return NULL;
7317 +       }
7318 +#endif
7319 +
7320 +#ifdef BSD4_4
7321 +       strcpy(rh->ifname,ttyname(fd));
7322 +       if (strlen(rh->ifname) < 1) {
7323 +               rc_log(LOG_ERR, "rc_getifname: can't get attached interface of %s: %s", tty, strerror(errno));
7324 +               close(fd);
7325 +               return NULL;
7326 +       }
7327 +#elif linux
7328 +       if (ioctl(fd, SIOCGIFNAME, rh->ifname) < 0) {
7329 +               rc_log(LOG_ERR, "rc_getifname: can't ioctl %s: %s", tty, strerror(errno));
7330 +               close(fd);
7331 +               return NULL;
7332 +       }
7333 +#else
7334 +       return NULL;
7335 +#endif
7336 +
7337 +#if defined(BSD4_4) || defined(linux)
7338 +       close(fd);
7339 +       return rh->ifname;
7340 +#endif
7341 +}
7342 +
7343 +/*
7344 + * Function: rc_getstr
7345 + *
7346 + * Purpose: Reads in a string from the user (with or witout echo)
7347 + *
7348 + */
7349 +#ifndef _MSC_VER
7350 +char *rc_getstr (rc_handle *rh, char const *prompt, int do_echo)
7351 +{
7352 +       int             in, out;
7353 +       char           *p;
7354 +       struct termios  term_old, term_new;
7355 +       int             is_term, flags, old_flags;
7356 +       char            c;
7357 +       int             flushed = 0;
7358 +       sigset_t        newset;
7359 +       sigset_t        oldset;
7360 +
7361 +       in = fileno(stdin);
7362 +       out = fileno(stdout);
7363 +
7364 +       (void) sigemptyset (&newset);
7365 +       (void) sigaddset (&newset, SIGINT);
7366 +       (void) sigaddset (&newset, SIGTSTP);
7367 +       (void) sigaddset (&newset, SIGQUIT);
7368 +
7369 +       (void) sigprocmask (SIG_BLOCK, &newset, &oldset);
7370 +
7371 +       if ((is_term = isatty(in)))
7372 +       {
7373 +
7374 +               (void) tcgetattr (in, &term_old);
7375 +               term_new = term_old;
7376 +               if (do_echo)
7377 +                       term_new.c_lflag |= ECHO;
7378 +               else
7379 +                       term_new.c_lflag &= ~ECHO;
7380 +
7381 +               if (tcsetattr (in, TCSAFLUSH, &term_new) == 0)
7382 +                       flushed = 1;
7383 +
7384 +       }
7385 +       else
7386 +       {
7387 +               is_term = 0;
7388 +               if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
7389 +                       old_flags = flags;
7390 +                       flags |= O_NONBLOCK;
7391 +
7392 +                       fcntl(in, F_SETFL, flags);
7393 +
7394 +                       while (read(in, &c, 1) > 0)
7395 +                               /* nothing */;
7396 +
7397 +                       fcntl(in, F_SETFL, old_flags);
7398 +
7399 +                       flushed = 1;
7400 +               }
7401 +       }
7402 +
7403 +       (void)write(out, prompt, strlen(prompt));
7404 +
7405 +       /* well, this looks ugly, but it handles the following end of line
7406 +          markers: \r \r\0 \r\n \n \n\r, at least at a second pass */
7407 +
7408 +       p = rh->buf;
7409 +       for (;;)
7410 +       {
7411 +               if (read(in, &c, 1) <= 0)
7412 +                       return NULL;
7413 +
7414 +               if (!flushed && ((c == '\0') || (c == '\r') || (c == '\n'))) {
7415 +                       flushed = 1;
7416 +                       continue;
7417 +               }
7418 +
7419 +               if ((c == '\r') || (c == '\n'))
7420 +                       break;
7421 +
7422 +               flushed = 1;
7423 +
7424 +               if (p < rh->buf + GETSTR_LENGTH)
7425 +               {
7426 +                       if (do_echo && !is_term)
7427 +                               (void)write(out, &c, 1);
7428 +                       *p++ = c;
7429 +               }
7430 +       }
7431 +
7432 +       *p = '\0';
7433 +
7434 +       if (!do_echo || !is_term) (void)write(out, "\r\n", 2);
7435 +
7436 +       if (is_term)
7437 +               tcsetattr (in, TCSAFLUSH, &term_old);
7438 +       else {
7439 +               if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
7440 +                       old_flags = flags;
7441 +                       flags |= O_NONBLOCK;
7442 +
7443 +                       fcntl(in, F_SETFL, flags);
7444 +
7445 +                       while (read(in, &c, 1) > 0)
7446 +                               /* nothing */;
7447 +
7448 +                       fcntl(in, F_SETFL, old_flags);
7449 +               }
7450 +       }
7451 +
7452 +       (void) sigprocmask (SIG_SETMASK, &oldset, NULL);
7453 +
7454 +       return rh->buf;
7455 +}
7456 +#endif
7457 +void rc_mdelay(int msecs)
7458 +{
7459 +       struct timeval tv;
7460 +
7461 +       tv.tv_sec = (int) msecs / 1000;
7462 +       tv.tv_usec = (msecs % 1000) * 1000;
7463 +
7464 +       select(0, NULL, NULL, NULL, &tv);
7465 +}
7466 +
7467 +/*
7468 + * Function: rc_mksid
7469 + *
7470 + * Purpose: generate a quite unique string
7471 + *
7472 + * Remarks: not that unique at all...
7473 + *
7474 + */
7475 +
7476 +char *
7477 +rc_mksid (rc_handle *rh)
7478 +{
7479 +  snprintf (rh->buf1, sizeof(rh->buf1), "%08lX%04X", (unsigned long int) time (NULL), (unsigned int) getpid ());
7480 +  return rh->buf1;
7481 +}
7482 +
7483 +/*
7484 + * Function: rc_new
7485 + *
7486 + * Purpose: Initialises new Radius Client handle
7487 + *
7488 + */
7489 +
7490 +rc_handle *
7491 +rc_new(void)
7492 +{
7493 +       rc_handle *rh;
7494 +
7495 +       rh = malloc(sizeof(*rh));
7496 +       if (rh == NULL) {
7497 +                rc_log(LOG_CRIT, "rc_new: out of memory");
7498 +                return NULL;
7499 +        }
7500 +       memset(rh, 0, sizeof(*rh));
7501 +       return rh;
7502 +}
7503 +
7504 +/*
7505 + * Function: rc_destroy
7506 + *
7507 + * Purpose: Destroys Radius Client handle reclaiming all memory
7508 + *
7509 + */
7510 +
7511 +void
7512 +rc_destroy(rc_handle *rh)
7513 +{
7514 +
7515 +       rc_map2id_free(rh);
7516 +       rc_dict_free(rh);
7517 +       rc_config_free(rh);
7518 +       if (rh->this_host_bind_ipaddr != NULL)
7519 +               free(rh->this_host_bind_ipaddr);
7520 +       free(rh);
7521 +}
7522 +
7523 +/*
7524 + * Function: rc_fgetln
7525 + *
7526 + * Purpose: Get next line from the stream.
7527 + *
7528 + */
7529 +
7530 +char *
7531 +rc_fgetln(FILE *fp, size_t *len)
7532 +{
7533 +       static char *buf = NULL;
7534 +       static size_t bufsiz = 0;
7535 +       char *ptr;
7536 +
7537 +       if (buf == NULL) {
7538 +               bufsiz = RC_BUFSIZ;
7539 +               if ((buf = malloc(bufsiz)) == NULL)
7540 +                       return NULL;
7541 +       }
7542 +
7543 +       if (fgets(buf, (int)bufsiz, fp) == NULL)
7544 +               return NULL;
7545 +       *len = 0;
7546 +
7547 +       while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
7548 +               size_t nbufsiz = bufsiz + RC_BUFSIZ;
7549 +               char *nbuf = realloc(buf, nbufsiz);
7550 +
7551 +               if (nbuf == NULL) {
7552 +                       int oerrno = errno;
7553 +                       free(buf);
7554 +                       errno = oerrno;
7555 +                       buf = NULL;
7556 +                       return NULL;
7557 +               } else
7558 +                       buf = nbuf;
7559 +
7560 +               *len = bufsiz;
7561 +               if (fgets(&buf[bufsiz], RC_BUFSIZ, fp) == NULL)
7562 +                       return buf;
7563 +
7564 +               bufsiz = nbufsiz;
7565 +       }
7566 +
7567 +       *len = (ptr - buf) + 1;
7568 +       return buf;
7569 +}
7570 +
7571 +/*
7572 + * Function: rc_getctime
7573 + *
7574 + * Purpose: Get current time (seconds since epoch) expressed as
7575 + * double-precision floating point number.
7576 + *
7577 + */
7578 +
7579 +double
7580 +rc_getctime(void)
7581 +{
7582 +    struct timeval timev;
7583 +
7584 +    if (gettimeofday(&timev, NULL) == -1)
7585 +        return -1;
7586 +
7587 +    return timev.tv_sec + ((double)timev.tv_usec) / 1000000.0;
7588 +}
7589 diff --git a/src/plugins/vbng/vbng.api b/src/plugins/vbng/vbng.api
7590 new file mode 100644
7591 index 0000000..eba9a10
7592 --- /dev/null
7593 +++ b/src/plugins/vbng/vbng.api
7594 @@ -0,0 +1,50 @@
7595 +/*
7596 + * Copyright (c) 2017 Intel Corp and/or its affiliates.
7597 + * Licensed under the Apache License, Version 2.0 (the "License");
7598 + * you may not use this file except in compliance with the License.
7599 + * You may obtain a copy of the License at:
7600 + *
7601 + *     http://www.apache.org/licenses/LICENSE-2.0
7602 + *
7603 + * Unless required by applicable law or agreed to in writing, software
7604 + * distributed under the License is distributed on an "AS IS" BASIS,
7605 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7606 + * See the License for the specific language governing permissions and
7607 + * limitations under the License.
7608 + */
7609 +
7610 +/** \brief vBNG DHCP config add / del request
7611 +    @param client_index - opaque cookie to identify the sender
7612 +    @param context - sender context, to match reply w/ request
7613 +    @param rx_vrf_id - Rx/interface vrf id
7614 +    @param server_vrf_id - server vrf id
7615 +    @param is_add - add the config if non-zero, else delete
7616 +    @param remote_addr[] - DHCP server address
7617 +    @param local_addr[] - Local Address which could reach DHCP server
7618 +*/
7619 +define vbng_dhcp4_config
7620 +{
7621 +  u32 client_index;
7622 +  u32 context;
7623 +  u32 rx_vrf_id;
7624 +  u32 server_vrf_id;
7625 +  u8 is_add;
7626 +  u8 remote_addr[16];
7627 +  u8 local_addr[16];
7628 +};
7629 +
7630 +/** \brief vBNG DHCP config response
7631 +    @param context - sender context, to match reply w/ request
7632 +    @param retval - return code for the request
7633 +*/
7634 +define vbng_dhcp4_config_reply
7635 +{
7636 +  u32 context;
7637 +  i32 retval;
7638 +};
7639 +
7640 +/*
7641 + * Local Variables:
7642 + * eval: (c-set-style "gnu")
7643 + * End:
7644 + */
7645 diff --git a/src/plugins/vbng/vbng_aaa.c b/src/plugins/vbng/vbng_aaa.c
7646 new file mode 100644
7647 index 0000000..5e8861f
7648 --- /dev/null
7649 +++ b/src/plugins/vbng/vbng_aaa.c
7650 @@ -0,0 +1,71 @@
7651 +/*
7652 + * Copyright (c) 2017 Intel and/or its affiliates.
7653 + *
7654 + * Licensed under the Apache License, Version 2.0 (the "License");
7655 + * you may not use this file except in compliance with the License.
7656 + * You may obtain a copy of the License at:
7657 + *
7658 + *     http://www.apache.org/licenses/LICENSE-2.0
7659 + *
7660 + * Unless required by applicable law or agreed to in writing, software
7661 + * distributed under the License is distributed on an "AS IS" BASIS,
7662 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7663 + * See the License for the specific language governing permissions and
7664 + * limitations under the License.
7665 + */
7666 +
7667 +#include <ctype.h>
7668 +#include <stdio.h>
7669 +#include <stdlib.h>
7670 +#include <string.h>
7671 +#include <unistd.h>
7672 +
7673 +#include <vbng/include/freeradius-client.h>
7674 +#include <vbng/vbng_aaa.h>
7675 +
7676 +int
7677 +process(void *rh, VALUE_PAIR *send, int nas_port)
7678 +{
7679 +    VALUE_PAIR *received = NULL;
7680 +    char msg[PW_MAX_MSG_SIZE];
7681 +    int retval;
7682 +
7683 +    retval = rc_auth(rh, nas_port, send, &received, msg);
7684 +    if (retval == OK_RC && received != NULL) {
7685 +        rc_avpair_free(received);
7686 +    }
7687 +
7688 +    return retval;
7689 +}
7690 +
7691 +int
7692 +vbng_auth(vbng_dhcp4_main_t *dm, int argc, char **argv)
7693 +{
7694 +    int i, nas_port = dm->config.nas_port;
7695 +    char *rc_conf = (char *)dm->config.config_file;
7696 +    VALUE_PAIR *send, **vp;
7697 +    void *rh;
7698 +
7699 +    if ((rh = rc_read_config(rc_conf)) == NULL) {
7700 +        fprintf(stderr, "error opening radius configuration file\n");
7701 +        return (1);
7702 +    }
7703 +
7704 +    if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) {
7705 +        fprintf(stderr, "error reading radius dictionary\n");
7706 +        return (2);
7707 +    }
7708 +
7709 +    send = NULL;
7710 +    vp = &send;
7711 +    for (i = 0; i < argc; i++) {
7712 +        if (rc_avpair_parse(rh, argv[i], vp) < 0) {
7713 +            fprintf(stderr, "%s: can't parse AV pair\n", argv[i]);
7714 +            return (3);
7715 +        }
7716 +        vp = &send->next;
7717 +    }
7718 +
7719 +    return process(rh, send, nas_port);
7720 +}
7721 +
7722 diff --git a/src/plugins/vbng/vbng_aaa.h b/src/plugins/vbng/vbng_aaa.h
7723 new file mode 100644
7724 index 0000000..411a753
7725 --- /dev/null
7726 +++ b/src/plugins/vbng/vbng_aaa.h
7727 @@ -0,0 +1,34 @@
7728 +/*
7729 + * vbng_aaa.h - vBNG FreeRADIUS client commons.
7730 + *
7731 + * Copyright (c) 2017 Intel and/or its affiliates.
7732 + * Licensed under the Apache License, Version 2.0 (the "License");
7733 + * you may not use this file except in compliance with the License.
7734 + * You may obtain a copy of the License at:
7735 + *
7736 + *     http://www.apache.org/licenses/LICENSE-2.0
7737 + *
7738 + * Unless required by applicable law or agreed to in writing, software
7739 + * distributed under the License is distributed on an "AS IS" BASIS,
7740 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7741 + * See the License for the specific language governing permissions and
7742 + * limitations under the License.
7743 + */
7744 +#ifndef _VBNG_AAA_H_
7745 +#define _VBNG_AAA_H_
7746 +
7747 +#include <vbng/vbng_dhcp4.h>
7748 +
7749 +/* Common configuration for RADIUS client */
7750 +#define AAA_DEFAULT_NAS_PORT   5060
7751 +#define AAA_DEFAULT_CONFIG_FILE        "/etc/vpp/vbng-aaa.cfg"
7752 +
7753 +#define BUF_LEN                4096
7754 +
7755 +/* String template for the vAAA attributes */
7756 +#define STR_TPL_ATTR_DHCP_AGENT_CIRCUIT_ID "DHCP-Agent-Circuit-Id=%c"
7757 +#define STR_TPL_ATTR_DHCP_AGENT_REMOTE_ID "DHCP-Agent-Remote-Id=%c"
7758 +
7759 +int vbng_auth(vbng_dhcp4_main_t *dm, int argc, char **argv);
7760 +
7761 +#endif /* _VBNG_AAA_H_ */
7762 diff --git a/src/plugins/vbng/vbng_all_api_h.h b/src/plugins/vbng/vbng_all_api_h.h
7763 new file mode 100644
7764 index 0000000..3f74427
7765 --- /dev/null
7766 +++ b/src/plugins/vbng/vbng_all_api_h.h
7767 @@ -0,0 +1,18 @@
7768 +/*
7769 + * vbng_all_api_h.h - skeleton vpp engine plug-in api #include file
7770 + *
7771 + * Copyright (c) 2017 Intel and/or its affiliates.
7772 + * Licensed under the Apache License, Version 2.0 (the "License");
7773 + * you may not use this file except in compliance with the License.
7774 + * You may obtain a copy of the License at:
7775 + *
7776 + *     http://www.apache.org/licenses/LICENSE-2.0
7777 + *
7778 + * Unless required by applicable law or agreed to in writing, software
7779 + * distributed under the License is distributed on an "AS IS" BASIS,
7780 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7781 + * See the License for the specific language governing permissions and
7782 + * limitations under the License.
7783 + */
7784 +
7785 +#include <vbng/vbng.api.h>
7786 diff --git a/src/plugins/vbng/vbng_api.c b/src/plugins/vbng/vbng_api.c
7787 new file mode 100644
7788 index 0000000..4080f77
7789 --- /dev/null
7790 +++ b/src/plugins/vbng/vbng_api.c
7791 @@ -0,0 +1,123 @@
7792 +/*
7793 + *------------------------------------------------------------------
7794 + * vbng_api.c - vbng api
7795 + *
7796 + * Copyright (c) 2017 Intel Corp and/or its affiliates.
7797 + * Licensed under the Apache License, Version 2.0 (the "License");
7798 + * you may not use this file except in compliance with the License.
7799 + * You may obtain a copy of the License at:
7800 + *
7801 + *     http://www.apache.org/licenses/LICENSE-2.0
7802 + *
7803 + * Unless required by applicable law or agreed to in writing, software
7804 + * distributed under the License is distributed on an "AS IS" BASIS,
7805 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7806 + * See the License for the specific language governing permissions and
7807 + * limitations under the License.
7808 + *------------------------------------------------------------------
7809 + */
7810 +
7811 +#include <vnet/vnet.h>
7812 +#include <vlibmemory/api.h>
7813 +
7814 +#include <vnet/interface.h>
7815 +#include <vnet/api_errno.h>
7816 +#include <vnet/dhcp/dhcp_proxy.h>
7817 +#include <vnet/dhcp/client.h>
7818 +#include <vnet/fib/fib_table.h>
7819 +
7820 +#include <vbng/vbng_msg_enum.h>
7821 +
7822 +#define vl_typedefs            /* define message structures */
7823 +#include <vbng/vbng_all_api_h.h>
7824 +#undef vl_typedefs
7825 +
7826 +#define vl_endianfun           /* define message structures */
7827 +#include <vbng/vbng_all_api_h.h>
7828 +#undef vl_endianfun
7829 +
7830 +/* instantiate all the print functions we know about */
7831 +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
7832 +#define vl_printfun
7833 +#include <vbng/vbng_all_api_h.h>
7834 +#undef vl_printfun
7835 +
7836 +#include <vlibapi/api_helper_macros.h>
7837 +
7838 +#define foreach_vpe_api_msg                       \
7839 +_(VBNG_DHCP4_CONFIG,vbng_dhcp4_config)
7840 +
7841 +static void vl_api_vbng_dhcp4_config_t_handler
7842 +  (vl_api_vbng_dhcp4_config_t * mp)
7843 +{
7844 +  vl_api_vbng_dhcp4_config_reply_t *rmp;
7845 +  ip46_address_t src, server;
7846 +  int rv = -1;
7847 +
7848 +  ip46_address_reset (&src);
7849 +  ip46_address_reset (&server);
7850 +
7851 +  clib_memcpy (&src.ip4, mp->local_addr, sizeof (src.ip4));
7852 +  clib_memcpy (&server.ip4, mp->remote_addr, sizeof (server.ip4));
7853 +
7854 +  rv = dhcp4_proxy_set_server (&server,
7855 +                  &src,
7856 +                                  (u32) ntohl (mp->rx_vrf_id),
7857 +                                  (u32) ntohl (mp->server_vrf_id),
7858 +                                  (int) (mp->is_add == 0));
7859 +
7860 +
7861 +  REPLY_MACRO (VL_API_VBNG_DHCP4_CONFIG_REPLY);
7862 +}
7863 +
7864 +/*
7865 + * vbng_api_hookup
7866 + * Add vpe's API message handlers to the table.
7867 + * vlib has alread mapped shared memory and
7868 + * added the client registration handlers.
7869 + * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
7870 + */
7871 +#define vl_msg_name_crc_list
7872 +#include <vbng/vbng_all_api_h.h>
7873 +#undef vl_msg_name_crc_list
7874 +
7875 +static void
7876 +setup_message_id_table (api_main_t * am)
7877 +{
7878 +#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
7879 +  foreach_vl_msg_name_crc_vbng;
7880 +#undef _
7881 +}
7882 +
7883 +static clib_error_t *
7884 +vbng_api_hookup (vlib_main_t * vm)
7885 +{
7886 +  api_main_t *am = &api_main;
7887 +
7888 +#define _(N,n)                                                  \
7889 +    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
7890 +                           vl_api_##n##_t_handler,              \
7891 +                           vl_noop_handler,                     \
7892 +                           vl_api_##n##_t_endian,               \
7893 +                           vl_api_##n##_t_print,                \
7894 +                           sizeof(vl_api_##n##_t), 1);
7895 +  foreach_vpe_api_msg;
7896 +#undef _
7897 +
7898 +  /*
7899 +   * Set up the (msg_name, crc, message-id) table
7900 +   */
7901 +  setup_message_id_table (am);
7902 +
7903 +  return 0;
7904 +}
7905 +
7906 +VLIB_API_INIT_FUNCTION (vbng_api_hookup);
7907 +
7908 +/*
7909 + * fd.io coding-style-patch-verification: ON
7910 + *
7911 + * Local Variables:
7912 + * eval: (c-set-style "gnu")
7913 + * End:
7914 + */
7915 diff --git a/src/plugins/vbng/vbng_dhcp4.c b/src/plugins/vbng/vbng_dhcp4.c
7916 new file mode 100644
7917 index 0000000..ed79df4
7918 --- /dev/null
7919 +++ b/src/plugins/vbng/vbng_dhcp4.c
7920 @@ -0,0 +1,160 @@
7921 +/*
7922 + * vbng_dhcp4.c: common dhcp v4 processing
7923 + *
7924 + * Copyright (c) 2017 Intel Corp and/or its affiliates and others.
7925 + * Licensed under the Apache License, Version 2.0 (the "License");
7926 + * you may not use this file except in compliance with the License.
7927 + * You may obtain a copy of the License at:
7928 + *
7929 + *     http://www.apache.org/licenses/LICENSE-2.0
7930 + *
7931 + * Unless required by applicable law or agreed to in writing, software
7932 + * distributed under the License is distributed on an "AS IS" BASIS,
7933 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7934 + * See the License for the specific language governing permissions and
7935 + * limitations under the License.
7936 + */
7937 +
7938 +#include <vnet/fib/fib_table.h>
7939 +#include <vnet/mfib/mfib_table.h>
7940 +
7941 +#include <vbng/vbng_dhcp4.h>
7942 +
7943 +/**
7944 + * @brief Shard 4/6 instance of DHCP main
7945 + */
7946 +vbng_dhcp4_main_t vbng_dhcp4_main;
7947 +
7948 +void
7949 +vbng_dhcp4_walk (vbng_dhcp4_walk_fn_t fn,
7950 +                 void *ctx)
7951 +{
7952 +  vbng_dhcp4_main_t *vdm = &vbng_dhcp4_main;
7953 +  dhcp_proxy_t * server;
7954 +  u32 server_index, i;
7955 +
7956 +  vec_foreach_index (i, vdm->dhcp_server_index_by_rx_fib_index)
7957 +  {
7958 +      server_index = vdm->dhcp_server_index_by_rx_fib_index[i];
7959 +      if (~0 == server_index)
7960 +          continue;
7961 +
7962 +      server = pool_elt_at_index (vdm->dhcp4_servers, server_index);
7963 +
7964 +      if (!fn(server, ctx))
7965 +          break;
7966 +    }
7967 +}
7968 +
7969 +static u32
7970 +dhcp_proxy_server_find (dhcp_proxy_t *proxy,
7971 +                        fib_protocol_t proto,
7972 +                        ip46_address_t *addr,
7973 +                        u32 server_table_id)
7974 +{
7975 +    dhcp_server_t *server;
7976 +    u32 ii, fib_index;
7977 +
7978 +    vec_foreach_index(ii, proxy->dhcp_servers)
7979 +    {
7980 +        server = &proxy->dhcp_servers[ii];
7981 +        fib_index = fib_table_find(proto, server_table_id);
7982 +
7983 +        if (ip46_address_is_equal(&server->dhcp_server,
7984 +                                  addr) &&
7985 +            (server->server_fib_index == fib_index))
7986 +        {
7987 +            return (ii);
7988 +        }
7989 +    }
7990 +    return (~0);
7991 +}
7992 +
7993 +int
7994 +vbng_dhcp4_server_del (fib_protocol_t proto,
7995 +                       u32 rx_fib_index,
7996 +                       ip46_address_t *addr,
7997 +                       u32 server_table_id)
7998 +{
7999 +  vbng_dhcp4_main_t *vdm = &vbng_dhcp4_main;
8000 +  dhcp_proxy_t *proxy = 0;
8001 +
8002 +  proxy = vbng_dhcp4_get_server(vdm, rx_fib_index);
8003 +
8004 +  if (NULL != proxy)
8005 +  {
8006 +      dhcp_server_t *server;
8007 +      u32 index;
8008 +
8009 +      index = dhcp_proxy_server_find(proxy, proto, addr, server_table_id);
8010 +
8011 +      if (~0 != index)
8012 +      {
8013 +          server = &proxy->dhcp_servers[index];
8014 +          fib_table_unlock (server->server_fib_index, proto);
8015 +
8016 +          vec_del1(proxy->dhcp_servers, index);
8017 +
8018 +          if (0 == vec_len(proxy->dhcp_servers))
8019 +          {
8020 +              /* no servers left, delete the proxy config */
8021 +              vdm->dhcp_server_index_by_rx_fib_index[rx_fib_index] = ~0;
8022 +              vec_free(proxy->dhcp_servers);
8023 +              pool_put (vdm->dhcp4_servers, proxy);
8024 +              return (1);
8025 +          }
8026 +      }
8027 +  }
8028 +
8029 +  /* the proxy still exists */
8030 +  return (0);
8031 +}
8032 +
8033 +int
8034 +vbng_dhcp4_server_add (fib_protocol_t proto,
8035 +                       ip46_address_t *addr,
8036 +                       ip46_address_t *src_address,
8037 +                       u32 rx_fib_index,
8038 +                       u32 server_table_id)
8039 +{
8040 +  vbng_dhcp4_main_t *vdm = &vbng_dhcp4_main;
8041 +  dhcp_proxy_t * proxy = 0;
8042 +  int new = 0;
8043 +
8044 +  proxy = vbng_dhcp4_get_server(vdm, rx_fib_index);
8045 +
8046 +  if (NULL == proxy)
8047 +  {
8048 +      vec_validate_init_empty(vdm->dhcp_server_index_by_rx_fib_index,
8049 +                              rx_fib_index,
8050 +                              ~0);
8051 +
8052 +      pool_get (vdm->dhcp4_servers, proxy);
8053 +      memset (proxy, 0, sizeof (*proxy));
8054 +      new = 1;
8055 +
8056 +      vdm->dhcp_server_index_by_rx_fib_index[rx_fib_index] =
8057 +          proxy - vdm->dhcp4_servers;
8058 +
8059 +      proxy->dhcp_src_address = *src_address;
8060 +      proxy->rx_fib_index = rx_fib_index;
8061 +  }
8062 +  else
8063 +  {
8064 +      if (~0 != dhcp_proxy_server_find(proxy, proto, addr, server_table_id))
8065 +      {
8066 +          return (new);
8067 +      }
8068 +  }
8069 +
8070 +  dhcp_server_t server = {
8071 +      .dhcp_server = *addr,
8072 +      .server_fib_index = fib_table_find_or_create_and_lock(proto,
8073 +                                                            server_table_id),
8074 +  };
8075 +
8076 +  vec_add1(proxy->dhcp_servers, server);
8077 +
8078 +  return (new);
8079 +}
8080 +
8081 diff --git a/src/plugins/vbng/vbng_dhcp4.h b/src/plugins/vbng/vbng_dhcp4.h
8082 new file mode 100644
8083 index 0000000..2f41575
8084 --- /dev/null
8085 +++ b/src/plugins/vbng/vbng_dhcp4.h
8086 @@ -0,0 +1,139 @@
8087 +/*
8088 + * vbng_dhcp4.h: DHCP v4 common functions/types
8089 + *
8090 + * Copyright (c) 2017 Intel Corp and/or its affiliates and others.
8091 + * Licensed under the Apache License, Version 2.0 (the "License");
8092 + * you may not use this file except in compliance with the License.
8093 + * You may obtain a copy of the License at:
8094 + *
8095 + *     http://www.apache.org/licenses/LICENSE-2.0
8096 + *
8097 + * Unless required by applicable law or agreed to in writing, software
8098 + * distributed under the License is distributed on an "AS IS" BASIS,
8099 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8100 + * See the License for the specific language governing permissions and
8101 + * limitations under the License.
8102 + */
8103 +
8104 +#ifndef _VBNG_DHCP4_H_
8105 +#define _VBNG_DHCP4_H_
8106 +
8107 +#include <vnet/vnet.h>
8108 +#include <vnet/dhcp/dhcp_proxy.h>
8109 +#include <vnet/dhcp/dhcp4_packet.h>
8110 +#include <vnet/ethernet/ethernet.h>
8111 +#include <vnet/ip/ip.h>
8112 +#include <vnet/ip/ip4.h>
8113 +#include <vnet/ip/ip4_packet.h>
8114 +#include <vnet/pg/pg.h>
8115 +#include <vnet/ip/format.h>
8116 +#include <vnet/udp/udp.h>
8117 +
8118 +typedef enum {
8119 +#define vbng_dhcp4_error(n,s) VBNG_DHCP4_ERROR_##n,
8120 +#include <vbng/vbng_dhcp4_err.def>
8121 +#undef vbng_dhcp4_error
8122 +  VBNG_DHCP4_N_ERROR,
8123 +} vbng_dhcp4_error_t;
8124 +
8125 +#define VBNG_AAA_DISABLED      0
8126 +#define VBNG_AAA_ENABLED       1
8127 +
8128 +typedef struct {
8129 +  int is_enabled;
8130 +  u32 nas_port; /* AAA server port */
8131 +  u8 *config_file; /* Radius Client config file path */
8132 +} vbng_aaa_config_t;
8133 +
8134 +/**
8135 + * @brief Global configuration for the vBNG plugin.
8136 + */
8137 +typedef struct {
8138 +  /* Pool of DHCP servers */
8139 +  dhcp_proxy_t *dhcp4_servers;
8140 +
8141 +  /* Pool of selected DHCP server. Zero is the default server */
8142 +  u32 * dhcp_server_index_by_rx_fib_index;
8143 +
8144 +  /* to drop pkts in server-to-client direction */
8145 +  u32 error_drop_node_index;
8146 +
8147 +  /* Configuration for the AAA client */
8148 +  vbng_aaa_config_t config;
8149 +
8150 +  /* convenience */
8151 +  vlib_main_t * vlib_main;
8152 +  vnet_main_t * vnet_main;
8153 +} vbng_dhcp4_main_t;
8154 +
8155 +extern vbng_dhcp4_main_t vbng_dhcp4_main;
8156 +
8157 +/**
8158 + * @brief Add a new DHCP proxy server configuration.
8159 + * @return 1 is the config is new,
8160 + *         0 otherwise (implying a modify of an existing)
8161 + */
8162 +int vbng_dhcp4_server_add(fib_protocol_t proto,
8163 +                          ip46_address_t *addr,
8164 +                          ip46_address_t *src_address,
8165 +                          u32 rx_fib_iindex,
8166 +                          u32 server_table_id);
8167 +
8168 +/**
8169 + * @brief Delete a DHCP proxy config
8170 + * @return 1 if the proxy is deleted, 0 otherwise
8171 + */
8172 +int vbng_dhcp4_server_del(fib_protocol_t proto,
8173 +                          u32 rx_fib_index,
8174 +                          ip46_address_t *addr,
8175 +                          u32 server_table_id);
8176 +
8177 +u32
8178 +dhcp_proxy_rx_table_get_table_id (fib_protocol_t proto,
8179 +                                  u32 fib_index);
8180 +
8181 +/**
8182 + * @brief Callback function invoked for each DHCP proxy entry
8183 + *  return 0 to break the walk, non-zero otherwise.
8184 + */
8185 +typedef int (*vbng_dhcp4_walk_fn_t)(dhcp_proxy_t *server,
8186 +                                    void *ctx);
8187 +
8188 +/**
8189 + * @brief Walk/Visit each vBNG DHCP server configurations
8190 + */
8191 +void vbng_dhcp4_walk(vbng_dhcp4_walk_fn_t fn,
8192 +                     void *ctx);
8193 +
8194 +/**
8195 + * @brief Get the DHCP proxy server data for the FIB index
8196 + */
8197 +static inline dhcp_proxy_t *
8198 +vbng_dhcp4_get_server(vbng_dhcp4_main_t *vm,
8199 +                     u32 rx_fib_index)
8200 +{
8201 +       dhcp_proxy_t *s = NULL;
8202 +
8203 +       if (vec_len(vm->dhcp_server_index_by_rx_fib_index) > rx_fib_index &&
8204 +           vm->dhcp_server_index_by_rx_fib_index[rx_fib_index] != ~0)
8205 +       {
8206 +               s = pool_elt_at_index (
8207 +                   vm->dhcp4_servers,
8208 +                   vm->dhcp_server_index_by_rx_fib_index[rx_fib_index]);
8209 +       }
8210 +
8211 +       return (s);
8212 +}
8213 +
8214 +int vbng_dhcp4_set_server(ip46_address_t *addr,
8215 +                          ip46_address_t *src_addr,
8216 +                          u32 rx_table_id,
8217 +                          u32 server_table_id,
8218 +                          int is_del);
8219 +
8220 +#define DHCP_PACKET_OPTION_82          82
8221 +#define DHCP_PACKET_OPTION82_SUB1      1
8222 +#define DHCP_PACKET_OPTION82_SUB2      2
8223 +#define DHCP_PACKET_OPTION82_SUB5      5
8224 +
8225 +#endif /* _VBNG_DHCP4_H_ */
8226 diff --git a/src/plugins/vbng/vbng_dhcp4_err.def b/src/plugins/vbng/vbng_dhcp4_err.def
8227 new file mode 100644
8228 index 0000000..23f2d0d
8229 --- /dev/null
8230 +++ b/src/plugins/vbng/vbng_dhcp4_err.def
8231 @@ -0,0 +1,29 @@
8232 +/*
8233 + * vbng_dhcp4_err.def: VBNG DHCP4 Errors
8234 + *
8235 + * Copyright (c) 2017 Intel Corp and/or its affiliates and others.
8236 + * Licensed under the Apache License, Version 2.0 (the "License");
8237 + * you may not use this file except in compliance with the License.
8238 + * You may obtain a copy of the License at:
8239 + *
8240 + *     http://www.apache.org/licenses/LICENSE-2.0
8241 + *
8242 + * Unless required by applicable law or agreed to in writing, software
8243 + * distributed under the License is distributed on an "AS IS" BASIS,
8244 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8245 + * See the License for the specific language governing permissions and
8246 + * limitations under the License.
8247 + */
8248 +
8249 +vbng_dhcp4_error (NONE, "no error")
8250 +vbng_dhcp4_error (NO_SERVER, "no dhcp server configured")
8251 +vbng_dhcp4_error (RELAY_TO_SERVER, "DHCP packets relayed to the server")
8252 +vbng_dhcp4_error (RELAY_TO_CLIENT, "DHCP packets relayed to clients")
8253 +vbng_dhcp4_error (NO_INTERFACE_ADDRESS, "DHCP no interface address")
8254 +vbng_dhcp4_error (BAD_YIADDR, "DHCP packets with bad your_ip_address fields")
8255 +vbng_dhcp4_error (BAD_SVR_FIB_OR_ADDRESS, "DHCP packets not from DHCP server or server FIB.")
8256 +vbng_dhcp4_error (PKT_TOO_BIG, "DHCP packets which are too big.")
8257 +vbng_dhcp4_error (AAA_FAILURE, "DHCP packets failed to pass the AAA check.")
8258 +vbng_dhcp4_error (NO_OPTION_82, "DHCP option 82 missing")
8259 +vbng_dhcp4_error (BAD_OPTION_82_ITF, "Bad DHCP option 82 interface value")
8260 +vbng_dhcp4_error (BAD_OPTION_82_ADDR, "Bad DHCP option 82 address value")
8261 diff --git a/src/plugins/vbng/vbng_dhcp4_node.c b/src/plugins/vbng/vbng_dhcp4_node.c
8262 new file mode 100644
8263 index 0000000..205959b
8264 --- /dev/null
8265 +++ b/src/plugins/vbng/vbng_dhcp4_node.c
8266 @@ -0,0 +1,1024 @@
8267 +/*
8268 + * proxy_node.c: dhcp proxy node processing
8269 + *
8270 + * Copyright (c) 2013 Cisco and/or its affiliates and others.
8271 + * Licensed under the Apache License, Version 2.0 (the "License");
8272 + * you may not use this file except in compliance with the License.
8273 + * You may obtain a copy of the License at:
8274 + *
8275 + *     http://www.apache.org/licenses/LICENSE-2.0
8276 + *
8277 + * Unless required by applicable law or agreed to in writing, software
8278 + * distributed under the License is distributed on an "AS IS" BASIS,
8279 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8280 + * See the License for the specific language governing permissions and
8281 + * limitations under the License.
8282 + */
8283 +
8284 +#include <vlib/vlib.h>
8285 +#include <vnet/pg/pg.h>
8286 +#include <vnet/fib/ip4_fib.h>
8287 +#include <vnet/dhcp/client.h>
8288 +#include <vnet/plugin/plugin.h>
8289 +#include <vpp/app/version.h>
8290 +
8291 +#include <vbng/vbng_dhcp4.h>
8292 +#include <vbng/vbng_aaa.h>
8293 +
8294 +static char * vbng_dhcp4_error_strings[] = {
8295 +#define vbng_dhcp4_error(n,s) s,
8296 +#include <vbng/vbng_dhcp4_err.def>
8297 +#undef vbng_dhcp4_error
8298 +};
8299 +
8300 +#define foreach_vbng_dhcp4_to_server_input_next \
8301 +  _ (DROP, "error-drop")                       \
8302 +  _ (LOOKUP, "ip4-lookup")                     \
8303 +  _ (SEND_TO_CLIENT, "vbng-dhcp-to-client")
8304 +
8305 +typedef enum {
8306 +#define _(s,n) VBNG_DHCP4_TO_SERVER_INPUT_NEXT_##s,
8307 +  foreach_vbng_dhcp4_to_server_input_next
8308 +#undef _
8309 +  VBNG_DHCP4_TO_SERVER_INPUT_N_NEXT,
8310 +} vbng_dhcp4_to_server_input_next_t;
8311 +
8312 +typedef struct {
8313 +  /* 0 => to server, 1 => to client */
8314 +  int which;
8315 +  ip4_address_t trace_ip4_address;
8316 +  u32 error;
8317 +  u32 sw_if_index;
8318 +  u32 original_sw_if_index;
8319 +} dhcp_proxy_trace_t;
8320 +
8321 +#define VPP_DHCP_OPTION82_SUB1_SIZE   6
8322 +#define VPP_DHCP_OPTION82_SUB5_SIZE   6
8323 +#define VPP_DHCP_OPTION82_VSS_SIZE    12
8324 +#define VPP_DHCP_OPTION82_SIZE (VPP_DHCP_OPTION82_SUB1_SIZE + \
8325 +                                VPP_DHCP_OPTION82_SUB5_SIZE + \
8326 +                                VPP_DHCP_OPTION82_VSS_SIZE +3)
8327 +
8328 +static vlib_node_registration_t vbng_dhcp4_to_server_node;
8329 +static vlib_node_registration_t vbng_dhcp4_to_client_node;
8330 +
8331 +static u8 *
8332 +format_dhcp_proxy_trace (u8 * s, va_list * args)
8333 +{
8334 +  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
8335 +  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
8336 +  dhcp_proxy_trace_t * t = va_arg (*args, dhcp_proxy_trace_t *);
8337
8338 +  if (t->which == 0)
8339 +    s = format (s, "DHCP proxy: sent to server %U\n",
8340 +                format_ip4_address, &t->trace_ip4_address, t->error);
8341 +  else
8342 +    s = format (s, "DHCP proxy: broadcast to client from %U\n",
8343 +                format_ip4_address, &t->trace_ip4_address);
8344 +
8345 +  if (t->error != (u32)~0)
8346 +    s = format (s, "  error: %s\n", vbng_dhcp4_error_strings[t->error]);
8347 +
8348 +  s = format (s, "  original_sw_if_index: %d, sw_if_index: %d\n",
8349 +              t->original_sw_if_index, t->sw_if_index);
8350 +  
8351 +  return s;
8352 +}
8353 +
8354 +static u8 *
8355 +format_dhcp_proxy_header_with_length (u8 * s, va_list * args)
8356 +{
8357 +  dhcp_header_t * h = va_arg (*args, dhcp_header_t *);
8358 +  u32 max_header_bytes = va_arg (*args, u32);
8359 +  u32 header_bytes;
8360 +
8361 +  header_bytes = sizeof (h[0]);
8362 +  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
8363 +    return format (s, "dhcp header truncated");
8364 +
8365 +  s = format (s, "DHCP Proxy");
8366 +
8367 +  return s;
8368 +}
8369 +
8370 +static uword
8371 +vbng_dhcp_to_server_input (vlib_main_t * vm,
8372 +                           vlib_node_runtime_t * node,
8373 +                           vlib_frame_t * from_frame)
8374 +{
8375 +  u32 n_left_from, next_index, * from, * to_next;
8376 +  vbng_dhcp4_main_t *dm = &vbng_dhcp4_main;
8377 +  from = vlib_frame_vector_args (from_frame);
8378 +  n_left_from = from_frame->n_vectors;
8379 +  u32 pkts_to_server=0, pkts_to_client=0, pkts_no_server=0;
8380 +  u32 pkts_no_interface_address=0;
8381 +  u32 pkts_too_big=0, pkts_aaa_fail = 0;
8382 +  ip4_main_t * im = &ip4_main;
8383 +
8384 +  next_index = node->cached_next_index;
8385 +
8386 +  while (n_left_from > 0)
8387 +    {
8388 +      u32 n_left_to_next;
8389 +
8390 +      vlib_get_next_frame (vm, node, next_index,
8391 +                          to_next, n_left_to_next);
8392 +
8393 +      while (n_left_from > 0 && n_left_to_next > 0)
8394 +       {
8395 +         u32 bi0;
8396 +         vlib_buffer_t * b0;
8397 +          udp_header_t * u0;
8398 +         dhcp_header_t * h0;
8399 +          ip4_header_t * ip0;
8400 +         u32 next0;
8401 +          u32 old0, new0;
8402 +          ip_csum_t sum0;
8403 +          u32 error0 = (u32) ~0;
8404 +          u32 sw_if_index = 0;
8405 +          u32 original_sw_if_index = 0;
8406 +          u8  *end = NULL;
8407 +          u32 fib_index;
8408 +          dhcp_proxy_t *proxy;
8409 +          dhcp_server_t *server;
8410 +          u32 rx_sw_if_index;
8411 +          dhcp_option_t *o;
8412 +          u32 len = 0;
8413 +          vlib_buffer_free_list_t *fl;
8414 +          u8 is_discover = 0;
8415 +
8416 +         bi0 = from[0];
8417 +         from += 1;
8418 +         n_left_from -= 1;
8419 +
8420 +         b0 = vlib_get_buffer (vm, bi0);
8421 +
8422 +          h0 = vlib_buffer_get_current (b0);
8423 +
8424 +          /* 
8425 +           * udp_local hands us the DHCP header, need udp hdr, 
8426 +           * ip hdr to relay to server
8427 +           */
8428 +          vlib_buffer_advance (b0, -(sizeof(*u0)));
8429 +         u0 = vlib_buffer_get_current (b0);
8430 +
8431 +          /* This blows. Return traffic has src_port = 67, dst_port = 67 */
8432 +          if (u0->src_port == clib_net_to_host_u16(UDP_DST_PORT_dhcp_to_server))
8433 +            {
8434 +              vlib_buffer_advance (b0, sizeof(*u0));
8435 +              next0 = VBNG_DHCP4_TO_SERVER_INPUT_NEXT_SEND_TO_CLIENT;
8436 +              error0 = 0;
8437 +              pkts_to_client++;
8438 +              goto do_enqueue;
8439 +            }
8440 +
8441 +          rx_sw_if_index = vnet_buffer(b0)->sw_if_index[VLIB_RX];
8442 +
8443 +          fib_index = im->fib_index_by_sw_if_index [rx_sw_if_index];
8444 +          proxy = vbng_dhcp4_get_server(dm, fib_index);
8445 +
8446 +          if (PREDICT_FALSE (NULL == proxy))
8447 +            {
8448 +              error0 = VBNG_DHCP4_ERROR_NO_SERVER;
8449 +              next0 = VBNG_DHCP4_TO_SERVER_INPUT_NEXT_DROP;
8450 +              pkts_no_server++;
8451 +              goto do_trace;
8452 +            }
8453 +
8454 +          server = &proxy->dhcp_servers[0];
8455 +          vlib_buffer_advance (b0, -(sizeof(*ip0)));
8456 +          ip0 = vlib_buffer_get_current (b0);
8457 +
8458 +          /* disable UDP checksum */
8459 +          u0->checksum = 0;
8460 +          sum0 = ip0->checksum;
8461 +          old0 = ip0->dst_address.as_u32;
8462 +          new0 = server->dhcp_server.ip4.as_u32;
8463 +          ip0->dst_address.as_u32 = server->dhcp_server.ip4.as_u32;
8464 +          sum0 = ip_csum_update (sum0, old0, new0, 
8465 +                                ip4_header_t /* structure */, 
8466 +                                dst_address /* changed member */);
8467 +          ip0->checksum = ip_csum_fold (sum0);
8468 +
8469 +          sum0 = ip0->checksum;
8470 +          old0 = ip0->src_address.as_u32;
8471 +          new0 = proxy->dhcp_src_address.ip4.as_u32;
8472 +          ip0->src_address.as_u32 = new0;
8473 +          sum0 = ip_csum_update (sum0, old0, new0, 
8474 +                                ip4_header_t /* structure */, 
8475 +                                src_address /* changed member */);
8476 +          ip0->checksum = ip_csum_fold (sum0);
8477 +
8478 +          /* Send to DHCP server via the configured FIB */
8479 +          vnet_buffer(b0)->sw_if_index[VLIB_TX] =
8480 +            server->server_fib_index;
8481 +
8482 +          h0->gateway_ip_address.as_u32 = proxy->dhcp_src_address.ip4.as_u32;
8483 +          pkts_to_server++;
8484 +
8485 +          o = (dhcp_option_t *) h0->options;
8486 +              
8487 +          fib_index = im->fib_index_by_sw_if_index 
8488 +              [vnet_buffer(b0)->sw_if_index[VLIB_RX]];
8489 +
8490 +          end = b0->data + b0->current_data + b0->current_length;
8491 +          /* TLVs are not performance-friendly... */
8492 +          while  (o->option != 0xFF /* end of options */ && (u8 *)o < end) 
8493 +            {
8494 +              if (DHCP_PACKET_OPTION_MSG_TYPE == o->option)
8495 +                {
8496 +                  if (DHCP_PACKET_DISCOVER == o->data[0])
8497 +                    {
8498 +                      is_discover = 1;
8499 +                    }
8500 +                }
8501 +
8502 +             if (DHCP_PACKET_OPTION_82 == o->option) {
8503 +                /* For Demo purpose only */
8504 +                if (dm->config.is_enabled) {
8505 +                  int i = 0, num_kvs = 0, retval = 0;
8506 +                  char *kv_pairs[1];
8507 +                  char key_string[32];
8508 +
8509 +                  if (DHCP_PACKET_OPTION82_SUB1 == o->data[0]) {
8510 +                      sprintf(key_string,  STR_TPL_ATTR_DHCP_AGENT_CIRCUIT_ID, o->data[2]);
8511 +                      for (i = 1; i < o->data[1]; i++) {
8512 +                          sprintf(key_string, "%s%c", key_string, o->data[2 + i]);
8513 +                      }
8514 +                  }
8515 +
8516 +                  if (DHCP_PACKET_OPTION82_SUB2 == o->data[0]) {
8517 +                      sprintf(key_string, STR_TPL_ATTR_DHCP_AGENT_REMOTE_ID, o->data[2]);
8518 +                      for (i = 1; i < o->data[1]; i++) {
8519 +                          sprintf(key_string, "%s%c", key_string, o->data[2 + i]);
8520 +                      }
8521 +                  }
8522 +
8523 +                  kv_pairs[num_kvs] = key_string;
8524 +                  num_kvs++;
8525 +
8526 +                 retval = vbng_auth(dm, num_kvs, kv_pairs);
8527 +                 if (retval) {
8528 +                    if (retval == 1 /* TIMEOUT_RC */) {
8529 +                        dm->config.is_enabled = VBNG_AAA_DISABLED;
8530 +                    }
8531 +                    error0 = VBNG_DHCP4_ERROR_AAA_FAILURE;
8532 +                    next0 = VBNG_DHCP4_TO_SERVER_INPUT_NEXT_DROP;
8533 +                    pkts_aaa_fail++;
8534 +                    goto do_trace;
8535 +                 }
8536 +               }
8537 +
8538 +                fl = vlib_buffer_get_free_list (vm, b0->free_list_index);
8539 +                if (((u8 *)o - (u8 *)b0->data + (VPP_DHCP_OPTION82_SUB1_SIZE + VPP_DHCP_OPTION82_SUB5_SIZE))
8540 +                    > fl->n_data_bytes)
8541 +                {
8542 +                    next0 = VBNG_DHCP4_TO_SERVER_INPUT_NEXT_DROP;
8543 +                    pkts_too_big++;
8544 +                    goto do_trace;
8545 +                }
8546 +
8547 +                /* Begin to appending new sub-options */
8548 +                {
8549 +                    vnet_main_t *vnm = vnet_get_main();   
8550 +                    u16 old_l0, new_l0, orig_len = 0;
8551 +                    ip4_address_t _ia0, * ia0 = &_ia0;
8552 +                    vnet_sw_interface_t *swif;
8553 +                    sw_if_index = 0;
8554 +                    original_sw_if_index = 0;
8555 +                        
8556 +                    original_sw_if_index = sw_if_index = 
8557 +                        vnet_buffer(b0)->sw_if_index[VLIB_RX];
8558 +                    swif = vnet_get_sw_interface (vnm, sw_if_index);
8559 +                    if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
8560 +                        sw_if_index = swif->unnumbered_sw_if_index;
8561 +                        
8562 +                    /* 
8563 +                     * Get the first ip4 address on the [client-side] 
8564 +                     * RX interface, if not unnumbered. otherwise use
8565 +                     * the loopback interface's ip address.
8566 +                     */
8567 +                    ia0 = ip4_interface_first_address(&ip4_main, sw_if_index, 0);
8568 +                        
8569 +                    if (ia0 == 0)
8570 +                    {
8571 +                        error0 = VBNG_DHCP4_ERROR_NO_INTERFACE_ADDRESS;
8572 +                        next0 = VBNG_DHCP4_TO_SERVER_INPUT_NEXT_DROP;
8573 +                        pkts_no_interface_address++;
8574 +                        goto do_trace;
8575 +                    }
8576 +
8577 +                    orig_len = o->length;
8578 +                    o->data[orig_len + 0] = 1;   /* suboption 1, circuit ID (=FIB id) */
8579 +                    o->data[orig_len + 1] = 4;   /* length of suboption */
8580 +                    o->data[orig_len + 2] = (original_sw_if_index >> 24) & 0xFF;
8581 +                    o->data[orig_len + 3] = (original_sw_if_index >> 16) & 0xFF;
8582 +                    o->data[orig_len + 4] = (original_sw_if_index >> 8)  & 0xFF;
8583 +                    o->data[orig_len + 5] = (original_sw_if_index >> 0)  & 0xFF;
8584 +                    o->data[orig_len + 6] = 5; /* suboption 5 (client RX intfc address) */
8585 +                    o->data[orig_len + 7] = 4; /* length 4 */
8586 +                    o->data[orig_len + 8] = ia0->as_u8[0];
8587 +                    o->data[orig_len + 9] = ia0->as_u8[1];
8588 +                    o->data[orig_len + 10] = ia0->as_u8[2];
8589 +                    o->data[orig_len + 11] = ia0->as_u8[3];
8590 +                    o->data[orig_len + 12] = 0xFF;
8591 +                    o->length += 12;   /* 12 octets appended*/
8592 +
8593 +                    len = o->length + 3;
8594 +                    b0->current_length += len;
8595 +                    /* Fix IP header length and checksum */
8596 +                    old_l0 = ip0->length;
8597 +                    new_l0 = clib_net_to_host_u16 (old_l0);
8598 +                    new_l0 += len;
8599 +                    new_l0 = clib_host_to_net_u16 (new_l0);
8600 +                    ip0->length = new_l0;
8601 +                    sum0 = ip0->checksum;
8602 +                    sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
8603 +                                           length /* changed member */);
8604 +                    ip0->checksum = ip_csum_fold (sum0);
8605 +      
8606 +                    /* Fix UDP length */
8607 +                    new_l0 = clib_net_to_host_u16 (u0->length);
8608 +                    new_l0 += len;
8609 +                    u0->length = clib_host_to_net_u16 (new_l0);
8610 +                }
8611 +              }
8612 +
8613 +              o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
8614 +          }
8615 +
8616 +          next0 = VBNG_DHCP4_TO_SERVER_INPUT_NEXT_LOOKUP;
8617 +
8618 +          /*
8619 +           * If we have multiple servers configured and this is the
8620 +           * client's discover message, then send copies to each of
8621 +           * those servers
8622 +           */
8623 +          if (is_discover && vec_len(proxy->dhcp_servers) > 1)
8624 +          {
8625 +              u32 ii;
8626 +
8627 +              for (ii = 1; ii < vec_len(proxy->dhcp_servers); ii++)
8628 +              {
8629 +                  vlib_buffer_t *c0;
8630 +                  u32 ci0;
8631 +              
8632 +                  c0 = vlib_buffer_copy(vm, b0);
8633 +                  ci0 = vlib_get_buffer_index(vm, c0);
8634 +                  server = &proxy->dhcp_servers[ii];
8635 +
8636 +                  ip0 = vlib_buffer_get_current (c0);
8637 +
8638 +                  sum0 = ip0->checksum;
8639 +                  old0 = ip0->dst_address.as_u32;
8640 +                  new0 = server->dhcp_server.ip4.as_u32;
8641 +                  ip0->dst_address.as_u32 = server->dhcp_server.ip4.as_u32;
8642 +                  sum0 = ip_csum_update (sum0, old0, new0, 
8643 +                                         ip4_header_t /* structure */, 
8644 +                                         dst_address /* changed member */);
8645 +                  ip0->checksum = ip_csum_fold (sum0);
8646 +
8647 +                  to_next[0] = ci0;
8648 +                  to_next += 1;
8649 +                  n_left_to_next -= 1;
8650 +
8651 +                  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
8652 +                                                   to_next, n_left_to_next,
8653 +                                                   ci0, next0);
8654 +
8655 +                  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) 
8656 +                  {
8657 +                      dhcp_proxy_trace_t *tr;
8658 +
8659 +                      tr = vlib_add_trace (vm, node, c0, sizeof (*tr));
8660 +                      tr->which = 0; /* to server */
8661 +                      tr->error = error0;
8662 +                      tr->original_sw_if_index = original_sw_if_index;
8663 +                      tr->sw_if_index = sw_if_index;
8664 +                      if (next0 == VBNG_DHCP4_TO_SERVER_INPUT_NEXT_LOOKUP)
8665 +                          tr->trace_ip4_address.as_u32 = server->dhcp_server.ip4.as_u32;
8666 +                  }
8667 +
8668 +                  if (PREDICT_FALSE(0 == n_left_to_next))
8669 +                  {
8670 +                      vlib_put_next_frame (vm, node, next_index,
8671 +                                           n_left_to_next);
8672 +                      vlib_get_next_frame (vm, node, next_index,
8673 +                                           to_next, n_left_to_next);
8674 +                  }
8675 +              }
8676 +          }
8677 +        do_trace:
8678 +          if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) 
8679 +            {
8680 +               dhcp_proxy_trace_t *tr = vlib_add_trace (vm, node, 
8681 +                                                        b0, sizeof (*tr));
8682 +               tr->which = 0; /* to server */
8683 +               tr->error = error0;
8684 +               tr->original_sw_if_index = original_sw_if_index;
8685 +               tr->sw_if_index = sw_if_index;
8686 +               if (next0 == VBNG_DHCP4_TO_SERVER_INPUT_NEXT_LOOKUP)
8687 +                 tr->trace_ip4_address.as_u32 =
8688 +                     proxy->dhcp_servers[0].dhcp_server.ip4.as_u32;
8689 +            }
8690 +
8691 +        do_enqueue:
8692 +         to_next[0] = bi0;
8693 +         to_next += 1;
8694 +         n_left_to_next -= 1;
8695 +
8696 +         vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
8697 +                                          to_next, n_left_to_next,
8698 +                                          bi0, next0);
8699 +       }
8700 +
8701 +      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
8702 +    }
8703 +
8704 +  vlib_node_increment_counter (vm, vbng_dhcp4_to_server_node.index,
8705 +                               VBNG_DHCP4_ERROR_RELAY_TO_CLIENT,
8706 +                               pkts_to_client);
8707 +  vlib_node_increment_counter (vm, vbng_dhcp4_to_server_node.index,
8708 +                               VBNG_DHCP4_ERROR_RELAY_TO_SERVER,
8709 +                               pkts_to_server);
8710 +  vlib_node_increment_counter (vm, vbng_dhcp4_to_server_node.index,
8711 +                               VBNG_DHCP4_ERROR_NO_SERVER,
8712 +                               pkts_no_server);
8713 +  vlib_node_increment_counter (vm, vbng_dhcp4_to_server_node.index,
8714 +                               VBNG_DHCP4_ERROR_NO_INTERFACE_ADDRESS,
8715 +                               pkts_no_interface_address);
8716 + vlib_node_increment_counter (vm, vbng_dhcp4_to_server_node.index,
8717 +                              VBNG_DHCP4_ERROR_PKT_TOO_BIG,
8718 +                              pkts_too_big);
8719 + vlib_node_increment_counter (vm, vbng_dhcp4_to_server_node.index,
8720 +                              VBNG_DHCP4_ERROR_AAA_FAILURE,
8721 +                              pkts_aaa_fail);
8722 +  return from_frame->n_vectors;
8723 +}
8724 +
8725 +VLIB_REGISTER_NODE (vbng_dhcp4_to_server_node, static) = {
8726 +  .function = vbng_dhcp_to_server_input,
8727 +  .name = "vbng-dhcp-to-server",
8728 +  /* Takes a vector of packets. */
8729 +  .vector_size = sizeof (u32),
8730 +
8731 +  .n_errors = VBNG_DHCP4_N_ERROR,
8732 +  .error_strings = vbng_dhcp4_error_strings,
8733 +
8734 +  .n_next_nodes = VBNG_DHCP4_TO_SERVER_INPUT_N_NEXT,
8735 +  .next_nodes = {
8736 +#define _(s,n) [VBNG_DHCP4_TO_SERVER_INPUT_NEXT_##s] = n,
8737 +    foreach_vbng_dhcp4_to_server_input_next
8738 +#undef _
8739 +  },
8740 +
8741 +  .format_buffer = format_dhcp_proxy_header_with_length,
8742 +  .format_trace = format_dhcp_proxy_trace,
8743 +};
8744 +
8745 +static uword
8746 +vbng_dhcp_to_client_input (vlib_main_t * vm,
8747 +                           vlib_node_runtime_t * node,
8748 +                           vlib_frame_t * from_frame)
8749 +{
8750 +  u32 n_left_from, * from;
8751 +  ethernet_main_t *em = ethernet_get_main (vm);
8752 +  vbng_dhcp4_main_t *dm = &vbng_dhcp4_main;
8753 +  vnet_main_t * vnm = vnet_get_main();
8754 +  ip4_main_t * im = &ip4_main;
8755 +
8756 +  from = vlib_frame_vector_args (from_frame);
8757 +  n_left_from = from_frame->n_vectors;
8758 +
8759 +  while (n_left_from > 0)
8760 +    {
8761 +      u32 bi0;
8762 +      vlib_buffer_t * b0;
8763 +      udp_header_t * u0;
8764 +      dhcp_header_t * h0;
8765 +      ip4_header_t * ip0 = 0;
8766 +      ip4_address_t * ia0 = 0;
8767 +      u32 old0, new0;
8768 +      ip_csum_t sum0;
8769 +      ethernet_interface_t *ei0;
8770 +      ethernet_header_t *mac0;
8771 +      vnet_hw_interface_t *hi0;
8772 +      vlib_frame_t *f0;
8773 +      u32 * to_next0;
8774 +      u32 sw_if_index = ~0;
8775 +      vnet_sw_interface_t *si0;
8776 +      u32 error0 = (u32)~0;
8777 +      vnet_sw_interface_t *swif;
8778 +      u32 fib_index;
8779 +      dhcp_proxy_t *proxy;
8780 +      dhcp_server_t *server;
8781 +      u32 original_sw_if_index = (u32) ~0;
8782 +      ip4_address_t relay_addr = {
8783 +          .as_u32 = 0,
8784 +      };
8785 +
8786 +      bi0 = from[0];
8787 +      from += 1;
8788 +      n_left_from -= 1;
8789 +
8790 +      b0 = vlib_get_buffer (vm, bi0);
8791 +      h0 = vlib_buffer_get_current (b0);
8792 +
8793 +      /* 
8794 +       * udp_local hands us the DHCP header, need udp hdr, 
8795 +       * ip hdr to relay to client
8796 +       */
8797 +      vlib_buffer_advance (b0, -(sizeof(*u0)));
8798 +      u0 = vlib_buffer_get_current (b0);
8799 +
8800 +      vlib_buffer_advance (b0, -(sizeof(*ip0)));
8801 +      ip0 = vlib_buffer_get_current (b0);
8802 +
8803 +      {
8804 +          dhcp_option_t *o = (dhcp_option_t *) h0->options;
8805 +          dhcp_option_t *sub;
8806 +              
8807 +          /* Parse through TLVs looking for option 82.
8808 +             The circuit-ID is the FIB number we need
8809 +             to track down the client-facing interface */
8810 +
8811 +          while (o->option != 0xFF /* end of options */ &&
8812 +                 (u8 *) o < (b0->data + b0->current_data + b0->current_length))
8813 +            {
8814 +              if (o->option == 82)
8815 +                {
8816 +                    sub = (dhcp_option_t *) &o->data[0];
8817 +                    while (sub->option != 0xFF /* end of options */ &&
8818 +                           (u8 *) sub < (u8 *)(o + o->length)) {
8819 +                        /* If this is one of ours, it will have
8820 +                           total length 12, circuit-id suboption type,
8821 +                           and the sw_if_index */
8822 +                        if (sub->option == 1 && sub->length == 4)
8823 +                          {
8824 +                            sw_if_index = ((sub->data[0] << 24) |
8825 +                                           (sub->data[1] << 16) |
8826 +                                           (sub->data[2] << 8)  |
8827 +                                           (sub->data[3]));
8828 +                          }
8829 +                        else if (sub->option == 5 && sub->length == 4)
8830 +                          {
8831 +                              relay_addr.as_u8[0] = sub->data[0];
8832 +                              relay_addr.as_u8[1] = sub->data[1];
8833 +                              relay_addr.as_u8[2] = sub->data[2];
8834 +                              relay_addr.as_u8[3] = sub->data[3];
8835 +                          }
8836 +                        sub = (dhcp_option_t *) 
8837 +                          (((uword) sub) + (sub->length + 2));
8838 +                    }
8839 +
8840 +                }
8841 +              o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
8842 +            }
8843 +        }
8844 +
8845 +      if (sw_if_index == (u32)~0)
8846 +        {
8847 +          error0 = VBNG_DHCP4_ERROR_NO_OPTION_82;
8848 +          
8849 +        drop_packet:
8850 +          vlib_node_increment_counter (vm, vbng_dhcp4_to_client_node.index,
8851 +                                       error0, 1);
8852 +          f0 = vlib_get_frame_to_node (vm, dm->error_drop_node_index);
8853 +          to_next0 = vlib_frame_vector_args (f0);
8854 +          to_next0[0] = bi0;
8855 +          f0->n_vectors = 1;
8856 +          vlib_put_frame_to_node (vm, dm->error_drop_node_index, f0);
8857 +          goto do_trace;
8858 +        }
8859 +      
8860 +      if (relay_addr.as_u32 == 0)
8861 +        {
8862 +          error0 = VBNG_DHCP4_ERROR_BAD_OPTION_82_ADDR;
8863 +          goto drop_packet;
8864 +        }
8865 +
8866 +      if (sw_if_index >= vec_len (im->fib_index_by_sw_if_index))
8867 +        {
8868 +          error0 = VBNG_DHCP4_ERROR_BAD_OPTION_82_ITF;
8869 +          goto drop_packet;
8870 +        }
8871 +
8872 +      fib_index = im->fib_index_by_sw_if_index [sw_if_index];
8873 +      proxy = vbng_dhcp4_get_server(dm, fib_index);
8874 +
8875 +      if (PREDICT_FALSE (NULL == proxy))
8876 +        {
8877 +          error0 = VBNG_DHCP4_ERROR_NO_SERVER;
8878 +          goto drop_packet;
8879 +        }
8880 +      
8881 +      vec_foreach(server, proxy->dhcp_servers)
8882 +        {
8883 +          if (ip0->src_address.as_u32 == server->dhcp_server.ip4.as_u32)
8884 +            {
8885 +              goto server_found;
8886 +            }
8887 +        }
8888 +
8889 +      error0 = VBNG_DHCP4_ERROR_BAD_SVR_FIB_OR_ADDRESS;
8890 +      goto drop_packet;
8891 +
8892 +    server_found:
8893 +      vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index;
8894 +
8895 +      swif = vnet_get_sw_interface (vnm, sw_if_index);
8896 +      original_sw_if_index = sw_if_index;
8897 +      if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
8898 +          sw_if_index = swif->unnumbered_sw_if_index;
8899 +
8900 +      ia0 = ip4_interface_first_address (&ip4_main, sw_if_index, 0);
8901 +      if (ia0 == 0)
8902 +        {
8903 +          error0 = VBNG_DHCP4_ERROR_NO_INTERFACE_ADDRESS;
8904 +          goto drop_packet;
8905 +        }
8906 +
8907 +      if (relay_addr.as_u32 != ia0->as_u32)
8908 +        {             
8909 +          error0 = VBNG_DHCP4_ERROR_BAD_YIADDR;
8910 +          goto drop_packet;
8911 +        }
8912 +
8913 +      u0->checksum = 0;
8914 +      u0->dst_port = clib_net_to_host_u16 (UDP_DST_PORT_dhcp_to_client);
8915 +      sum0 = ip0->checksum;
8916 +      old0 = ip0->dst_address.as_u32;
8917 +      new0 = 0xFFFFFFFF;
8918 +      ip0->dst_address.as_u32 = new0;
8919 +      sum0 = ip_csum_update (sum0, old0, new0, 
8920 +                            ip4_header_t /* structure */, 
8921 +                            dst_address /* offset of changed member */);
8922 +      ip0->checksum = ip_csum_fold (sum0);
8923 +
8924 +      sum0 = ip0->checksum;
8925 +      old0 = ip0->src_address.as_u32;
8926 +      new0 = ia0->as_u32;
8927 +      ip0->src_address.as_u32 = new0;
8928 +      sum0 = ip_csum_update (sum0, old0, new0, 
8929 +                            ip4_header_t /* structure */, 
8930 +                            src_address /* offset of changed member */);
8931 +      ip0->checksum = ip_csum_fold (sum0);
8932 +
8933 +      vlib_buffer_advance (b0, -(sizeof(ethernet_header_t)));
8934 +      si0 = vnet_get_sw_interface (vnm, original_sw_if_index);
8935 +      if (si0->type == VNET_SW_INTERFACE_TYPE_SUB)
8936 +         vlib_buffer_advance (b0, -4 /* space for VLAN tag */);
8937 +
8938 +      mac0 = vlib_buffer_get_current (b0);
8939 +
8940 +      hi0 = vnet_get_sup_hw_interface (vnm, original_sw_if_index);
8941 +      ei0 = pool_elt_at_index (em->interfaces, hi0->hw_instance);
8942 +      clib_memcpy (mac0->src_address, ei0->address, sizeof (ei0->address));
8943 +      memset (mac0->dst_address, 0xff, sizeof (mac0->dst_address));
8944 +      mac0->type = (si0->type == VNET_SW_INTERFACE_TYPE_SUB) ?
8945 +       clib_net_to_host_u16(0x8100) : clib_net_to_host_u16 (0x0800);
8946 +
8947 +      if (si0->type == VNET_SW_INTERFACE_TYPE_SUB)
8948 +       {
8949 +         u32 * vlan_tag = (u32 *)(mac0+1);
8950 +         u32 tmp;
8951 +         tmp = (si0->sub.id << 16) | 0x0800;
8952 +         *vlan_tag = clib_host_to_net_u32 (tmp);
8953 +       }
8954 +
8955 +      /* $$$ This needs to be rewritten, for sure */
8956 +      f0 = vlib_get_frame_to_node (vm, hi0->output_node_index);
8957 +      to_next0 = vlib_frame_vector_args (f0);
8958 +      to_next0[0] = bi0;
8959 +      f0->n_vectors = 1;
8960 +      vlib_put_frame_to_node (vm, hi0->output_node_index, f0);
8961 +
8962 +    do_trace:
8963 +      if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) 
8964 +        {
8965 +          dhcp_proxy_trace_t *tr = vlib_add_trace (vm, node, 
8966 +                                                   b0, sizeof (*tr));
8967 +          tr->which = 1; /* to client */
8968 +          tr->trace_ip4_address.as_u32 = ia0 ? ia0->as_u32 : 0;
8969 +          tr->error = error0;
8970 +          tr->original_sw_if_index = original_sw_if_index;
8971 +          tr->sw_if_index = sw_if_index;
8972 +        }
8973 +    }
8974 +  return from_frame->n_vectors;
8975 +}
8976 +
8977 +VLIB_REGISTER_NODE (vbng_dhcp4_to_client_node, static) = {
8978 +  .function = vbng_dhcp_to_client_input,
8979 +  .name = "vbng-dhcp-to-client",
8980 +  /* Takes a vector of packets. */
8981 +  .vector_size = sizeof (u32),
8982 +
8983 +  .n_errors = VBNG_DHCP4_N_ERROR,
8984 +  .error_strings = vbng_dhcp4_error_strings,
8985 +  .format_buffer = format_dhcp_proxy_header_with_length,
8986 +  .format_trace = format_dhcp_proxy_trace,
8987 +};
8988 +
8989 +static clib_error_t *
8990 +vbng_dhcp4_proxy_init (vlib_main_t * vm)
8991 +{
8992 +  vbng_dhcp4_main_t *dm = &vbng_dhcp4_main;
8993 +  vlib_node_t * error_drop_node;
8994 +
8995 +  error_drop_node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
8996 +  dm->error_drop_node_index = error_drop_node->index;
8997 +
8998 +  udp_register_dst_port (vm, UDP_DST_PORT_dhcp_to_client, 
8999 +                         vbng_dhcp4_to_client_node.index, 1 /* is_ip4 */);
9000 +
9001 +  udp_register_dst_port (vm, UDP_DST_PORT_dhcp_to_server, 
9002 +                         vbng_dhcp4_to_server_node.index, 1 /* is_ip4 */);
9003 +
9004 +  dm->vlib_main = vm;
9005 +  dm->vnet_main = vnet_get_main();
9006 +
9007 +  return 0;
9008 +}
9009 +
9010 +/* *INDENT-OFF* */
9011 +VLIB_INIT_FUNCTION (vbng_dhcp4_proxy_init);
9012 +/* *INDENT-ON* */
9013 +
9014 +int
9015 +vbng_dhcp4_set_server (ip46_address_t *addr,
9016 +                       ip46_address_t *src_addr,
9017 +                       u32 rx_table_id,
9018 +                       u32 server_table_id, 
9019 +                       int is_del)
9020 +{
9021 +  u32 rx_fib_index = 0;
9022 +  int rc = 0;
9023 +
9024 +  const fib_prefix_t all_1s =
9025 +  {
9026 +      .fp_len = 32,
9027 +      .fp_addr.ip4.as_u32 = 0xffffffff,
9028 +      .fp_proto = FIB_PROTOCOL_IP4,
9029 +  };
9030 +
9031 +  if (ip46_address_is_zero(addr))
9032 +    return VNET_API_ERROR_INVALID_DST_ADDRESS;
9033 +  
9034 +  if (ip46_address_is_zero(src_addr))
9035 +    return VNET_API_ERROR_INVALID_SRC_ADDRESS;
9036 +
9037 +  rx_fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
9038 +                                                   rx_table_id);
9039 +
9040 +  if (is_del)
9041 +    {
9042 +      if (vbng_dhcp4_server_del (FIB_PROTOCOL_IP4, rx_fib_index,
9043 +                                 addr, server_table_id))
9044 +      {
9045 +          fib_table_entry_special_remove(rx_fib_index,
9046 +                                         &all_1s,
9047 +                                         FIB_SOURCE_DHCP);
9048 +          fib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP4);
9049 +      }
9050 +    }
9051 +  else
9052 +  {
9053 +      if (vbng_dhcp4_server_add (FIB_PROTOCOL_IP4,
9054 +                                 addr, src_addr,
9055 +                                 rx_fib_index, server_table_id))
9056 +      {
9057 +          fib_table_entry_special_add(rx_fib_index,
9058 +                                      &all_1s,
9059 +                                      FIB_SOURCE_DHCP,
9060 +                                      FIB_ENTRY_FLAG_LOCAL);
9061 +          fib_table_lock (rx_fib_index, FIB_PROTOCOL_IP4);
9062 +      }
9063 +  }
9064 +  fib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP4);
9065 +
9066 +  return (rc);
9067 +}
9068 +
9069 +static clib_error_t *
9070 +dhcp4_proxy_set_command_fn (vlib_main_t * vm,
9071 +                            unformat_input_t * input,
9072 +                            vlib_cli_command_t * cmd)
9073 +{
9074 +  ip46_address_t server_addr, src_addr;
9075 +  u32 server_table_id = 0, rx_table_id = 0;
9076 +  int is_del = 0;
9077 +  int set_src = 0, set_server = 0;
9078 +
9079 +  memset(&server_addr, 0, sizeof(server_addr));
9080 +  memset(&src_addr, 0, sizeof(src_addr));
9081 +
9082 +  while (unformat_check_input(input) != UNFORMAT_END_OF_INPUT) 
9083 +    {
9084 +      if (unformat (input, "remote %U", 
9085 +                    unformat_ip4_address, &server_addr.ip4)) 
9086 +        set_server = 1;
9087 +      else if (unformat (input, "server-fib-id %d", &server_table_id))
9088 +        ;
9089 +      else if (unformat (input, "rx-fib-id %d", &rx_table_id))
9090 +        ;
9091 +      else if (unformat(input, "local %U", 
9092 +                       unformat_ip4_address, &src_addr.ip4))
9093 +        set_src = 1;
9094 +      else if (unformat (input, "delete") ||
9095 +               unformat (input, "del"))
9096 +        is_del = 1;
9097 +      else
9098 +        break;
9099 +    }
9100 +
9101 +  if (is_del || (set_server && set_src))
9102 +    {
9103 +      int rv;
9104 +
9105 +      rv = vbng_dhcp4_set_server (&server_addr, &src_addr, rx_table_id, 
9106 +                                   server_table_id, is_del);
9107 +      switch (rv)
9108 +        {
9109 +        case 0:
9110 +          return 0;
9111 +
9112 +        case VNET_API_ERROR_INVALID_DST_ADDRESS:
9113 +          return clib_error_return (0, "Invalid remote address");
9114 +          
9115 +        case VNET_API_ERROR_INVALID_SRC_ADDRESS:
9116 +          return clib_error_return (0, "Invalid local address");
9117 +
9118 +        case VNET_API_ERROR_NO_SUCH_ENTRY:
9119 +          return clib_error_return 
9120 +            (0, "Fib id %d: no per-fib DHCP server configured", rx_table_id);
9121 +
9122 +        default:
9123 +          return clib_error_return (0, "BUG: rv %d", rv);
9124 +        }
9125 +    }
9126 +  else
9127 +    return clib_error_return (0, "parse error`%U'",
9128 +                              format_unformat_error, input);
9129 +}
9130 +
9131 +VLIB_CLI_COMMAND (vbng_dhcp4_set_command, static) = {
9132 +  .path = "set vbng dhcp4",
9133 +  .short_help = "set vbng dhcp4 [del] remote <ip-addr> local <ip-addr> [server-fib-id <n>] [rx-fib-id <n>]",
9134 +  .function = dhcp4_proxy_set_command_fn,
9135 +};
9136 +
9137 +static u8 *
9138 +format_dhcp4_proxy_server (u8 * s, va_list * args)
9139 +{
9140 +  dhcp_proxy_t *proxy = va_arg (*args, dhcp_proxy_t *);
9141 +  ip4_fib_t * rx_fib, * server_fib;
9142 +  dhcp_server_t *server;
9143 +
9144 +  if (proxy == 0)
9145 +    {
9146 +        s = format (s, "%=14s%=16s%s", "RX FIB", "Src Address", 
9147 +                    "Servers FIB,Address");
9148 +      return s;
9149 +    }
9150 +
9151 +  rx_fib = ip4_fib_get(proxy->rx_fib_index);
9152 +
9153 +  s = format (s, "%=14u%=16U",
9154 +              rx_fib->table_id,
9155 +              format_ip46_address, &proxy->dhcp_src_address, IP46_TYPE_ANY);
9156 +
9157 +  vec_foreach(server, proxy->dhcp_servers)
9158 +  {
9159 +      server_fib = ip4_fib_get(server->server_fib_index);
9160 +      s = format (s, "%u,%U  ",
9161 +                  server_fib->table_id,
9162 +                  format_ip46_address, &server->dhcp_server, IP46_TYPE_ANY);
9163 +  }
9164 +  return s;
9165 +}
9166 +
9167 +static int
9168 +dhcp4_proxy_show_walk (dhcp_proxy_t *server,
9169 +                       void *ctx)
9170 +{
9171 +    vlib_main_t * vm = ctx;
9172 +
9173 +    vlib_cli_output (vm, "%U", format_dhcp4_proxy_server, server);
9174 +
9175 +    return (1);
9176 +}
9177 +
9178 +static clib_error_t *
9179 +vbng_dhcp4_show_command_fn (vlib_main_t * vm,
9180 +                            unformat_input_t * input,
9181 +                            vlib_cli_command_t * cmd)
9182 +{
9183 +  vlib_cli_output (vm, "%U", format_dhcp4_proxy_server, NULL /* header line */);
9184 +
9185 +  vbng_dhcp4_walk(dhcp4_proxy_show_walk, vm);
9186 +
9187 +  return (NULL);
9188 +}
9189 +
9190 +VLIB_CLI_COMMAND (vbng_dhcp4_show_command, static) = {
9191 +  .path = "show vbng dhcp4",
9192 +  .short_help = "Display vbng DHCP4 configuration info",
9193 +  .function = vbng_dhcp4_show_command_fn,
9194 +};
9195 +
9196 +static clib_error_t *
9197 +vbng_aaa_set_command_fn (vlib_main_t * vm,
9198 +                         unformat_input_t * input,
9199 +                         vlib_cli_command_t * cmd)
9200 +{
9201 +       vbng_dhcp4_main_t *dm = &vbng_dhcp4_main;
9202 +       u8 *config_file = NULL;
9203 +       u32 nas_port  = 0;
9204 +       int set_config = 0, is_del = 0;
9205 +
9206 +       while (unformat_check_input(input) != UNFORMAT_END_OF_INPUT) {
9207 +               if (unformat (input, "nas-port %d", &nas_port))
9208 +                       ;
9209 +               else if (unformat (input, "config %v", &config_file))
9210 +                       set_config = 1;
9211 +               else if (unformat (input, "delete") ||
9212 +                   unformat (input, "del"))
9213 +                       is_del = 1;
9214 +               else
9215 +                       break;
9216 +       }
9217 +
9218 +       if (!is_del && set_config) {
9219 +               if (dm->config.is_enabled == VBNG_AAA_ENABLED) {
9220 +                       return 0;
9221 +               }
9222 +
9223 +               if (nas_port) {
9224 +                       dm->config.nas_port = nas_port;
9225 +               } else {
9226 +                       dm->config.nas_port = AAA_DEFAULT_NAS_PORT;
9227 +               }
9228 +               dm->config.config_file = config_file;
9229 +               dm->config.is_enabled = VBNG_AAA_ENABLED;
9230 +       } else if (is_del) {
9231 +               if (dm->config.is_enabled == VBNG_AAA_DISABLED) {
9232 +                       return 0;
9233 +               }
9234 +
9235 +               vec_free (dm->config.config_file);
9236 +               dm->config.config_file = format(0, "%s",  AAA_DEFAULT_CONFIG_FILE);
9237 +               dm->config.nas_port = AAA_DEFAULT_NAS_PORT;
9238 +               dm->config.is_enabled = VBNG_AAA_DISABLED;
9239 +       } else {
9240 +               return clib_error_return (0, "parse error`%U'",
9241 +                   format_unformat_error, input);
9242 +       }
9243 +
9244 +       return 0;
9245 +}
9246 +
9247 +VLIB_CLI_COMMAND (vbng_aaa_set_command, static) = {
9248 +       .path = "set vbng aaa",
9249 +       .short_help = "set vbng aaa [del] config <file> [nas-port <n>]",
9250 +       .function = vbng_aaa_set_command_fn,
9251 +};
9252 +
9253 +static u8 *
9254 +format_vbng_aaa_config(u8 *s, va_list *args)
9255 +{
9256 +       vbng_dhcp4_main_t *dm = &vbng_dhcp4_main;
9257 +
9258 +       s = format(s, "%=8s %=8s %s\n", "Enabled",
9259 +                  "NAS Port", "Config File");
9260 +
9261 +       s = format(s, "%=8s %=8d %v\n",
9262 +               dm->config.is_enabled ? "True" : "False",
9263 +               dm->config.nas_port,
9264 +               dm->config.config_file);
9265 +
9266 +       return s;
9267 +}
9268 +
9269 +static clib_error_t *
9270 +vbng_aaa_show_command_fn (vlib_main_t * vm,
9271 +                          unformat_input_t * input,
9272 +                          vlib_cli_command_t * cmd)
9273 +{
9274 +  vlib_cli_output (vm, "%U", format_vbng_aaa_config, NULL);
9275 +
9276 +  return (NULL);
9277 +}
9278 +
9279 +VLIB_CLI_COMMAND (vbng_aaa_show_command, static) = {
9280 +       .path = "show vbng aaa",
9281 +       .short_help = "Display vbng AAA configuration info",
9282 +       .function = vbng_aaa_show_command_fn,
9283 +};
9284 +
9285 +/* *INDENT-OFF* */
9286 +VLIB_PLUGIN_REGISTER () = {
9287 +       .version = VPP_BUILD_VER,
9288 +       .description = "DHCP V4 Proxy With Radius Client",
9289 +};
9290 +/* *INDENT-ON* */
9291 diff --git a/src/plugins/vbng/vbng_msg_enum.h b/src/plugins/vbng/vbng_msg_enum.h
9292 new file mode 100644
9293 index 0000000..1dc1357
9294 --- /dev/null
9295 +++ b/src/plugins/vbng/vbng_msg_enum.h
9296 @@ -0,0 +1,31 @@
9297 +/*
9298 + * vbng_msg_enum.h - vpp engine plug-in message enumeration
9299 + *
9300 + * Copyright (c) 2017 Intel and/or its affiliates.
9301 + * Licensed under the Apache License, Version 2.0 (the "License");
9302 + * you may not use this file except in compliance with the License.
9303 + * You may obtain a copy of the License at:
9304 + *
9305 + *     http://www.apache.org/licenses/LICENSE-2.0
9306 + *
9307 + * Unless required by applicable law or agreed to in writing, software
9308 + * distributed under the License is distributed on an "AS IS" BASIS,
9309 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9310 + * See the License for the specific language governing permissions and
9311 + * limitations under the License.
9312 + */
9313 +#ifndef _VBNG_MSG_ENUM_H_
9314 +#define _VBNG_MSG_ENUM_H_
9315 +
9316 +#include <vppinfra/byte_order.h>
9317 +
9318 +#define vl_msg_id(n,h) n,
9319 +typedef enum
9320 +{
9321 +#include <vbng/vbng_all_api_h.h>
9322 +  /* We'll want to know how many messages IDs we need... */
9323 +  VL_MSG_FIRST_AVAILABLE,
9324 +} vl_msg_id_t;
9325 +#undef vl_msg_id
9326 +
9327 +#endif /* _VBNG_MSG_ENUM_H_ */
9328 diff --git a/src/vnet.am b/src/vnet.am
9329 index 9e099f3..7c107f0 100644
9330 --- a/src/vnet.am
9331 +++ b/src/vnet.am
9332 @@ -682,31 +682,31 @@ endif
9333  ########################################
9334  # DHCP client
9335  ########################################
9336 -libvnet_la_SOURCES +=                          \
9337 - vnet/dhcp/client.c                            \
9338 - vnet/dhcp/client.h                            \
9339 - vnet/dhcp/dhcp_api.c
9340 -
9341 -nobase_include_HEADERS +=                      \
9342 - vnet/dhcp/client.h                            \
9343 - vnet/dhcp/dhcp.api.h
9344 -
9345 -API_FILES += vnet/dhcp/dhcp.api
9346 +#libvnet_la_SOURCES +=                         \
9347 +# vnet/dhcp/client.c                           \
9348 +# vnet/dhcp/client.h                           \
9349 +# vnet/dhcp/dhcp_api.c
9350 +#
9351 +#nobase_include_HEADERS +=                     \
9352 +# vnet/dhcp/client.h                           \
9353 +# vnet/dhcp/dhcp.api.h
9354 +#
9355 +#API_FILES += vnet/dhcp/dhcp.api
9356  
9357  ########################################
9358  # DHCP proxy
9359  ########################################
9360 -libvnet_la_SOURCES +=                          \
9361 - vnet/dhcp/dhcp6_proxy_node.c                   \
9362 - vnet/dhcp/dhcp4_proxy_node.c                  \
9363 - vnet/dhcp/dhcp_proxy.c
9364 -
9365 -nobase_include_HEADERS +=                      \
9366 - vnet/dhcp/dhcp4_packet.h                      \
9367 - vnet/dhcp/dhcp6_packet.h                      \
9368 - vnet/dhcp/dhcp_proxy.h                                \
9369 - vnet/dhcp/dhcp6_proxy_error.def                \
9370 - vnet/dhcp/dhcp4_proxy_error.def
9371 +#libvnet_la_SOURCES +=                         \
9372 +# vnet/dhcp/dhcp6_proxy_node.c                   \
9373 +# vnet/dhcp/dhcp4_proxy_node.c                 \
9374 +# vnet/dhcp/dhcp_proxy.c
9375 +#
9376 +#nobase_include_HEADERS +=                     \
9377 +# vnet/dhcp/dhcp4_packet.h                     \
9378 +# vnet/dhcp/dhcp6_packet.h                     \
9379 +# vnet/dhcp/dhcp_proxy.h                               \
9380 +# vnet/dhcp/dhcp6_proxy_error.def                \
9381 +# vnet/dhcp/dhcp4_proxy_error.def
9382  
9383  ########################################
9384  # ipv6 segment routing
9385 diff --git a/src/vpp-api/java/Makefile.am b/src/vpp-api/java/Makefile.am
9386 index f18e0c2..cadaa8d 100644
9387 --- a/src/vpp-api/java/Makefile.am
9388 +++ b/src/vpp-api/java/Makefile.am
9389 @@ -149,6 +149,26 @@ jvpp-snat/io_fd_vpp_jvpp_snat_JVppSnatImpl.h: $(jvpp_registry_ok) $(jvpp_snat_js
9390  endif
9391  
9392  #
9393 +# VBNG Plugin
9394 +#
9395 +if ENABLE_VBNG_PLUGIN
9396 +noinst_LTLIBRARIES += libjvpp_vbng.la
9397 +libjvpp_vbng_la_SOURCES = jvpp-vbng/jvpp_vbng.c
9398 +libjvpp_vbng_la_CPPFLAGS = -Ijvpp-vbng
9399 +libjvpp_vbng_la_LIBADD = $(JVPP_LIBS)
9400 +libjvpp_vbng_la_DEPENDENCIES = libjvpp_common.la
9401 +
9402 +BUILT_SOURCES += jvpp-vbng/io_fd_vpp_jvpp_vbng_JVppVbngImpl.h
9403 +JAR_FILES += jvpp-vbng-$(PACKAGE_VERSION).jar
9404 +CLEANDIRS += jvpp-vbng/target
9405 +
9406 +jvpp_vbng_json_files = @top_builddir@/plugins/vbng/vbng.api.json
9407 +
9408 +jvpp-vbng/io_fd_vpp_jvpp_vbng_JVppVbngImpl.h: $(jvpp_registry_ok) $(jvpp_vbng_json_files)
9409 +       $(call japigen,vbng,JVppVbngImpl)
9410 +endif
9411 +
9412 +#
9413  # iOAM Trace Plugin
9414  #
9415  if ENABLE_IOAM_PLUGIN
9416 diff --git a/src/vpp-api/java/jvpp-vbng/jvpp_vbng.c b/src/vpp-api/java/jvpp-vbng/jvpp_vbng.c
9417 new file mode 100644
9418 index 0000000..b722a50
9419 --- /dev/null
9420 +++ b/src/vpp-api/java/jvpp-vbng/jvpp_vbng.c
9421 @@ -0,0 +1,108 @@
9422 +/*
9423 + * Copyright (c) 2017 Intel Corp and/or its affiliates.
9424 + *
9425 + * Licensed under the Apache License, Version 2.0 (the "License");
9426 + * you may not use this file except in compliance with the License.
9427 + * You may obtain a copy of the License at:
9428 + *
9429 + *     http://www.apache.org/licenses/LICENSE-2.0
9430 + *
9431 + * Unless required by applicable law or agreed to in writing, software
9432 + * distributed under the License is distributed on an "AS IS" BASIS,
9433 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9434 + * See the License for the specific language governing permissions and
9435 + * limitations under the License.
9436 + */
9437 +
9438 +#include <vnet/vnet.h>
9439 +
9440 +#include <vbng/vbng_msg_enum.h>
9441 +#define vl_typedefs             /* define message structures */
9442 +#include <vbng/vbng_all_api_h.h>
9443 +#undef vl_typedefs
9444 +
9445 +#include <vnet/api_errno.h>
9446 +#include <vlibapi/api.h>
9447 +#include <vlibmemory/api.h>
9448 +
9449 +#if VPPJNI_DEBUG == 1
9450 +  #define DEBUG_LOG(...) clib_warning(__VA_ARGS__)
9451 +#else
9452 +  #define DEBUG_LOG(...)
9453 +#endif
9454 +
9455 +#include <jvpp-common/jvpp_common.h>
9456 +
9457 +#include "jvpp-vbng/io_fd_vpp_jvpp_vbng_JVppVbngImpl.h"
9458 +#include "jvpp_vbng.h"
9459 +#include "jvpp-vbng/jvpp_vbng_gen.h"
9460 +
9461 +/*
9462 + * Class:     io_fd_vpp_jvpp_vbng_JVppVbngImpl
9463 + * Method:    init0
9464 + * Signature: (JI)V
9465 + */
9466 +JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_vbng_JVppVbngImpl_init0
9467 +  (JNIEnv *env, jclass clazz, jobject callback, jlong queue_address, jint my_client_index) {
9468 +  vbng_main_t * plugin_main = &vbng_main;
9469 +  clib_warning ("Java_io_fd_vpp_jvpp_vbng_JVppVbngImpl_init0");
9470 +
9471 +  plugin_main->my_client_index = my_client_index;
9472 +  plugin_main->vl_input_queue = (unix_shared_memory_queue_t *)queue_address;
9473 +
9474 +  plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback);
9475 +  plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback));
9476 +
9477 +  // verify API has not changed since jar generation
9478 +  #define _(N)             \
9479 +      get_message_id(env, #N);
9480 +      foreach_supported_api_message;
9481 +  #undef _
9482 +
9483 +  #define _(N,n)                                  \
9484 +      vl_msg_api_set_handlers(get_message_id(env, #N), #n,     \
9485 +              vl_api_##n##_t_handler,             \
9486 +              vl_noop_handler,                    \
9487 +              vl_noop_handler,                    \
9488 +              vl_noop_handler,                    \
9489 +              sizeof(vl_api_##n##_t), 1);
9490 +      foreach_api_reply_handler;
9491 +  #undef _
9492 +}
9493 +
9494 +JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_vbng_JVppVbngImpl_close0
9495 +(JNIEnv *env, jclass clazz) {
9496 +  vbng_main_t * plugin_main = &vbng_main;
9497 +
9498 +    // cleanup:
9499 +    (*env)->DeleteGlobalRef(env, plugin_main->callbackClass);
9500 +    (*env)->DeleteGlobalRef(env, plugin_main->callbackObject);
9501 +
9502 +    plugin_main->callbackClass = NULL;
9503 +    plugin_main->callbackObject = NULL;
9504 +}
9505 +
9506 +/* Attach thread to JVM and cache class references when initiating JVPP VES */
9507 +jint JNI_OnLoad(JavaVM *vm, void *reserved) {
9508 +    JNIEnv* env;
9509 +
9510 +    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) {
9511 +        return JNI_EVERSION;
9512 +    }
9513 +
9514 +    if (cache_class_references(env) != 0) {
9515 +        clib_warning ("Failed to cache class references\n");
9516 +        return JNI_ERR;
9517 +    }
9518 +
9519 +    return JNI_VERSION_1_8;
9520 +}
9521 +
9522 +/* Clean up cached references when disposing JVPP VES */
9523 +void JNI_OnUnload(JavaVM *vm, void *reserved) {
9524 +    JNIEnv* env;
9525 +    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) {
9526 +        return;
9527 +    }
9528 +    delete_class_references(env);
9529 +}
9530 diff --git a/src/vpp-api/java/jvpp-vbng/jvpp_vbng.h b/src/vpp-api/java/jvpp-vbng/jvpp_vbng.h
9531 new file mode 100644
9532 index 0000000..62b4cda
9533 --- /dev/null
9534 +++ b/src/vpp-api/java/jvpp-vbng/jvpp_vbng.h
9535 @@ -0,0 +1,42 @@
9536 +/*
9537 + * Copyright (c) 2017 Intel Corp and/or its affiliates.
9538 + *
9539 + * Licensed under the Apache License, Version 2.0 (the "License");
9540 + * you may not use this file except in compliance with the License.
9541 + * You may obtain a copy of the License at:
9542 + *
9543 + *     http://www.apache.org/licenses/LICENSE-2.0
9544 + *
9545 + * Unless required by applicable law or agreed to in writing, software
9546 + * distributed under the License is distributed on an "AS IS" BASIS,
9547 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9548 + * See the License for the specific language governing permissions and
9549 + * limitations under the License.
9550 + */
9551 +#ifndef __included_jvpp_vbng_h__
9552 +#define __included_jvpp_vbng_h__
9553 +
9554 +#include <vnet/vnet.h>
9555 +#include <vnet/ip/ip.h>
9556 +#include <vnet/api_errno.h>
9557 +#include <vlibapi/api.h>
9558 +#include <vlibmemory/api.h>
9559 +#include <jni.h>
9560 +
9561 +/* Global state for JVPP-VES */
9562 +typedef struct {
9563 +    /* Pointer to shared memory queue */
9564 +    unix_shared_memory_queue_t * vl_input_queue;
9565 +
9566 +    /* VPP api client index */
9567 +    u32 my_client_index;
9568 +
9569 +    /* Callback object and class references enabling asynchronous Java calls */
9570 +    jobject callbackObject;
9571 +    jclass callbackClass;
9572 +
9573 +} vbng_main_t;
9574 +
9575 +vbng_main_t vbng_main __attribute__((aligned (64)));
9576 +
9577 +#endif /* __included_jvpp_vbng_h__ */