Merge branch 'nm-gtk4'
[strongswan.git] / src / libcharon / plugins / dhcp / dhcp_transaction.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
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 "dhcp_transaction.h"
17
18 #include <collections/linked_list.h>
19
20 typedef struct private_dhcp_transaction_t private_dhcp_transaction_t;
21
22 /**
23 * Private data of an dhcp_transaction_t object.
24 */
25 struct private_dhcp_transaction_t {
26
27 /**
28 * Public dhcp_transaction_t interface.
29 */
30 dhcp_transaction_t public;
31
32 /**
33 * DHCP transaction ID
34 */
35 uint32_t id;
36
37 /**
38 * Peer identity
39 */
40 identification_t *identity;
41
42 /**
43 * received DHCP address
44 */
45 host_t *address;
46
47 /**
48 * discovered DHCP server address
49 */
50 host_t *server;
51
52 /**
53 * List of added attributes, as attribute_entry_t
54 */
55 linked_list_t *attributes;
56 };
57
58 /**
59 * Entry for an added attribute
60 */
61 typedef struct {
62 configuration_attribute_type_t type;
63 chunk_t data;
64 } attribute_entry_t;
65
66 METHOD(dhcp_transaction_t, get_id, uint32_t,
67 private_dhcp_transaction_t *this)
68 {
69 return this->id;
70 }
71
72 METHOD(dhcp_transaction_t, get_identity, identification_t*,
73 private_dhcp_transaction_t *this)
74 {
75 return this->identity;
76 }
77
78 METHOD(dhcp_transaction_t, set_address, void,
79 private_dhcp_transaction_t *this, host_t *address)
80 {
81 DESTROY_IF(this->address);
82 this->address = address;
83 }
84
85 METHOD(dhcp_transaction_t, get_address, host_t*,
86 private_dhcp_transaction_t *this)
87 {
88 return this->address;
89 }
90
91 METHOD(dhcp_transaction_t, set_server, void,
92 private_dhcp_transaction_t *this, host_t *server)
93 {
94 DESTROY_IF(this->server);
95 this->server = server;
96 }
97
98 METHOD(dhcp_transaction_t, get_server, host_t*,
99 private_dhcp_transaction_t *this)
100 {
101 return this->server;
102 }
103
104 METHOD(dhcp_transaction_t, add_attribute, void,
105 private_dhcp_transaction_t *this, configuration_attribute_type_t type,
106 chunk_t data)
107 {
108 attribute_entry_t *entry;
109
110 INIT(entry,
111 .type = type,
112 .data = chunk_clone(data),
113 );
114 this->attributes->insert_last(this->attributes, entry);
115 }
116
117 CALLBACK(attribute_filter, bool,
118 void *null, enumerator_t *orig, va_list args)
119 {
120 configuration_attribute_type_t *type;
121 attribute_entry_t *entry;
122 chunk_t *data;
123
124 VA_ARGS_VGET(args, type, data);
125
126 if (orig->enumerate(orig, &entry))
127 {
128 *type = entry->type;
129 *data = entry->data;
130 return TRUE;
131 }
132 return FALSE;
133 }
134
135 METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*,
136 private_dhcp_transaction_t *this)
137 {
138 return enumerator_create_filter(
139 this->attributes->create_enumerator(this->attributes),
140 attribute_filter, NULL, NULL);
141 }
142
143 /**
144 * Clean up an attribute entry
145 */
146 static void attribute_entry_destroy(attribute_entry_t *entry)
147 {
148 free(entry->data.ptr);
149 free(entry);
150 }
151
152 METHOD(dhcp_transaction_t, destroy, void,
153 private_dhcp_transaction_t *this)
154 {
155 this->identity->destroy(this->identity);
156 DESTROY_IF(this->address);
157 DESTROY_IF(this->server);
158 this->attributes->destroy_function(this->attributes,
159 (void*)attribute_entry_destroy);
160 free(this);
161 }
162
163 /**
164 * See header
165 */
166 dhcp_transaction_t *dhcp_transaction_create(uint32_t id,
167 identification_t *identity)
168 {
169 private_dhcp_transaction_t *this;
170
171 INIT(this,
172 .public = {
173 .get_id = _get_id,
174 .get_identity = _get_identity,
175 .set_address = _set_address,
176 .get_address = _get_address,
177 .set_server = _set_server,
178 .get_server = _get_server,
179 .add_attribute = _add_attribute,
180 .create_attribute_enumerator = _create_attribute_enumerator,
181 .destroy = _destroy,
182 },
183 .id = id,
184 .identity = identity->clone(identity),
185 .attributes = linked_list_create(),
186 );
187
188 return &this->public;
189 }
190