Merge branch 'stable' into pud
[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,
404                                         PUD_NODEIDTYPE_MSISDN_BYTES);
405
406                 case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
407                         return setupNodeIdNumberForOlsrCache(0LL, 99999999999999999LL,
408                                         PUD_NODEIDTYPE_TETRA_BYTES);
409
410                 case PUD_NODEIDTYPE_DNS: /* DNS name */
411                 {
412                         bool invalidChars;
413                         char report[256];
414
415                         invalidChars = nmea_string_has_invalid_chars((char *) getNodeId(),
416                                         PUD_NODE_ID_NAME, &report[0], sizeof(report));
417                         if (invalidChars) {
418                                 pudError(false, &report[0]);
419                         }
420                         return !invalidChars;
421                 }
422
423                 case PUD_NODEIDTYPE_192:
424                         return setupNodeIdNumberForOlsrCache(0LL, 9999999LL,
425                                         PUD_NODEIDTYPE_192_BYTES);
426
427                 case PUD_NODEIDTYPE_193:
428                         return setupNodeIdNumberForOlsrCache(0LL, 999999LL,
429                                         PUD_NODEIDTYPE_193_BYTES);
430
431                 case PUD_NODEIDTYPE_194:
432                         return setupNodeIdNumberForOlsrCache(1LL, 8191LL,
433                                         PUD_NODEIDTYPE_194_BYTES);
434
435                 default: /* unsupported */
436                         /* explicit return: configured nodeId is not relevant, will
437                          * fallback to IP addresses */
438                         return true;
439         }
440
441         return false;
442 }
443
444 /*
445  * rxNonOlsrIf
446  */
447
448 /** The maximum number of RX non-OLSR interfaces */
449 #define PUD_RX_NON_OLSR_IF_MAX 32
450
451 /** Array with RX non-OLSR interface names */
452 static unsigned char rxNonOlsrInterfaceNames[PUD_RX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
453
454 /** The number of RX non-OLSR interface names in the array */
455 static unsigned int rxNonOlsrInterfaceCount = 0;
456
457 /**
458  Determine whether a give interface name is configured as a receive non-OLSR
459  interface.
460
461  @param ifName
462  The interface name to check
463
464  @return
465  - true when the given interface name is configured as a receive non-OLSR
466  interface
467  - false otherwise
468  */
469 bool isRxNonOlsrInterface(const char *ifName) {
470         unsigned int i;
471
472         assert (ifName != NULL);
473
474         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
475                 if (strncmp((char *) &rxNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
476                                 + 1) == 0) {
477                         return true;
478                 }
479         }
480
481         return false;
482 }
483
484 /**
485  Add a receive non-OLSR interface
486
487  @param value
488  The name of the non-OLSR interface to add
489  @param data
490  Unused
491  @param addon
492  Unused
493
494  @return
495  - true when an error is detected
496  - false otherwise
497  */
498 int addRxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
499                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
500         unsigned long valueLength;
501
502         assert (value != NULL);
503
504         valueLength = strlen(value);
505         if (valueLength > IFNAMSIZ) {
506                 pudError(false, "Configured %s (%s) is too long,"
507                         " maximum length is %u, current length is %lu",
508                                 PUD_RX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
509                 return true;
510         }
511
512         if (!isRxNonOlsrInterface(value)) {
513                 if (rxNonOlsrInterfaceCount >= PUD_RX_NON_OLSR_IF_MAX) {
514                         pudError(false, "Can't configure more than %u receive interfaces",
515                                         PUD_RX_NON_OLSR_IF_MAX);
516                         return true;
517                 }
518
519                 strcpy((char *) &rxNonOlsrInterfaceNames[rxNonOlsrInterfaceCount][0],
520                                 value);
521                 rxNonOlsrInterfaceCount++;
522         }
523
524         return false;
525 }
526
527 /*
528  * rxAllowedSourceIpAddress
529  */
530
531 /** The maximum number of RX allowed source IP addresses */
532 #define PUD_RX_ALLOWED_SOURCE_IP_MAX 32
533
534 /** Array with RX allowed source IP addresses */
535 static struct sockaddr rxAllowedSourceIpAddresses[PUD_RX_ALLOWED_SOURCE_IP_MAX];
536
537 /** The number of RX allowed source IP addresses in the array */
538 static unsigned int rxAllowedSourceIpAddressesCount = 0;
539
540 /**
541  Determine whether a give IP address is configured as an allowed source IP
542  address.
543
544  @param sender
545  The IP address to check
546
547  @return
548  - true when the given IP address is configured as an allowed source IP
549  address
550  - false otherwise
551  */
552 bool isRxAllowedSourceIpAddress(struct sockaddr * sender) {
553         void * addr;
554         unsigned int addrSize;
555         unsigned int i;
556
557         if (rxAllowedSourceIpAddressesCount == 0) {
558                 return true;
559         }
560
561         if (sender == NULL) {
562                 return false;
563         }
564
565         if (sender->sa_family == AF_INET) {
566                 addr = (void *) (&((struct sockaddr_in *) sender)->sin_addr);
567                 addrSize = sizeof(struct in_addr);
568         } else {
569                 addr = (void *) (&((struct sockaddr_in6 *) sender)->sin6_addr);
570                 addrSize = sizeof(struct in6_addr);
571         }
572
573         for (i = 0; i < rxAllowedSourceIpAddressesCount; i++) {
574                 if ((rxAllowedSourceIpAddresses[i].sa_family == sender->sa_family)
575                                 && (memcmp(&rxAllowedSourceIpAddresses[i].sa_data, addr,
576                                                 addrSize) == 0)) {
577                         return true;
578                 }
579         }
580
581         return false;
582 }
583
584 /**
585  Set the RX allowed source IP addresses.
586
587  @param value
588  The RX allowed source IP address (in string representation)
589  @param data
590  Unused
591  @param addon
592  Unused
593
594  @return
595  - true when an error is detected
596  - false otherwise
597  */
598 int addRxAllowedSourceIpAddress(const char *value, void *data __attribute__ ((unused)),
599                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
600         static const char * valueName = PUD_RX_ALLOWED_SOURCE_IP_NAME;
601         const char * valueInternal = value;
602         int conversion;
603         struct sockaddr addr;
604
605         assert (value != NULL);
606
607         memset(&addr, 0, sizeof(addr));
608
609         addr.sa_family = olsr_cnf->ip_version;
610         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, &addr.sa_data);
611         if (conversion != 1) {
612                 pudError((conversion == -1) ? true : false,
613                                 "Configured %s (%s) is not an IP address", valueName,
614                                 valueInternal);
615                 return true;
616         }
617
618         if ((rxAllowedSourceIpAddressesCount == 0) || !isRxAllowedSourceIpAddress(&addr)) {
619                 if (rxAllowedSourceIpAddressesCount >= PUD_RX_ALLOWED_SOURCE_IP_MAX) {
620                         pudError(false, "Can't configure more than %u allowed source IP"
621                                 " addresses", PUD_RX_ALLOWED_SOURCE_IP_MAX);
622                         return true;
623                 }
624
625                 memcpy(&rxAllowedSourceIpAddresses[rxAllowedSourceIpAddressesCount],
626                                 &addr, sizeof(addr));
627                 rxAllowedSourceIpAddressesCount++;
628         }
629
630         return false;
631 }
632
633 /*
634  * rxMcAddr
635  */
636
637 /** The rx multicast address */
638 static union olsr_sockaddr rxMcAddr;
639
640 /** True when the rx multicast address is set */
641 static bool rxMcAddrSet = false;
642
643 /**
644  @return
645  The receive multicast address (in network byte order). Sets both the address
646  and the port to their default values when the address was not yet set.
647  */
648 union olsr_sockaddr * getRxMcAddr(void) {
649         if (!rxMcAddrSet) {
650                 setRxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
651         }
652         return &rxMcAddr;
653 }
654
655 /**
656  Set the receive multicast address. Sets the address to its default value when
657  the value is NULL. Also sets the port to its default value when the address
658  was not yet set.
659
660  @param value
661  The receive multicast address (in string representation)
662  @param data
663  Unused
664  @param addon
665  Unused
666
667  @return
668  - true when an error is detected
669  - false otherwise
670  */
671 int setRxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
672         static const char * valueName = PUD_RX_MC_ADDR_NAME;
673         void * ipAddress;
674         in_port_t * port;
675         const char * valueInternal = value;
676         int conversion;
677
678         getOlsrSockAddrAndPort(olsr_cnf->ip_version, &rxMcAddr, &ipAddress, &port);
679         if (olsr_cnf->ip_version == AF_INET) {
680                 rxMcAddr.in4.sin_family = olsr_cnf->ip_version;
681                 if (valueInternal == NULL) {
682                         valueInternal = PUD_RX_MC_ADDR_4_DEFAULT;
683                 }
684         } else {
685                 rxMcAddr.in6.sin6_family = olsr_cnf->ip_version;
686                 if (valueInternal == NULL) {
687                         valueInternal = PUD_RX_MC_ADDR_6_DEFAULT;
688                 }
689         }
690
691         if (!rxMcAddrSet) {
692                 *port = htons(PUD_RX_MC_PORT_DEFAULT);
693         }
694
695         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
696         if (conversion != 1) {
697                 pudError((conversion == -1) ? true : false,
698                                 "Configured %s (%s) is not an IP address", valueName,
699                                 valueInternal);
700                 return true;
701         }
702
703         if (!isMulticast(olsr_cnf->ip_version, &rxMcAddr)) {
704                 pudError(false, "Configured %s (%s) is not a multicast address",
705                                 valueName, valueInternal);
706                 return true;
707         }
708
709         rxMcAddrSet = true;
710         return false;
711 }
712
713 /*
714  * rxMcPort
715  */
716
717 /**
718  @return
719  The receive multicast port (in network byte order)
720  */
721 unsigned short getRxMcPort(void) {
722         union olsr_sockaddr * addr = getRxMcAddr();
723         return *getOlsrSockaddrPort(olsr_cnf->ip_version, addr);
724 }
725
726 /**
727  Set the receive multicast port
728
729  @param value
730  The receive multicast port (a number in string representation)
731  @param data
732  Unused
733  @param addon
734  Unused
735
736  @return
737  - true when an error is detected
738  - false otherwise
739  */
740 int setRxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
741         static const char * valueName = PUD_RX_MC_PORT_NAME;
742         unsigned long long rxMcPortNew;
743         in_port_t * port;
744         union olsr_sockaddr * addr = getRxMcAddr();
745
746         assert (value != NULL);
747
748         if (!readULL(valueName, value, &rxMcPortNew)) {
749                 return true;
750         }
751
752         if ((rxMcPortNew < 1) || (rxMcPortNew > 65535)) {
753                 pudError(false, "Configured %s (%llu) is outside of"
754                         " valid range 1-65535", valueName, rxMcPortNew);
755                 return true;
756         }
757
758         port = getOlsrSockaddrPort(olsr_cnf->ip_version, addr);
759         *port = htons((uint16_t) rxMcPortNew);
760
761         return false;
762 }
763
764 /*
765  * txNonOlsrIf
766  */
767
768 /** The maximum number of rx non-olsr interfaces */
769 #define PUD_TX_NON_OLSR_IF_MAX 32
770
771 /** Array with tx non-olsr interface names */
772 static unsigned char txNonOlsrInterfaceNames[PUD_TX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
773
774 /** The number of tx interface names in the array */
775 static unsigned int txNonOlsrInterfaceCount = 0;
776
777 /**
778  Determine whether a give interface name is configured as a transmit non-OLSR
779  interface.
780
781  @param ifName
782  The interface to check
783
784  @return
785  - true when the given interface name is configured as a transmit non-OLSR
786  interface
787  - false otherwise
788  */
789 bool isTxNonOlsrInterface(const char *ifName) {
790         unsigned int i;
791
792         assert (ifName != NULL);
793
794         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
795                 if (strncmp((char *) &txNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
796                                 + 1) == 0) {
797                         return true;
798                 }
799         }
800
801         return false;
802 }
803
804 /**
805  Add a transmit non-OLSR interface
806
807  @param value
808  The name of the non-OLSR interface to add
809  @param data
810  Unused
811  @param addon
812  Unused
813
814  @return
815  - true when an error is detected
816  - false otherwise
817  */
818 int addTxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
819                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
820         unsigned long valueLength;
821
822         assert (value != NULL);
823
824         valueLength = strlen(value);
825         if (valueLength > IFNAMSIZ) {
826                 pudError(false, "Configured %s (%s) is too long,"
827                         " maximum length is %u, current length is %lu",
828                                 PUD_TX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
829                 return true;
830         }
831
832         if (!isTxNonOlsrInterface(value)) {
833                 if (txNonOlsrInterfaceCount >= PUD_TX_NON_OLSR_IF_MAX) {
834                         pudError(false, "Can not configure more than %u transmit"
835                                 " interfaces", PUD_TX_NON_OLSR_IF_MAX);
836                         return true;
837                 }
838
839                 strcpy((char *) &txNonOlsrInterfaceNames[txNonOlsrInterfaceCount][0],
840                                 value);
841                 txNonOlsrInterfaceCount++;
842         }
843
844         return false;
845 }
846
847 /*
848  * txMcAddr
849  */
850
851 /** The tx multicast address */
852 static union olsr_sockaddr txMcAddr;
853
854 /** True when the tx multicast address is set */
855 static bool txMcAddrSet = false;
856
857 /**
858  @return
859  The transmit multicast address (in network byte order). Sets both the address
860  and the port to their default values when the address was not yet set.
861  */
862 union olsr_sockaddr * getTxMcAddr(void) {
863         if (!txMcAddrSet) {
864                 setTxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
865         }
866         return &txMcAddr;
867 }
868
869 /**
870  Set the transmit multicast address. Sets the address to its default value when
871  the value is NULL. Also sets the port to its default value when the address
872  was not yet set.
873
874  @param value
875  The transmit multicast address (in string representation)
876  @param data
877  Unused
878  @param addon
879  Unused
880
881  @return
882  - true when an error is detected
883  - false otherwise
884  */
885 int setTxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
886         static const char * valueName = PUD_TX_MC_ADDR_NAME;
887         void * ipAddress;
888         in_port_t * port;
889         const char * valueInternal = value;
890         int conversion;
891
892         getOlsrSockAddrAndPort(olsr_cnf->ip_version, &txMcAddr, &ipAddress, &port);
893         if (olsr_cnf->ip_version == AF_INET) {
894                 txMcAddr.in4.sin_family = olsr_cnf->ip_version;
895                 if (valueInternal == NULL) {
896                         valueInternal = PUD_TX_MC_ADDR_4_DEFAULT;
897                 }
898         } else {
899                 txMcAddr.in6.sin6_family = olsr_cnf->ip_version;
900                 if (valueInternal == NULL) {
901                         valueInternal = PUD_TX_MC_ADDR_6_DEFAULT;
902                 }
903         }
904
905         if (!txMcAddrSet) {
906                 *port = htons(PUD_TX_MC_PORT_DEFAULT);
907         }
908
909         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
910         if (conversion != 1) {
911                 pudError((conversion == -1) ? true : false,
912                                 "Configured %s (%s) is not an IP address", valueName,
913                                 valueInternal);
914                 return true;
915         }
916
917         if (!isMulticast(olsr_cnf->ip_version, &txMcAddr)) {
918                 pudError(false, "Configured %s (%s) is not a multicast address",
919                                 valueName, valueInternal);
920                 return true;
921         }
922
923         txMcAddrSet = true;
924         return false;
925 }
926
927 /*
928  * txMcPort
929  */
930
931 /**
932  @return
933  The transmit multicast port (in network byte order)
934  */
935 unsigned short getTxMcPort(void) {
936         union olsr_sockaddr * addr = getTxMcAddr();
937         return *getOlsrSockaddrPort(olsr_cnf->ip_version, addr);
938 }
939
940 /**
941  Set the transmit multicast port
942
943  @param value
944  The transmit multicast port (a number in string representation)
945  @param data
946  Unused
947  @param addon
948  Unused
949
950  @return
951  - true when an error is detected
952  - false otherwise
953  */
954 int setTxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
955         static const char * valueName = PUD_TX_MC_PORT_NAME;
956         unsigned long long txMcPortNew;
957         in_port_t * port;
958         union olsr_sockaddr * addr = getTxMcAddr();
959
960         assert (value != NULL);
961
962         if (!readULL(valueName, value, &txMcPortNew)) {
963                 return true;
964         }
965
966         if ((txMcPortNew < 1) || (txMcPortNew > 65535)) {
967                 pudError(false, "Configured %s (%llu) is outside of"
968                         " valid range 1-65535", valueName, txMcPortNew);
969                 return true;
970         }
971
972         port = getOlsrSockaddrPort(olsr_cnf->ip_version, addr);
973         *port = htons((uint16_t) txMcPortNew);
974
975         return false;
976 }
977
978 /*
979  * txTtl
980  */
981
982 /** The tx TTL */
983 static unsigned char txTtl = PUD_TX_TTL_DEFAULT;
984
985 /**
986  @return
987  The transmit multicast IP packet time-to-live
988  */
989 unsigned char getTxTtl(void) {
990         return txTtl;
991 }
992
993 /**
994  Set the transmit multicast IP packet time-to-live
995
996  @param value
997  The transmit multicast IP packet time-to-live (a number in string representation)
998  @param data
999  Unused
1000  @param addon
1001  Unused
1002
1003  @return
1004  - true when an error is detected
1005  - false otherwise
1006  */
1007 int setTxTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1008         static const char * valueName = PUD_TX_TTL_NAME;
1009         unsigned long long txTtlNew;
1010
1011         assert (value != NULL);
1012
1013         if (!readULL(valueName, value, &txTtlNew)) {
1014                 return true;
1015         }
1016
1017         if ((txTtlNew < 1) || (txTtlNew > MAX_TTL)) {
1018                 pudError(false, "Configured %s (%llu) is outside of"
1019                         " valid range 1-%u", valueName, txTtlNew, MAX_TTL);
1020                 return true;
1021         }
1022
1023         txTtl = txTtlNew;
1024
1025         return false;
1026 }
1027
1028 /*
1029  * txNmeaMessagePrefix
1030  */
1031
1032 /** The exact length of the tx NMEA message prefix */
1033 #define PUD_TXNMEAMESSAGEPREFIXLENGTH 4
1034
1035 /** The tx NMEA message prefix buffer */
1036 static unsigned char txNmeaMessagePrefix[PUD_TXNMEAMESSAGEPREFIXLENGTH + 1];
1037
1038 /** True when the tx NMEA message prefix is set */
1039 static bool txNmeaMessagePrefixSet = false;
1040
1041 /**
1042  @return
1043  The transmit multicast NMEA message prefix
1044  */
1045 unsigned char * getTxNmeaMessagePrefix(void) {
1046         if (!txNmeaMessagePrefixSet) {
1047                 setTxNmeaMessagePrefix(PUD_TX_NMEAMESSAGEPREFIX_DEFAULT, NULL,
1048                                 (set_plugin_parameter_addon) {.pc = NULL});
1049         }
1050         return &txNmeaMessagePrefix[0];
1051 }
1052
1053 /**
1054  Set the transmit multicast NMEA message prefix
1055
1056  @param value
1057  The transmit multicast NMEA message prefix (in string representation)
1058  @param data
1059  Unused
1060  @param addon
1061  Unused
1062
1063  @return
1064  - true when an error is detected
1065  - false otherwise
1066  */
1067 int setTxNmeaMessagePrefix(const char *value, void *data __attribute__ ((unused)),
1068                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1069         static const char * valueName = PUD_TX_NMEAMESSAGEPREFIX_NAME;
1070         size_t valueLength;
1071         bool invalidChars;
1072         char report[256];
1073
1074         assert (value != NULL);
1075
1076         valueLength = strlen(value);
1077         if (valueLength != PUD_TXNMEAMESSAGEPREFIXLENGTH) {
1078                 pudError(false, "Configured %s (%s) must be %u exactly characters",
1079                                 valueName, value, PUD_TXNMEAMESSAGEPREFIXLENGTH);
1080                 return true;
1081         }
1082
1083         invalidChars = nmea_string_has_invalid_chars(value, valueName, &report[0],
1084                         sizeof(report));
1085         if (invalidChars) {
1086                 pudError(false, &report[0]);
1087                 return true;
1088         }
1089
1090         if ((strchr(value, ' ') != NULL) || (strchr(value, '\t') != NULL)) {
1091                 pudError(false, "Configured %s (%s) can not contain whitespace",
1092                                 valueName, value);
1093                 return true;
1094         }
1095
1096         strcpy((char *) &txNmeaMessagePrefix[0], value);
1097         txNmeaMessagePrefixSet = true;
1098         return false;
1099 }
1100
1101 /*
1102  * olsrTtl
1103  */
1104
1105 /** The OLSR TTL */
1106 static unsigned char olsrTtl = PUD_OLSR_TTL_DEFAULT;
1107
1108 /**
1109  @return
1110  The OLSR multicast IP packet time-to-live
1111  */
1112 unsigned char getOlsrTtl(void) {
1113         return olsrTtl;
1114 }
1115
1116 /**
1117  Set the OLSR multicast IP packet time-to-live
1118
1119  @param value
1120  The OLSR multicast IP packet time-to-live (a number in string representation)
1121  @param data
1122  Unused
1123  @param addon
1124  Unused
1125
1126  @return
1127  - true when an error is detected
1128  - false otherwise
1129  */
1130 int setOlsrTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1131         static const char * valueName = PUD_OLSR_TTL_NAME;
1132         unsigned long long olsrTtlNew;
1133
1134         assert (value != NULL);
1135
1136         if (!readULL(valueName, value, &olsrTtlNew)) {
1137                 return true;
1138         }
1139
1140         if ((olsrTtlNew < 1) || (olsrTtlNew > MAX_TTL)) {
1141                 pudError(false, "Configured %s (%llu) is outside of valid range 1-%u",
1142                                 valueName, olsrTtlNew, MAX_TTL);
1143                 return true;
1144         }
1145
1146         olsrTtl = olsrTtlNew;
1147
1148         return false;
1149 }
1150
1151 /*
1152  * updateIntervalStationary
1153  */
1154
1155 /** The stationary interval update plugin parameter (in seconds) */
1156 static unsigned long long updateIntervalStationary = PUD_UPDATE_INTERVAL_STATIONARY_DEFAULT;
1157
1158 /**
1159  @return
1160  The stationary interval update plugin parameter (in seconds)
1161  */
1162 unsigned long long getUpdateIntervalStationary(void) {
1163         return updateIntervalStationary;
1164 }
1165
1166 /**
1167  Set stationary interval update plugin parameter
1168
1169  @param value
1170  The stationary interval update plugin parameter (in seconds)
1171  @param data
1172  Unused
1173  @param addon
1174  Unused
1175
1176  @return
1177  - true when an error is detected
1178  - false otherwise
1179  */
1180 int setUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1181                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1182         static const char * valueName = PUD_UPDATE_INTERVAL_STATIONARY_NAME;
1183         unsigned long long updateIntervalStationaryNew;
1184
1185         assert (value != NULL);
1186
1187         if (!readULL(valueName, value, &updateIntervalStationaryNew)) {
1188                 return true;
1189         }
1190
1191         if (updateIntervalStationaryNew < 1) {
1192                 pudError(false, "Configured %s must be at least 1", valueName);
1193                 return true;
1194         }
1195
1196         updateIntervalStationary = updateIntervalStationaryNew;
1197
1198         return false;
1199 }
1200
1201 /*
1202  * updateIntervalMoving
1203  */
1204
1205 /** The moving interval update plugin parameter (in seconds) */
1206 static unsigned long long updateIntervalMoving = PUD_UPDATE_INTERVAL_MOVING_DEFAULT;
1207
1208 /**
1209  @return
1210  The moving interval update plugin parameter (in seconds)
1211  */
1212 unsigned long long getUpdateIntervalMoving(void) {
1213         return updateIntervalMoving;
1214 }
1215
1216 /**
1217  Set moving interval update plugin parameter
1218
1219  @param value
1220  The moving interval update plugin parameter (in seconds)
1221  @param data
1222  Unused
1223  @param addon
1224  Unused
1225
1226  @return
1227  - true when an error is detected
1228  - false otherwise
1229  */
1230 int setUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1231                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1232         static const char * valueName = PUD_UPDATE_INTERVAL_MOVING_NAME;
1233         unsigned long long updateIntervalMovingNew;
1234
1235         assert (value != NULL);
1236
1237         if (!readULL(valueName, value, &updateIntervalMovingNew)) {
1238                 return true;
1239         }
1240
1241         if (updateIntervalMovingNew < 1) {
1242                 pudError(false, "Configured %s must be at least 1", valueName);
1243                 return true;
1244         }
1245
1246         updateIntervalMoving = updateIntervalMovingNew;
1247
1248         return false;
1249 }
1250
1251 /*
1252  * movingSpeedThreshold
1253  */
1254
1255 /** The moving speed threshold plugin parameter (in kph) */
1256 static unsigned long long movingSpeedThreshold = PUD_MOVING_SPEED_THRESHOLD_DEFAULT;
1257
1258 /**
1259  @return
1260  The moving speed threshold plugin parameter (in kph)
1261  */
1262 unsigned long long getMovingSpeedThreshold(void) {
1263         return movingSpeedThreshold;
1264 }
1265
1266 /**
1267  Set moving speed threshold plugin parameter
1268
1269  @param value
1270  The moving speed threshold plugin parameter (in kph)
1271  @param data
1272  Unused
1273  @param addon
1274  Unused
1275
1276  @return
1277  - true when an error is detected
1278  - false otherwise
1279  */
1280 int setMovingSpeedThreshold(const char *value, void *data __attribute__ ((unused)),
1281                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1282         static const char * valueName = PUD_MOVING_SPEED_THRESHOLD_NAME;
1283         unsigned long long movingSpeedThresholdNew;
1284
1285         assert (value != NULL);
1286
1287         if (!readULL(valueName, value, &movingSpeedThresholdNew)) {
1288                 return true;
1289         }
1290
1291         movingSpeedThreshold = movingSpeedThresholdNew;
1292
1293         return false;
1294 }
1295
1296 /*
1297  * movingDistanceThreshold
1298  */
1299
1300 /** The moving distance threshold plugin parameter (in meters) */
1301 static unsigned long long movingDistanceThreshold = PUD_MOVING_DISTANCE_THRESHOLD_DEFAULT;
1302
1303 /**
1304  @return
1305  The moving distance threshold plugin parameter (in meters)
1306  */
1307 unsigned long long getMovingDistanceThreshold(void) {
1308         return movingDistanceThreshold;
1309 }
1310
1311 /**
1312  Set moving distance threshold plugin parameter
1313
1314  @param value
1315  The moving distance threshold plugin parameter (in meter)
1316  @param data
1317  Unused
1318  @param addon
1319  Unused
1320
1321  @return
1322  - true when an error is detected
1323  - false otherwise
1324  */
1325 int setMovingDistanceThreshold(const char *value, void *data __attribute__ ((unused)),
1326                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1327         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1328         unsigned long long movingDistanceThresholdNew;
1329
1330         assert (value != NULL);
1331
1332         if (!readULL(valueName, value, &movingDistanceThresholdNew)) {
1333                 return true;
1334         }
1335
1336         movingDistanceThreshold = movingDistanceThresholdNew;
1337
1338         return false;
1339 }
1340
1341 /*
1342  * dopMultiplier
1343  */
1344
1345 /* The DOP multiplier plugin parameter */
1346 static double dopMultiplier = PUD_DOP_MULTIPLIER_DEFAULT;
1347
1348 /**
1349  @return
1350  The DOP multiplier plugin parameter
1351  */
1352 double getDopMultiplier(void) {
1353         return dopMultiplier;
1354 }
1355
1356 /**
1357  Set DOP multiplier plugin parameter
1358
1359  @param value
1360  The DOP multiplier plugin parameter
1361  @param data
1362  Unused
1363  @param addon
1364  Unused
1365
1366  @return
1367  - true when an error is detected
1368  - false otherwise
1369  */
1370 int setDopMultiplier(const char *value, void *data __attribute__ ((unused)),
1371                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1372         static const char * valueName = PUD_DOP_MULTIPLIER_NAME;
1373         double dopMultiplierNew;
1374
1375         assert (value != NULL);
1376
1377         if (!readDouble(valueName, value, &dopMultiplierNew)) {
1378                 return true;
1379         }
1380
1381         dopMultiplier = dopMultiplierNew;
1382
1383         return false;
1384 }
1385
1386 /*
1387  * defaultHdop
1388  */
1389
1390 /** The default HDOP plugin parameter (in meters) */
1391 static unsigned long long defaultHdop = PUD_DEFAULT_HDOP_DEFAULT;
1392
1393 /**
1394  @return
1395  The default HDOP plugin parameter (in meters)
1396  */
1397 unsigned long long getDefaultHdop(void) {
1398         return defaultHdop;
1399 }
1400
1401 /**
1402  Set default HDOP plugin parameter
1403
1404  @param value
1405  The default HDOP plugin parameter (in meters)
1406  @param data
1407  Unused
1408  @param addon
1409  Unused
1410
1411  @return
1412  - true when an error is detected
1413  - false otherwise
1414  */
1415 int setDefaultHdop(const char *value, void *data __attribute__ ((unused)),
1416                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1417         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1418         unsigned long long defaultHdopNew;
1419
1420         assert (value != NULL);
1421
1422         if (!readULL(valueName, value, &defaultHdopNew)) {
1423                 return true;
1424         }
1425
1426         defaultHdop = defaultHdopNew;
1427
1428         return false;
1429 }
1430
1431 /*
1432  * defaultVdop
1433  */
1434
1435 /** The default VDOP plugin parameter (in meters) */
1436 static unsigned long long defaultVdop = PUD_DEFAULT_VDOP_DEFAULT;
1437
1438 /**
1439  @return
1440  The default VDOP plugin parameter (in meters)
1441  */
1442 unsigned long long getDefaultVdop(void) {
1443         return defaultVdop;
1444 }
1445
1446 /**
1447  Set default VDOP plugin parameter
1448
1449  @param value
1450  The default VDOP plugin parameter (in meters)
1451  @param data
1452  Unused
1453  @param addon
1454  Unused
1455
1456  @return
1457  - true when an error is detected
1458  - false otherwise
1459  */
1460 int setDefaultVdop(const char *value, void *data __attribute__ ((unused)),
1461                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1462         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1463         unsigned long long defaultVdopNew;
1464
1465         assert (value != NULL);
1466
1467         if (!readULL(valueName, value, &defaultVdopNew)) {
1468                 return true;
1469         }
1470
1471         defaultVdop = defaultVdopNew;
1472
1473         return false;
1474 }
1475
1476 /*
1477  * averageDepth
1478  */
1479
1480 /** The depth of the average list */
1481 static unsigned long long averageDepth = PUD_AVERAGE_DEPTH_DEFAULT;
1482
1483 /**
1484  @return
1485  The depth of the average list
1486  */
1487 unsigned long long getAverageDepth(void) {
1488         return averageDepth;
1489 }
1490
1491 /**
1492  Set average depth plugin parameter
1493
1494  @param value
1495  The average depth plugin parameter
1496  @param data
1497  Unused
1498  @param addon
1499  Unused
1500
1501  @return
1502  - true when an error is detected
1503  - false otherwise
1504  */
1505 int setAverageDepth(const char *value, void *data __attribute__ ((unused)),
1506                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1507         static const char * valueName = PUD_AVERAGE_DEPTH_NAME;
1508         unsigned long long averageDepthNew;
1509
1510         assert (value != NULL);
1511
1512         if (!readULL(valueName, value, &averageDepthNew)) {
1513                 return true;
1514         }
1515
1516         if (averageDepthNew < 1) {
1517                 pudError(false, "Configured %s must be at least 1", valueName);
1518                 return true;
1519         }
1520
1521         averageDepth = averageDepthNew;
1522
1523         return false;
1524 }
1525
1526 /*
1527  * hysteresisCountToStationary
1528  */
1529
1530 /** The hysteresis count for changing state from moving to stationary */
1531 static unsigned long long hysteresisCountToStationary = PUD_HYSTERESIS_COUNT_2STAT_DEFAULT;
1532
1533 /**
1534  @return
1535  The hysteresis count for changing state from moving to stationary
1536  */
1537 unsigned long long getHysteresisCountToStationary(void) {
1538         return hysteresisCountToStationary;
1539 }
1540
1541 /**
1542  Set hysteresis count plugin parameter
1543
1544  @param value
1545  The hysteresis count plugin parameter
1546  @param data
1547  Unused
1548  @param addon
1549  Unused
1550
1551  @return
1552  - true when an error is detected
1553  - false otherwise
1554  */
1555 int setHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1556                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1557         static const char * valueName = PUD_HYSTERESIS_COUNT_2STAT_NAME;
1558         unsigned long long hysteresisCountNew;
1559
1560         assert (value != NULL);
1561
1562         if (!readULL(valueName, value, &hysteresisCountNew)) {
1563                 return true;
1564         }
1565
1566         hysteresisCountToStationary = hysteresisCountNew;
1567
1568         return false;
1569 }
1570
1571 /*
1572  * hysteresisCountToMoving
1573  */
1574
1575 /** The hysteresis count for changing state from stationary to moving */
1576 static unsigned long long hysteresisCountToMoving = PUD_HYSTERESIS_COUNT_2MOV_DEFAULT;
1577
1578 /**
1579  @return
1580  The hysteresis count for changing state from stationary to moving
1581  */
1582 unsigned long long getHysteresisCountToMoving(void) {
1583         return hysteresisCountToMoving;
1584 }
1585
1586 /**
1587  Set hysteresis count plugin parameter
1588
1589  @param value
1590  The hysteresis count plugin parameter
1591  @param data
1592  Unused
1593  @param addon
1594  Unused
1595
1596  @return
1597  - true when an error is detected
1598  - false otherwise
1599  */
1600 int setHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1601                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1602         static const char * valueName = PUD_HYSTERESIS_COUNT_2MOV_NAME;
1603         unsigned long long hysteresisCountNew;
1604
1605         assert (value != NULL);
1606
1607         if (!readULL(valueName, value, &hysteresisCountNew)) {
1608                 return true;
1609         }
1610
1611         hysteresisCountToMoving = hysteresisCountNew;
1612
1613         return false;
1614 }
1615
1616 /*
1617  * useDeDup
1618  */
1619
1620 /* when true then duplicate message detection is performed */
1621 static bool useDeDup = PUD_USE_DEDUP_DEFAULT;
1622
1623 /**
1624  @return
1625  The duplicate message detection setting
1626  */
1627 bool getUseDeDup(void) {
1628         return useDeDup;
1629 }
1630
1631 /**
1632  Set duplicate message detection setting plugin parameter
1633
1634  @param value
1635  The duplicate message detection setting plugin parameter
1636  @param data
1637  Unused
1638  @param addon
1639  Unused
1640
1641  @return
1642  - true when an error is detected
1643  - false otherwise
1644  */
1645 int setUseDeDup(const char *value, void *data __attribute__ ((unused)),
1646                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1647         static const char * valueName = PUD_USE_DEDUP_NAME;
1648         unsigned long long useDeDupNew;
1649
1650         assert (value != NULL);
1651
1652         if (!readULL(valueName, value, &useDeDupNew)) {
1653                 return true;
1654         }
1655
1656         if ((useDeDupNew != 0) && (useDeDupNew != 1)) {
1657                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
1658                                 valueName);
1659                 return true;
1660         }
1661
1662         useDeDup = (useDeDupNew == 1);
1663
1664         return false;
1665 }
1666
1667 /*
1668  * deDupDepth
1669  */
1670
1671 /** The hysteresis count for changing state from stationary to moving */
1672 static unsigned long long deDupDepth = PUD_DEDUP_DEPTH_DEFAULT;
1673
1674 /**
1675  @return
1676  The hysteresis count for changing state from stationary to moving
1677  */
1678 unsigned long long getDeDupDepth(void) {
1679         return deDupDepth;
1680 }
1681
1682 /**
1683  Set de-duplication depth plugin parameter
1684
1685  @param value
1686  The de-duplication depth plugin parameter
1687  @param data
1688  Unused
1689  @param addon
1690  Unused
1691
1692  @return
1693  - true when an error is detected
1694  - false otherwise
1695  */
1696 int setDeDupDepth(const char *value, void *data __attribute__ ((unused)),
1697                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1698         static const char * valueName = PUD_DEDUP_DEPTH_NAME;
1699         unsigned long long deDupDepthNew;
1700
1701         assert (value != NULL);
1702
1703         if (!readULL(valueName, value, &deDupDepthNew)) {
1704                 return true;
1705         }
1706
1707         deDupDepth = deDupDepthNew;
1708
1709         return false;
1710 }
1711
1712 /*
1713  * useLoopback
1714  */
1715
1716 /* when true then loopback is performed */
1717 static bool useLoopback = PUD_USE_LOOPBACK_DEFAULT;
1718
1719 /**
1720  @return
1721  The loopback usage setting
1722  */
1723 bool getUseLoopback(void) {
1724         return useLoopback;
1725 }
1726
1727 /**
1728  Set loopback usage plugin parameter
1729
1730  @param value
1731  The loopback usage plugin parameter
1732  @param data
1733  Unused
1734  @param addon
1735  Unused
1736
1737  @return
1738  - true when an error is detected
1739  - false otherwise
1740  */
1741 int setUseLoopback(const char *value, void *data __attribute__ ((unused)),
1742                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1743         static const char * valueName = PUD_USE_LOOPBACK_NAME;
1744         unsigned long long useLoopbackNew;
1745
1746         assert (value != NULL);
1747
1748         if (!readULL(valueName, value, &useLoopbackNew)) {
1749                 return true;
1750         }
1751
1752         if ((useLoopbackNew != 0) && (useLoopbackNew != 1)) {
1753                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
1754                                 valueName);
1755                 return true;
1756         }
1757
1758         useLoopback = (useLoopbackNew == 1);
1759
1760         return false;
1761 }
1762
1763 /*
1764  * Check Functions
1765  */
1766
1767 /**
1768  Check the configuration for consistency and validity.
1769
1770  @return
1771  - true when the configuration is consistent and valid
1772  - false otherwise
1773  */
1774 unsigned int checkConfig(void) {
1775         int retval = true;
1776
1777         if (rxNonOlsrInterfaceCount == 0) {
1778                 pudError(false, "No receive non-OLSR interfaces configured");
1779                 retval = false;
1780         }
1781
1782         if (txNonOlsrInterfaceCount == 0) {
1783                 pudError(false, "No transmit non-OLSR interfaces configured");
1784                 retval = false;
1785         }
1786
1787         if (!nodeIdSet) {
1788                 if (nodeIdType == PUD_NODEIDTYPE_DNS) {
1789                         char name[PUD_NODEIDMAXLENGTH + 1];
1790
1791                         errno = 0;
1792                         if (gethostname(&name[0], sizeof(name)) < 0) {
1793                                 pudError(true, "Could not get the host name");
1794                                 retval = false;
1795                         } else {
1796                                 setNodeId(&name[0], NULL,
1797                                                 (set_plugin_parameter_addon) {.pc = NULL});
1798                         }
1799                 } else if ((nodeIdType != PUD_NODEIDTYPE_MAC) && (nodeIdType
1800                                 != PUD_NODEIDTYPE_IPV4) && (nodeIdType != PUD_NODEIDTYPE_IPV6)) {
1801                         pudError(false, "No node ID set while one is required for"
1802                                 " node type %u", nodeIdType);
1803                         retval = false;
1804                 }
1805         }
1806
1807         if (!setupNodeIdNumberForOlsrCacheAndValidate(nodeIdType)) {
1808                 retval = false;
1809         }
1810
1811         if (updateIntervalMoving > updateIntervalStationary) {
1812                 pudError(false,"The update interval for moving situations must not be"
1813                 " larger than that for stationary situations");
1814                 retval = false;
1815         }
1816
1817         return retval;
1818 }
1819
1820 /**
1821  Check the configuration for consistency and validity after everything has been
1822  setup.
1823
1824  @return
1825  - true when the configuration is consistent and valid
1826  - false otherwise
1827  */
1828 unsigned int checkRunSetup(void) {
1829         int retval = true;
1830         unsigned int i;
1831
1832         /* any receive interface name that is configured but is not the name of an
1833          * actual receive interface is not a valid interface name */
1834         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
1835                 unsigned char * nonOlsrInterfaceName = &rxNonOlsrInterfaceNames[i][0];
1836
1837                 TRxTxNetworkInterface * interfaceObject = getRxNetworkInterfaces();
1838                 bool found = false;
1839                 while (interfaceObject != NULL) {
1840                         if (strncmp((char *) nonOlsrInterfaceName,
1841                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
1842                                 found = true;
1843                                 break;
1844                         }
1845                         interfaceObject = interfaceObject->next;
1846                 }
1847                 if (!found) {
1848                         pudError(false, "Configured receive non-OLSR interface %s is not"
1849                                 " a known interface name", nonOlsrInterfaceName);
1850                         retval = false;
1851                 }
1852         }
1853
1854         /* any transmit interface name that is configured but is not the name of an
1855          * actual transmit interface is not a valid interface name */
1856         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
1857                 unsigned char * nonOlsrInterfaceName = &txNonOlsrInterfaceNames[i][0];
1858
1859                 TRxTxNetworkInterface * interfaceObject = getTxNetworkInterfaces();
1860                 bool found = false;
1861                 while (interfaceObject != NULL) {
1862                         if (strncmp((char *) nonOlsrInterfaceName,
1863                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
1864                                 found = true;
1865                                 break;
1866                         }
1867                         interfaceObject = interfaceObject->next;
1868                 }
1869                 if (!found) {
1870                         pudError(false, "Configured transmit non-OLSR interface %s is not"
1871                                 " a known interface name", nonOlsrInterfaceName);
1872                         retval = false;
1873                 }
1874         }
1875
1876         return retval;
1877 }