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