4 * @brief Implementation of host_t.
9 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
10 * Copyright (C) 2005-2006 Martin Willi
11 * Copyright (C) 2005 Jan Hutter
12 * Hochschule fuer Technik Rapperswil
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31 typedef struct private_host_t private_host_t
;
34 * @brief Private Data of a host object.
36 struct private_host_t
{
43 * low-lewel structure, wich stores the address
47 struct sockaddr address
;
48 /** maximux sockaddr size */
49 struct sockaddr_storage address_max
;
51 struct sockaddr_in address4
;
53 struct sockaddr_in6 address6
;
56 * length of address structure
63 * implements host_t.get_sockaddr
65 static sockaddr_t
*get_sockaddr(private_host_t
*this)
67 return &(this->address
);
71 * implements host_t.get_sockaddr_len
73 static socklen_t
*get_sockaddr_len(private_host_t
*this)
75 return &(this->socklen
);
79 * Implementation of host_t.is_anyaddr.
81 static bool is_anyaddr(private_host_t
*this)
83 switch (this->address
.sa_family
)
87 u_int8_t default_route
[4];
88 memset(default_route
, 0, sizeof(default_route
));
89 return memeq(default_route
, &(this->address4
.sin_addr
.s_addr
),
90 sizeof(default_route
));
94 u_int8_t default_route
[16];
95 memset(default_route
, 0, sizeof(default_route
));
96 return memeq(default_route
, &(this->address6
.sin6_addr
.s6_addr
),
97 sizeof(default_route
));
107 * output handler in printf()
109 static int print(FILE *stream
, const struct printf_info
*info
,
110 const void *const *args
)
112 private_host_t
*this = *((private_host_t
**)(args
[0]));
113 char buffer
[INET6_ADDRSTRLEN
];
119 return fprintf(stream
, "(null)");
122 if (is_anyaddr(this))
124 return fprintf(stream
, "%%any");
127 switch (this->address
.sa_family
)
130 address
= &this->address4
.sin_addr
;
131 port
= this->address4
.sin_port
;
134 address
= &this->address6
.sin6_addr
;
135 port
= this->address6
.sin6_port
;
138 return fprintf(stream
, "(family not supported)");
141 if (inet_ntop(this->address
.sa_family
, address
,
142 buffer
, sizeof(buffer
)) == NULL
)
144 return fprintf(stream
, "(address conversion failed)");
149 return fprintf(stream
, "%s[%d]", buffer
, ntohs(port
));
153 return fprintf(stream
, "%s", buffer
);
158 * register printf() handlers
160 static void __attribute__ ((constructor
))print_register()
162 register_printf_function(PRINTF_HOST
, print
, arginfo_ptr
);
166 * Implementation of host_t.get_address.
168 static chunk_t
get_address(private_host_t
*this)
170 chunk_t address
= chunk_empty
;
172 switch (this->address
.sa_family
)
176 address
.ptr
= (char*)&(this->address4
.sin_addr
.s_addr
);
182 address
.ptr
= (char*)&(this->address6
.sin6_addr
.s6_addr
);
188 /* return empty chunk */
195 * implements host_t.get_family
197 static int get_family(private_host_t
*this)
199 return this->address
.sa_family
;
203 * implements host_t.get_port
205 static u_int16_t
get_port(private_host_t
*this)
207 switch (this->address
.sa_family
)
211 return ntohs(this->address4
.sin_port
);
215 return ntohs(this->address6
.sin6_port
);
225 * implements host_t.set_port
227 static void set_port(private_host_t
*this, u_int16_t port
)
229 switch (this->address
.sa_family
)
233 this->address4
.sin_port
= htons(port
);
238 this->address6
.sin6_port
= htons(port
);
249 * Implements host_t.clone.
251 static private_host_t
*clone(private_host_t
*this)
253 private_host_t
*new = malloc_thing(private_host_t
);
255 memcpy(new, this, sizeof(private_host_t
));
260 * Impelements host_t.ip_equals
262 static bool ip_equals(private_host_t
*this, private_host_t
*other
)
264 if (this->address
.sa_family
!= other
->address
.sa_family
)
266 /* 0.0.0.0 and ::0 are equal */
267 if (is_anyaddr(this) && is_anyaddr(other
))
275 switch (this->address
.sa_family
)
279 if (memeq(&this->address4
.sin_addr
, &other
->address4
.sin_addr
,
280 sizeof(this->address4
.sin_addr
)))
288 if (memeq(&this->address6
.sin6_addr
, &other
->address6
.sin6_addr
,
289 sizeof(this->address6
.sin6_addr
)))
301 * Implements host_t.get_differences
303 static host_diff_t
get_differences(host_t
*this, host_t
*other
)
305 host_diff_t ret
= HOST_DIFF_NONE
;
307 if (!this->ip_equals(this, other
))
309 ret
|= HOST_DIFF_ADDR
;
312 if (this->get_port(this) != other
->get_port(other
))
314 ret
|= HOST_DIFF_PORT
;
321 * Impelements host_t.equals
323 static bool equals(private_host_t
*this, private_host_t
*other
)
325 if (!ip_equals(this, other
))
330 switch (this->address
.sa_family
)
334 if (this->address4
.sin_port
== other
->address4
.sin_port
)
342 if (this->address6
.sin6_port
== other
->address6
.sin6_port
)
355 * Implements host_t.destroy
357 static void destroy(private_host_t
*this)
363 * Creates an empty host_t object
365 static private_host_t
*host_create_empty(void)
367 private_host_t
*this = malloc_thing(private_host_t
);
369 this->public.get_sockaddr
= (sockaddr_t
* (*) (host_t
*))get_sockaddr
;
370 this->public.get_sockaddr_len
= (socklen_t
*(*) (host_t
*))get_sockaddr_len
;
371 this->public.clone
= (host_t
* (*) (host_t
*))clone
;
372 this->public.get_family
= (int (*) (host_t
*))get_family
;
373 this->public.get_address
= (chunk_t (*) (host_t
*)) get_address
;
374 this->public.get_port
= (u_int16_t (*) (host_t
*))get_port
;
375 this->public.set_port
= (void (*) (host_t
*,u_int16_t
))set_port
;
376 this->public.get_differences
= get_differences
;
377 this->public.ip_equals
= (bool (*) (host_t
*,host_t
*)) ip_equals
;
378 this->public.equals
= (bool (*) (host_t
*,host_t
*)) equals
;
379 this->public.is_anyaddr
= (bool (*) (host_t
*)) is_anyaddr
;
380 this->public.destroy
= (void (*) (host_t
*))destroy
;
386 * Described in header.
388 host_t
*host_create_from_string(char *string
, u_int16_t port
)
390 private_host_t
*this = host_create_empty();
392 if (strchr(string
, '.'))
394 this->address
.sa_family
= AF_INET
;
398 this->address
.sa_family
= AF_INET6
;
401 switch (this->address
.sa_family
)
405 if (inet_pton(AF_INET
, string
, &this->address4
.sin_addr
) <=0)
409 this->address4
.sin_port
= htons(port
);
410 this->socklen
= sizeof(struct sockaddr_in
);
411 return &this->public;
415 if (inet_pton(AF_INET6
, string
, &this->address6
.sin6_addr
) <=0)
419 this->address6
.sin6_port
= htons(port
);
420 this->socklen
= sizeof(struct sockaddr_in6
);
421 return &this->public;
433 * Described in header.
435 host_t
*host_create_from_chunk(int family
, chunk_t address
, u_int16_t port
)
437 private_host_t
*this = host_create_empty();
439 this->address
.sa_family
= family
;
444 if (address
.len
!= 4)
448 memcpy(&(this->address4
.sin_addr
.s_addr
), address
.ptr
,4);
449 this->address4
.sin_port
= htons(port
);
450 this->socklen
= sizeof(struct sockaddr_in
);
451 return &(this->public);
455 if (address
.len
!= 16)
459 memcpy(&(this->address6
.sin6_addr
.s6_addr
), address
.ptr
, 16);
460 this->address6
.sin6_port
= htons(port
);
461 this->socklen
= sizeof(struct sockaddr_in6
);
462 return &this->public;
472 * Described in header.
474 host_t
*host_create_from_sockaddr(sockaddr_t
*sockaddr
)
476 private_host_t
*this = host_create_empty();
478 switch (sockaddr
->sa_family
)
482 memcpy(&this->address4
, sockaddr
, sizeof(struct sockaddr_in
));
483 this->socklen
= sizeof(struct sockaddr_in
);
484 return &this->public;
488 memcpy(&this->address6
, sockaddr
, sizeof(struct sockaddr_in6
));
489 this->socklen
= sizeof(struct sockaddr_in6
);
490 return &this->public;