implemented the right|leftallowany feature
[strongswan.git] / src / charon-nm / nm / nm_handler.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "nm_handler.h"
17
18 #include <daemon.h>
19
20 typedef struct private_nm_handler_t private_nm_handler_t;
21
22 /**
23 * Private data of an nm_handler_t object.
24 */
25 struct private_nm_handler_t {
26
27 /**
28 * Public nm_handler_t interface.
29 */
30 nm_handler_t public;
31
32 /**
33 * list of received DNS server attributes, pointer to 4 byte data
34 */
35 linked_list_t *dns;
36
37 /**
38 * list of received NBNS server attributes, pointer to 4 byte data
39 */
40 linked_list_t *nbns;
41 };
42
43 METHOD(attribute_handler_t, handle, bool,
44 private_nm_handler_t *this, identification_t *server,
45 configuration_attribute_type_t type, chunk_t data)
46 {
47 linked_list_t *list;
48
49 switch (type)
50 {
51 case INTERNAL_IP4_DNS:
52 list = this->dns;
53 break;
54 case INTERNAL_IP4_NBNS:
55 list = this->nbns;
56 break;
57 default:
58 return FALSE;
59 }
60 if (data.len != 4)
61 {
62 return FALSE;
63 }
64 list->insert_last(list, chunk_clone(data).ptr);
65 return TRUE;
66 }
67
68 /**
69 * Implementation of create_attribute_enumerator().enumerate() for WINS
70 */
71 static bool enumerate_nbns(enumerator_t *this,
72 configuration_attribute_type_t *type, chunk_t *data)
73 {
74 *type = INTERNAL_IP4_NBNS;
75 *data = chunk_empty;
76 /* done */
77 this->enumerate = (void*)return_false;
78 return TRUE;
79 }
80
81 /**
82 * Implementation of create_attribute_enumerator().enumerate() for DNS
83 */
84 static bool enumerate_dns(enumerator_t *this,
85 configuration_attribute_type_t *type, chunk_t *data)
86 {
87 *type = INTERNAL_IP4_DNS;
88 *data = chunk_empty;
89 /* enumerate WINS server as next attribute ... */
90 this->enumerate = (void*)enumerate_nbns;
91 return TRUE;
92 }
93
94 METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
95 private_nm_handler_t *this, identification_t *server, host_t *vip)
96 {
97 if (vip && vip->get_family(vip) == AF_INET)
98 { /* no IPv6 attributes yet */
99 enumerator_t *enumerator = malloc_thing(enumerator_t);
100 /* enumerate DNS attribute first ... */
101 enumerator->enumerate = (void*)enumerate_dns;
102 enumerator->destroy = (void*)free;
103
104 return enumerator;
105 }
106 return enumerator_create_empty();
107 }
108
109 /**
110 * convert plain byte ptrs to handy chunk during enumeration
111 */
112 static bool filter_chunks(void* null, char **in, chunk_t *out)
113 {
114 *out = chunk_create(*in, 4);
115 return TRUE;
116 }
117
118 METHOD(nm_handler_t, create_enumerator, enumerator_t*,
119 private_nm_handler_t *this, configuration_attribute_type_t type)
120 {
121 linked_list_t *list;
122
123 switch (type)
124 {
125 case INTERNAL_IP4_DNS:
126 list = this->dns;
127 break;
128 case INTERNAL_IP4_NBNS:
129 list = this->nbns;
130 break;
131 default:
132 return enumerator_create_empty();
133 }
134 return enumerator_create_filter(list->create_enumerator(list),
135 (void*)filter_chunks, NULL, NULL);
136 }
137
138 METHOD(nm_handler_t, reset, void,
139 private_nm_handler_t *this)
140 {
141 void *data;
142
143 while (this->dns->remove_last(this->dns, (void**)&data) == SUCCESS)
144 {
145 free(data);
146 }
147 while (this->nbns->remove_last(this->nbns, (void**)&data) == SUCCESS)
148 {
149 free(data);
150 }
151 }
152
153 METHOD(nm_handler_t, destroy, void,
154 private_nm_handler_t *this)
155 {
156 reset(this);
157 this->dns->destroy(this->dns);
158 this->nbns->destroy(this->nbns);
159 free(this);
160 }
161
162 /**
163 * See header
164 */
165 nm_handler_t *nm_handler_create()
166 {
167 private_nm_handler_t *this;
168
169 INIT(this,
170 .public = {
171 .handler = {
172 .handle = _handle,
173 .release = nop,
174 .create_attribute_enumerator = _create_attribute_enumerator,
175 },
176 .create_enumerator = _create_enumerator,
177 .reset = _reset,
178 .destroy = _destroy,
179 },
180 .dns = linked_list_create(),
181 .nbns = linked_list_create(),
182 );
183
184 return &this->public;
185 }
186