2
* Copyright (C) 2006 B.A.T.M.A.N. contributors:
3
* Thomas Lopatic, Corinna 'Elektra' Aichele, Axel Neumann,
4
* Felix Fietkau, Marek Lindner
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of version 2 of the GNU General Public
8
* License as published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29
#include "originator.h"
32
#include <errno.h> /* should be removed together with tcp control channel */
35
/* "-d" is the command line switch for the debug level,
36
* specify it multiple times to increase verbosity
37
* 0 gives a minimum of messages to save CPU-Power
41
* Beware that high debugging levels eat a lot of CPU-Power
44
uint8_t debug_level = 0;
46
/* "-g" is the command line switch for the gateway class,
59
* this option is used to determine packet path
62
char *gw2string[] = { "No Gateway",
63
"56 KBit (e.g. Modem)",
64
"64 KBit (e.g. ISDN)",
65
"128 KBit (e.g. double ISDN)",
67
"512 KBit (e.g. UMTS)",
75
uint8_t gateway_class = 0;
77
/* "-r" is the command line switch for the routing class,
78
* 0 set no default route
79
* 1 use fast internet connection
80
* 2 use stable internet connection
81
* 3 use use best statistic (olsr style)
82
* this option is used to set the routing behaviour
85
uint8_t routing_class = 0;
88
int16_t orginator_interval = 1000; /* orginator message interval in miliseconds */
90
struct gw_node *curr_gateway = NULL;
91
pthread_t curr_gateway_thread_id = 0;
92
pthread_mutex_t curr_gw_mutex = PTHREAD_MUTEX_INITIALIZER;
94
uint32_t pref_gateway = 0;
96
unsigned char *hna_buff = NULL;
100
uint8_t found_ifs = 0;
101
int32_t receive_max_sock = 0;
102
fd_set receive_wait_set;
104
uint8_t unix_client = 0;
106
struct hashtable_t *orig_hash;
108
LIST_HEAD(forw_list);
113
struct vis_if vis_if;
114
struct unix_if unix_if;
115
struct debug_clients debug_clients;
117
unsigned char *vis_packet = NULL;
118
uint16_t vis_packet_size = 0;
124
fprintf( stderr, "Usage: batman [options] interface [interface interface]\n" );
125
fprintf( stderr, " -a announce network(s)\n" );
126
fprintf( stderr, " -b run connection in batch mode\n" );
127
fprintf( stderr, " -c connect via unix socket\n" );
128
fprintf( stderr, " -d debug level\n" );
129
fprintf( stderr, " -g gateway class\n" );
130
fprintf( stderr, " -h this help\n" );
131
fprintf( stderr, " -H verbose help\n" );
132
fprintf( stderr, " -o orginator interval in ms\n" );
133
fprintf( stderr, " -p preferred gateway\n" );
134
fprintf( stderr, " -r routing class\n" );
135
fprintf( stderr, " -s visualisation server\n" );
136
fprintf( stderr, " -v print version\n" );
142
void verbose_usage( void ) {
144
fprintf( stderr, "Usage: batman [options] interface [interface interface]\n\n" );
145
fprintf( stderr, " -a announce network(s)\n" );
146
fprintf( stderr, " network/netmask is expected\n" );
147
fprintf( stderr, " -b run connection in batch mode\n" );
148
fprintf( stderr, " -c connect to running batmand via unix socket\n" );
149
fprintf( stderr, " -d debug level\n" );
150
fprintf( stderr, " default: 0 -> debug disabled\n" );
151
fprintf( stderr, " allowed values: 1 -> list neighbours\n" );
152
fprintf( stderr, " 2 -> list gateways\n" );
153
fprintf( stderr, " 3 -> observe batman\n" );
154
fprintf( stderr, " 4 -> observe batman (very verbose)\n\n" );
155
fprintf( stderr, " -g gateway class\n" );
156
fprintf( stderr, " default: 0 -> this is not an internet gateway\n" );
157
fprintf( stderr, " allowed values: 1 -> modem line\n" );
158
fprintf( stderr, " 2 -> ISDN line\n" );
159
fprintf( stderr, " 3 -> double ISDN\n" );
160
fprintf( stderr, " 4 -> 256 KBit\n" );
161
fprintf( stderr, " 5 -> UMTS / 0.5 MBit\n" );
162
fprintf( stderr, " 6 -> 1 MBit\n" );
163
fprintf( stderr, " 7 -> 2 MBit\n" );
164
fprintf( stderr, " 8 -> 3 MBit\n" );
165
fprintf( stderr, " 9 -> 5 MBit\n" );
166
fprintf( stderr, " 10 -> 6 MBit\n" );
167
fprintf( stderr, " 11 -> >6 MBit\n\n" );
168
fprintf( stderr, " -h shorter help\n" );
169
fprintf( stderr, " -H this help\n" );
170
fprintf( stderr, " -o orginator interval in ms\n" );
171
fprintf( stderr, " default: 1000, allowed values: >0\n\n" );
172
fprintf( stderr, " -p preferred gateway\n" );
173
fprintf( stderr, " default: none, allowed values: IP\n\n" );
174
fprintf( stderr, " -r routing class (only needed if gateway class = 0)\n" );
175
fprintf( stderr, " default: 0 -> set no default route\n" );
176
fprintf( stderr, " allowed values: 1 -> use fast internet connection\n" );
177
fprintf( stderr, " 2 -> use stable internet connection\n" );
178
fprintf( stderr, " 3 -> use best statistic internet connection (olsr style)\n\n" );
179
fprintf( stderr, " -s visualisation server\n" );
180
fprintf( stderr, " default: none, allowed values: IP\n\n" );
181
fprintf( stderr, " -v print version\n" );
187
void add_del_hna( struct orig_node *orig_node, int8_t del ) {
189
uint16_t hna_buff_count = 0;
190
uint32_t hna, netmask;
193
while ( ( hna_buff_count + 1 ) * 5 <= orig_node->hna_buff_len ) {
195
memcpy( &hna, ( uint32_t *)&orig_node->hna_buff[ hna_buff_count * 5 ], 4 );
196
netmask = ( uint32_t )orig_node->hna_buff[ ( hna_buff_count * 5 ) + 4 ];
198
if ( ( netmask > 0 ) && ( netmask < 33 ) )
199
add_del_route( hna, netmask, orig_node->router->addr, del, orig_node->batman_if->dev, orig_node->batman_if->udp_send_sock );
207
debugFree( orig_node->hna_buff, 1101 );
208
orig_node->hna_buff_len = 0;
218
prof_start( PROF_choose_gw );
219
struct list_head *pos;
220
struct gw_node *gw_node, *tmp_curr_gw = NULL;
221
uint8_t max_gw_class = 0, max_packets = 0, max_gw_factor = 0;
222
static char orig_str[ADDR_STR_LEN];
225
if ( routing_class == 0 ) {
227
prof_stop( PROF_choose_gw );
232
if ( list_empty(&gw_list) ) {
234
if ( curr_gateway != NULL ) {
236
debug_output( 3, "Removing default route - no gateway in range \n" );
242
prof_stop( PROF_choose_gw );
248
list_for_each(pos, &gw_list) {
250
gw_node = list_entry(pos, struct gw_node, list);
252
/* ignore this gateway if recent connection attempts were unsuccessful */
253
if ( ( gw_node->unavail_factor * gw_node->unavail_factor * 30000 ) + gw_node->last_failure > get_time() )
256
if ( gw_node->orig_node->router == NULL )
259
if ( gw_node->deleted )
262
switch ( routing_class ) {
264
case 1: /* fast connection */
265
if ( ( ( gw_node->orig_node->router->packet_count * gw_node->orig_node->gwflags ) > max_gw_factor ) || ( ( ( gw_node->orig_node->router->packet_count * gw_node->orig_node->gwflags ) == max_gw_factor ) && ( gw_node->orig_node->router->packet_count > max_packets ) ) )
266
tmp_curr_gw = gw_node;
269
case 2: /* stable connection */
270
/* FIXME - not implemented yet */
271
if ( ( ( gw_node->orig_node->router->packet_count * gw_node->orig_node->gwflags ) > max_gw_factor ) || ( ( ( gw_node->orig_node->router->packet_count * gw_node->orig_node->gwflags ) == max_gw_factor ) && ( gw_node->orig_node->router->packet_count > max_packets ) ) )
272
tmp_curr_gw = gw_node;
275
default: /* use best statistic (olsr style) */
276
if ( gw_node->orig_node->router->packet_count > max_packets )
277
tmp_curr_gw = gw_node;
282
if ( gw_node->orig_node->gwflags > max_gw_class )
283
max_gw_class = gw_node->orig_node->gwflags;
285
if ( gw_node->orig_node->router->packet_count > max_packets )
286
max_packets = gw_node->orig_node->router->packet_count;
288
if ( ( gw_node->orig_node->router->packet_count * gw_node->orig_node->gwflags ) > max_gw_class )
289
max_gw_factor = ( gw_node->orig_node->router->packet_count * gw_node->orig_node->gwflags );
291
if ( ( pref_gateway != 0 ) && ( pref_gateway == gw_node->orig_node->orig ) ) {
293
tmp_curr_gw = gw_node;
295
addr_to_string( tmp_curr_gw->orig_node->orig, orig_str, ADDR_STR_LEN );
296
debug_output( 3, "Preferred gateway found: %s (%i,%i,%i) \n", orig_str, gw_node->orig_node->gwflags, gw_node->orig_node->router->packet_count, ( gw_node->orig_node->router->packet_count * gw_node->orig_node->gwflags ) );
305
if ( curr_gateway != tmp_curr_gw ) {
307
if ( pthread_mutex_trylock( &curr_gw_mutex ) == 0 ) {
309
if ( curr_gateway != NULL ) {
311
debug_output( 3, "Removing default route - better gateway found \n" );
317
curr_gateway = tmp_curr_gw;
319
/* may be the last gateway is now gone */
320
if ( ( curr_gateway != NULL ) && ( !is_aborted() ) ) {
322
addr_to_string( curr_gateway->orig_node->orig, orig_str, ADDR_STR_LEN );
323
debug_output( 3, "Adding default route to %s (%i,%i,%i) \n", orig_str, max_gw_class, max_packets, max_gw_factor );
329
if ( pthread_mutex_unlock( &curr_gw_mutex ) < 0 )
330
debug_output( 0, "Error - could not unlock mutex (choose_gw): %s \n", strerror( errno ) );
334
debug_output( 0, "Warning - could not change default route (mutex locked): %s \n", strerror( EBUSY ) );
340
prof_stop( PROF_choose_gw );
346
void update_routes( struct orig_node *orig_node, struct neigh_node *neigh_node, unsigned char *hna_recv_buff, int16_t hna_buff_len ) {
348
prof_start( PROF_update_routes );
349
static char orig_str[ADDR_STR_LEN], next_str[ADDR_STR_LEN];
352
debug_output( 4, "update_routes() \n" );
355
if ( ( orig_node != NULL ) && ( orig_node->router != neigh_node ) ) {
357
if ( ( orig_node != NULL ) && ( neigh_node != NULL ) ) {
358
addr_to_string( orig_node->orig, orig_str, ADDR_STR_LEN );
359
addr_to_string( neigh_node->addr, next_str, ADDR_STR_LEN );
360
debug_output( 4, "Route to %s via %s \n", orig_str, next_str );
363
/* route altered or deleted */
364
if ( ( ( orig_node->router != NULL ) && ( neigh_node != NULL ) ) || ( neigh_node == NULL ) ) {
366
if ( neigh_node == NULL ) {
367
debug_output( 4, "Deleting previous route \n" );
369
debug_output( 4, "Route changed \n" );
372
/* remove old announced network(s) */
373
if ( orig_node->hna_buff_len > 0 )
374
add_del_hna( orig_node, 1 );
376
add_del_route( orig_node->orig, 32, orig_node->router->addr, 1, orig_node->batman_if->dev, orig_node->batman_if->udp_send_sock );
380
/* route altered or new route added */
381
if ( ( ( orig_node->router != NULL ) && ( neigh_node != NULL ) ) || ( orig_node->router == NULL ) ) {
383
if ( orig_node->router == NULL ) {
384
debug_output( 4, "Adding new route \n" );
386
debug_output( 4, "Route changed \n" );
389
add_del_route( orig_node->orig, 32, neigh_node->addr, 0, neigh_node->if_incoming->dev, neigh_node->if_incoming->udp_send_sock );
391
orig_node->batman_if = neigh_node->if_incoming;
392
orig_node->router = neigh_node;
394
/* add new announced network(s) */
395
if ( hna_buff_len > 0 ) {
397
orig_node->hna_buff = debugMalloc( hna_buff_len, 101 );
398
orig_node->hna_buff_len = hna_buff_len;
400
memmove( orig_node->hna_buff, hna_recv_buff, hna_buff_len );
402
add_del_hna( orig_node, 0 );
408
orig_node->router = neigh_node;
410
} else if ( orig_node != NULL ) {
412
/* may be just HNA changed */
413
if ( ( hna_buff_len != orig_node->hna_buff_len ) || ( ( hna_buff_len > 0 ) && ( orig_node->hna_buff_len > 0 ) && ( memcmp( orig_node->hna_buff, hna_recv_buff, hna_buff_len ) != 0 ) ) ) {
415
if ( orig_node->hna_buff_len > 0 )
416
add_del_hna( orig_node, 1 );
418
if ( hna_buff_len > 0 ) {
420
orig_node->hna_buff = debugMalloc( hna_buff_len, 102 );
421
orig_node->hna_buff_len = hna_buff_len;
423
memcpy( orig_node->hna_buff, hna_recv_buff, hna_buff_len );
425
add_del_hna( orig_node, 0 );
433
prof_stop( PROF_update_routes );
439
void update_gw_list( struct orig_node *orig_node, uint8_t new_gwflags ) {
441
prof_start( PROF_update_gw_list );
442
struct list_head *gw_pos, *gw_pos_tmp;
443
struct gw_node *gw_node;
444
static char orig_str[ADDR_STR_LEN];
446
list_for_each_safe( gw_pos, gw_pos_tmp, &gw_list ) {
448
gw_node = list_entry(gw_pos, struct gw_node, list);
450
if ( gw_node->orig_node == orig_node ) {
452
addr_to_string( gw_node->orig_node->orig, orig_str, ADDR_STR_LEN );
453
debug_output( 3, "Gateway class of originator %s changed from %i to %i \n", orig_str, gw_node->orig_node->gwflags, new_gwflags );
455
if ( new_gwflags == 0 ) {
457
gw_node->deleted = get_time();
459
debug_output( 3, "Gateway %s removed from gateway list \n", orig_str );
463
gw_node->deleted = 0;
464
gw_node->orig_node->gwflags = new_gwflags;
468
prof_stop( PROF_update_gw_list );
476
addr_to_string( orig_node->orig, orig_str, ADDR_STR_LEN );
477
debug_output( 3, "Found new gateway %s -> class: %i - %s \n", orig_str, new_gwflags, gw2string[new_gwflags] );
479
gw_node = debugMalloc( sizeof(struct gw_node), 103 );
480
memset( gw_node, 0, sizeof(struct gw_node) );
481
INIT_LIST_HEAD( &gw_node->list );
483
gw_node->orig_node = orig_node;
484
gw_node->unavail_factor = 0;
485
gw_node->last_failure = get_time();
487
list_add_tail( &gw_node->list, &gw_list );
489
prof_stop( PROF_update_gw_list );
497
int isDuplicate( struct orig_node *orig_node, uint16_t seqno ) {
499
prof_start( PROF_is_duplicate );
500
struct list_head *neigh_pos;
501
struct neigh_node *neigh_node;
503
list_for_each( neigh_pos, &orig_node->neigh_list ) {
505
neigh_node = list_entry( neigh_pos, struct neigh_node, list );
507
if ( get_bit_status( neigh_node->seq_bits, orig_node->last_seqno, seqno ) ) {
509
prof_stop( PROF_is_duplicate );
516
prof_stop( PROF_is_duplicate );
522
int isBntog( uint32_t neigh, struct orig_node *orig_tog_node ) {
524
if ( ( orig_tog_node->router != NULL ) && ( orig_tog_node->router->addr == neigh ) )
531
int isBidirectionalNeigh( struct orig_node *orig_neigh_node, struct batman_if *if_incoming ) {
533
if ( ( if_incoming->out.seqno - 2 - orig_neigh_node->bidirect_link[if_incoming->if_num] ) < BIDIRECT_TIMEOUT )
542
void generate_vis_packet() {
544
struct hash_it_t *hashit = NULL;
545
struct orig_node *orig_node;
548
if ( vis_packet != NULL ) {
550
debugFree( vis_packet, 1102 );
556
/* sender ip and gateway class */
558
vis_packet = debugMalloc( vis_packet_size, 104 );
560
memcpy( vis_packet, (unsigned char *)&(((struct batman_if *)if_list.next)->addr.sin_addr.s_addr), 4 );
561
vis_packet[4] = gateway_class;
562
vis_packet[5] = SEQ_RANGE;
565
while ( NULL != ( hashit = hash_iterate( orig_hash, hashit ) ) ) {
567
orig_node = hashit->bucket->data;
569
/* we interested in 1 hop neighbours only */
570
if ( ( orig_node->router != NULL ) && ( orig_node->orig == orig_node->router->addr ) ) {
572
/* neighbour ip and packet count */
573
vis_packet_size += 5;
575
vis_packet = debugRealloc( vis_packet, vis_packet_size, 105 );
577
memcpy( vis_packet + vis_packet_size - 5, (unsigned char *)&orig_node->orig, 4 );
579
vis_packet[vis_packet_size - 1] = orig_node->router->packet_count;
585
if ( vis_packet_size == 6 ) {
587
debugFree( vis_packet, 1107 );
597
void send_vis_packet() {
599
generate_vis_packet();
601
if ( vis_packet != NULL )
602
send_packet( vis_packet, vis_packet_size, &vis_if.addr, vis_if.sock );
610
struct list_head *if_pos, *neigh_pos, *hna_pos, *hna_pos_tmp, *forw_pos, *forw_pos_tmp;
611
struct orig_node *orig_neigh_node, *orig_node;
612
struct batman_if *batman_if, *if_incoming;
613
struct neigh_node *neigh_node;
614
struct hna_node *hna_node;
615
struct forw_node *forw_node;
616
uint32_t neigh, hna, netmask, debug_timeout, vis_timeout, select_timeout, curr_time, rcvd_time;
617
unsigned char in[1501], *hna_recv_buff;
618
static char orig_str[ADDR_STR_LEN], neigh_str[ADDR_STR_LEN], ifaddr_str[ADDR_STR_LEN];
619
int16_t hna_buff_count, hna_buff_len;
620
uint8_t forward_old, if_rp_filter_all_old, if_rp_filter_default_old, if_send_redirects_all_old, if_send_redirects_default_old;
621
uint8_t is_my_addr, is_my_orig, is_broadcast, is_duplicate, is_bidirectional, is_bntog, is_directNeigh, forward_duplicate_packet, has_unidirectional_flag, has_directlink_flag, has_version;
625
debug_timeout = vis_timeout = get_time();
629
if ( NULL == ( orig_hash = hash_new( 128, compare_orig, choose_orig ) ) )
632
/* for profiling the functions */
633
prof_init( PROF_choose_gw, "choose_gw" );
634
prof_init( PROF_update_routes, "update_routes" );
635
prof_init( PROF_update_gw_list, "update_gw_list" );
636
prof_init( PROF_is_duplicate, "isDuplicate" );
637
prof_init( PROF_get_orig_node, "get_orig_node" );
638
prof_init( PROF_update_originator, "update_orig" );
639
prof_init( PROF_purge_orginator, "purge_orig" );
640
prof_init( PROF_schedule_forward_packet, "schedule_forward_packet" );
641
prof_init( PROF_send_outstanding_packets, "send_outstanding_packets" );
643
if ( !( list_empty( &hna_list ) ) ) {
645
list_for_each( hna_pos, &hna_list ) {
647
hna_node = list_entry(hna_pos, struct hna_node, list);
649
hna_buff = debugRealloc( hna_buff, ( num_hna + 1 ) * 5 * sizeof( unsigned char ), 15 );
651
memmove( &hna_buff[ num_hna * 5 ], ( unsigned char *)&hna_node->addr, 4 );
652
hna_buff[ ( num_hna * 5 ) + 4 ] = ( unsigned char ) hna_node->netmask;
660
list_for_each( if_pos, &if_list ) {
662
batman_if = list_entry( if_pos, struct batman_if, list );
664
batman_if->out.orig = batman_if->addr.sin_addr.s_addr;
665
batman_if->out.flags = 0x00;
666
batman_if->out.ttl = TTL;
667
batman_if->out.seqno = 1;
668
batman_if->out.gwflags = gateway_class;
669
batman_if->out.version = COMPAT_VERSION;
671
batman_if->if_rp_filter_old = get_rp_filter( batman_if->dev );
672
set_rp_filter( 0 , batman_if->dev );
674
batman_if->if_send_redirects_old = get_send_redirects( batman_if->dev );
675
set_send_redirects( 0 , batman_if->dev );
677
schedule_own_packet( batman_if );
681
if_rp_filter_all_old = get_rp_filter( "all" );
682
if_rp_filter_default_old = get_rp_filter( "default" );
684
if_send_redirects_all_old = get_send_redirects( "all" );
685
if_send_redirects_default_old = get_send_redirects( "default" );
687
set_rp_filter( 0, "all" );
688
set_rp_filter( 0, "default" );
690
set_send_redirects( 0, "all" );
691
set_send_redirects( 0, "default" );
693
forward_old = get_forwarding();
696
while ( !is_aborted() ) {
698
debug_output( 4, " \n \n" );
700
/* harden select_timeout against sudden time change (e.g. ntpdate) */
701
curr_time = get_time();
702
select_timeout = ( curr_time < ((struct forw_node *)forw_list.next)->send_time ? ((struct forw_node *)forw_list.next)->send_time - curr_time : 10 );
704
res = receive_packet( ( unsigned char *)&in, sizeof(in), &hna_buff_len, &neigh, select_timeout, &if_incoming );
706
rcvd_time = get_time();
714
is_my_addr = is_my_orig = is_broadcast = is_duplicate = is_bidirectional = is_bntog = forward_duplicate_packet = 0;
716
has_unidirectional_flag = ((struct packet *)&in)->flags & UNIDIRECTIONAL ? 1 : 0;
717
has_directlink_flag = ((struct packet *)&in)->flags & DIRECTLINK ? 1 : 0;
718
has_version = ((struct packet *)&in)->version;
720
addr_to_string( ((struct packet *)&in)->orig, orig_str, sizeof(orig_str) );
721
addr_to_string( neigh, neigh_str, sizeof(neigh_str) );
722
addr_to_string( if_incoming->addr.sin_addr.s_addr, ifaddr_str, sizeof(ifaddr_str) );
724
debug_output( 4, "Received BATMAN packet via NB: %s, IF: %s %s (from OG: %s, seqno %d, TTL %d, V %d, UDF %d, IDF %d) \n",
725
neigh_str, if_incoming->dev, ifaddr_str, orig_str, ((struct packet *)&in)->seqno, ((struct packet *)&in)->ttl,
726
has_version, has_unidirectional_flag, has_directlink_flag );
728
hna_buff_len -= sizeof(struct packet);
729
hna_recv_buff = ( hna_buff_len > 4 ? in + sizeof(struct packet) : NULL );
731
list_for_each( if_pos, &if_list ) {
733
batman_if = list_entry(if_pos, struct batman_if, list);
735
if ( neigh == batman_if->addr.sin_addr.s_addr )
738
if ( ((struct packet *)&in)->orig == batman_if->addr.sin_addr.s_addr )
741
if ( neigh == batman_if->broad.sin_addr.s_addr )
747
if ( ((struct packet *)&in)->gwflags != 0 )
748
debug_output( 4, "Is an internet gateway (class %i) \n", ((struct packet *)&in)->gwflags );
750
if ( hna_buff_len > 4 ) {
752
debug_output( 4, "HNA information received (%i HNA network%s): \n", hna_buff_len / 5, ( hna_buff_len / 5 > 1 ? "s": "" ) );
755
while ( ( hna_buff_count + 1 ) * 5 <= hna_buff_len ) {
757
memmove( &hna, ( uint32_t *)&hna_recv_buff[ hna_buff_count * 5 ], 4 );
758
netmask = ( uint32_t )hna_recv_buff[ ( hna_buff_count * 5 ) + 4 ];
760
addr_to_string( hna, orig_str, sizeof (orig_str) );
762
if ( ( netmask > 0 ) && ( netmask < 33 ) )
763
debug_output( 4, "hna: %s/%i \n", orig_str, netmask );
765
debug_output( 4, "hna: %s/%i -> ignoring (invalid netmask) \n", orig_str, netmask );
774
if ( ((struct packet *)&in)->version != COMPAT_VERSION ) {
776
debug_output( 4, "Drop packet: incompatible batman version (%i) \n", ((struct packet *)&in)->version );
778
} else if ( is_my_addr ) {
780
debug_output( 4, "Drop packet: received my own broadcast (sender: %s) \n", neigh_str );
782
} else if ( is_broadcast ) {
784
debug_output( 4, "Drop packet: ignoring all packets with broadcast source IP (sender: %s) \n", neigh_str );
786
} else if ( is_my_orig ) {
788
orig_neigh_node = get_orig_node( neigh );
791
debug_output( 4, "received my own OGM via NB lastTxIfSeqno: %d, currRxSeqno: %d, prevRxSeqno: %d, currRxSeqno-prevRxSeqno %d \n",
792
(if_incoming->out.seqno - 2), ((struct packet *)&in)->seqno, orig_neigh_node->bidirect_link[if_incoming->if_num], ((struct packet *)&in)->seqno - orig_neigh_node->bidirect_link[if_incoming->if_num] );
794
/* neighbour has to indicate direct link and it has to come via the corresponding interface */
795
/* if received seqno equals last send seqno save new seqno for bidirectional check */
796
if ( ( has_directlink_flag ) && ( if_incoming->addr.sin_addr.s_addr == ((struct packet *)&in)->orig ) &&
797
( ( ((struct packet *)&in)->seqno + 2) == if_incoming->out.seqno ) ) {
798
debug_output( 4, "indicating bidirectional link - updating bidirect_link seqno \n");
800
orig_neigh_node->bidirect_link[if_incoming->if_num] = ((struct packet *)&in)->seqno;
804
debug_output( 4, "NOT indicating bidirectional link - NOT updating bidirect_link seqno \n");
808
debug_output( 4, "Drop packet: originator packet from myself (via neighbour) \n" );
810
} else if ( ((struct packet *)&in)->flags & UNIDIRECTIONAL ) {
812
debug_output( 4, "Drop packet: originator packet with unidirectional flag \n" );
816
is_directNeigh = ( ((struct packet *)&in)->orig == neigh ) ? 1 : 0 ;
818
orig_node = get_orig_node( ((struct packet *)&in)->orig );
820
if( is_directNeigh ) {
822
orig_neigh_node = orig_node;
826
orig_neigh_node = get_orig_node( neigh );
830
if ( is_directNeigh == 0 && orig_neigh_node->router == NULL ) {
832
debug_output( 4, "Drop packet: OGM via unkown neighbor! \n" );
836
is_duplicate = isDuplicate( orig_node, ((struct packet *)&in)->seqno );
838
is_bidirectional = isBidirectionalNeigh( orig_neigh_node, if_incoming );
841
if ( ( is_bidirectional ) && ( !is_duplicate ) )
842
update_orig( orig_node, (struct packet *)&in, neigh, if_incoming, hna_recv_buff, hna_buff_len, rcvd_time );
844
is_bntog = isBntog(neigh, orig_node );
846
/* is single hop (direct) neighbour */
847
if ( is_directNeigh ) {
849
/* it is our best route towards him */
850
if ( is_bidirectional && is_bntog ) {
852
/* mark direct link on incoming interface */
853
schedule_forward_packet( (struct packet *)&in, 0, 1, hna_recv_buff, hna_buff_len, if_incoming );
855
debug_output( 4, "Forward packet: rebroadcast neighbour packet with direct link flag \n" );
857
/* if an unidirectional neighbour sends us a packet - retransmit it with unidirectional flag to tell him that we get its packets */
858
/* if a bidirectional neighbour sends us a packet - retransmit it with unidirectional flag if it is not our best link to it in order to prevent routing problems */
859
} else if ( ( is_bidirectional && !is_bntog ) || ( !is_bidirectional ) ) {
861
schedule_forward_packet( (struct packet *)&in, 1, 1, hna_recv_buff, hna_buff_len, if_incoming );
863
debug_output( 4, "Forward packet: rebroadcast neighbour packet with direct link and unidirectional flag \n" );
867
/* multihop orginator */
870
if ( is_bidirectional && is_bntog ) {
872
if ( !is_duplicate ) {
874
schedule_forward_packet( (struct packet *)&in, 0, 0, hna_recv_buff, hna_buff_len, if_incoming );
876
debug_output( 4, "Forward packet: rebroadcast orginator packet \n" );
878
} else { /* is_bntog anyway */
880
list_for_each( neigh_pos, &orig_node->neigh_list ) {
882
neigh_node = list_entry(neigh_pos, struct neigh_node, list);
884
if ( ( neigh_node->addr == neigh ) && ( neigh_node->if_incoming == if_incoming ) ) {
886
if ( neigh_node->last_ttl == ((struct packet *)&in)->ttl ) {
888
forward_duplicate_packet = 1;
890
/* also update only last_valid time if arrived (and rebroadcasted because best neighbor) */
891
orig_node->last_valid = rcvd_time;
892
neigh_node->last_valid = rcvd_time;
902
/* we are forwarding duplicate o-packets if they come via our best neighbour and ttl is valid */
903
if ( forward_duplicate_packet ) {
905
schedule_forward_packet( (struct packet *)&in, 0, 0, hna_recv_buff, hna_buff_len, if_incoming );
907
debug_output( 4, "Forward packet: duplicate packet received via best neighbour with best ttl \n" );
911
debug_output( 4, "Drop packet: duplicate packet received via best neighbour but not best ttl \n" );
919
debug_output( 4, "Drop packet: received via bidirectional link: %s, BNTOG: %s ! \n",
920
is_bidirectional?"YES":" NO", is_bntog?"YES":" NO" );
933
send_outstanding_packets();
939
if ( debug_timeout + 1000 < rcvd_time ) {
941
debug_timeout = rcvd_time;
943
purge_orig( rcvd_time );
949
if ( debug_clients.clients_num[2] > 0 )
952
if ( ( routing_class != 0 ) && ( curr_gateway == NULL ) )
955
if ( ( vis_if.sock ) && ( vis_timeout + 10000 < rcvd_time ) ){
957
vis_timeout = rcvd_time;
967
if ( debug_level > 0 )
968
printf( "Deleting all BATMAN routes\n" );
970
purge_orig( get_time() + ( 5 * PURGE_TIMEOUT ) + orginator_interval );
972
hash_destroy( orig_hash );
975
list_for_each_safe( hna_pos, hna_pos_tmp, &hna_list ) {
977
hna_node = list_entry(hna_pos, struct hna_node, list);
979
debugFree( hna_node, 1103 );
983
if ( hna_buff != NULL )
984
debugFree( hna_buff, 1104 );
987
list_for_each_safe( forw_pos, forw_pos_tmp, &forw_list ) {
988
forw_node = list_entry( forw_pos, struct forw_node, list );
990
list_del( forw_pos );
992
debugFree( forw_node->pack_buff, 1105 );
993
debugFree( forw_node, 1106 );
997
if ( vis_packet != NULL )
998
debugFree( vis_packet, 1108 );
1000
set_forwarding( forward_old );
1002
list_for_each( if_pos, &if_list ) {
1004
batman_if = list_entry(if_pos, struct batman_if, list);
1006
set_rp_filter( batman_if->if_rp_filter_old , batman_if->dev );
1007
set_send_redirects( batman_if->if_send_redirects_old , batman_if->dev );
1011
set_rp_filter( if_rp_filter_all_old, "all" );
1012
set_rp_filter( if_rp_filter_default_old, "default" );
1014
set_send_redirects( if_send_redirects_all_old, "all" );
1015
set_send_redirects( if_send_redirects_default_old, "default" );