PUD: add getOlsrSockAddrAndPort helper function
[olsrd.git] / lib / pud / src / configuration.c
1 #include "configuration.h"
2
3 /* Plugin includes */
4 #include "pud.h"
5 #include "netTools.h"
6 #include "networkInterfaces.h"
7
8 /* OLSR includes */
9 #include "olsr_types.h"
10 #include "olsr_cfg.h"
11
12 /* System includes */
13 #include <assert.h>
14 #include <errno.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <net/if.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <sys/socket.h>
21 #include <unistd.h>
22 #include <nmea/util.h>
23
24 /*
25  * Utility functions
26  */
27
28 /**
29  Determine the address of the port in an OLSR socket address
30
31  @param ipVersion
32  The IP version (AF_INET or AF_INET6)
33  @param addr
34  A pointer to OLSR socket address
35  @return
36  A pointer to the port
37  */
38 static in_port_t * getOlsrSockaddrPort(int ipVersion, union olsr_sockaddr * addr) {
39         if (ipVersion == AF_INET) {
40                 return &addr->in4.sin_port;
41         } else {
42                 return &addr->in6.sin6_port;
43         }
44 }
45
46 /**
47  Get pointer to the IP address and port in an OLSR socket address
48  @param ipVersion
49  The IP version (AF_INET or AF_INET6)
50  @param addr
51  A pointer to OLSR socket address
52  @param ipAddress
53  A pointer to the location where the pointer to the IP address will be stored
54  @param port
55  A pointer to the location where the pointer to the port will be stored
56  */
57 static void getOlsrSockAddrAndPort(int ipVersion, union olsr_sockaddr * addr,
58                 void ** ipAddress, in_port_t ** port) {
59         if (ipVersion == AF_INET) {
60                 *ipAddress = (void *) &addr->in4.sin_addr;
61                 *port = (void *) &addr->in4.sin_port;
62         } else {
63                 *ipAddress = (void *) &addr->in6.sin6_addr;
64                 *port = (void *) &addr->in6.sin6_port;
65         }
66 }
67
68 /**
69  Read an unsigned long long number from a value string
70
71  @param valueName
72  the name of the value
73  @param value
74  the string to convert to a number
75  @param valueNumber
76  a pointer to the location where to store the number upon successful conversion
77
78  @return
79  - true on success
80  - false otherwise
81  */
82 static bool readULL(const char * valueName, const char * value,
83                 unsigned long long * valueNumber) {
84         char * endPtr = NULL;
85         unsigned long long valueNew;
86
87         errno = 0;
88         valueNew = strtoull(value, &endPtr, 10);
89
90         if (!((endPtr != value) && (*value != '\0') && (*endPtr == '\0'))) {
91                 /* invalid conversion */
92                 pudError(true, "Configured %s (%s) could not be converted to a number",
93                                 valueName, value);
94                 return false;
95         }
96
97         *valueNumber = valueNew;
98
99         return true;
100 }
101
102 /**
103  Read a double number from a value string
104
105  @param valueName
106  the name of the value
107  @param value
108  the string to convert to a number
109  @param valueNumber
110  a pointer to the location where to store the number upon successful conversion
111
112  @return
113  - true on success
114  - false otherwise
115  */
116 static bool readDouble(const char * valueName, const char * value,
117                 double * valueNumber) {
118         char * endPtr = NULL;
119         double valueNew;
120
121         errno = 0;
122         valueNew = strtod(value, &endPtr);
123
124         if (!((endPtr != value) && (*value != '\0') && (*endPtr == '\0'))) {
125                 /* invalid conversion */
126                 pudError(true, "Configured %s (%s) could not be converted to a number",
127                                 valueName, value);
128                 return false;
129         }
130
131         *valueNumber = valueNew;
132
133         return true;
134 }
135
136 /*
137  * nodeIdType
138  */
139
140 /** The nodeIdType */
141 static NodeIdType nodeIdType = PUD_NODE_ID_TYPE_DEFAULT;
142
143 /**
144  @return
145  The node ID type
146  */
147 NodeIdType getNodeIdTypeNumber(void) {
148         return nodeIdType;
149 }
150
151 /**
152  Set the node ID type.
153
154  @param value
155  The value of the node ID type to set (a number in string representation)
156  @param data
157  Unused
158  @param addon
159  Unused
160
161  @return
162  - true when an error is detected
163  - false otherwise
164  */
165 int setNodeIdType(const char *value, void *data __attribute__ ((unused)),
166                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
167         static const char * valueName = PUD_NODE_ID_TYPE_NAME;
168         unsigned long long nodeIdTypeNew;
169
170         assert (value != NULL);
171
172         if (!readULL(valueName, value, &nodeIdTypeNew)) {
173                 return true;
174         }
175
176         if (nodeIdTypeNew > PUD_NODE_ID_TYPE_MAX) {
177                 pudError(false, "Configured %s (%llu) is out of range 0-%u", valueName,
178                                 nodeIdTypeNew, PUD_NODE_ID_TYPE_MAX);
179                 return true;
180         }
181
182         switch (nodeIdTypeNew) {
183                 case PUD_NODEIDTYPE_MAC:
184                 case PUD_NODEIDTYPE_MSISDN:
185                 case PUD_NODEIDTYPE_TETRA:
186                 case PUD_NODEIDTYPE_DNS:
187                 case PUD_NODEIDTYPE_IPV4:
188                 case PUD_NODEIDTYPE_IPV6:
189                 case PUD_NODEIDTYPE_192:
190                 case PUD_NODEIDTYPE_193:
191                 case PUD_NODEIDTYPE_194:
192                         break;
193
194                 default:
195                         pudError(false, "Configured %s (%llu) is reserved", valueName,
196                                         nodeIdTypeNew);
197                         return true;
198         }
199
200         nodeIdType = nodeIdTypeNew;
201
202         return false;
203 }
204
205 /*
206  * nodeId
207  */
208
209 /** The maximum length of a nodeId */
210 #define PUD_NODEIDMAXLENGTH 255
211
212 /** The nodeId buffer */
213 static unsigned char nodeId[PUD_NODEIDMAXLENGTH + 1];
214
215 /** The length of the string in the nodeId buffer */
216 static size_t nodeIdLength = 0;
217
218 /** True when the nodeId is set */
219 static bool nodeIdSet = false;
220
221 /** The nodeId as a nuber */
222 static unsigned long long nodeIdNumber = 0;
223
224 /** True when the nodeIdNumber is set */
225 static bool nodeIdNumberSet = false;
226
227 /**
228  @return
229  The node ID
230  */
231 unsigned char * getNodeId(void) {
232         return getNodeIdWithLength(NULL);
233 }
234
235 /**
236  @param value
237  A pointer to the node ID number
238  @return
239  - true on success
240  - false otherwise
241  */
242 bool getNodeIdAsNumber(unsigned long long * value) {
243         if (!nodeIdNumberSet) {
244                 if (!readULL(PUD_NODE_ID_NAME, (char *) &nodeId[0], &nodeIdNumber)) {
245                         return false;
246                 }
247                 nodeIdNumberSet = true;
248         }
249         *value = nodeIdNumber;
250         return true;
251 }
252
253 /**
254  Get the nodeId and its length
255
256  @param length
257  a pointer to the variable in which to store the nodeId length (allowed to be
258  NULL, in which case the length is not stored)
259
260  @return
261  The node ID
262  */
263 unsigned char * getNodeIdWithLength(size_t *length) {
264         if (!nodeIdSet) {
265                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
266         }
267
268         if (length != NULL) {
269                 *length = nodeIdLength;
270         }
271
272         return &nodeId[0];
273 }
274
275 /**
276  Set the node ID.
277
278  @param value
279  The value of the node ID to set (in string representation)
280  @param data
281  Unused
282  @param addon
283  Unused
284
285  @return
286  - true when an error is detected
287  - false otherwise
288  */
289 int setNodeId(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
290         static const char * valueName = PUD_NODE_ID_NAME;
291         size_t valueLength;
292
293         assert (value != NULL);
294
295         valueLength = strlen(value);
296         if (valueLength > PUD_NODEIDMAXLENGTH) {
297                 pudError(false, "Configured %s is too long, maximum length is"
298                         " %u, current length is %lu", valueName, PUD_NODEIDMAXLENGTH,
299                                 (unsigned long) valueLength);
300                 return true;
301         }
302
303         strcpy((char *) &nodeId[0], value);
304         nodeIdLength = valueLength;
305         nodeIdSet = true;
306
307         return false;
308 }
309
310 /*
311  * nodeId Cache
312  */
313
314 /** The size of the cached nodeId buffer */
315 #define PUD_CACHED_NODEID_BUFFER_SIZE 16
316
317 /** The cached nodeId buffer: contains a pre-processed version of the nodeId
318  in order to improve performance. It is currently used for nodeIdTypes
319  PUD_NODEIDTYPE_MSISDN, PUD_NODEIDTYPE_TETRA, PUD_NODEIDTYPE_192,
320  PUD_NODEIDTYPE_193 (so basically for numbers that will not change) */
321 static unsigned char cachedNodeIdBuffer[PUD_CACHED_NODEID_BUFFER_SIZE];
322
323 /** The number of bytes stored in cachedNodeIdBuffer */
324 static unsigned int cachedNodeIdBufferLength = 0;
325
326 /**
327  @param buffer
328  A pointer to the location in which to store a pointer to the nodeId cache
329  buffer
330  @param length
331  A pointer to the location in which to store the number of bytes in the buffer
332  */
333 void getNodeIdNumberForOlsrCache(unsigned char ** buffer, unsigned int * length) {
334         *buffer = &cachedNodeIdBuffer[0];
335         *length = cachedNodeIdBufferLength;
336 }
337
338 /**
339  Check a nodeId number for validity and if valid set it up in the
340  cachedNodeIdBuffer. The valid range for the number is [min, max].
341
342  @param min
343  The lower bound for a valid number
344  @param max
345  The upper bound for a valid number
346  @param bytes
347  The number of bytes used by the number in the wire format
348
349  @return
350  - true when the number is valid
351  - false otherwise
352  */
353 static bool setupNodeIdNumberForOlsrCache(unsigned long long min,
354                 unsigned long long max, unsigned int bytes) {
355         unsigned long long val;
356
357         assert (bytes <= PUD_CACHED_NODEID_BUFFER_SIZE);
358
359         if (!getNodeIdAsNumber(&val)) {
360                 return false;
361         }
362
363         if ((val >= min) && (val <= max)) {
364                 int i = bytes - 1;
365                 while (i >= 0) {
366                         cachedNodeIdBuffer[i] = val & 0xff;
367                         val >>= 8;
368                         i--;
369                 }
370
371                 assert(val == 0);
372
373                 cachedNodeIdBufferLength = bytes;
374                 return true;
375         }
376
377         pudError(false, "%s value %llu is out of range [%llu,%llu]",
378                         PUD_NODE_ID_NAME, val, min, max);
379         return false;
380 }
381
382 /*
383  * nodeId Validation
384  */
385
386 /**
387  Validate whether the configured nodeId is valid w.r.t. the configured
388  nodeIdType
389
390  @return
391  - true when ok
392  - false on failure
393  */
394 static bool setupNodeIdNumberForOlsrCacheAndValidate(NodeIdType nodeIdTypeNumber) {
395         switch (nodeIdTypeNumber) {
396                 case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
397                 case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
398                 case PUD_NODEIDTYPE_MAC: /* hardware address */
399                         /* explicit return: configured nodeId is not relevant */
400                         return true;
401
402                 case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
403                         return setupNodeIdNumberForOlsrCache(0LL, 999999999999999LL, 7);
404
405                 case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
406                         return setupNodeIdNumberForOlsrCache(0LL, 99999999999999999LL, 8);
407
408                 case PUD_NODEIDTYPE_DNS: /* DNS name */
409                 {
410                         bool invalidChars;
411                         char report[256];
412
413                         invalidChars = nmea_string_has_invalid_chars((char *) getNodeId(),
414                                         PUD_NODE_ID_NAME, &report[0], sizeof(report));
415                         if (invalidChars) {
416                                 pudError(false, &report[0]);
417                         }
418                         return !invalidChars;
419                 }
420
421                 case PUD_NODEIDTYPE_192:
422                         return setupNodeIdNumberForOlsrCache(0LL, 9999999LL, 3);
423
424                 case PUD_NODEIDTYPE_193:
425                         return setupNodeIdNumberForOlsrCache(0LL, 999999LL, 3);
426
427                 case PUD_NODEIDTYPE_194:
428                         return setupNodeIdNumberForOlsrCache(1LL, 8191LL, 2);
429
430                 default: /* unsupported */
431                         /* explicit return: configured nodeId is not relevant, will
432                          * fallback to IP addresses */
433                         return true;
434         }
435
436         return false;
437 }
438
439 /*
440  * rxNonOlsrIf
441  */
442
443 /** The maximum number of RX non-OLSR interfaces */
444 #define PUD_RX_NON_OLSR_IF_MAX 32
445
446 /** Array with RX non-OLSR interface names */
447 static unsigned char rxNonOlsrInterfaceNames[PUD_RX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
448
449 /** The number of RX non-OLSR interface names in the array */
450 static unsigned int rxNonOlsrInterfaceCount = 0;
451
452 /**
453  Determine whether a give interface name is configured as a receive non-OLSR
454  interface.
455
456  @param ifName
457  The interface name to check
458
459  @return
460  - true when the given interface name is configured as a receive non-OLSR
461  interface
462  - false otherwise
463  */
464 bool isRxNonOlsrInterface(const char *ifName) {
465         unsigned int i;
466
467         assert (ifName != NULL);
468
469         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
470                 if (strncmp((char *) &rxNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
471                                 + 1) == 0) {
472                         return true;
473                 }
474         }
475
476         return false;
477 }
478
479 /**
480  Add a receive non-OLSR interface
481
482  @param value
483  The name of the non-OLSR interface to add
484  @param data
485  Unused
486  @param addon
487  Unused
488
489  @return
490  - true when an error is detected
491  - false otherwise
492  */
493 int addRxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
494                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
495         unsigned long valueLength;
496
497         assert (value != NULL);
498
499         valueLength = strlen(value);
500         if (valueLength > IFNAMSIZ) {
501                 pudError(false, "Configured %s (%s) is too long,"
502                         " maximum length is %u, current length is %lu",
503                                 PUD_RX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
504                 return true;
505         }
506
507         if (!isRxNonOlsrInterface(value)) {
508                 if (rxNonOlsrInterfaceCount >= PUD_RX_NON_OLSR_IF_MAX) {
509                         pudError(false, "Can't configure more than %u receive interfaces",
510                                         PUD_RX_NON_OLSR_IF_MAX);
511                         return true;
512                 }
513
514                 strcpy((char *) &rxNonOlsrInterfaceNames[rxNonOlsrInterfaceCount][0],
515                                 value);
516                 rxNonOlsrInterfaceCount++;
517         }
518
519         return false;
520 }
521
522 /*
523  * rxAllowedSourceIpAddress
524  */
525
526 /** The maximum number of RX allowed source IP addresses */
527 #define PUD_RX_ALLOWED_SOURCE_IP_MAX 32
528
529 /** Array with RX allowed source IP addresses */
530 static struct sockaddr rxAllowedSourceIpAddresses[PUD_RX_ALLOWED_SOURCE_IP_MAX];
531
532 /** The number of RX allowed source IP addresses in the array */
533 static unsigned int rxAllowedSourceIpAddressesCount = 0;
534
535 /**
536  Determine whether a give IP address is configured as an allowed source IP
537  address.
538
539  @param sender
540  The IP address to check
541
542  @return
543  - true when the given IP address is configured as an allowed source IP
544  address
545  - false otherwise
546  */
547 bool isRxAllowedSourceIpAddress(struct sockaddr * sender) {
548         void * addr;
549         unsigned int addrSize;
550         unsigned int i;
551
552         if (rxAllowedSourceIpAddressesCount == 0) {
553                 return true;
554         }
555
556         if (sender == NULL) {
557                 return false;
558         }
559
560         if (sender->sa_family == AF_INET) {
561                 addr = (void *) (&((struct sockaddr_in *) sender)->sin_addr);
562                 addrSize = sizeof(struct in_addr);
563         } else {
564                 addr = (void *) (&((struct sockaddr_in6 *) sender)->sin6_addr);
565                 addrSize = sizeof(struct in6_addr);
566         }
567
568         for (i = 0; i < rxAllowedSourceIpAddressesCount; i++) {
569                 if ((rxAllowedSourceIpAddresses[i].sa_family == sender->sa_family)
570                                 && (memcmp(&rxAllowedSourceIpAddresses[i].sa_data, addr,
571                                                 addrSize) == 0)) {
572                         return true;
573                 }
574         }
575
576         return false;
577 }
578
579 /**
580  Set the RX allowed source IP addresses.
581
582  @param value
583  The RX allowed source IP address (in string representation)
584  @param data
585  Unused
586  @param addon
587  Unused
588
589  @return
590  - true when an error is detected
591  - false otherwise
592  */
593 int addRxAllowedSourceIpAddress(const char *value, void *data __attribute__ ((unused)),
594                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
595         static const char * valueName = PUD_RX_ALLOWED_SOURCE_IP_NAME;
596         const char * valueInternal = value;
597         int conversion;
598         struct sockaddr addr;
599
600         assert (value != NULL);
601
602         memset(&addr, 0, sizeof(addr));
603
604         addr.sa_family = olsr_cnf->ip_version;
605         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, &addr.sa_data);
606         if (conversion != 1) {
607                 pudError((conversion == -1) ? true : false,
608                                 "Configured %s (%s) is not an IP address", valueName,
609                                 valueInternal);
610                 return true;
611         }
612
613         if ((rxAllowedSourceIpAddressesCount == 0) || !isRxAllowedSourceIpAddress(&addr)) {
614                 if (rxAllowedSourceIpAddressesCount >= PUD_RX_ALLOWED_SOURCE_IP_MAX) {
615                         pudError(false, "Can't configure more than %u allowed source IP"
616                                 " addresses", PUD_RX_ALLOWED_SOURCE_IP_MAX);
617                         return true;
618                 }
619
620                 memcpy(&rxAllowedSourceIpAddresses[rxAllowedSourceIpAddressesCount],
621                                 &addr, sizeof(addr));
622                 rxAllowedSourceIpAddressesCount++;
623         }
624
625         return false;
626 }
627
628 /*
629  * rxMcAddr
630  */
631
632 /** The rx multicast address */
633 static union olsr_sockaddr rxMcAddr;
634
635 /** True when the rx multicast address is set */
636 static bool rxMcAddrSet = false;
637
638 /**
639  @return
640  The receive multicast address (in network byte order). Sets both the address
641  and the port to their default values when the address was not yet set.
642  */
643 union olsr_sockaddr * getRxMcAddr(void) {
644         if (!rxMcAddrSet) {
645                 setRxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
646         }
647         return &rxMcAddr;
648 }
649
650 /**
651  Set the receive multicast address. Sets the address to its default value when
652  the value is NULL. Also sets the port to its default value when the address
653  was not yet set.
654
655  @param value
656  The receive multicast address (in string representation)
657  @param data
658  Unused
659  @param addon
660  Unused
661
662  @return
663  - true when an error is detected
664  - false otherwise
665  */
666 int setRxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
667         static const char * valueName = PUD_RX_MC_ADDR_NAME;
668         void * ipAddress;
669         in_port_t * port;
670         const char * valueInternal = value;
671         int conversion;
672
673         getOlsrSockAddrAndPort(olsr_cnf->ip_version, &rxMcAddr, &ipAddress, &port);
674         if (olsr_cnf->ip_version == AF_INET) {
675                 rxMcAddr.in4.sin_family = olsr_cnf->ip_version;
676                 if (valueInternal == NULL) {
677                         valueInternal = PUD_RX_MC_ADDR_4_DEFAULT;
678                 }
679         } else {
680                 rxMcAddr.in6.sin6_family = olsr_cnf->ip_version;
681                 if (valueInternal == NULL) {
682                         valueInternal = PUD_RX_MC_ADDR_6_DEFAULT;
683                 }
684         }
685
686         if (!rxMcAddrSet) {
687                 *port = htons(PUD_RX_MC_PORT_DEFAULT);
688         }
689
690         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
691         if (conversion != 1) {
692                 pudError((conversion == -1) ? true : false,
693                                 "Configured %s (%s) is not an IP address", valueName,
694                                 valueInternal);
695                 return true;
696         }
697
698         if (!isMulticast(olsr_cnf->ip_version, &rxMcAddr)) {
699                 pudError(false, "Configured %s (%s) is not a multicast address",
700                                 valueName, valueInternal);
701                 return true;
702         }
703
704         rxMcAddrSet = true;
705         return false;
706 }
707
708 /*
709  * rxMcPort
710  */
711
712 /**
713  @return
714  The receive multicast port (in network byte order)
715  */
716 unsigned short getRxMcPort(void) {
717         union olsr_sockaddr * addr = getRxMcAddr();
718         return *getOlsrSockaddrPort(olsr_cnf->ip_version, addr);
719 }
720
721 /**
722  Set the receive multicast port
723
724  @param value
725  The receive multicast port (a number in string representation)
726  @param data
727  Unused
728  @param addon
729  Unused
730
731  @return
732  - true when an error is detected
733  - false otherwise
734  */
735 int setRxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
736         static const char * valueName = PUD_RX_MC_PORT_NAME;
737         unsigned long long rxMcPortNew;
738         in_port_t * port;
739         union olsr_sockaddr * addr = getRxMcAddr();
740
741         assert (value != NULL);
742
743         if (!readULL(valueName, value, &rxMcPortNew)) {
744                 return true;
745         }
746
747         if ((rxMcPortNew < 1) || (rxMcPortNew > 65535)) {
748                 pudError(false, "Configured %s (%llu) is outside of"
749                         " valid range 1-65535", valueName, rxMcPortNew);
750                 return true;
751         }
752
753         port = getOlsrSockaddrPort(olsr_cnf->ip_version, addr);
754         *port = htons((uint16_t) rxMcPortNew);
755
756         return false;
757 }
758
759 /*
760  * txNonOlsrIf
761  */
762
763 /** The maximum number of rx non-olsr interfaces */
764 #define PUD_TX_NON_OLSR_IF_MAX 32
765
766 /** Array with tx non-olsr interface names */
767 static unsigned char txNonOlsrInterfaceNames[PUD_TX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
768
769 /** The number of tx interface names in the array */
770 static unsigned int txNonOlsrInterfaceCount = 0;
771
772 /**
773  Determine whether a give interface name is configured as a transmit non-OLSR
774  interface.
775
776  @param ifName
777  The interface to check
778
779  @return
780  - true when the given interface name is configured as a transmit non-OLSR
781  interface
782  - false otherwise
783  */
784 bool isTxNonOlsrInterface(const char *ifName) {
785         unsigned int i;
786
787         assert (ifName != NULL);
788
789         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
790                 if (strncmp((char *) &txNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
791                                 + 1) == 0) {
792                         return true;
793                 }
794         }
795
796         return false;
797 }
798
799 /**
800  Add a transmit non-OLSR interface
801
802  @param value
803  The name of the non-OLSR interface to add
804  @param data
805  Unused
806  @param addon
807  Unused
808
809  @return
810  - true when an error is detected
811  - false otherwise
812  */
813 int addTxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
814                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
815         unsigned long valueLength;
816
817         assert (value != NULL);
818
819         valueLength = strlen(value);
820         if (valueLength > IFNAMSIZ) {
821                 pudError(false, "Configured %s (%s) is too long,"
822                         " maximum length is %u, current length is %lu",
823                                 PUD_TX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
824                 return true;
825         }
826
827         if (!isTxNonOlsrInterface(value)) {
828                 if (txNonOlsrInterfaceCount >= PUD_TX_NON_OLSR_IF_MAX) {
829                         pudError(false, "Can not configure more than %u transmit"
830                                 " interfaces", PUD_TX_NON_OLSR_IF_MAX);
831                         return true;
832                 }
833
834                 strcpy((char *) &txNonOlsrInterfaceNames[txNonOlsrInterfaceCount][0],
835                                 value);
836                 txNonOlsrInterfaceCount++;
837         }
838
839         return false;
840 }
841
842 /*
843  * txMcAddr
844  */
845
846 /** The tx multicast address */
847 static union olsr_sockaddr txMcAddr;
848
849 /** True when the tx multicast address is set */
850 static bool txMcAddrSet = false;
851
852 /**
853  @return
854  The transmit multicast address (in network byte order). Sets both the address
855  and the port to their default values when the address was not yet set.
856  */
857 union olsr_sockaddr * getTxMcAddr(void) {
858         if (!txMcAddrSet) {
859                 setTxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
860         }
861         return &txMcAddr;
862 }
863
864 /**
865  Set the transmit multicast address. Sets the address to its default value when
866  the value is NULL. Also sets the port to its default value when the address
867  was not yet set.
868
869  @param value
870  The transmit multicast address (in string representation)
871  @param data
872  Unused
873  @param addon
874  Unused
875
876  @return
877  - true when an error is detected
878  - false otherwise
879  */
880 int setTxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
881         static const char * valueName = PUD_TX_MC_ADDR_NAME;
882         void * ipAddress;
883         in_port_t * port;
884         const char * valueInternal = value;
885         int conversion;
886
887         getOlsrSockAddrAndPort(olsr_cnf->ip_version, &txMcAddr, &ipAddress, &port);
888         if (olsr_cnf->ip_version == AF_INET) {
889                 txMcAddr.in4.sin_family = olsr_cnf->ip_version;
890                 if (valueInternal == NULL) {
891                         valueInternal = PUD_TX_MC_ADDR_4_DEFAULT;
892                 }
893         } else {
894                 txMcAddr.in6.sin6_family = olsr_cnf->ip_version;
895                 if (valueInternal == NULL) {
896                         valueInternal = PUD_TX_MC_ADDR_6_DEFAULT;
897                 }
898         }
899
900         if (!txMcAddrSet) {
901                 *port = htons(PUD_TX_MC_PORT_DEFAULT);
902         }
903
904         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
905         if (conversion != 1) {
906                 pudError((conversion == -1) ? true : false,
907                                 "Configured %s (%s) is not an IP address", valueName,
908                                 valueInternal);
909                 return true;
910         }
911
912         if (!isMulticast(olsr_cnf->ip_version, &txMcAddr)) {
913                 pudError(false, "Configured %s (%s) is not a multicast address",
914                                 valueName, valueInternal);
915                 return true;
916         }
917
918         txMcAddrSet = true;
919         return false;
920 }
921
922 /*
923  * txMcPort
924  */
925
926 /**
927  @return
928  The transmit multicast port (in network byte order)
929  */
930 unsigned short getTxMcPort(void) {
931         union olsr_sockaddr * addr = getTxMcAddr();
932         return *getOlsrSockaddrPort(olsr_cnf->ip_version, addr);
933 }
934
935 /**
936  Set the transmit multicast port
937
938  @param value
939  The transmit multicast port (a number in string representation)
940  @param data
941  Unused
942  @param addon
943  Unused
944
945  @return
946  - true when an error is detected
947  - false otherwise
948  */
949 int setTxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
950         static const char * valueName = PUD_TX_MC_PORT_NAME;
951         unsigned long long txMcPortNew;
952         in_port_t * port;
953         union olsr_sockaddr * addr = getTxMcAddr();
954
955         assert (value != NULL);
956
957         if (!readULL(valueName, value, &txMcPortNew)) {
958                 return true;
959         }
960
961         if ((txMcPortNew < 1) || (txMcPortNew > 65535)) {
962                 pudError(false, "Configured %s (%llu) is outside of"
963                         " valid range 1-65535", valueName, txMcPortNew);
964                 return true;
965         }
966
967         port = getOlsrSockaddrPort(olsr_cnf->ip_version, addr);
968         *port = htons((uint16_t) txMcPortNew);
969
970         return false;
971 }
972
973 /*
974  * txTtl
975  */
976
977 /** The tx TTL */
978 static unsigned char txTtl = PUD_TX_TTL_DEFAULT;
979
980 /**
981  @return
982  The transmit multicast IP packet time-to-live
983  */
984 unsigned char getTxTtl(void) {
985         return txTtl;
986 }
987
988 /**
989  Set the transmit multicast IP packet time-to-live
990
991  @param value
992  The transmit multicast IP packet time-to-live (a number in string representation)
993  @param data
994  Unused
995  @param addon
996  Unused
997
998  @return
999  - true when an error is detected
1000  - false otherwise
1001  */
1002 int setTxTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1003         static const char * valueName = PUD_TX_TTL_NAME;
1004         unsigned long long txTtlNew;
1005
1006         assert (value != NULL);
1007
1008         if (!readULL(valueName, value, &txTtlNew)) {
1009                 return true;
1010         }
1011
1012         if ((txTtlNew < 1) || (txTtlNew > MAX_TTL)) {
1013                 pudError(false, "Configured %s (%llu) is outside of"
1014                         " valid range 1-%u", valueName, txTtlNew, MAX_TTL);
1015                 return true;
1016         }
1017
1018         txTtl = txTtlNew;
1019
1020         return false;
1021 }
1022
1023 /*
1024  * txNmeaMessagePrefix
1025  */
1026
1027 /** The exact length of the tx NMEA message prefix */
1028 #define PUD_TXNMEAMESSAGEPREFIXLENGTH 4
1029
1030 /** The tx NMEA message prefix buffer */
1031 static unsigned char txNmeaMessagePrefix[PUD_TXNMEAMESSAGEPREFIXLENGTH + 1];
1032
1033 /** True when the tx NMEA message prefix is set */
1034 static bool txNmeaMessagePrefixSet = false;
1035
1036 /**
1037  @return
1038  The transmit multicast NMEA message prefix
1039  */
1040 unsigned char * getTxNmeaMessagePrefix(void) {
1041         if (!txNmeaMessagePrefixSet) {
1042                 setTxNmeaMessagePrefix(PUD_TX_NMEAMESSAGEPREFIX_DEFAULT, NULL,
1043                                 (set_plugin_parameter_addon) {.pc = NULL});
1044         }
1045         return &txNmeaMessagePrefix[0];
1046 }
1047
1048 /**
1049  Set the transmit multicast NMEA message prefix
1050
1051  @param value
1052  The transmit multicast NMEA message prefix (in string representation)
1053  @param data
1054  Unused
1055  @param addon
1056  Unused
1057
1058  @return
1059  - true when an error is detected
1060  - false otherwise
1061  */
1062 int setTxNmeaMessagePrefix(const char *value, void *data __attribute__ ((unused)),
1063                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1064         static const char * valueName = PUD_TX_NMEAMESSAGEPREFIX_NAME;
1065         size_t valueLength;
1066         bool invalidChars;
1067         char report[256];
1068
1069         assert (value != NULL);
1070
1071         valueLength = strlen(value);
1072         if (valueLength != PUD_TXNMEAMESSAGEPREFIXLENGTH) {
1073                 pudError(false, "Configured %s (%s) must be %u exactly characters",
1074                                 valueName, value, PUD_TXNMEAMESSAGEPREFIXLENGTH);
1075                 return true;
1076         }
1077
1078         invalidChars = nmea_string_has_invalid_chars(value, valueName, &report[0],
1079                         sizeof(report));
1080         if (invalidChars) {
1081                 pudError(false, &report[0]);
1082                 return true;
1083         }
1084
1085         if ((strchr(value, ' ') != NULL) || (strchr(value, '\t') != NULL)) {
1086                 pudError(false, "Configured %s (%s) can not contain whitespace",
1087                                 valueName, value);
1088                 return true;
1089         }
1090
1091         strcpy((char *) &txNmeaMessagePrefix[0], value);
1092         txNmeaMessagePrefixSet = true;
1093         return false;
1094 }
1095
1096 /*
1097  * olsrTtl
1098  */
1099
1100 /** The OLSR TTL */
1101 static unsigned char olsrTtl = PUD_OLSR_TTL_DEFAULT;
1102
1103 /**
1104  @return
1105  The OLSR multicast IP packet time-to-live
1106  */
1107 unsigned char getOlsrTtl(void) {
1108         return olsrTtl;
1109 }
1110
1111 /**
1112  Set the OLSR multicast IP packet time-to-live
1113
1114  @param value
1115  The OLSR multicast IP packet time-to-live (a number in string representation)
1116  @param data
1117  Unused
1118  @param addon
1119  Unused
1120
1121  @return
1122  - true when an error is detected
1123  - false otherwise
1124  */
1125 int setOlsrTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1126         static const char * valueName = PUD_OLSR_TTL_NAME;
1127         unsigned long long olsrTtlNew;
1128
1129         assert (value != NULL);
1130
1131         if (!readULL(valueName, value, &olsrTtlNew)) {
1132                 return true;
1133         }
1134
1135         if ((olsrTtlNew < 1) || (olsrTtlNew > MAX_TTL)) {
1136                 pudError(false, "Configured %s (%llu) is outside of valid range 1-%u",
1137                                 valueName, olsrTtlNew, MAX_TTL);
1138                 return true;
1139         }
1140
1141         olsrTtl = olsrTtlNew;
1142
1143         return false;
1144 }
1145
1146 /*
1147  * updateIntervalStationary
1148  */
1149
1150 /** The stationary interval update plugin parameter (in seconds) */
1151 static unsigned long long updateIntervalStationary = PUD_UPDATE_INTERVAL_STATIONARY_DEFAULT;
1152
1153 /**
1154  @return
1155  The stationary interval update plugin parameter (in seconds)
1156  */
1157 unsigned long long getUpdateIntervalStationary(void) {
1158         return updateIntervalStationary;
1159 }
1160
1161 /**
1162  Set stationary interval update plugin parameter
1163
1164  @param value
1165  The stationary interval update plugin parameter (in seconds)
1166  @param data
1167  Unused
1168  @param addon
1169  Unused
1170
1171  @return
1172  - true when an error is detected
1173  - false otherwise
1174  */
1175 int setUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1176                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1177         static const char * valueName = PUD_UPDATE_INTERVAL_STATIONARY_NAME;
1178         unsigned long long updateIntervalStationaryNew;
1179
1180         assert (value != NULL);
1181
1182         if (!readULL(valueName, value, &updateIntervalStationaryNew)) {
1183                 return true;
1184         }
1185
1186         if (updateIntervalStationaryNew < 1) {
1187                 pudError(false, "Configured %s must be at least 1", valueName);
1188                 return true;
1189         }
1190
1191         updateIntervalStationary = updateIntervalStationaryNew;
1192
1193         return false;
1194 }
1195
1196 /*
1197  * updateIntervalMoving
1198  */
1199
1200 /** The moving interval update plugin parameter (in seconds) */
1201 static unsigned long long updateIntervalMoving = PUD_UPDATE_INTERVAL_MOVING_DEFAULT;
1202
1203 /**
1204  @return
1205  The moving interval update plugin parameter (in seconds)
1206  */
1207 unsigned long long getUpdateIntervalMoving(void) {
1208         return updateIntervalMoving;
1209 }
1210
1211 /**
1212  Set moving interval update plugin parameter
1213
1214  @param value
1215  The moving interval update plugin parameter (in seconds)
1216  @param data
1217  Unused
1218  @param addon
1219  Unused
1220
1221  @return
1222  - true when an error is detected
1223  - false otherwise
1224  */
1225 int setUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1226                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1227         static const char * valueName = PUD_UPDATE_INTERVAL_MOVING_NAME;
1228         unsigned long long updateIntervalMovingNew;
1229
1230         assert (value != NULL);
1231
1232         if (!readULL(valueName, value, &updateIntervalMovingNew)) {
1233                 return true;
1234         }
1235
1236         if (updateIntervalMovingNew < 1) {
1237                 pudError(false, "Configured %s must be at least 1", valueName);
1238                 return true;
1239         }
1240
1241         updateIntervalMoving = updateIntervalMovingNew;
1242
1243         return false;
1244 }
1245
1246 /*
1247  * movingSpeedThreshold
1248  */
1249
1250 /** The moving speed threshold plugin parameter (in kph) */
1251 static unsigned long long movingSpeedThreshold = PUD_MOVING_SPEED_THRESHOLD_DEFAULT;
1252
1253 /**
1254  @return
1255  The moving speed threshold plugin parameter (in kph)
1256  */
1257 unsigned long long getMovingSpeedThreshold(void) {
1258         return movingSpeedThreshold;
1259 }
1260
1261 /**
1262  Set moving speed threshold plugin parameter
1263
1264  @param value
1265  The moving speed threshold plugin parameter (in kph)
1266  @param data
1267  Unused
1268  @param addon
1269  Unused
1270
1271  @return
1272  - true when an error is detected
1273  - false otherwise
1274  */
1275 int setMovingSpeedThreshold(const char *value, void *data __attribute__ ((unused)),
1276                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1277         static const char * valueName = PUD_MOVING_SPEED_THRESHOLD_NAME;
1278         unsigned long long movingSpeedThresholdNew;
1279
1280         assert (value != NULL);
1281
1282         if (!readULL(valueName, value, &movingSpeedThresholdNew)) {
1283                 return true;
1284         }
1285
1286         movingSpeedThreshold = movingSpeedThresholdNew;
1287
1288         return false;
1289 }
1290
1291 /*
1292  * movingDistanceThreshold
1293  */
1294
1295 /** The moving distance threshold plugin parameter (in meters) */
1296 static unsigned long long movingDistanceThreshold = PUD_MOVING_DISTANCE_THRESHOLD_DEFAULT;
1297
1298 /**
1299  @return
1300  The moving distance threshold plugin parameter (in meters)
1301  */
1302 unsigned long long getMovingDistanceThreshold(void) {
1303         return movingDistanceThreshold;
1304 }
1305
1306 /**
1307  Set moving distance threshold plugin parameter
1308
1309  @param value
1310  The moving distance threshold plugin parameter (in meter)
1311  @param data
1312  Unused
1313  @param addon
1314  Unused
1315
1316  @return
1317  - true when an error is detected
1318  - false otherwise
1319  */
1320 int setMovingDistanceThreshold(const char *value, void *data __attribute__ ((unused)),
1321                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1322         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1323         unsigned long long movingDistanceThresholdNew;
1324
1325         assert (value != NULL);
1326
1327         if (!readULL(valueName, value, &movingDistanceThresholdNew)) {
1328                 return true;
1329         }
1330
1331         movingDistanceThreshold = movingDistanceThresholdNew;
1332
1333         return false;
1334 }
1335
1336 /*
1337  * dopMultiplier
1338  */
1339
1340 /* The DOP multiplier plugin parameter */
1341 static double dopMultiplier = PUD_DOP_MULTIPLIER_DEFAULT;
1342
1343 /**
1344  @return
1345  The DOP multiplier plugin parameter
1346  */
1347 double getDopMultiplier(void) {
1348         return dopMultiplier;
1349 }
1350
1351 /**
1352  Set DOP multiplier plugin parameter
1353
1354  @param value
1355  The DOP multiplier plugin parameter
1356  @param data
1357  Unused
1358  @param addon
1359  Unused
1360
1361  @return
1362  - true when an error is detected
1363  - false otherwise
1364  */
1365 int setDopMultiplier(const char *value, void *data __attribute__ ((unused)),
1366                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1367         static const char * valueName = PUD_DOP_MULTIPLIER_NAME;
1368         double dopMultiplierNew;
1369
1370         assert (value != NULL);
1371
1372         if (!readDouble(valueName, value, &dopMultiplierNew)) {
1373                 return true;
1374         }
1375
1376         dopMultiplier = dopMultiplierNew;
1377
1378         return false;
1379 }
1380
1381 /*
1382  * defaultHdop
1383  */
1384
1385 /** The default HDOP plugin parameter (in meters) */
1386 static unsigned long long defaultHdop = PUD_DEFAULT_HDOP_DEFAULT;
1387
1388 /**
1389  @return
1390  The default HDOP plugin parameter (in meters)
1391  */
1392 unsigned long long getDefaultHdop(void) {
1393         return defaultHdop;
1394 }
1395
1396 /**
1397  Set default HDOP plugin parameter
1398
1399  @param value
1400  The default HDOP plugin parameter (in meters)
1401  @param data
1402  Unused
1403  @param addon
1404  Unused
1405
1406  @return
1407  - true when an error is detected
1408  - false otherwise
1409  */
1410 int setDefaultHdop(const char *value, void *data __attribute__ ((unused)),
1411                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1412         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1413         unsigned long long defaultHdopNew;
1414
1415         assert (value != NULL);
1416
1417         if (!readULL(valueName, value, &defaultHdopNew)) {
1418                 return true;
1419         }
1420
1421         defaultHdop = defaultHdopNew;
1422
1423         return false;
1424 }
1425
1426 /*
1427  * defaultVdop
1428  */
1429
1430 /** The default VDOP plugin parameter (in meters) */
1431 static unsigned long long defaultVdop = PUD_DEFAULT_VDOP_DEFAULT;
1432
1433 /**
1434  @return
1435  The default VDOP plugin parameter (in meters)
1436  */
1437 unsigned long long getDefaultVdop(void) {
1438         return defaultVdop;
1439 }
1440
1441 /**
1442  Set default VDOP plugin parameter
1443
1444  @param value
1445  The default VDOP plugin parameter (in meters)
1446  @param data
1447  Unused
1448  @param addon
1449  Unused
1450
1451  @return
1452  - true when an error is detected
1453  - false otherwise
1454  */
1455 int setDefaultVdop(const char *value, void *data __attribute__ ((unused)),
1456                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1457         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1458         unsigned long long defaultVdopNew;
1459
1460         assert (value != NULL);
1461
1462         if (!readULL(valueName, value, &defaultVdopNew)) {
1463                 return true;
1464         }
1465
1466         defaultVdop = defaultVdopNew;
1467
1468         return false;
1469 }
1470
1471 /*
1472  * averageDepth
1473  */
1474
1475 /** The depth of the average list */
1476 static unsigned long long averageDepth = PUD_AVERAGE_DEPTH_DEFAULT;
1477
1478 /**
1479  @return
1480  The depth of the average list
1481  */
1482 unsigned long long getAverageDepth(void) {
1483         return averageDepth;
1484 }
1485
1486 /**
1487  Set average depth plugin parameter
1488
1489  @param value
1490  The average depth plugin parameter
1491  @param data
1492  Unused
1493  @param addon
1494  Unused
1495
1496  @return
1497  - true when an error is detected
1498  - false otherwise
1499  */
1500 int setAverageDepth(const char *value, void *data __attribute__ ((unused)),
1501                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1502         static const char * valueName = PUD_AVERAGE_DEPTH_NAME;
1503         unsigned long long averageDepthNew;
1504
1505         assert (value != NULL);
1506
1507         if (!readULL(valueName, value, &averageDepthNew)) {
1508                 return true;
1509         }
1510
1511         if (averageDepthNew < 1) {
1512                 pudError(false, "Configured %s must be at least 1", valueName);
1513                 return true;
1514         }
1515
1516         averageDepth = averageDepthNew;
1517
1518         return false;
1519 }
1520
1521 /*
1522  * hysteresisCountToStationary
1523  */
1524
1525 /** The hysteresis count for changing state from moving to stationary */
1526 static unsigned long long hysteresisCountToStationary = PUD_HYSTERESIS_COUNT_2STAT_DEFAULT;
1527
1528 /**
1529  @return
1530  The hysteresis count for changing state from moving to stationary
1531  */
1532 unsigned long long getHysteresisCountToStationary(void) {
1533         return hysteresisCountToStationary;
1534 }
1535
1536 /**
1537  Set hysteresis count plugin parameter
1538
1539  @param value
1540  The hysteresis count plugin parameter
1541  @param data
1542  Unused
1543  @param addon
1544  Unused
1545
1546  @return
1547  - true when an error is detected
1548  - false otherwise
1549  */
1550 int setHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1551                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1552         static const char * valueName = PUD_HYSTERESIS_COUNT_2STAT_NAME;
1553         unsigned long long hysteresisCountNew;
1554
1555         assert (value != NULL);
1556
1557         if (!readULL(valueName, value, &hysteresisCountNew)) {
1558                 return true;
1559         }
1560
1561         hysteresisCountToStationary = hysteresisCountNew;
1562
1563         return false;
1564 }
1565
1566 /*
1567  * hysteresisCountToMoving
1568  */
1569
1570 /** The hysteresis count for changing state from stationary to moving */
1571 static unsigned long long hysteresisCountToMoving = PUD_HYSTERESIS_COUNT_2MOV_DEFAULT;
1572
1573 /**
1574  @return
1575  The hysteresis count for changing state from stationary to moving
1576  */
1577 unsigned long long getHysteresisCountToMoving(void) {
1578         return hysteresisCountToMoving;
1579 }
1580
1581 /**
1582  Set hysteresis count plugin parameter
1583
1584  @param value
1585  The hysteresis count plugin parameter
1586  @param data
1587  Unused
1588  @param addon
1589  Unused
1590
1591  @return
1592  - true when an error is detected
1593  - false otherwise
1594  */
1595 int setHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1596                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1597         static const char * valueName = PUD_HYSTERESIS_COUNT_2MOV_NAME;
1598         unsigned long long hysteresisCountNew;
1599
1600         assert (value != NULL);
1601
1602         if (!readULL(valueName, value, &hysteresisCountNew)) {
1603                 return true;
1604         }
1605
1606         hysteresisCountToMoving = hysteresisCountNew;
1607
1608         return false;
1609 }
1610
1611 /*
1612  * useDeDup
1613  */
1614
1615 /* when true then duplicate message detection is performed */
1616 static bool useDeDup = PUD_USE_DEDUP_DEFAULT;
1617
1618 /**
1619  @return
1620  The duplicate message detection setting
1621  */
1622 bool getUseDeDup(void) {
1623         return useDeDup;
1624 }
1625
1626 /**
1627  Set duplicate message detection setting plugin parameter
1628
1629  @param value
1630  The duplicate message detection setting plugin parameter
1631  @param data
1632  Unused
1633  @param addon
1634  Unused
1635
1636  @return
1637  - true when an error is detected
1638  - false otherwise
1639  */
1640 int setUseDeDup(const char *value, void *data __attribute__ ((unused)),
1641                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1642         static const char * valueName = PUD_USE_DEDUP_NAME;
1643         unsigned long long useDeDupNew;
1644
1645         assert (value != NULL);
1646
1647         if (!readULL(valueName, value, &useDeDupNew)) {
1648                 return true;
1649         }
1650
1651         if ((useDeDupNew != 0) && (useDeDupNew != 1)) {
1652                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
1653                                 valueName);
1654                 return true;
1655         }
1656
1657         useDeDup = (useDeDupNew == 1);
1658
1659         return false;
1660 }
1661
1662 /*
1663  * deDupDepth
1664  */
1665
1666 /** The hysteresis count for changing state from stationary to moving */
1667 static unsigned long long deDupDepth = PUD_DEDUP_DEPTH_DEFAULT;
1668
1669 /**
1670  @return
1671  The hysteresis count for changing state from stationary to moving
1672  */
1673 unsigned long long getDeDupDepth(void) {
1674         return deDupDepth;
1675 }
1676
1677 /**
1678  Set de-duplication depth plugin parameter
1679
1680  @param value
1681  The de-duplication depth plugin parameter
1682  @param data
1683  Unused
1684  @param addon
1685  Unused
1686
1687  @return
1688  - true when an error is detected
1689  - false otherwise
1690  */
1691 int setDeDupDepth(const char *value, void *data __attribute__ ((unused)),
1692                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1693         static const char * valueName = PUD_DEDUP_DEPTH_NAME;
1694         unsigned long long deDupDepthNew;
1695
1696         assert (value != NULL);
1697
1698         if (!readULL(valueName, value, &deDupDepthNew)) {
1699                 return true;
1700         }
1701
1702         deDupDepth = deDupDepthNew;
1703
1704         return false;
1705 }
1706
1707 /*
1708  * useLoopback
1709  */
1710
1711 /* when true then loopback is performed */
1712 static bool useLoopback = PUD_USE_LOOPBACK_DEFAULT;
1713
1714 /**
1715  @return
1716  The loopback usage setting
1717  */
1718 bool getUseLoopback(void) {
1719         return useLoopback;
1720 }
1721
1722 /**
1723  Set loopback usage plugin parameter
1724
1725  @param value
1726  The loopback usage plugin parameter
1727  @param data
1728  Unused
1729  @param addon
1730  Unused
1731
1732  @return
1733  - true when an error is detected
1734  - false otherwise
1735  */
1736 int setUseLoopback(const char *value, void *data __attribute__ ((unused)),
1737                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1738         static const char * valueName = PUD_USE_LOOPBACK_NAME;
1739         unsigned long long useLoopbackNew;
1740
1741         assert (value != NULL);
1742
1743         if (!readULL(valueName, value, &useLoopbackNew)) {
1744                 return true;
1745         }
1746
1747         if ((useLoopbackNew != 0) && (useLoopbackNew != 1)) {
1748                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
1749                                 valueName);
1750                 return true;
1751         }
1752
1753         useLoopback = (useLoopbackNew == 1);
1754
1755         return false;
1756 }
1757
1758 /*
1759  * Check Functions
1760  */
1761
1762 /**
1763  Check the configuration for consistency and validity.
1764
1765  @return
1766  - true when the configuration is consistent and valid
1767  - false otherwise
1768  */
1769 unsigned int checkConfig(void) {
1770         int retval = true;
1771
1772         if (rxNonOlsrInterfaceCount == 0) {
1773                 pudError(false, "No receive non-OLSR interfaces configured");
1774                 retval = false;
1775         }
1776
1777         if (txNonOlsrInterfaceCount == 0) {
1778                 pudError(false, "No transmit non-OLSR interfaces configured");
1779                 retval = false;
1780         }
1781
1782         if (!nodeIdSet) {
1783                 if (nodeIdType == PUD_NODEIDTYPE_DNS) {
1784                         char name[PUD_NODEIDMAXLENGTH + 1];
1785
1786                         errno = 0;
1787                         if (gethostname(&name[0], sizeof(name)) < 0) {
1788                                 pudError(true, "Could not get the host name");
1789                                 retval = false;
1790                         } else {
1791                                 setNodeId(&name[0], NULL,
1792                                                 (set_plugin_parameter_addon) {.pc = NULL});
1793                         }
1794                 } else if ((nodeIdType != PUD_NODEIDTYPE_MAC) && (nodeIdType
1795                                 != PUD_NODEIDTYPE_IPV4) && (nodeIdType != PUD_NODEIDTYPE_IPV6)) {
1796                         pudError(false, "No node ID set while one is required for"
1797                                 " node type %u", nodeIdType);
1798                         retval = false;
1799                 }
1800         }
1801
1802         if (!setupNodeIdNumberForOlsrCacheAndValidate(nodeIdType)) {
1803                 retval = false;
1804         }
1805
1806         if (updateIntervalMoving > updateIntervalStationary) {
1807                 pudError(false,"The update interval for moving situations must not be"
1808                 " larger than that for stationary situations");
1809                 retval = false;
1810         }
1811
1812         return retval;
1813 }
1814
1815 /**
1816  Check the configuration for consistency and validity after everything has been
1817  setup.
1818
1819  @return
1820  - true when the configuration is consistent and valid
1821  - false otherwise
1822  */
1823 unsigned int checkRunSetup(void) {
1824         int retval = true;
1825         unsigned int i;
1826
1827         /* any receive interface name that is configured but is not the name of an
1828          * actual receive interface is not a valid interface name */
1829         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
1830                 unsigned char * nonOlsrInterfaceName = &rxNonOlsrInterfaceNames[i][0];
1831
1832                 TRxTxNetworkInterface * interfaceObject = getRxNetworkInterfaces();
1833                 bool found = false;
1834                 while (interfaceObject != NULL) {
1835                         if (strncmp((char *) nonOlsrInterfaceName,
1836                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
1837                                 found = true;
1838                                 break;
1839                         }
1840                         interfaceObject = interfaceObject->next;
1841                 }
1842                 if (!found) {
1843                         pudError(false, "Configured receive non-OLSR interface %s is not"
1844                                 " a known interface name", nonOlsrInterfaceName);
1845                         retval = false;
1846                 }
1847         }
1848
1849         /* any transmit interface name that is configured but is not the name of an
1850          * actual transmit interface is not a valid interface name */
1851         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
1852                 unsigned char * nonOlsrInterfaceName = &txNonOlsrInterfaceNames[i][0];
1853
1854                 TRxTxNetworkInterface * interfaceObject = getTxNetworkInterfaces();
1855                 bool found = false;
1856                 while (interfaceObject != NULL) {
1857                         if (strncmp((char *) nonOlsrInterfaceName,
1858                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
1859                                 found = true;
1860                                 break;
1861                         }
1862                         interfaceObject = interfaceObject->next;
1863                 }
1864                 if (!found) {
1865                         pudError(false, "Configured transmit non-OLSR interface %s is not"
1866                                 " a known interface name", nonOlsrInterfaceName);
1867                         retval = false;
1868                 }
1869         }
1870
1871         return retval;
1872 }