]> git.ipfire.org Git - thirdparty/strongswan.git/blob - programs/charon/lib/utils/host.c
- renamed get_block_size of hasher
[thirdparty/strongswan.git] / programs / charon / lib / utils / host.c
1 /**
2 * @file host.c
3 *
4 * @brief Implementation of host_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <string.h>
24
25 #include "host.h"
26
27
28 typedef struct private_host_t private_host_t;
29
30 /**
31 * @brief Private Data of a host object.
32 */
33 struct private_host_t {
34 /**
35 * Public data
36 */
37 host_t public;
38
39 /**
40 * Address family to use, such as AF_INET or AF_INET6
41 */
42 int family;
43
44 /**
45 * string representation of host
46 */
47 char *string;
48
49 /**
50 * low-lewel structure, wich stores the address
51 */
52 union {
53 struct sockaddr address;
54 struct sockaddr_in address4;
55 };
56 /**
57 * length of address structure
58 */
59 socklen_t socklen;
60 };
61
62
63 /**
64 * implements host_t.get_sockaddr
65 */
66 static sockaddr_t *get_sockaddr(private_host_t *this)
67 {
68 return &(this->address);
69 }
70
71 /**
72 * implements host_t.get_sockaddr_len
73 */
74 static socklen_t *get_sockaddr_len(private_host_t *this)
75 {
76 return &(this->socklen);
77 }
78
79 /**
80 * Implementation of host_t.is_default_route.
81 */
82 static bool is_default_route (private_host_t *this)
83 {
84 switch (this->family)
85 {
86 case AF_INET:
87 {
88 static u_int8_t default_route[4] = {0x00,0x00,0x00,0x00};
89
90 if (memcmp(default_route,&(this->address4.sin_addr.s_addr),4) == 0)
91 {
92 return TRUE;
93 }
94 return FALSE;
95 }
96 default:
97 {
98 /* empty chunk is returned */
99 return FALSE;
100 }
101 }
102 }
103
104 /**
105 * implements host_t.get_address
106 */
107 static char *get_address(private_host_t *this)
108 {
109 switch (this->family)
110 {
111 case AF_INET:
112 {
113 char *string;
114 /* we need to clone it, since inet_ntoa overwrites
115 * internal buffer on subsequent calls
116 */
117 free(this->string);
118 string = inet_ntoa(this->address4.sin_addr);
119 this->string = malloc(strlen(string)+1);
120 strcpy(this->string, string);
121 return this->string;
122 }
123 default:
124 {
125 return "(family not supported)";
126 }
127 }
128 }
129
130 /**
131 * Implementation of host_t.get_address_as_chunk.
132 */
133 static chunk_t get_address_as_chunk(private_host_t *this)
134 {
135 chunk_t address = CHUNK_INITIALIZER;
136
137 switch (this->family)
138 {
139 case AF_INET:
140 {
141 /* allocate 4 bytes for IPV4 address*/
142 address.ptr = malloc(4);
143 address.len = 4;
144 memcpy(address.ptr,&(this->address4.sin_addr.s_addr),4);
145 }
146 default:
147 {
148 /* empty chunk is returned */
149 return address;
150 }
151 }
152 }
153
154 static xfrm_address_t get_xfrm_addr(private_host_t *this)
155 {
156 switch (this->family)
157 {
158 case AF_INET:
159 {
160 return (xfrm_address_t)(this->address4.sin_addr.s_addr);
161 }
162 default:
163 {
164 /* todo */
165 return (xfrm_address_t)(this->address4.sin_addr.s_addr);
166 }
167 }
168 }
169
170 static int get_family(private_host_t *this)
171 {
172 return this->family;
173 }
174
175 /**
176 * implements host_t.get_port
177 */
178 static u_int16_t get_port(private_host_t *this)
179 {
180 switch (this->family)
181 {
182 case AF_INET:
183 {
184 return ntohs(this->address4.sin_port);
185 }
186 default:
187 {
188 return 0;
189 }
190 }
191 }
192
193
194 /**
195 * Implements host_t.clone.
196 */
197 static private_host_t *clone(private_host_t *this)
198 {
199 private_host_t *new = malloc_thing(private_host_t);
200
201
202 memcpy(new, this, sizeof(private_host_t));
203 if (this->string)
204 {
205 new->string = malloc(strlen(this->string)+1);
206 strcpy(new->string, this->string);
207 }
208 return new;
209 }
210
211 /**
212 * Impelements host_t.ip_equals
213 */
214 static bool ip_equals(private_host_t *this, private_host_t *other)
215 {
216 switch (this->family)
217 {
218 /* IPv4 */
219 case AF_INET:
220 {
221 if ((this->address4.sin_family == other->address4.sin_family) &&
222 (this->address4.sin_addr.s_addr == other->address4.sin_addr.s_addr))
223 {
224 return TRUE;
225 }
226 }
227 }
228 return FALSE;
229 }
230
231 /**
232 * Impelements host_t.equals
233 */
234 static bool equals(private_host_t *this, private_host_t *other)
235 {
236 switch (this->family)
237 {
238 /* IPv4 */
239 case AF_INET:
240 {
241 if ((this->address4.sin_family == other->address4.sin_family) &&
242 (this->address4.sin_addr.s_addr == other->address4.sin_addr.s_addr) &&
243 (this->address4.sin_port == other->address4.sin_port))
244 {
245 return TRUE;
246 }
247 }
248 }
249 return FALSE;
250 }
251
252 /**
253 * Implements host_t.destroy
254 */
255 static void destroy(private_host_t *this)
256 {
257 free(this->string);
258 free(this);
259 }
260
261 /**
262 * Creates an empty host_t object
263 */
264 static private_host_t *host_create_empty()
265 {
266 private_host_t *this = malloc_thing(private_host_t);
267
268 this->public.get_sockaddr = (sockaddr_t* (*) (host_t*))get_sockaddr;
269 this->public.get_sockaddr_len = (socklen_t*(*) (host_t*))get_sockaddr_len;
270 this->public.clone = (host_t* (*) (host_t*))clone;
271 this->public.get_family = (int (*) (host_t*))get_family;
272 this->public.get_xfrm_addr = (xfrm_address_t (*) (host_t *))get_xfrm_addr;
273 this->public.get_address = (char* (*) (host_t *))get_address;
274 this->public.get_address_as_chunk = (chunk_t (*) (host_t *)) get_address_as_chunk;
275 this->public.get_port = (u_int16_t (*) (host_t *))get_port;
276 this->public.ip_equals = (bool (*) (host_t *,host_t *)) ip_equals;
277 this->public.equals = (bool (*) (host_t *,host_t *)) equals;
278 this->public.is_default_route = (bool (*) (host_t *)) is_default_route;
279 this->public.destroy = (void (*) (host_t*))destroy;
280
281 this->string = NULL;
282
283 return this;
284 }
285
286 /*
287 * Described in header.
288 */
289 host_t *host_create(int family, char *address, u_int16_t port)
290 {
291 private_host_t *this = host_create_empty();
292
293 this->family = family;
294
295 switch (family)
296 {
297 /* IPv4 */
298 case AF_INET:
299 {
300 this->address4.sin_family = AF_INET;
301 this->address4.sin_addr.s_addr = inet_addr(address);
302 this->address4.sin_port = htons(port);
303 this->socklen = sizeof(struct sockaddr_in);
304 return &(this->public);
305 }
306 default:
307 {
308 free(this);
309 return NULL;
310
311 }
312 }
313
314 }
315
316 /*
317 * Described in header.
318 */
319 host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
320 {
321 private_host_t *this = host_create_empty();
322
323 this->family = family;
324 switch (family)
325 {
326 /* IPv4 */
327 case AF_INET:
328 {
329 if (address.len != 4)
330 {
331 break;
332 }
333 this->address4.sin_family = AF_INET;
334 memcpy(&(this->address4.sin_addr.s_addr),address.ptr,4);
335 this->address4.sin_port = htons(port);
336 this->socklen = sizeof(struct sockaddr_in);
337 return &(this->public);
338 }
339 }
340 free(this);
341 return NULL;
342 }
343
344 /*
345 * Described in header.
346 */
347 host_t *host_create_from_sockaddr(sockaddr_t *sockaddr)
348 {
349 chunk_t address;
350
351 switch (sockaddr->sa_family)
352 {
353 /* IPv4 */
354 case AF_INET:
355 {
356 struct sockaddr_in *sin = (struct sockaddr_in *)sockaddr;
357 address.ptr = (void*)&(sin->sin_addr.s_addr);
358 address.len = 4;
359 return host_create_from_chunk(AF_INET, address, ntohs(sin->sin_port));
360 }
361 default:
362 return NULL;
363 }
364 }
365