From 4c23a8c9ecc8ad175ccce9fb956c8b540f4f592e Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Mon, 28 Aug 2006 08:45:22 +0000 Subject: moved interface enumeration code to socket, where it belongs query interfaces every time we need it to respect changes in network config added address listing on startup and "ipsec statusall" --- src/charon/network/interfaces.c | 154 ---------------------------------------- src/charon/network/interfaces.h | 80 --------------------- src/charon/network/socket.c | 132 ++++++++++++++++++++++++++++------ src/charon/network/socket.h | 37 +++++++--- 4 files changed, 135 insertions(+), 268 deletions(-) delete mode 100644 src/charon/network/interfaces.c delete mode 100644 src/charon/network/interfaces.h (limited to 'src/charon/network') diff --git a/src/charon/network/interfaces.c b/src/charon/network/interfaces.c deleted file mode 100644 index b1244c97f..000000000 --- a/src/charon/network/interfaces.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file interfaces.c - * - * @brief Implementation of interfaces_t. - * - */ - -/* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include -#include -#include - -#include "interfaces.h" - -typedef struct private_interfaces_t private_interfaces_t; - -/** - * Private data of an interfaces_t object. - */ -struct private_interfaces_t { - - /** - * Public part of a interfaces_t object. - */ - interfaces_t public; - - /** - * port that gets added to the host_t obbjects - */ - u_int16_t port; - - /** - * list of addresses - */ - linked_list_t *addresses; -}; - -/** - * Implements interfaces_t.create_address_iterator - */ -static iterator_t* create_address_iterator(private_interfaces_t *this) -{ - return this->addresses->create_iterator(this->addresses, TRUE); -} - -/** - * Implements interfaces_t.is_local_address - */ -static bool is_local_address(private_interfaces_t *this, host_t *host) -{ - iterator_t *iterator; - host_t *lhost; - - if (host->is_anyaddr(host)) - { - return FALSE; - } - - iterator = this->addresses->create_iterator(this->addresses, TRUE); - while (iterator->iterate(iterator, (void**)&lhost)) - { - if (host->get_family(host) == lhost->get_family(lhost) && - streq(host->get_string(host), lhost->get_string(lhost))) - { - iterator->destroy(iterator); - return TRUE; - } - } - - iterator->destroy(iterator); - return FALSE; -} - -/** - * Implements interfaces_t.destroy. - */ -static void destroy(private_interfaces_t *this) -{ - host_t *host; - while (this->addresses->remove_last(this->addresses, (void**)&host) == SUCCESS) - { - host->destroy(host); - } - this->addresses->destroy(this->addresses); - free(this); -} - -static status_t initialize(private_interfaces_t *this) -{ - struct ifaddrs *list; - struct ifaddrs *cur; - host_t *host; - - if (getifaddrs(&list) < 0) - { - return FAILED; - } - - for (cur = list; cur != NULL; cur = cur->ifa_next) - { - if (!(cur->ifa_flags & IFF_UP)) - continue; - - if (cur->ifa_addr == NULL || cur->ifa_addr->sa_family != AF_INET) - continue; - - host = host_create_from_sockaddr(cur->ifa_addr); - if (host) { - host->set_port(host, this->port); - this->addresses->insert_last(this->addresses, (void*) host); - } - } - - freeifaddrs(list); - return SUCCESS; -} - -/* - * Documented in header - */ -interfaces_t *interfaces_create(u_int16_t port) -{ - private_interfaces_t *this = malloc_thing(private_interfaces_t); - - this->port = port; - - this->public.create_address_iterator = (iterator_t* (*) (interfaces_t*)) create_address_iterator; - this->public.is_local_address = (bool (*) (interfaces_t*, host_t*)) is_local_address; - this->public.destroy = (void (*) (interfaces_t*)) destroy; - - this->addresses = linked_list_create(); - - if (initialize(this) != SUCCESS) - { - destroy(this); - return NULL; - } - - return &this->public; -} diff --git a/src/charon/network/interfaces.h b/src/charon/network/interfaces.h deleted file mode 100644 index 33143e07c..000000000 --- a/src/charon/network/interfaces.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file interfaces.h - * - * @brief Interface of interfaces_t. - * - */ - -/* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#ifndef INTERFACES_H_ -#define INTERFACES_H_ - -#include -#include - -typedef struct interfaces_t interfaces_t; - -/** - * @brief Provides methods to enumerate local interfaces - * - * @b Constructors: - * - interfaces_create() - * - * @todo Handle changes in interface list. - * - * @ingroup network - */ -struct interfaces_t { - - /** - * @brief Get an iterator over addresses of local interfaces - * - * @param this calling object - * @return iterator over host_t objects - */ - iterator_t* (*create_address_iterator) (interfaces_t *this); - - /** - * @brief Check if address is associated with a local interface - * - * @param this calling object - * @param host address to set as destination - * @return TRUE if address is associated with a local interface, FALSE otherwise - */ - bool (*is_local_address) (interfaces_t *this, host_t *host); - - /** - * @brief Destroy the object, freeing contained data. - * - * @param this object to destroy - */ - void (*destroy) (interfaces_t *ifaces); -}; - -/** - * @brief Create an object of type interfaces_t - * - * @param port the port that gets added to the addresses - * - * @return interfaces_t object - * - * @ingroup network - */ -interfaces_t *interfaces_create(u_int16_t port); - - -#endif /* INTERFACES_H_ */ diff --git a/src/charon/network/socket.c b/src/charon/network/socket.c index c0c53ff54..aca48ec5e 100644 --- a/src/charon/network/socket.c +++ b/src/charon/network/socket.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include "socket.h" @@ -106,22 +108,6 @@ struct private_socket_t{ * logger for this socket */ logger_t *logger; - - /** - * Setup a send socket - * - * @param this calling object - * @param port the port - * @param send_fd returns the file descriptor of this new socket - */ - status_t (*setup_send_socket) (private_socket_t *this, u_int16_t port, int *send_fd); - - /** - * Initialize - * - * @param this calling object - */ - status_t (*initialize) (private_socket_t *this); }; /** @@ -246,6 +232,108 @@ status_t sender(private_socket_t *this, packet_t *packet) return SUCCESS; } +/** + * implements socket_t.is_local_address + */ +static bool is_local_address(private_socket_t *this, host_t *host) +{ + struct ifaddrs *list; + struct ifaddrs *cur; + bool found = FALSE; + + if (getifaddrs(&list) < 0) + { + return FALSE; + } + + for (cur = list; cur != NULL; cur = cur->ifa_next) + { + if (!(cur->ifa_flags & IFF_UP)) + { + /* ignore interface which are down */ + continue; + } + + if (cur->ifa_addr == NULL || + cur->ifa_addr->sa_family != host->get_family(host)) + { + /* no match in family */ + continue; + } + + switch (cur->ifa_addr->sa_family) + { + case AF_INET: + { + struct sockaddr_in *listed, *requested; + listed = (struct sockaddr_in*)cur->ifa_addr; + requested = (struct sockaddr_in*)host->get_sockaddr(host); + if (listed->sin_addr.s_addr == requested->sin_addr.s_addr) + { + found = TRUE; + } + break; + } + case AF_INET6: + { + struct sockaddr_in6 *listed, *requested; + listed = (struct sockaddr_in6*)cur->ifa_addr; + requested = (struct sockaddr_in6*)host->get_sockaddr(host); + if (memcmp(&listed->sin6_addr, &requested->sin6_addr, + sizeof(listed->sin6_addr)) == 0) + { + found = TRUE; + } + break; + } + default: + break; + } + + if (found) + { + break; + } + } + freeifaddrs(list); + return found; +} + + +/** + * implements socket_t.create_local_address_list + */ +static linked_list_t* create_local_address_list(private_socket_t *this) +{ + struct ifaddrs *list; + struct ifaddrs *cur; + host_t *host; + linked_list_t *result = linked_list_create(); + + if (getifaddrs(&list) < 0) + { + return result; + } + + for (cur = list; cur != NULL; cur = cur->ifa_next) + { + if (!(cur->ifa_flags & IFF_UP)) + { + /* ignore interface which are down */ + continue; + } + + host = host_create_from_sockaddr(cur->ifa_addr); + if (host) + { + /* address supported, add to list */ + result->insert_last(result, host); + } + } + freeifaddrs(list); + return result; +} + /** * setup a send socket on a specified port */ @@ -389,12 +477,12 @@ static status_t initialize(private_socket_t *this) } /* setup the send sockets */ - if (this->setup_send_socket(this, this->port, &this->send_fd) != SUCCESS) + if (setup_send_socket(this, this->port, &this->send_fd) != SUCCESS) { this->logger->log(this->logger, ERROR, "unable to setup send socket on port %d!", this->port); return FAILED; } - if (this->setup_send_socket(this, this->natt_port, &this->natt_fd) != SUCCESS) + if (setup_send_socket(this, this->natt_port, &this->natt_fd) != SUCCESS) { this->logger->log(this->logger, ERROR, "unable to setup send socket on port %d!", this->natt_port); return FAILED; @@ -429,13 +517,11 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port) { private_socket_t *this = malloc_thing(private_socket_t); - /* private functions */ - this->initialize = (status_t(*)(private_socket_t*))initialize; - this->setup_send_socket = (status_t(*)(private_socket_t*,u_int16_t, int*))setup_send_socket; - /* public functions */ this->public.send = (status_t(*)(socket_t*, packet_t*))sender; this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver; + this->public.is_local_address = (bool(*)(socket_t*, host_t*))is_local_address; + this->public.create_local_address_list = (linked_list_t*(*)(socket_t*))create_local_address_list; this->public.destroy = (void(*)(socket_t*)) destroy; this->logger = logger_manager->get_logger(logger_manager, SOCKET); @@ -443,7 +529,7 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port) this->port = port; this->natt_port = natt_port; - if (this->initialize(this) != SUCCESS) + if (initialize(this) != SUCCESS) { free(this); charon->kill(charon, "could not init socket!"); diff --git a/src/charon/network/socket.h b/src/charon/network/socket.h index b8defc369..9d74651da 100644 --- a/src/charon/network/socket.h +++ b/src/charon/network/socket.h @@ -28,6 +28,8 @@ #include #include +#include +#include /** @@ -57,27 +59,23 @@ typedef struct socket_t socket_t; * * @todo add IPv6 support * - * @todo We currently use multiple sockets for historic reasons. With the - * new RAW socket mechanism, we could use just one socket and filter - * addresses in userspace (or via linux socket filter). This would allow - * realtime interface/address management in a easy way... - * * @ingroup network */ struct socket_t { + /** * @brief Receive a packet. * * Reads a packet from the socket and sets source/dest * appropriately. * - * @param sock socket_t object to work on + * @param this socket_t object to work on * @param packet pinter gets address from allocated packet_t * @return * - SUCCESS when packet successfully received * - FAILED when unable to receive */ - status_t (*receive) (socket_t *sock, packet_t **packet); + status_t (*receive) (socket_t *this, packet_t **packet); /** * @brief Send a packet. @@ -86,22 +84,39 @@ struct socket_t { * Packet is sent using default routing mechanisms, thus the * source address in packet is ignored. * - * @param sock socket_t object to work on + * @param this socket_t object to work on * @param packet[out] packet_t to send * @return * - SUCCESS when packet successfully sent * - FAILED when unable to send */ - status_t (*send) (socket_t *sock, packet_t *packet); + status_t (*send) (socket_t *this, packet_t *packet); + + /** + * @brief Check if an address is an address of this host. + * + * @param this socket_t object to work on + * @param host address to check + * @return TRUE if local address, FALSE otherwise + */ + bool (*is_local_address) (socket_t *this, host_t *host); + + /** + * @brief Create a list of hosts with all local addresses. + * + * @param this socket_t object to work on + * @return list with host_t objects + */ + linked_list_t *(*create_local_address_list) (socket_t *this); /** * @brief Destroy sockets. * * close sockets and destroy socket_t object * - * @param sock socket_t to destroy + * @param this socket_t to destroy */ - void (*destroy) (socket_t *sock); + void (*destroy) (socket_t *this); }; /** -- cgit v1.2.3