4 * @brief Implementation of host_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
28 typedef struct private_host_t private_host_t
;
31 * @brief Private Data of a host object.
33 struct private_host_t
{
40 * Address family to use, such as AF_INET or AF_INET6
45 * string representation of host
50 * low-lewel structure, wich stores the address
53 struct sockaddr address
;
54 struct sockaddr_in address4
;
57 * length of address structure
64 * implements host_t.get_sockaddr
66 static sockaddr_t
*get_sockaddr(private_host_t
*this)
68 return &(this->address
);
72 * implements host_t.get_sockaddr_len
74 static socklen_t
*get_sockaddr_len(private_host_t
*this)
76 return &(this->socklen
);
80 * Implementation of host_t.is_default_route.
82 static bool is_default_route (private_host_t
*this)
88 static u_int8_t default_route
[4] = {0x00,0x00,0x00,0x00};
90 if (memcmp(default_route
,&(this->address4
.sin_addr
.s_addr
),4) == 0)
98 /* empty chunk is returned */
105 * implements host_t.get_address
107 static char *get_address(private_host_t
*this)
109 switch (this->family
)
114 /* we need to clone it, since inet_ntoa overwrites
115 * internal buffer on subsequent calls
118 string
= inet_ntoa(this->address4
.sin_addr
);
119 this->string
= malloc(strlen(string
)+1);
120 strcpy(this->string
, string
);
125 return "(family not supported)";
131 * Implementation of host_t.get_address_as_chunk.
133 static chunk_t
get_address_as_chunk(private_host_t
*this)
135 chunk_t address
= CHUNK_INITIALIZER
;
137 switch (this->family
)
141 /* allocate 4 bytes for IPV4 address*/
142 address
.ptr
= malloc(4);
144 memcpy(address
.ptr
,&(this->address4
.sin_addr
.s_addr
),4);
148 /* empty chunk is returned */
154 static xfrm_address_t
get_xfrm_addr(private_host_t
*this)
156 switch (this->family
)
160 return (xfrm_address_t
)(this->address4
.sin_addr
.s_addr
);
165 return (xfrm_address_t
)(this->address4
.sin_addr
.s_addr
);
170 static int get_family(private_host_t
*this)
176 * implements host_t.get_port
178 static u_int16_t
get_port(private_host_t
*this)
180 switch (this->family
)
184 return ntohs(this->address4
.sin_port
);
195 * Implements host_t.clone.
197 static private_host_t
*clone(private_host_t
*this)
199 private_host_t
*new = malloc_thing(private_host_t
);
202 memcpy(new, this, sizeof(private_host_t
));
205 new->string
= malloc(strlen(this->string
)+1);
206 strcpy(new->string
, this->string
);
212 * Impelements host_t.ip_equals
214 static bool ip_equals(private_host_t
*this, private_host_t
*other
)
216 switch (this->family
)
221 if ((this->address4
.sin_family
== other
->address4
.sin_family
) &&
222 (this->address4
.sin_addr
.s_addr
== other
->address4
.sin_addr
.s_addr
))
232 * Impelements host_t.equals
234 static bool equals(private_host_t
*this, private_host_t
*other
)
236 switch (this->family
)
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
))
253 * Implements host_t.destroy
255 static void destroy(private_host_t
*this)
262 * Creates an empty host_t object
264 static private_host_t
*host_create_empty()
266 private_host_t
*this = malloc_thing(private_host_t
);
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
;
287 * Described in header.
289 host_t
*host_create(int family
, char *address
, u_int16_t port
)
291 private_host_t
*this = host_create_empty();
293 this->family
= family
;
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);
317 * Described in header.
319 host_t
*host_create_from_chunk(int family
, chunk_t address
, u_int16_t port
)
321 private_host_t
*this = host_create_empty();
323 this->family
= family
;
329 if (address
.len
!= 4)
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);
345 * Described in header.
347 host_t
*host_create_from_sockaddr(sockaddr_t
*sockaddr
)
351 switch (sockaddr
->sa_family
)
356 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sockaddr
;
357 address
.ptr
= (void*)&(sin
->sin_addr
.s_addr
);
359 return host_create_from_chunk(AF_INET
, address
, ntohs(sin
->sin_port
));