-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathbmx.h
1217 lines (813 loc) · 29.9 KB
/
bmx.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (c) 2010 BMX protocol contributor(s):
* Axel Neumann <neumann at cgws dot de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
*/
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/rtnetlink.h>
#include "cyassl/sha.h"
#include "cyassl/random.h"
/*
* from other headers:
* TODO: partly move this to system.h
* dont touch this for compatibility reasons:
*/
/* Android has these under a different name since the NDK target android-8:
*
* glibc defines dprintf(int, const char*, ...), which is poorly named
* and likely to conflict with locally defined debugging printfs
* fdprintf is a better name, and some programs that use fdprintf use a
* #define fdprintf dprintf for compatibility
*/
#ifdef __ANDROID__
#define dprintf fdprintf
#define vdprintf vfdprintf
#endif
#define BMX_BRANCH "BMX6"
#define BRANCH_VERSION "0.1-alpha" //put exactly one distinct word inside the string like "0.3-pre-alpha" or "0.3-rc1" or "0.3"
#define COMPATIBILITY_VERSION 16
#ifndef GIT_REV
#define GIT_REV "0" // to be incremented after each critical code change
#endif
extern uint32_t rev_u32;
/*
* from iid.h:
*/
typedef uint16_t IID_T;
typedef struct neigh_node IID_NEIGH_T;
typedef struct dhash_node IID_NODE_T;
/*
* from ip.h:
*/
#define GEN_ADDR_LEN 20
#define IP6_ADDR_LEN 16
#define IP4_ADDR_LEN 4
#define MAC_ADDR_LEN 6
//#define INET_ADDRSTRLEN INET_ADDRSTRLEN // from in.h
//#define INET6_ADDRSTRLEN INET6_ADDRSTRLEN // from in.h
#define IPX_STR_LEN INET6_ADDRSTRLEN
#define IPX_PREFIX_STR_LEN (INET6_ADDRSTRLEN + 4)
typedef uint16_t DEVADV_SQN_T;
#define DEVADV_SQN_DISABLED 0 // dev-adv are not provided by this node!
#define DEVADV_SQN_DAD_RANGE 256
#define DEVADV_SQN_MAX ((DEVADV_SQN_T)-1)
typedef uint8_t DEVADV_IDX_T;
//#define DEVADV_IDX_BIT_SIZE (8*sizeof(DEVADV_IDX_T))
#define DEVADV_IDX_INVALID 0
#define DEVADV_IDX_ALL 0
#define DEVADV_IDX_MIN 1
#define DEVADV_IDX_MAX ((DEVADV_IDX_T)-1)
typedef uint32_t IP4_T;
typedef struct in6_addr IP6_T;
typedef IP6_T IPX_T;
struct net_key {
uint8_t af; //family
uint8_t mask; //prefixlen
IPX_T ip; //address
} __attribute__((packed));
struct dev_ip_key {
IPX_T ip; // copy of dev->if_llocal_addr->ip_addr
DEVADV_IDX_T idx;
} __attribute__((packed));
typedef union {
uint8_t u8[GEN_ADDR_LEN];
uint16_t u16[GEN_ADDR_LEN / sizeof(uint16_t)];
uint32_t u32[GEN_ADDR_LEN / sizeof(uint32_t)];
uint64_t u64[GEN_ADDR_LEN / sizeof(uint64_t)];
} ADDR_T;
typedef union {
uint8_t u8[MAC_ADDR_LEN];
uint16_t u16[MAC_ADDR_LEN / sizeof(uint16_t)];
} MAC_T;
/*
* from hna.h:
*/
/*
* from bmx.h:
*/
typedef uint32_t TIME_T;
#define TIME_MAX ((TIME_T)-1)
typedef uint32_t TIME_SEC_T;
typedef int8_t IDM_T; // smallest int which size does NOT matter
// to be used:
typedef uint64_t UMETRIC_T;
#define OGM_MANTISSA_BIT_SIZE 5
#define OGM_EXPONENT_BIT_SIZE 5
#define OGM_EXPONENT_OFFSET OGM_MANTISSA_BIT_SIZE
#define OGM_EXPONENT_MAX ((1<<OGM_EXPONENT_BIT_SIZE)-1)
#define OGM_MANTISSA_MASK ((1<<OGM_MANTISSA_BIT_SIZE)-1)
#define OGM_EXPONENT_MASK ((1<<OGM_EXPONENT_BIT_SIZE)-1)
#define OGM_MANTISSA_INVALID 0
#define OGM_MANTISSA_MIN__NOT_ROUTABLE 1
#define OGM_MANTISSA_ROUTABLE 2
#define FM8_EXPONENT_BIT_SIZE OGM_EXPONENT_BIT_SIZE
#define FM8_MANTISSA_BIT_SIZE (8-FM8_EXPONENT_BIT_SIZE)
#define FM8_MANTISSA_MASK ((1<<FM8_MANTISSA_BIT_SIZE)-1)
#define FM8_MANTISSA_MIN (1)
#define OGM_MANTISSA_MAX (FM8_MANTISSA_MASK << (OGM_MANTISSA_BIT_SIZE - FM8_MANTISSA_BIT_SIZE))
#define UMETRIC_SHIFT_MAX ((sizeof(UMETRIC_T)*8) - (OGM_EXPONENT_OFFSET+OGM_EXPONENT_MAX+1))
#define UMETRIC_MULTIPLY_MAX (((UMETRIC_T)-1)>>(OGM_EXPONENT_OFFSET+OGM_EXPONENT_MAX+1))
#define UMETRIC_MASK ((((UMETRIC_T) 1) << (OGM_EXPONENT_OFFSET+OGM_EXPONENT_MAX+1)) -1)
#define UMETRIC_INVALID ((((UMETRIC_T) 1) << OGM_EXPONENT_OFFSET) + OGM_MANTISSA_INVALID)
#define UMETRIC_MIN__NOT_ROUTABLE ((((UMETRIC_T) 1) << OGM_EXPONENT_OFFSET) + OGM_MANTISSA_MIN__NOT_ROUTABLE)
#define UMETRIC_ROUTABLE ((((UMETRIC_T) 1) << OGM_EXPONENT_OFFSET) + OGM_MANTISSA_ROUTABLE)
#define UMETRIC_FM8_MAX ((((UMETRIC_T) 1) << (OGM_EXPONENT_OFFSET+OGM_EXPONENT_MAX)) + (((UMETRIC_T) FM8_MANTISSA_MASK) << ((OGM_EXPONENT_OFFSET+OGM_EXPONENT_MAX)-FM8_MANTISSA_BIT_SIZE)))
#define UMETRIC_FM8_MIN ((((UMETRIC_T) 1) << OGM_EXPONENT_OFFSET) + (((UMETRIC_T) FM8_MANTISSA_MIN) << (OGM_EXPONENT_OFFSET-FM8_MANTISSA_BIT_SIZE)))
#define UMETRIC_MAX UMETRIC_FM8_MAX
#define UMETRIC_MAXX ((uint64_t)-1)
//#define UMETRIC_MAX ((((UMETRIC_T) 1) << (OGM_EXPONENT_OFFSET+OGM_EXPONENT_MAX)) + (((UMETRIC_T) OGM_MANTISSA_MAX) << ((OGM_EXPONENT_OFFSET+OGM_EXPONENT_MAX)-OGM_MANTISSA_BIT_SIZE)))
// these fixes are used to improove (average) rounding errors in umetric_to_fmetric()
#define UMETRIC_TO_FMETRIC_INPUT_FIX (79)
//#define UMETRIC_MAX_SQRT ((UMETRIC_T)358956) // sqrt(UMETRIC_MAX)
//#define UMETRIC_MAX_HALF_SQRT ((UMETRIC_T)253821) // sqrt(UMETRIC_MAX/2)
//#define U64_MAX_QUARTER_SQRT ((UMETRIC_T)2147493120) // sqrt(U64_MAX/4)
struct float_u16 {
union {
struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t mantissa_fm16;
uint8_t exp_fm16;
#elif __BYTE_ORDER == __BIG_ENDIAN
uint8_t exp_fm16;
uint8_t mantissa_fm16;
#else
#error "Please fix <bits/endian.h>"
#endif
} __attribute__((packed)) f;
uint8_t u8[2];
uint16_t u16;
}val;
};
typedef struct float_u16 FMETRIC_U16_T;
struct float_u8 {
union {
struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int mantissa_fmu8 : FM8_MANTISSA_BIT_SIZE;
unsigned int exp_fmu8 : FM8_EXPONENT_BIT_SIZE;
#elif __BYTE_ORDER == __BIG_ENDIAN
unsigned int exp_fmu8 : FM8_EXPONENT_BIT_SIZE;
unsigned int mantissa_fmu8 : FM8_MANTISSA_BIT_SIZE;
#else
#error "Please fix <bits/endian.h>"
#endif
} __attribute__((packed)) f;
uint8_t u8;
} val;
};
typedef struct float_u8 FMETRIC_U8_T;
#define MIN_TX_INTERVAL 35
#define MAX_TX_INTERVAL 10000 // < U16_MAX due to metricalgo->ogm_interval field
#define DEF_TX_INTERVAL 500
#define ARG_TX_INTERVAL "txInterval"
extern int32_t my_tx_interval;
#define DEF_TX_DELAY ((2*my_tx_interval) + rand_num(my_tx_interval))
#define ARG_OGM_INTERVAL "ogmInterval"
#define DEF_OGM_INTERVAL 5000
#define MIN_OGM_INTERVAL 200
#define MAX_OGM_INTERVAL 60000 // 60000 = 1 minutes
extern int32_t my_ogm_interval;
#define MIN_OGM_PURGE_TO (MAX_OGM_INTERVAL + MAX_TX_INTERVAL)
#define MAX_OGM_PURGE_TO 864000000 /*10 days*/
#define DEF_OGM_PURGE_TO 100000
#define ARG_OGM_PURGE_TO "purgeTimeout"
// extern int32_t purge_to;
#define DEF_DAD_TO 20000//(MAX_OGM_INTERVAL + MAX_TX_INTERVAL)
#define MIN_DAD_TO 100
#define MAX_DAD_TO 360000000
#define ARG_DAD_TO "dadTimeout"
extern int32_t dad_to;
#define DEF_DROP_ALL_FRAMES 0
#define MIN_DROP_ALL_FRAMES 0
#define MAX_DROP_ALL_FRAMES 1
#define ARG_DROP_ALL_FRAMES "dropAllFrames"
#define DEF_DROP_ALL_PACKETS 0
#define MIN_DROP_ALL_PACKETS 0
#define MAX_DROP_ALL_PACKETS 1
#define ARG_DROP_ALL_PACKETS "dropAllPackets"
#define MIN_DHASH_TO 300000
#define DHASH_TO_TOLERANCE_FK 10
/*
* from msg.h:
*/
// deprecated:
typedef uint16_t SQN_T;
#define SQN_MAX ((SQN_T)-1)
#define MAX_SQN_RANGE 8192 // the maxumim of all .._SQN_RANGE ranges, should never be more than SQN_MAX/4
// OGMs:
typedef uint16_t OGM_SQN_T;
#define OGM_SQN_BIT_SIZE (16)
#define OGM_SQN_MASK ((1<<OGM_SQN_BIT_SIZE)-1)
#define OGM_SQN_MAX OGM_SQN_MASK
#define OGM_SQN_STEP 1
typedef uint16_t OGM_MIX_T;
#define OGM_MIX_BIT_SIZE (sizeof (OGM_MIX_T) * 8)
#define OGM_IIDOFFST_BIT_SIZE (OGM_MIX_BIT_SIZE-(OGM_MANTISSA_BIT_SIZE+OGM_EXPONENT_BIT_SIZE))
#define OGM_IIDOFFST_MASK ((1<<OGM_IIDOFFST_BIT_SIZE)-1)
#define OGM_EXPONENT_BIT_POS (0)
#define OGM_MANTISSA_BIT_POS (0 + OGM_EXPONENT_BIT_SIZE)
#define OGM_IIDOFFST_BIT_POS (0 + OGM_MANTISSA_BIT_SIZE + OGM_EXPONENT_BIT_SIZE)
// aggregations of OGMs:
typedef uint8_t AGGREG_SQN_T;
#define AGGREG_SQN_BIT_SIZE (8)
#define AGGREG_SQN_MASK ((1<<AGGREG_SQN_BIT_SIZE)-1)
#define AGGREG_SQN_MAX AGGREG_SQN_MASK
#define AGGREG_SQN_CACHE_RANGE 64
#define AGGREG_SQN_CACHE_WARN (AGGREG_SQN_CACHE_RANGE/2)
#define AGGREG_ARRAY_BYTE_SIZE (AGGREG_SQN_CACHE_RANGE/8)
typedef uint8_t OGM_DEST_T;
#define OGM_DEST_BIT_SIZE (8)
#define OGM_DEST_MASK ((1<<OGM_DEST_BIT_SIZE)-1)
#define OGM_DEST_MAX OGM_DEST_MASK
#define OGM_DEST_ARRAY_BIT_SIZE (1<<OGM_DEST_BIT_SIZE)
#define LOCALS_MAX (1<<OGM_DEST_BIT_SIZE) // because each local needs a bit to be indicated in the ogm.dest_field
typedef uint32_t PKT_SQN_T;
#define PKT_SQN_DAD_RANGE 1000
#define PKT_SQN_DAD_TOLERANCE 100
#define PKT_SQN_MAX ((PKT_SQN_T)-1)
typedef uint16_t LINKADV_SQN_T;
#define LINKADV_SQN_DAD_RANGE 256
#define LINKADV_SQN_MAX ((LINKADV_SQN_T)-1)
typedef uint32_t LOCAL_ID_T;
#define LOCAL_ID_BIT_SIZE (8*sizeof(LOCAL_ID_T))
#define LOCAL_ID_INVALID 0
#define LOCAL_ID_MIN 1
#define LOCAL_ID_MAX ((LOCAL_ID_T)-1)
#define LOCAL_ID_ITERATIONS_MAX 256
#define LOCAL_ID_ITERATIONS_WARN (LOCAL_ID_ITERATIONS_MAX>>3)
extern LOCAL_ID_T my_local_id;
// hello and hello reply messages:
typedef uint16_t HELLO_SQN_T;
#define HELLO_SQN_BIT_SIZE (sizeof(HELLO_SQN_T)*8)
#define HELLO_SQN_MASK ((HELLO_SQN_T)-1)
#define HELLO_SQN_MAX HELLO_SQN_MASK
#define HELLO_SQN_TOLERANCE 4
#define MAX_HELLO_SQN_WINDOW 128
#define MIN_HELLO_SQN_WINDOW 1
#define DEF_HELLO_SQN_WINDOW 48
#define ARG_HELLO_SQN_WINDOW "linkWindow"
//extern int32_t my_link_window; // my link window size used to quantify the link qualities to direct neighbors
//#define RP_PURGE_ITERATIONS MAX_LINK_WINDOW
#define DEF_LINK_PURGE_TO 100000
#define MIN_LINK_PURGE_TO (MAX_TX_INTERVAL*2)
#define MAX_LINK_PURGE_TO 864000000 /*10 days*/
#define ARG_LINK_PURGE_TO "linkPurgeTimeout"
// descriptions
typedef uint16_t DESC_SQN_T;
#define DESC_SQN_BIT_SIZE (16)
#define DESC_SQN_MASK ((1<<DESC_SQN_BIT_SIZE)-1)
#define DESC_SQN_MAX DESC_SQN_MASK
#define DEF_DESCRIPTION_DAD_RANGE 8192
typedef uint8_t FRAME_TYPE_T;
#define FRAME_ISSHORT_BIT_SIZE (1)
#define FRAME_RELEVANCE_BIT_SIZE (1)
#define FRAME_TYPE_BIT_SIZE ((8*sizeof(FRAME_TYPE_T)) - FRAME_ISSHORT_BIT_SIZE - FRAME_RELEVANCE_BIT_SIZE)
#define FRAME_TYPE_MASK XMIN( (0x1F) /*some bits reserved*/, ((1<<FRAME_TYPE_BIT_SIZE)-1))
#define FRAME_TYPE_ARRSZ (FRAME_TYPE_MASK+1)
#define HASH_SHA1_LEN SHA_DIGEST_SIZE // sha.h: 20 bytes
#define MAX_PACKET_SIZE 1500
struct packet_header // 17 bytes
{
uint8_t bmx_version; // 8
uint8_t reserved; // 8 reserved
uint16_t pkt_length; // 16 the relevant data size in bytes (including the bmx_header)
IID_T transmitterIID; // 16 IID of transmitter node
LINKADV_SQN_T link_adv_sqn; // 16 used for processing: link_adv, lq_adv, rp_adv, ogm_adv, ogm_ack
PKT_SQN_T pkt_sqn; // 32
LOCAL_ID_T local_id; // 32
DEVADV_IDX_T dev_idx; // 8
// uint8_t reserved_for_2byte_alignement; // 8
} __attribute__((packed));
/*
* from metrics.h
*/
typedef uint16_t ALGO_T;
struct host_metricalgo {
FMETRIC_U16_T fmetric_u16_min;
UMETRIC_T umetric_min;
ALGO_T algo_type;
uint16_t flags;
uint8_t algo_rp_exp_numerator;
uint8_t algo_rp_exp_divisor;
uint8_t algo_tp_exp_numerator;
uint8_t algo_tp_exp_divisor;
uint8_t window_size; // MUST be given as multiple of sqn_steps
uint8_t lounge_size; // MUST be given as multiple of sqn_steps e.g. 6
uint8_t regression; // e.g. 16
// uint8_t fast_regression; // e.g. 2
// uint8_t fast_regression_impact; // e.g. 8
uint8_t hystere;
uint8_t hop_penalty;
uint8_t late_penalty;
};
struct lndev_probe_record {
HELLO_SQN_T hello_sqn_max; // SQN which has been applied (if equals wa_pos) then wa_unscaled MUST NOT be set again!
uint8_t hello_array[MAX_HELLO_SQN_WINDOW/8];
uint32_t hello_sum;
UMETRIC_T hello_umetric;
TIME_T hello_time_max;
};
struct metric_record {
SQN_T sqn_bit_mask;
SQN_T clr; // SQN upto which waightedAverageVal has been purged
SQN_T set; // SQN which has been applied (if equals wa_pos) then wa_unscaled MUST NOT be set again!
// UMETRIC_T umetric;
// UMETRIC_T umetric_fast;
UMETRIC_T umetric;
// UMETRIC_T umetric_prev;
};
#define ZERO_METRIC_RECORD {0, 0, 0, 0,0,0}
#include "avl.h"
#include "list.h"
#include "iid.h"
#include "control.h"
#include "allocate.h"
#define GLOBAL_ID_NAME_LEN 32
#define GLOBAL_ID_PKID_LEN HASH_SHA1_LEN
#define GLOBAL_ID_PKID_RAND_POS (GLOBAL_ID_PKID_LEN / 2)
#define GLOBAL_ID_PKID_RAND_LEN (GLOBAL_ID_PKID_LEN / 2)
typedef union {
uint8_t u8[GLOBAL_ID_PKID_LEN];
uint16_t u16[GLOBAL_ID_PKID_LEN / sizeof(uint16_t)];
uint32_t u32[GLOBAL_ID_PKID_LEN / sizeof(uint32_t)];
} PKID_T;
struct GLOBAL_ID {
char name[GLOBAL_ID_NAME_LEN];
PKID_T pkid;
} __attribute__((packed));
typedef struct GLOBAL_ID GLOBAL_ID_T;
struct description_hash {
union {
uint8_t u8[HASH_SHA1_LEN];
uint32_t u32[HASH_SHA1_LEN/sizeof(uint32_t)];
} h;
};
typedef struct description_hash SHA1_T;
#define BMX_ENV_LIB_PATH "BMX6_LIB_PATH"
#define BMX_DEF_LIB_PATH "/usr/lib"
// e.g. sudo BMX_LIB_PATH="$(pwd)/lib" ./bmx6 -d3 eth0:bmx
#define BMX_ENV_DEBUG "BMX6_DEBUG"
#define DEF_TTL 50 /* Time To Live of OGM broadcast messages */
#define MAX_TTL 63
#define MIN_TTL 1
#define ARG_TTL "ttl"
extern int32_t my_ttl;
#define ARG_HELP "help"
#define ARG_VERBOSE_HELP "verboseHelp"
#define ARG_VERSION "version"
#define ARG_TEST "test"
#define ARG_SHOW_PARAMETER "parameters"
#define ARG_SHOW "show"
#define ARG_ORIGINATORS "originators"
#define ARG_STATUS "status"
#define ARG_LINKS "links"
#define ARG_THROW "throw"
#define MAX_DBG_STR_SIZE 1500
#define OUT_SEQNO_OFFSET 1
enum NoYes {
NO,
YES
};
extern const IDM_T CONST_YES;
extern const IDM_T CONST_NO;
enum ADGSN {
ADD,
DEL,
GET,
SET,
NOP
};
#define SUCCESS 0
#define FAILURE -1
#define MAX_SELECT_TIMEOUT_MS 1100 /* MUST be smaller than (1000/2) to fit into max tv_usec */
#define MAX_SELECT_SAFETY_MS 200 /* MUST be smaller than (1000/2) to fit into max tv_usec */
#define CRITICAL_PURGE_TIME_DRIFT 20
#define XMAX( a, b ) ( (a>b) ? (a) : (b) )
#define XMIN( a, b ) ( (a<b) ? (a) : (b) )
#define U64_MAX ((uint64_t)(-1))
#define U32_MAX ((uint32_t)(-1))
#define I32_MAX ((U32_MAX>>1))
#define U16_MAX ((uint16_t)(-1))
#define I16_MAX ((U16_MAX>>1))
#define U8_MAX ((uint8_t)(-1))
#define I8_MAX ((U8_MAX>>1))
#define U32_LT( a, b ) ( ((uint32_t)( (a) - (b) ) ) > I32_MAX )
#define U32_LE( a, b ) ( ((uint32_t)( (b) - (a) ) ) <= I32_MAX )
#define U32_GT( a, b ) ( ((uint32_t)( (b) - (a) ) ) > I32_MAX )
#define U32_GE( a, b ) ( ((uint32_t)( (a) - (b) ) ) <= I32_MAX )
#define UXX_LT( mask, a, b ) ( ((mask)&( (a) - (b) ) ) > (((mask)&U32_MAX)>>1) )
#define UXX_LE( mask, a, b ) ( ((mask)&( (b) - (a) ) ) <= (((mask)&U32_MAX)>>1) )
#define UXX_GT( mask, a, b ) ( ((mask)&( (b) - (a) ) ) > (((mask)&U32_MAX)>>1) )
#define UXX_GE( mask, a, b ) ( ((mask)&( (a) - (b) ) ) <= (((mask)&U32_MAX)>>1) )
#define MAX_UXX( mask, a, b ) ( (UXX_GT(mask,a,b)) ? (a) : (b) )
#define MIN_UXX( mask, a, b ) ( (UXX_LT(mask,a,b)) ? (a) : (b) )
#define UXX_GET_MAX(mask, a, b ) ( (UXX_GT( (mask), (a), (b) )) ? (a) : (b) )
#define WARNING_PERIOD 20000
#define MAX_PATH_SIZE 300
#define MAX_ARG_SIZE 200
extern TIME_T bmx_time;
extern TIME_SEC_T bmx_time_sec;
extern IDM_T initializing;
extern IDM_T terminating;
extern IDM_T cleaning_up;
extern uint32_t s_curr_avg_cpu_load;
extern IDM_T my_description_changed;
extern struct orig_node *self;
/**
* The most important data structures
*/
enum {
FIELD_TYPE_UINT,
FIELD_TYPE_HEX,
FIELD_TYPE_STRING_SIZE,
FIELD_TYPE_STRING_CHAR,
FIELD_TYPE_STRING_BINARY,
FIELD_TYPE_POINTER_CHAR,
FIELD_TYPE_POINTER_GLOBAL_ID,
FIELD_TYPE_GLOBAL_ID,
FIELD_TYPE_UMETRIC,
FIELD_TYPE_POINTER_UMETRIC,
FIELD_TYPE_FMETRIC8,
FIELD_TYPE_IP4,
FIELD_TYPE_IPX,
FIELD_TYPE_IPX4,
FIELD_TYPE_IPX6,
FIELD_TYPE_IPX6P,
FIELD_TYPE_NETP,
FIELD_TYPE_MAC,
FIELD_TYPE_END
};
#define FIELD_STANDARD_SIZES {-1,-1,-1,-8,-8,(8*sizeof(char*)),(8*sizeof(GLOBAL_ID_T*)),(8*sizeof(GLOBAL_ID_T)), \
(8*sizeof(UMETRIC_T)),(8*sizeof(UMETRIC_T*)),(8*sizeof(FMETRIC_U8_T)), \
(8*sizeof(IP4_T)), (8*sizeof(IPX_T)), (8*sizeof(IPX_T)), (8*sizeof(IP6_T)), \
(8*sizeof(IP6_T*)), (8*sizeof(struct net_key*)), (8*sizeof(MAC_T))}
// negative values mean size must be multiple of negativ value, positive values mean absolute bit sizes
#define FIELD_FORMAT_MAX_ITEMS 100
enum {
FIELD_RELEVANCE_LOW,
FIELD_RELEVANCE_MEDI,
FIELD_RELEVANCE_HIGH
};
#define ARG_RELEVANCE "relevance"
#define DEF_RELEVANCE FIELD_RELEVANCE_HIGH
#define MAX_RELEVANCE FIELD_RELEVANCE_HIGH
#define MIN_RELEVANCE FIELD_RELEVANCE_LOW
#define HLP_ARG_RELEVANCE "filter for given minimum relevance"
struct field_format {
uint16_t field_type;
int32_t field_pos; // -1 means relative to previous
uint32_t field_bits;
uint8_t field_host_order;
uint8_t field_relevance;
const char * field_name;
};
#define FIELD_FORMAT_END {FIELD_TYPE_END, 0, 0, 0, FIELD_RELEVANCE_LOW, NULL}
#define FIELD_STR_VALUE(name) #name
#define FIELD_FORMAT_INIT(f_type, f_struct_name, f_struct_field, f_host_order, f_relevance) { \
.field_type = f_type, \
.field_pos = (((unsigned long)&(((struct f_struct_name*) NULL)->f_struct_field))*8), \
.field_bits = (sizeof( (((struct f_struct_name *) NULL)->f_struct_field) ) * 8), \
.field_host_order = f_host_order, \
.field_relevance = f_relevance, \
.field_name = FIELD_STR_VALUE(f_struct_field) \
}
struct field_iterator {
const struct field_format *format;
// char * msg_name;
uint8_t *data;
uint32_t data_size;
uint32_t min_msg_size;
// uint8_t fixed_msg_size;
uint32_t field;
uint32_t field_bits;
uint32_t var_bits;
uint32_t field_bit_pos;
uint32_t msg_bit_pos;
};
struct status_handl {
uint16_t min_msg_size;
IDM_T multiline;
char status_name[16];
uint8_t *data;
int32_t (*frame_creator) (struct status_handl *status_handl, void *data);
const struct field_format *format;
};
extern struct avl_tree status_tree;
int16_t field_format_get_items(const struct field_format *format);
int64_t field_get_value(const struct field_format *format, uint16_t min_msg_size, uint8_t *data, uint32_t pos_bit, uint32_t bits);
char *field_dbg_value(const struct field_format *format, uint16_t min_msg_size, uint8_t *data, uint32_t pos_bit, uint32_t bits);
uint32_t fields_dbg_lines(struct ctrl_node *cn, uint16_t relevance, uint16_t data_size, uint8_t *data,
uint16_t min_msg_size, const struct field_format *format);
uint32_t field_iterate(struct field_iterator *it);
void register_status_handl(uint16_t min_msg_size, IDM_T multiline, const struct field_format* format, char *name,
int32_t(*creator) (struct status_handl *status_handl, void *data));
struct task_node {
struct list_node list;
TIME_T expire;
void (* task) (void *fpara); // pointer to the function to be executed
void *data; //NULL or pointer to data to be given to function. Data will be freed after functio is called.
};
struct tx_task_content {
struct dev_node *dev; // the outgoing interface to be used for transmitting
struct link_node *link;
uint32_t u32;
uint16_t u16;
IID_T myIID4x;
IID_T neighIID4x;
uint16_t type;
} __attribute__((packed));
struct tx_task_node {
struct list_node list;
struct tx_task_content task;
uint16_t frame_msgs_length;
int16_t tx_iterations;
TIME_T considered_ts;
TIME_T send_ts;
};
extern struct avl_tree local_tree;
struct local_node {
LOCAL_ID_T local_id;
struct avl_tree link_tree;
struct link_dev_node *best_rp_lndev;
struct link_dev_node *best_tp_lndev;
struct link_dev_node *best_lndev;
struct neigh_node *neigh; // to be set when confirmed, use carefully
PKT_SQN_T packet_sqn;
TIME_T packet_time;
LINKADV_SQN_T packet_link_sqn_ref; //indicating the maximum existing link_adv_sqn
// the latest received link_adv:
LINKADV_SQN_T link_adv_sqn;
TIME_T link_adv_time;
uint16_t link_adv_msgs;
int16_t link_adv_msg_for_me;
int16_t link_adv_msg_for_him;
struct msg_link_adv *link_adv;
DEVADV_SQN_T link_adv_dev_sqn_ref;
// the latest received dev_adv:
DEVADV_SQN_T dev_adv_sqn;
uint16_t dev_adv_msgs;
struct msg_dev_adv *dev_adv;
// the latest received rp_adv:
TIME_T rp_adv_time;
IDM_T rp_ogm_request_rcvd;
int32_t orig_routes;
} __attribute__((packed));
extern struct avl_tree link_tree;
struct link_node_key {
DEVADV_IDX_T dev_idx;
LOCAL_ID_T local_id;
} __attribute__((packed));
struct link_node {
struct link_node_key key;
IPX_T link_ip;
TIME_T pkt_time_max;
TIME_T hello_time_max;
HELLO_SQN_T hello_sqn_max;
struct local_node *local; // set immediately
struct list_head lndev_list; // list with one link_node_dev element per link
};
struct link_dev_key {
struct link_node *link;
struct dev_node *dev;
} __attribute__((packed));
struct router_node {
// struct link_dev_key key_2BRemoved;
struct local_node *local_key;
struct metric_record mr;
OGM_SQN_T ogm_sqn_last;
UMETRIC_T ogm_umetric_last;
UMETRIC_T path_metric_best; //TODO removed
struct link_dev_node *path_lndev_best;
};
extern struct avl_tree link_dev_tree;
struct link_dev_node {
struct list_node list;
struct link_dev_key key;
UMETRIC_T tx_probe_umetric;
UMETRIC_T timeaware_tx_probe;
struct lndev_probe_record rx_probe_record;
UMETRIC_T timeaware_rx_probe;
struct list_head tx_task_lists[FRAME_TYPE_ARRSZ]; // scheduled frames and messages
int16_t link_adv_msg;
TIME_T pkt_time_max;
};
extern struct avl_tree neigh_tree;
struct neigh_node {
struct neigh_node *nnkey;
struct dhash_node *dhn; // confirmed dhash
struct local_node *local; // to be set when confirmed, use carefully
// filled in by ???:
IID_T neighIID4me;
struct iid_repos neighIID4x_repos;
// AGGREG_SQN_T ogm_aggregation_rcvd_set;
TIME_T ogm_new_aggregation_rcvd;
AGGREG_SQN_T ogm_aggregation_cleard_max;
uint8_t ogm_aggregations_not_acked[AGGREG_ARRAY_BYTE_SIZE];
uint8_t ogm_aggregations_rcvd[AGGREG_ARRAY_BYTE_SIZE];
};
extern struct avl_tree orig_tree;
//extern struct avl_tree blocked_tree;
struct desc_tlv_hash_node {
SHA1_T prev_hash;
SHA1_T curr_hash;
SHA1_T test_hash;
uint8_t tlv_type;
uint8_t test_changed;
uint8_t prev_changed;
};
struct orig_node {
// filled in by validate_new_link_desc0():
GLOBAL_ID_T global_id;
struct dhash_node *dhn;
struct description *desc;
struct avl_tree desc_tlv_hash_tree;
TIME_T updated_timestamp; // last time this on's desc was succesfully updated
DESC_SQN_T descSqn;
OGM_SQN_T ogmSqn_rangeMin;
OGM_SQN_T ogmSqn_rangeSize;
// filled in by process_desc0_tlvs()->
IPX_T primary_ip;
char primary_ip_str[IPX_STR_LEN];
uint8_t blocked; // blocked description
uint8_t added; // added description
struct host_metricalgo *path_metricalgo;
// calculated by update_path_metric()
OGM_SQN_T ogmSqn_maxRcvd;
OGM_SQN_T ogmSqn_next;
UMETRIC_T ogmMetric_next;
OGM_SQN_T ogmSqn_send;
// UMETRIC_T ogmMetric_send;
UMETRIC_T *metricSqnMaxArr; // TODO: remove
struct avl_tree rt_tree;
struct router_node * best_rt_local; // TODO: remove
struct router_node *curr_rt_local; // the currently used local neighbor for routing
struct link_dev_node *curr_rt_lndev; // the configured route in the kernel!
//size of plugin data is defined during intialization and depends on registered PLUGIN_DATA_ORIG hooks
void *plugin_data[];
};
extern struct avl_tree dhash_tree;
extern struct avl_tree dhash_invalid_tree;
struct dhash_node {
struct description_hash dhash;
TIME_T referred_by_me_timestamp; // last time this dhn was referred
struct neigh_node *neigh;
IID_T myIID4orig;
struct orig_node *on;