The following commit has been merged in the master branch: commit 6adca4eb3e189089df9b5ac639fb95998dc3d774 Author: Marek Lindner lindner_marek@yahoo.de Date: Sat Jan 20 22:35:26 2007 +0100
- fix double free in purge() [0.1.x branch] - fix free of gateway clients on shutdown [0.1.x branch] - add unix socket to get debug output from running batmand (experimental)
diff --git a/batman.c b/batman.c index a3a6197..ff1a546 100644 --- a/batman.c +++ b/batman.c @@ -19,6 +19,8 @@ * */
+ +#define _GNU_SOURCE #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -87,6 +89,8 @@ unsigned int bidirectional_timeout = 0; /* bidirectional neighbour reply timeo struct gw_node *curr_gateway = NULL; pthread_t curr_gateway_thread_id = 0;
+pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER; + unsigned int pref_gateway = 0;
unsigned char *hna_buff = NULL; @@ -104,11 +108,14 @@ LIST_HEAD(hna_list); static unsigned int last_own_packet;
struct vis_if vis_if; +struct unix_if unix_if;
void usage(void) { fprintf(stderr, "Usage: batman [options] interface [interface interface]\n" ); fprintf(stderr, " -a announce network(s)\n" ); + fprintf(stderr, " -b run connection in batch mode\n" ); + fprintf(stderr, " -c connect via unix socket\n" ); fprintf(stderr, " -d debug level\n" ); fprintf(stderr, " -g gateway class\n" ); fprintf(stderr, " -h this help\n" ); @@ -125,6 +132,8 @@ void verbose_usage(void) fprintf(stderr, "Usage: batman [options] interface [interface interface]\n\n" ); fprintf(stderr, " -a announce network(s)\n" ); fprintf(stderr, " network/netmask is expected\n" ); + fprintf(stderr, " -b run connection in batch mode\n" ); + fprintf(stderr, " -c connect to running batmand via unix socket\n" ); fprintf(stderr, " -d debug level\n" ); fprintf(stderr, " default: 0 -> debug disabled\n" ); fprintf(stderr, " allowed values: 1 -> list neighbours\n" ); @@ -494,7 +503,7 @@ static void update_gw_list( struct orig_node *orig_node, unsigned char new_gwfla
-static void debug() { +void debug( int fd, char send_clear, char max_output, char show_gw ) {
struct list_head *forw_pos, *orig_pos, *neigh_pos; struct forw_node *forw_node; @@ -505,17 +514,14 @@ static void debug() { static char str[ADDR_STR_LEN], str2[ADDR_STR_LEN];
- if ( ( debug_level == 0 ) || ( debug_level == 3 ) ) - return; - - if ( debug_level != 4 ) + if ( send_clear ) system( "clear" );
- if ( debug_level == 2 ) { + if ( show_gw ) {
if ( list_empty(&gw_list) ) {
- printf( "No gateways in range ...\n" ); + dprintf( fd, "No gateways in range ...\n" );
} else {
@@ -526,9 +532,9 @@ static void debug() { addr_to_string( gw_node->orig_node->router->addr, str2, sizeof (str2) );
if ( curr_gateway == gw_node ) { - printf( "=> %s via: %s(%i), gw_class %i - %s, reliability: %i\n", str, str2, gw_node->orig_node->router->packet_count, gw_node->orig_node->gwflags, gw2string[gw_node->orig_node->gwflags], gw_node->unavail_factor ); + dprintf( fd, "=> %s via: %s(%i), gw_class %i - %s, reliability: %i\n", str, str2, gw_node->orig_node->router->packet_count, gw_node->orig_node->gwflags, gw2string[gw_node->orig_node->gwflags], gw_node->unavail_factor ); } else { - printf( "%s via: %s(%i), gw_class %i - %s, reliability: %i\n", str, str2, gw_node->orig_node->router->packet_count, gw_node->orig_node->gwflags, gw2string[gw_node->orig_node->gwflags], gw_node->unavail_factor ); + dprintf( fd, "%s via: %s(%i), gw_class %i - %s, reliability: %i\n", str, str2, gw_node->orig_node->router->packet_count, gw_node->orig_node->gwflags, gw2string[gw_node->orig_node->gwflags], gw_node->unavail_factor ); }
} @@ -537,7 +543,7 @@ static void debug() {
} else {
- if ( debug_level == 4 ) { + if ( max_output ) {
output( "------------------ DEBUG ------------------\n" ); output( "Forward list\n" ); @@ -563,10 +569,10 @@ static void debug() { addr_to_string( orig_node->orig, str, sizeof (str) ); addr_to_string( orig_node->router->addr, str2, sizeof (str2) );
- if ( debug_level != 4 ) { - printf( "%s, GW: %s(%i) via:", str, str2, orig_node->router->packet_count ); - } else { + if ( max_output ) { output( "%s, GW: %s(%i), last_aware:%u via:\n", str, str2, orig_node->router->packet_count, orig_node->last_aware ); + } else { + dprintf( fd, "%s, GW: %s(%i) via:", str, str2, orig_node->router->packet_count ); }
list_for_each(neigh_pos, &orig_node->neigh_list) { @@ -574,30 +580,30 @@ static void debug() {
addr_to_string(neigh_node->addr, str, sizeof (str));
- if ( debug_level != 4 ) { - printf( " %s(%i)", str, neigh_node->packet_count ); - } else { + if ( max_output ) { output( "\t\t%s (%d)\n", str, neigh_node->packet_count ); + } else { + dprintf( fd, " %s(%i)", str, neigh_node->packet_count ); }
}
- if ( debug_level != 4 ) - printf( "\n" ); + if ( ! max_output ) + dprintf( fd, "\n" );
}
if ( batman_count == 0 ) {
- if ( debug_level != 4 ) { - printf( "No batman nodes in range ...\n" ); - } else { + if ( max_output ) { output( "No batman nodes in range ...\n" ); + } else { + dprintf( fd, "No batman nodes in range ...\n" ); }
}
- if ( debug_level == 4 ) + if ( max_output ) output( "---------------------------------------------- END DEBUG\n" );
} @@ -1141,12 +1147,16 @@ int batman() send_vis_packet(); }
+ pthread_mutex_unlock( &data_mutex ); + /* harden select_timeout against sudden time change (e.g. ntpdate) */ curr_time = get_time(); select_timeout = ( curr_time >= last_own_packet + orginator_interval - 10 ? orginator_interval : last_own_packet + orginator_interval - curr_time );
res = receive_packet( ( unsigned char *)&in, 1501, &hna_buff_len, &neigh, select_timeout, &if_incoming );
+ pthread_mutex_lock( &data_mutex ); + if (res < 0) return -1;
@@ -1387,7 +1397,10 @@ int batman() if ( debug_timeout + 1000 < get_time() ) {
debug_timeout = get_time(); - debug(); + + if ( ( debug_level != 0 ) && ( debug_level != 3 ) ) + debug( 1, ( debug_level == 4 ? 0 : 1 ), ( debug_level == 4 ? 1 : 0 ), ( debug_level == 2 ? 1 : 0 ) ); + checkIntegrity();
} diff --git a/batman.h b/batman.h index 32ae120..a8681c5 100644 --- a/batman.h +++ b/batman.h @@ -22,6 +22,7 @@
#include <netinet/in.h> #include <pthread.h> +#include <sys/un.h> #include "list.h"
@@ -32,6 +33,8 @@ #define DIRECTLINK 0x40 #define ADDR_STR_LEN 16
+#define UNIX_PATH "/var/run/batmand.socket" +
/* * No configuration files or fancy command line switches yet @@ -66,11 +69,14 @@ extern unsigned char *hna_buff; extern struct gw_node *curr_gateway; pthread_t curr_gateway_thread_id;
+extern pthread_mutex_t data_mutex; + extern short found_ifs;
extern struct list_head if_list; extern struct list_head hna_list; extern struct vis_if vis_if; +extern struct unix_if unix_if;
struct packet { @@ -164,6 +170,19 @@ struct vis_if { struct sockaddr_in addr; };
+struct unix_if { + int unix_sock; + pthread_t listen_thread_id; + struct sockaddr_un addr; + struct list_head client_list; +}; + +struct unix_client { + struct list_head list; + int sock; + struct sockaddr_un addr; +}; +
int batman(); diff --git a/os.h b/os.h index 5f9a79d..2567d59 100644 --- a/os.h +++ b/os.h @@ -52,6 +52,8 @@ void *gw_listen( void *arg );
void *client_to_gw_tun( void *arg );
+void debug( int fd, char send_clear, char max_output, char show_gw ); + //int is_aborted();
//static void handler(int sig); diff --git a/posix-specific.c b/posix-specific.c index 946a0cc..11e251c 100644 --- a/posix-specific.c +++ b/posix-specific.c @@ -43,23 +43,160 @@
+void *unix_listen( void *arg ) { + + struct unix_client *unix_client; + struct list_head *unix_pos, *unix_pos_tmp; + struct timeval tv; + int res, status, max_sock; + unsigned char buff[1500]; + fd_set wait_sockets, tmp_wait_sockets; + socklen_t sun_size = sizeof(struct sockaddr_un); + + + INIT_LIST_HEAD(&unix_if.client_list); + + FD_ZERO(&wait_sockets); + FD_SET(unix_if.unix_sock, &wait_sockets); + + max_sock = unix_if.unix_sock; + + while (!is_aborted()) { + + tv.tv_sec = 1; + tv.tv_usec = 0; + tmp_wait_sockets = wait_sockets; + + res = select( max_sock + 1, &tmp_wait_sockets, NULL, NULL, &tv ); + + if ( res > 0 ) { + + /* new client */ + if ( FD_ISSET( unix_if.unix_sock, &tmp_wait_sockets ) ) { + + unix_client = debugMalloc( sizeof(struct unix_client), 133 ); + memset( unix_client, 0, sizeof(struct unix_client) ); + + if ( ( unix_client->sock = accept( unix_if.unix_sock, (struct sockaddr *)&unix_client->addr, &sun_size) ) == -1 ) { + do_log( "Error - can't accept unix client: %s\n", strerror(errno) ); + continue; + } + + INIT_LIST_HEAD(&unix_client->list); + + FD_SET(unix_client->sock, &wait_sockets); + if ( unix_client->sock > max_sock ) + max_sock = unix_client->sock; + + list_add_tail(&unix_client->list, &unix_if.client_list); + + if ( debug_level == 3 ) + printf( "unix socket: got connection\n" ); + + /* client sent data */ + } else { + + max_sock = unix_if.unix_sock; + + list_for_each_safe(unix_pos, unix_pos_tmp, &unix_if.client_list) { + + unix_client = list_entry(unix_pos, struct unix_client, list); + + if ( FD_ISSET( unix_client->sock, &tmp_wait_sockets ) ) { + + status = read( unix_client->sock, buff, sizeof( buff ) ); + + if ( status > 0 ) { + + if ( unix_client->sock > max_sock ) + max_sock = unix_client->sock; + + /* if ( debug_level == 3 ) + printf( "gateway: client sent data via unix socket: %s\n", buff ); */ + + if ( ( buff[2] == '1' ) || ( buff[2] == '2' ) ) { + + pthread_mutex_lock( &data_mutex ); + debug( unix_client->sock, 0, 0, ( buff[2] == '2' ? 1 : 0 ) ); + pthread_mutex_unlock( &data_mutex ); + + } + + } else { + + if ( status < 0 ) { + + do_log( "Error - can't read unix message: %s\n", strerror(errno) ); + + } else { + + if ( debug_level == 3 ) + printf( "Unix client closed connection ...\n" ); + + } + + FD_CLR(unix_client->sock, &wait_sockets); + close( unix_client->sock ); + + list_del( unix_pos ); + debugFree( unix_pos, 231 ); + + } + + } else { + + if ( unix_client->sock > max_sock ) + max_sock = unix_client->sock; + + } + + } + + } + + } else if ( ( res < 0 ) && ( errno != EINTR ) ) { + + do_log( "Error - can't select: %s\n", strerror(errno) ); + break; + + } + + } + + list_for_each_safe(unix_pos, unix_pos_tmp, &unix_if.client_list) { + + unix_client = list_entry(unix_pos, struct unix_client, list); + + list_del( unix_pos ); + debugFree( unix_pos, 241 ); + + } + + return NULL; + +} + + + void apply_init_args( int argc, char *argv[] ) {
struct in_addr tmp_ip_holder; struct batman_if *batman_if; struct hna_node *hna_node; struct ifreq int_req; - short on = 1, found_args = 1, netmask; - int optchar; - char str1[16], str2[16], *slash_ptr; + struct timeval tv; + short on = 1, found_args = 1, unix_client = 0, batch_mode = 0, netmask; + int optchar, res, recv_buff_len; + char str1[16], str2[16], *slash_ptr, unix_string[100], buff[1500]; unsigned int vis_server = 0; + fd_set wait_sockets, tmp_wait_sockets;
memset(&tmp_ip_holder, 0, sizeof (struct in_addr));
printf( "WARNING: You are using the unstable batman branch. If you are interested in *using* batman get the latest stable release !\n" );
- while ( ( optchar = getopt ( argc, argv, "a:d:hHo:g:p:r:s:vV" ) ) != -1 ) { + while ( ( optchar = getopt ( argc, argv, "a:bcd:hHo:g:p:r:s:vV" ) ) != -1 ) {
switch ( optchar ) {
@@ -111,6 +248,14 @@ void apply_init_args( int argc, char *argv[] ) { found_args += 2; break;
+ case 'b': + batch_mode++; + break; + + case 'c': + unix_client++; + break; + case 'd':
errno = 0; @@ -241,228 +386,250 @@ void apply_init_args( int argc, char *argv[] ) {
}
+ if ( ( gateway_class != 0 ) && ( routing_class != 0 ) ) { fprintf( stderr, "Error - routing class can't be set while gateway class is in use !\n" ); usage(); - close_all_sockets(); exit(EXIT_FAILURE); }
if ( ( gateway_class != 0 ) && ( pref_gateway != 0 ) ) { fprintf( stderr, "Error - preferred gateway can't be set while gateway class is in use !\n" ); usage(); - close_all_sockets(); exit(EXIT_FAILURE); }
if ( ( routing_class == 0 ) && ( pref_gateway != 0 ) ) { fprintf( stderr, "Error - preferred gateway can't be set without specifying routing class !\n" ); usage(); - close_all_sockets(); exit(EXIT_FAILURE); }
if ( ( ( routing_class != 0 ) || ( gateway_class != 0 ) ) && ( !probe_tun() ) ) { - close_all_sockets(); exit( 1 ); }
- if ( argc <= found_args ) { - fprintf( stderr, "Error - no interface specified\n" ); - usage(); - close_all_sockets(); - exit(EXIT_FAILURE); - } - - /* daemonize */ - if ( debug_level == 0 ) { - - if ( daemon( 0, 0 ) < 0 ) { + if ( ! unix_client ) {
- printf( "Error - can't fork to background: %s\n", strerror(errno) ); + if ( argc <= found_args ) { + fprintf( stderr, "Error - no interface specified\n" ); + usage(); close_all_sockets(); exit(EXIT_FAILURE); - }
- openlog( "batmand", LOG_PID, LOG_DAEMON ); - - } else { + /* daemonize */ + if ( debug_level == 0 ) {
- printf( "B.A.T.M.A.N.-III v%s (compability version %i)\n", SOURCE_VERSION, COMPAT_VERSION ); + if ( daemon( 0, 0 ) < 0 ) {
- } - - while ( argc > found_args ) { - - batman_if = debugMalloc(sizeof(struct batman_if), 17); - memset(batman_if, 0, sizeof(struct batman_if)); - INIT_LIST_HEAD(&batman_if->list); - INIT_LIST_HEAD(&batman_if->client_list); - - batman_if->dev = argv[found_args]; - batman_if->if_num = found_ifs; - - list_add_tail(&batman_if->list, &if_list); - - if ( strlen(batman_if->dev) > IFNAMSIZ - 1 ) { - do_log( "Error - interface name too long: %s\n", batman_if->dev ); - close_all_sockets(); - exit(EXIT_FAILURE); - } - - batman_if->udp_send_sock = socket(PF_INET, SOCK_DGRAM, 0); - if (batman_if->udp_send_sock < 0) { - do_log( "Error - can't create send socket: %s", strerror(errno) ); - close_all_sockets(); - exit(EXIT_FAILURE); - } - - batman_if->udp_recv_sock = socket(PF_INET, SOCK_DGRAM, 0); - if ( batman_if->udp_recv_sock < 0 ) { - - do_log( "Error - can't create recieve socket: %s", strerror(errno) ); - close_all_sockets(); - exit(EXIT_FAILURE); - - } - - memset(&int_req, 0, sizeof (struct ifreq)); - strncpy(int_req.ifr_name, batman_if->dev, IFNAMSIZ - 1); - - if ( ioctl( batman_if->udp_recv_sock, SIOCGIFADDR, &int_req ) < 0 ) { - - do_log( "Error - can't get IP address of interface %s\n", batman_if->dev ); - close_all_sockets(); - exit(EXIT_FAILURE); + printf( "Error - can't fork to background: %s\n", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE);
- } + }
- batman_if->addr.sin_family = AF_INET; - batman_if->addr.sin_port = htons(PORT); - batman_if->addr.sin_addr.s_addr = ((struct sockaddr_in *)&int_req.ifr_addr)->sin_addr.s_addr; + openlog( "batmand", LOG_PID, LOG_DAEMON );
- if ( ioctl( batman_if->udp_recv_sock, SIOCGIFBRDADDR, &int_req ) < 0 ) { + } else {
- do_log( "Error - can't get broadcast IP address of interface %s\n", batman_if->dev ); - close_all_sockets(); - exit(EXIT_FAILURE); + printf( "B.A.T.M.A.N.-III v%s (compability version %i)\n", SOURCE_VERSION, COMPAT_VERSION );
}
- batman_if->broad.sin_family = AF_INET; - batman_if->broad.sin_port = htons(PORT); - batman_if->broad.sin_addr.s_addr = ((struct sockaddr_in *)&int_req.ifr_broadaddr)->sin_addr.s_addr; - - if ( setsockopt( batman_if->udp_send_sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (int) ) < 0 ) { - - do_log( "Error - can't enable broadcasts: %s\n", strerror(errno) ); - close_all_sockets(); - exit(EXIT_FAILURE); - - } + while ( argc > found_args ) {
- if ( bind_to_iface( batman_if->udp_send_sock, batman_if->dev ) < 0 ) { + batman_if = debugMalloc(sizeof(struct batman_if), 17); + memset(batman_if, 0, sizeof(struct batman_if)); + INIT_LIST_HEAD(&batman_if->list); + INIT_LIST_HEAD(&batman_if->client_list);
- close_all_sockets(); - exit(EXIT_FAILURE); + batman_if->dev = argv[found_args]; + batman_if->if_num = found_ifs;
- } + list_add_tail(&batman_if->list, &if_list);
- if ( bind( batman_if->udp_send_sock, (struct sockaddr *)&batman_if->addr, sizeof (struct sockaddr_in) ) < 0 ) { + if ( strlen(batman_if->dev) > IFNAMSIZ - 1 ) { + do_log( "Error - interface name too long: %s\n", batman_if->dev ); + close_all_sockets(); + exit(EXIT_FAILURE); + }
- do_log( "Error - can't bind send socket: %s\n", strerror(errno) ); - close_all_sockets(); - exit(EXIT_FAILURE); + batman_if->udp_send_sock = socket(PF_INET, SOCK_DGRAM, 0); + if (batman_if->udp_send_sock < 0) { + do_log( "Error - can't create send socket: %s", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + }
- } + batman_if->udp_recv_sock = socket(PF_INET, SOCK_DGRAM, 0); + if ( batman_if->udp_recv_sock < 0 ) {
- if ( bind_to_iface( batman_if->udp_recv_sock, batman_if->dev ) < 0 ) { + do_log( "Error - can't create recieve socket: %s", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE);
- close_all_sockets(); - exit(EXIT_FAILURE); + }
- } + memset(&int_req, 0, sizeof (struct ifreq)); + strncpy(int_req.ifr_name, batman_if->dev, IFNAMSIZ - 1);
- if ( bind( batman_if->udp_recv_sock, (struct sockaddr *)&batman_if->broad, sizeof (struct sockaddr_in) ) < 0 ) { + if ( ioctl( batman_if->udp_recv_sock, SIOCGIFADDR, &int_req ) < 0 ) {
- do_log( "Error - can't bind receive socket: %s\n", strerror(errno) ); - close_all_sockets(); - exit(EXIT_FAILURE); + do_log( "Error - can't get IP address of interface %s\n", batman_if->dev ); + close_all_sockets(); + exit(EXIT_FAILURE);
- } + }
+ batman_if->addr.sin_family = AF_INET; + batman_if->addr.sin_port = htons(PORT); + batman_if->addr.sin_addr.s_addr = ((struct sockaddr_in *)&int_req.ifr_addr)->sin_addr.s_addr;
- addr_to_string(batman_if->addr.sin_addr.s_addr, str1, sizeof (str1)); - addr_to_string(batman_if->broad.sin_addr.s_addr, str2, sizeof (str2)); + if ( ioctl( batman_if->udp_recv_sock, SIOCGIFBRDADDR, &int_req ) < 0 ) {
- if ( debug_level > 0 ) - printf("Using interface %s with address %s and broadcast address %s\n", batman_if->dev, str1, str2); + do_log( "Error - can't get broadcast IP address of interface %s\n", batman_if->dev ); + close_all_sockets(); + exit(EXIT_FAILURE);
- if ( gateway_class != 0 ) { + }
- batman_if->addr.sin_port = htons(PORT + 1); + batman_if->broad.sin_family = AF_INET; + batman_if->broad.sin_port = htons(PORT); + batman_if->broad.sin_addr.s_addr = ((struct sockaddr_in *)&int_req.ifr_broadaddr)->sin_addr.s_addr;
- batman_if->tcp_gw_sock = socket(PF_INET, SOCK_STREAM, 0); + if ( setsockopt( batman_if->udp_send_sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (int) ) < 0 ) {
- if ( batman_if->tcp_gw_sock < 0 ) { - do_log( "Error - can't create socket: %s", strerror(errno) ); + do_log( "Error - can't enable broadcasts: %s\n", strerror(errno) ); close_all_sockets(); exit(EXIT_FAILURE); + }
- if ( setsockopt(batman_if->tcp_gw_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)) < 0 ) { - do_log( "Error - can't enable reuse of address: %s\n", strerror(errno) ); + if ( bind_to_iface( batman_if->udp_send_sock, batman_if->dev ) < 0 ) { + close_all_sockets(); exit(EXIT_FAILURE); + }
- if ( bind( batman_if->tcp_gw_sock, (struct sockaddr*)&batman_if->addr, sizeof(struct sockaddr_in)) < 0 ) { - do_log( "Error - can't bind socket: %s\n", strerror(errno) ); + if ( bind( batman_if->udp_send_sock, (struct sockaddr *)&batman_if->addr, sizeof (struct sockaddr_in) ) < 0 ) { + + do_log( "Error - can't bind send socket: %s\n", strerror(errno) ); close_all_sockets(); exit(EXIT_FAILURE); + }
- if ( listen( batman_if->tcp_gw_sock, 10 ) < 0 ) { - do_log( "Error - can't listen socket: %s\n", strerror(errno) ); + if ( bind_to_iface( batman_if->udp_recv_sock, batman_if->dev ) < 0 ) { + close_all_sockets(); exit(EXIT_FAILURE); + }
- batman_if->tunnel_sock = socket(PF_INET, SOCK_DGRAM, 0); - if ( batman_if->tunnel_sock < 0 ) { - do_log( "Error - can't create tunnel socket: %s", strerror(errno) ); + if ( bind( batman_if->udp_recv_sock, (struct sockaddr *)&batman_if->broad, sizeof (struct sockaddr_in) ) < 0 ) { + + do_log( "Error - can't bind receive socket: %s\n", strerror(errno) ); close_all_sockets(); exit(EXIT_FAILURE); + }
- if ( bind(batman_if->tunnel_sock, (struct sockaddr *)&batman_if->addr, sizeof (struct sockaddr_in)) < 0 ) { - do_log( "Error - can't bind tunnel socket: %s\n", strerror(errno) ); - close_all_sockets(); - exit(EXIT_FAILURE); + + addr_to_string(batman_if->addr.sin_addr.s_addr, str1, sizeof (str1)); + addr_to_string(batman_if->broad.sin_addr.s_addr, str2, sizeof (str2)); + + if ( debug_level > 0 ) + printf("Using interface %s with address %s and broadcast address %s\n", batman_if->dev, str1, str2); + + if ( gateway_class != 0 ) { + + batman_if->addr.sin_port = htons(PORT + 1); + + batman_if->tcp_gw_sock = socket(PF_INET, SOCK_STREAM, 0); + + if ( batman_if->tcp_gw_sock < 0 ) { + do_log( "Error - can't create socket: %s", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + if ( setsockopt( batman_if->tcp_gw_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int) ) < 0 ) { + do_log( "Error - can't enable reuse of address: %s\n", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + if ( bind( batman_if->tcp_gw_sock, (struct sockaddr*)&batman_if->addr, sizeof(struct sockaddr_in) ) < 0 ) { + do_log( "Error - can't bind socket: %s\n", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + if ( listen( batman_if->tcp_gw_sock, 10 ) < 0 ) { + do_log( "Error - can't listen socket: %s\n", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + batman_if->tunnel_sock = socket(PF_INET, SOCK_DGRAM, 0); + if ( batman_if->tunnel_sock < 0 ) { + do_log( "Error - can't create tunnel socket: %s", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + if ( bind( batman_if->tunnel_sock, (struct sockaddr *)&batman_if->addr, sizeof (struct sockaddr_in) ) < 0 ) { + do_log( "Error - can't bind tunnel socket: %s\n", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + batman_if->addr.sin_port = htons(PORT); + + pthread_create( &batman_if->listen_thread_id, NULL, &gw_listen, batman_if ); + }
- batman_if->addr.sin_port = htons(PORT); + found_ifs++; + found_args++;
- pthread_create(&batman_if->listen_thread_id, NULL, &gw_listen, batman_if); + }
+ if(vis_server) + { + memset(&vis_if.addr, 0, sizeof(vis_if.addr)); + vis_if.addr.sin_family = AF_INET; + vis_if.addr.sin_port = htons(1967); + vis_if.addr.sin_addr.s_addr = vis_server; + /*vis_if.sock = socket( PF_INET, SOCK_DGRAM, 0);*/ + vis_if.sock = ((struct batman_if *)if_list.next)->udp_send_sock; + } else { + memset(&vis_if, 0, sizeof(vis_if)); }
- found_ifs++; - found_args++;
- } + unlink( UNIX_PATH ); + unix_if.unix_sock = socket(AF_LOCAL, SOCK_STREAM, 0);
- if(vis_server) - { - memset(&vis_if.addr, 0, sizeof(vis_if.addr)); - vis_if.addr.sin_family = AF_INET; - vis_if.addr.sin_port = htons(1967); - vis_if.addr.sin_addr.s_addr = vis_server; - /*vis_if.sock = socket( PF_INET, SOCK_DGRAM, 0);*/ - vis_if.sock = ((struct batman_if *)if_list.next)->udp_send_sock; - } else - memset(&vis_if, 0, sizeof(vis_if)); + memset( &unix_if.addr, 0, sizeof(struct sockaddr_un) ); + unix_if.addr.sun_family = AF_LOCAL; + strcpy( unix_if.addr.sun_path, UNIX_PATH ); + + if ( bind ( unix_if.unix_sock, (struct sockaddr *)&unix_if.addr, sizeof (struct sockaddr_un) ) < 0 ) { + do_log( "Error - can't bind unix socket: %s\n", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + if ( listen( unix_if.unix_sock, 10 ) < 0 ) { + do_log( "Error - can't listen unix socket: %s\n", strerror(errno) ); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + pthread_create( &unix_if.listen_thread_id, NULL, &unix_listen, NULL );
if ( debug_level > 0 ) { @@ -490,6 +657,96 @@ void apply_init_args( int argc, char *argv[] ) {
}
+ /* connect to running batmand via unix socket */ + } else { + + if ( ( debug_level == 1 ) || ( debug_level == 2 ) ) { + + unix_if.unix_sock = socket(AF_LOCAL, SOCK_STREAM, 0); + + memset( &unix_if.addr, 0, sizeof(struct sockaddr_un) ); + unix_if.addr.sun_family = AF_LOCAL; + strcpy( unix_if.addr.sun_path, UNIX_PATH ); + + if ( connect ( unix_if.unix_sock, (struct sockaddr *)&unix_if.addr, sizeof(struct sockaddr_un) ) < 0 ) { + + printf( "Error - can't connect to unix socket: %s\n", strerror(errno) ); + close( unix_if.unix_sock ); + + exit(EXIT_FAILURE); + + } + + snprintf( unix_string, sizeof( unix_string ), "d:%i", debug_level ); + + FD_ZERO(&wait_sockets); + FD_SET(unix_if.unix_sock, &wait_sockets); + + while ( 1 ) { + + if ( write( unix_if.unix_sock, unix_string, strlen( unix_string ) ) < 0 ) { + + printf( "Error - can't write to unix socket: %s\n", strerror(errno) ); + close( unix_if.unix_sock ); + exit(EXIT_FAILURE); + + } + + if ( ! batch_mode ) + system( "clear" ); + + while ( 1 ) { + + tv.tv_sec = 1; + tv.tv_usec = 0; + tmp_wait_sockets = wait_sockets; + + res = select( unix_if.unix_sock + 1, &tmp_wait_sockets, NULL, NULL, &tv ); + + if ( res > 0 ) { + + if ( ( recv_buff_len = read( unix_if.unix_sock, buff, sizeof( buff ) ) ) < 0 ) { + + printf( "Error - can't read from unix socket: %s\n", strerror(errno) ); + close( unix_if.unix_sock ); + exit(EXIT_FAILURE); + + } else if ( recv_buff_len > 0 ) { + + printf( "%s", buff ); + + } + + /* timeout reached */ + } else if ( res == 0 ) { + + break; + + } else if ( ( res < 0 ) && ( errno != EINTR ) ) { + + printf( "Error - can't select: %s\n", strerror(errno) ); + close( unix_if.unix_sock ); + exit(EXIT_FAILURE); + + } + + } + + if ( batch_mode ) + break; + + sleep( 1 ); + + } + + close( unix_if.unix_sock ); + + } + + exit(EXIT_SUCCESS); + + } + }
@@ -703,7 +960,7 @@ void *client_to_gw_tun( void *arg ) {
}
- } else if ( ( res < 0 ) && (errno != EINTR) ) { + } else if ( ( res < 0 ) && ( errno != EINTR ) ) {
do_log( "Error - can't select: %s\n", strerror(errno) ); break; @@ -783,6 +1040,14 @@ void close_all_sockets() { if (vis_if.sock) close(vis_if.sock);
+ if ( unix_if.unix_sock ) + close( unix_if.unix_sock ); + + if ( unix_if.listen_thread_id != 0 ) + pthread_join( unix_if.listen_thread_id, NULL ); + + unlink( UNIX_PATH ); + if ( debug_level == 0 ) closelog();
@@ -822,7 +1087,7 @@ int receive_packet( unsigned char *packet_buff, int packet_buff_len, int *hna_bu { res = select( max_sock + 1, &wait_set, NULL, NULL, &tv );
- if (res >= 0) + if ( res >= 0 ) break;
if ( errno != EINTR ) { @@ -1069,7 +1334,7 @@ void *gw_listen( void *arg ) {
}
- } else if ( ( res < 0 ) && (errno != EINTR) ) { + } else if ( ( res < 0 ) && ( errno != EINTR ) ) {
do_log( "Error - can't select: %s\n", strerror(errno) ); break; @@ -1117,7 +1382,17 @@ void *gw_listen( void *arg ) { /* delete tun devices on exit */ del_dev_tun( tun_fd );
+ list_for_each_safe(client_pos, client_pos_tmp, &batman_if->client_list) { + + gw_client = list_entry(client_pos, struct gw_client, list); + + list_del( client_pos ); + debugFree( client_pos, 297 ); + + } + return NULL;
}
+