pud: update nmealib to 2.0.0
[olsrd.git] / lib / pud / src / configuration.c
1 #include "configuration.h"
2
3 /* Plugin includes */
4 #include "pud.h"
5 #include "networkInterfaces.h"
6 #include "netTools.h"
7 #include "posFile.h"
8 #include "configTools.h"
9
10 /* OLSR includes */
11 #include <olsr_protocol.h>
12 #include <olsr.h>
13
14 /* System includes */
15 #include <unistd.h>
16 #include <nmea/parse.h>
17 #include <OlsrdPudWireFormat/nodeIdConversion.h>
18 #include <limits.h>
19
20 /* forward declarations */
21 static bool setupNodeIdBinaryAndValidate(NodeIdType nodeIdTypeNumber);
22
23 /*
24  * Note:
25  * Setters must return true when an error is detected, false otherwise
26  */
27
28 /*
29  * nodeIdType
30  */
31
32 /** The nodeIdType */
33 static NodeIdType nodeIdType = PUD_NODE_ID_TYPE_DEFAULT;
34
35 /**
36  @return
37  The node ID type
38  */
39 NodeIdType getNodeIdTypeNumber(void) {
40         return nodeIdType;
41 }
42
43 static int setNodeIdType(const char *value, const char * valueName) {
44         unsigned long long nodeIdTypeNew;
45
46         if (!readULL(valueName, value, &nodeIdTypeNew, 10)) {
47                 return true;
48         }
49
50         if (!isValidNodeIdType(nodeIdTypeNew)) {
51                 pudError(false, "Value in parameter %s (%llu) is reserved", valueName,
52                                 nodeIdTypeNew);
53                 return true;
54         }
55
56         nodeIdType = nodeIdTypeNew;
57
58         return false;
59 }
60
61 /*
62  * nodeId
63  */
64
65 /** The nodeId buffer */
66 static unsigned char nodeId[PUD_TX_NODEID_BUFFERSIZE];
67
68 /** The length of the string in the nodeId buffer */
69 static size_t nodeIdLength = 0;
70
71 /** True when the nodeId is set */
72 static bool nodeIdSet = false;
73
74 /** The nodeId as a binary representation, with status */
75 static nodeIdBinaryType nodeIdBinary;
76
77 /**
78  Get the nodeId and its length
79
80  @param length
81  a pointer to the variable in which to store the nodeId length (allowed to be
82  NULL, in which case the length is not stored)
83
84  @return
85  The node ID
86  */
87 unsigned char * getNodeId(size_t *length) {
88         if (!nodeIdSet) {
89                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
90         }
91
92         if (length != NULL) {
93                 *length = nodeIdLength;
94         }
95
96         return &nodeId[0];
97 }
98
99 /**
100  Get the nodeIdBinary
101
102  @return
103  The node ID in binary representation
104  */
105 nodeIdBinaryType * getNodeIdBinary(void) {
106         if (!nodeIdBinary.set) {
107                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
108         }
109
110         return &nodeIdBinary;
111 }
112
113 int setNodeId(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
114         size_t valueLength;
115         char * number;
116         char * identification;
117
118         assert (value != NULL);
119
120   nodeId[0] = '\0';
121   nodeIdLength = 0;
122   nodeIdSet = false;
123   nodeIdBinary.set = false;
124
125         valueLength = strlen(value);
126   number = olsr_malloc(valueLength + 1, "setNodeId");
127   strcpy(number, value);
128
129   /* split "number,identification" */
130   identification = strchr(number, ',');
131   if (identification) {
132     *identification = '\0';
133     identification++;
134   }
135
136   /* parse number into nodeIdType (if present) */
137   valueLength = strlen(number);
138   if (valueLength && setNodeIdType(number, PUD_NODE_ID_NAME)) {
139     free(number);
140     return true;
141   }
142
143   /* copy identification into nodeId (if present) */
144   if (identification) {
145     valueLength = strlen(identification);
146     if (valueLength > (PUD_TX_NODEID_BUFFERSIZE - 1)) {
147       pudError(false, "Value in parameter %s is too long, maximum length is"
148         " %u, current length is %lu", PUD_NODE_ID_NAME, (PUD_TX_NODEID_BUFFERSIZE - 1),
149           (unsigned long) valueLength);
150       free(number);
151       return true;
152     }
153
154     if (valueLength) {
155       strcpy((char *) &nodeId[0], identification);
156       nodeIdLength = valueLength;
157       nodeIdSet = true;
158     }
159   }
160
161   free(number);
162
163   /* fill in automatic values */
164   if (!nodeIdSet) {
165     if (nodeIdType == PUD_NODEIDTYPE_DNS) {
166       memset(nodeId, 0, sizeof(nodeId));
167       errno = 0;
168       if (gethostname((char *)&nodeId[0], sizeof(nodeId) - 1) < 0) {
169         pudError(true, "Could not get the host name");
170         return true;
171       }
172
173       nodeIdLength = strlen((char *)nodeId);
174       nodeIdSet = true;
175     } else if ((nodeIdType != PUD_NODEIDTYPE_MAC) && (nodeIdType != PUD_NODEIDTYPE_IPV4)
176         && (nodeIdType != PUD_NODEIDTYPE_IPV6)) {
177       pudError(false, "No node ID set while one is required for nodeId type %u", nodeIdType);
178       return true;
179     }
180   }
181
182   if (!setupNodeIdBinaryAndValidate(nodeIdType)) {
183     pudError(false, "nodeId (type %u) is incorrectly configured", nodeIdType);
184     return true;
185   }
186
187   return false;
188 }
189
190 /*
191  * nodeId Validation
192  */
193
194 /**
195  Validate whether the configured nodeId is valid w.r.t. the configured
196  nodeIdType, for types that are MAC addresses
197
198  @return
199  - true when ok
200  - false on failure
201  */
202 static bool intSetupNodeIdBinaryMAC(void) {
203         unsigned char * mac = getMainIpMacAddress();
204         if (!mac) {
205                 return false;
206         }
207
208         return setupNodeIdBinaryMAC(&nodeIdBinary, mac);
209 }
210
211 /**
212  Validate whether the configured nodeId is valid w.r.t. the configured
213  nodeIdType, for types that fit in an unsigned long long (64 bits)
214
215  @param min
216  the minimum value
217  @param max
218  the maximum value
219  @param bytes
220  the number of bytes in the buffer
221
222  @return
223  - true when ok
224  - false on failure
225  */
226 static bool intSetupNodeIdBinaryLongLong(unsigned long long min,
227     unsigned long long max, unsigned int bytes) {
228   unsigned long long longValue = 0;
229   if (!readULL(PUD_NODE_ID_NAME, (char *) getNodeId(NULL), &longValue, 10)) {
230     return false;
231   }
232
233   if ((longValue < min) || (longValue > max)) {
234     pudError(false, "%s value %llu is out of range [%llu,%llu]",
235         PUD_NODE_ID_NAME, longValue, min, max);
236     return false;
237   }
238
239   return setupNodeIdBinaryLongLong(&nodeIdBinary, longValue, bytes);
240 }
241
242 /**
243  Validate whether the configured nodeId is valid w.r.t. the configured
244  nodeIdType, for types that fit in a double unsigned long long (128 bits) with
245  a certain split that defined by chars1
246
247  @param chars1
248  the number of characters of the first part
249  @param min1
250  the minimum value of the first part
251  @param max1
252  the maximum value of the first part
253  @param bytes1
254  the number of bytes of the first part in the buffer
255  @param min2
256  the minimum value of the second part
257  @param max2
258  the maximum value of the second part
259  @param bytes2
260  the number of bytes of the second part in the buffer
261  @param base
262  the base of the number conversion: 10 for decimal, 16 for hexadecimal
263
264  @return
265  - true when ok
266  - false on failure
267  */
268 static bool intSetupNodeIdBinaryDoubleLongLong(
269     unsigned char * dst,
270     unsigned int chars1,
271     unsigned long long min1, unsigned long long max1,
272     unsigned int bytes1,
273                 unsigned long long min2, unsigned long long max2,
274                 unsigned int bytes2,
275                 int base) {
276         unsigned long long longValue1 = 0;
277         unsigned long long longValue2 = 0;
278
279         unsigned char * node_id = getNodeId(NULL);
280         size_t node_id_len = strlen((char *)node_id);
281
282         assert(chars1 > 0);
283         assert(bytes1 > 0);
284         assert(bytes2 > 0);
285
286   /* part 1 */
287         if (node_id_len > 0) {
288     unsigned char first[chars1 + 1];
289     int cpylen = node_id_len < chars1 ? node_id_len : chars1;
290
291     memcpy(first, node_id, cpylen);
292     first[cpylen] = '\0';
293
294     if (!readULL(PUD_NODE_ID_NAME, (char *)first, &longValue1, base)) {
295       return false;
296     }
297
298     if ((longValue1 < min1) || (longValue1 > max1)) {
299       pudError(false, "First %u character(s) of %s value %llu are out of range [%llu,%llu]",
300           cpylen, PUD_NODE_ID_NAME, longValue1, min1, max1);
301       return false;
302     }
303         }
304
305   /* part 2 */
306         if (node_id_len > chars1) {
307     if (!readULL(PUD_NODE_ID_NAME, (char *)&node_id[chars1], &longValue2, base)) {
308       return false;
309     }
310
311     if ((longValue2 < min2) || (longValue2 > max2)) {
312       pudError(false, "Last %u character(s) of %s value %llu are out of range [%llu,%llu]",
313           (unsigned int)(node_id_len - chars1), PUD_NODE_ID_NAME, longValue2, min2, max2);
314       return false;
315     }
316   } else {
317     /* longvalue1 is the only value, so it is the least significant value:
318      * exchange the 2 values */
319     unsigned long long tmp = longValue1;
320     longValue1 = longValue2;
321     longValue2 = tmp;
322   }
323
324         return setupNodeIdBinaryDoubleLongLong(&nodeIdBinary,
325             longValue1, &dst[0], bytes1,
326             longValue2, &dst[bytes1], bytes2);
327 }
328
329 /**
330  Validate whether the configured nodeId is valid w.r.t. the configured
331  nodeIdType, for types that are strings
332
333  @return
334  - true when ok
335  - false on failure
336  */
337 static bool intSetupNodeIdBinaryString(void) {
338   const char * invalidCharName;
339   size_t nodeidlength;
340   char * nodeid = (char *) getNodeId(&nodeidlength);
341
342   invalidCharName = nmea_parse_sentence_has_invalid_chars(nodeid, nodeidlength);
343   if (invalidCharName) {
344     char report[256];
345     snprintf(report, sizeof(report), "Configured %s (%s),"
346         " contains invalid NMEA characters (%s)", PUD_NODE_ID_NAME, nodeid, invalidCharName);
347     pudError(false, "%s", &report[0]);
348     return false;
349   }
350
351   if (nodeidlength > (PUD_TX_NODEID_BUFFERSIZE - 1)) {
352     pudError(false, "Length of parameter %s (%s) is too great", PUD_NODE_ID_NAME, &nodeid[0]);
353     return false;
354   }
355
356   return setupNodeIdBinaryString(&nodeIdBinary, nodeid, nodeidlength);
357 }
358
359 /**
360  Validate whether the configured nodeId is valid w.r.t. the configured
361  nodeIdType, for types that are IP addresses
362
363  @return
364  - true when ok
365  - false on failure
366  */
367 static bool intSetupNodeIdBinaryIp(void) {
368         void * src;
369         size_t length;
370         if (olsr_cnf->ip_version == AF_INET) {
371                 src = &olsr_cnf->main_addr.v4;
372                 length = sizeof(struct in_addr);
373         } else {
374                 src = &olsr_cnf->main_addr.v6;
375                 length = sizeof(struct in6_addr);
376         }
377
378         return setupNodeIdBinaryIp(&nodeIdBinary, src, length);
379 }
380
381 /**
382  Validate whether the configured nodeId is valid w.r.t. the configured
383  nodeIdType and setup the binary value
384
385  @return
386  - true when ok
387  - false on failure
388  */
389 static bool setupNodeIdBinaryAndValidate(NodeIdType nodeIdTypeNumber) {
390         switch (nodeIdTypeNumber) {
391                 case PUD_NODEIDTYPE_MAC: /* hardware address */
392                         return intSetupNodeIdBinaryMAC();
393
394                 case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
395                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_MSISDN_MIN,
396                                 PUD_NODEIDTYPE_MSISDN_MAX, PUD_NODEIDTYPE_MSISDN_BYTES);
397
398                 case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
399                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_TETRA_MIN,
400                                 PUD_NODEIDTYPE_TETRA_MAX, PUD_NODEIDTYPE_TETRA_BYTES);
401
402                 case PUD_NODEIDTYPE_DNS: /* DNS name */
403                         return intSetupNodeIdBinaryString();
404
405                 case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
406                 case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
407                         return intSetupNodeIdBinaryIp();
408
409                 case PUD_NODEIDTYPE_UUID: /* a UUID number */
410                         return intSetupNodeIdBinaryDoubleLongLong(
411                             &nodeIdBinary.buffer.uuid[0],
412                             PUD_NODEIDTYPE_UUID_CHARS1,
413                             PUD_NODEIDTYPE_UUID_MIN1, PUD_NODEIDTYPE_UUID_MAX1,
414                             PUD_NODEIDTYPE_UUID_BYTES1,
415                             PUD_NODEIDTYPE_UUID_MIN2, PUD_NODEIDTYPE_UUID_MAX2,
416                             PUD_NODEIDTYPE_UUID_BYTES - PUD_NODEIDTYPE_UUID_BYTES1,
417                             16);
418
419                 case PUD_NODEIDTYPE_MMSI: /* an AIS MMSI number */
420                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_MMSI_MIN,
421                                 PUD_NODEIDTYPE_MMSI_MAX, PUD_NODEIDTYPE_MMSI_BYTES);
422
423                 case PUD_NODEIDTYPE_URN: /* a URN number */
424                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_URN_MIN,
425                                 PUD_NODEIDTYPE_URN_MAX, PUD_NODEIDTYPE_URN_BYTES);
426
427                 case PUD_NODEIDTYPE_MIP: /* a MIP OID number */
428                         return intSetupNodeIdBinaryDoubleLongLong(
429                             &nodeIdBinary.buffer.mip[0],
430                             PUD_NODEIDTYPE_MIP_CHARS1,
431                             PUD_NODEIDTYPE_MIP_MIN1, PUD_NODEIDTYPE_MIP_MAX1,
432                             PUD_NODEIDTYPE_MIP_BYTES1,
433                             PUD_NODEIDTYPE_MIP_MIN2, PUD_NODEIDTYPE_MIP_MAX2,
434                             PUD_NODEIDTYPE_MIP_BYTES - PUD_NODEIDTYPE_MIP_BYTES1,
435                             10);
436
437                 case PUD_NODEIDTYPE_192:
438                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_192_MIN,
439                                 PUD_NODEIDTYPE_192_MAX, PUD_NODEIDTYPE_192_BYTES);
440
441                 case PUD_NODEIDTYPE_193:
442                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_193_MIN,
443                                 PUD_NODEIDTYPE_193_MAX, PUD_NODEIDTYPE_193_BYTES);
444
445                 case PUD_NODEIDTYPE_194:
446                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_194_MIN,
447                                 PUD_NODEIDTYPE_194_MAX, PUD_NODEIDTYPE_194_BYTES);
448
449                 default:
450                   pudError(false, "nodeId type %u is not supported", nodeIdTypeNumber);
451                   return false;
452         }
453
454         return false;
455 }
456
457 /*
458  * rxNonOlsrIf
459  */
460
461 /** The maximum number of RX non-OLSR interfaces */
462 #define PUD_RX_NON_OLSR_IF_MAX 32
463
464 /** Array with RX non-OLSR interface names */
465 static unsigned char rxNonOlsrInterfaceNames[PUD_RX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
466
467 /** The number of RX non-OLSR interface names in the array */
468 static unsigned int rxNonOlsrInterfaceCount = 0;
469
470 /**
471  Determine whether a give interface name is configured as a receive non-OLSR
472  interface.
473
474  @param ifName
475  The interface name to check
476
477  @return
478  - true when the given interface name is configured as a receive non-OLSR
479  interface
480  - false otherwise
481  */
482 bool isRxNonOlsrInterface(const char *ifName) {
483         unsigned int i;
484
485         assert (ifName != NULL);
486
487         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
488                 if (strncmp((char *) &rxNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
489                                 + 1) == 0) {
490                         return true;
491                 }
492         }
493
494         return false;
495 }
496
497 int addRxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
498                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
499         size_t valueLength;
500
501         if (rxNonOlsrInterfaceCount >= PUD_RX_NON_OLSR_IF_MAX) {
502                 pudError(false, "Can't configure more than %u receive interfaces",
503                                 PUD_RX_NON_OLSR_IF_MAX);
504                 return true;
505         }
506
507         assert (value != NULL);
508
509         valueLength = strlen(value);
510         if (valueLength > IFNAMSIZ) {
511                 pudError(false, "Value of parameter %s (%s) is too long,"
512                         " maximum length is %u, current length is %lu",
513                                 PUD_RX_NON_OLSR_IF_NAME, value, IFNAMSIZ, (long unsigned int)valueLength);
514                 return true;
515         }
516
517         if (!isRxNonOlsrInterface(value)) {
518                 strcpy((char *) &rxNonOlsrInterfaceNames[rxNonOlsrInterfaceCount][0],
519                                 value);
520                 rxNonOlsrInterfaceCount++;
521         }
522
523         return false;
524 }
525
526 /**
527  * @return the number of configured non-olsr receive interfaces
528  */
529 unsigned int getRxNonOlsrInterfaceCount(void) {
530         return rxNonOlsrInterfaceCount;
531 }
532
533 /**
534  * @param idx the index of the configured non-olsr receive interface
535  * @return the index-th interface name
536  */
537 unsigned char * getRxNonOlsrInterfaceName(unsigned int idx) {
538         return &rxNonOlsrInterfaceNames[idx][0];
539 }
540
541 /*
542  * rxAllowedSourceIpAddress
543  */
544
545 /** The maximum number of RX allowed source IP addresses */
546 #define PUD_RX_ALLOWED_SOURCE_IP_MAX 32
547
548 /** Array with RX allowed source IP addresses */
549 static union olsr_sockaddr rxAllowedSourceIpAddresses[PUD_RX_ALLOWED_SOURCE_IP_MAX];
550
551 /** The number of RX allowed source IP addresses in the array */
552 static unsigned int rxAllowedSourceIpAddressesCount = 0;
553
554 /**
555  Determine whether a give IP address is configured as an allowed source IP
556  address.
557
558  @param sender
559  The IP address to check
560
561  @return
562  - true when the given IP address is configured as an allowed source IP
563  address
564  - false otherwise
565  */
566 bool isRxAllowedSourceIpAddress(union olsr_sockaddr * sender) {
567         unsigned int i;
568
569         if (rxAllowedSourceIpAddressesCount == 0) {
570                 return true;
571         }
572
573         if (sender == NULL) {
574                 return false;
575         }
576
577         for (i = 0; i < rxAllowedSourceIpAddressesCount; i++) {
578                 if (sender->in.sa_family != rxAllowedSourceIpAddresses[i].in.sa_family) {
579                         continue;
580                 }
581
582                 if (sender->in.sa_family == AF_INET) {
583                         if (memcmp(&rxAllowedSourceIpAddresses[i].in4.sin_addr, &sender->in4.sin_addr, sizeof(struct in_addr))
584                                         == 0) {
585                                 return true;
586                         }
587                 } else {
588                         if (memcmp(&rxAllowedSourceIpAddresses[i].in6.sin6_addr, &sender->in6.sin6_addr, sizeof(struct in6_addr))
589                                         == 0) {
590                                 return true;
591                         }
592                 }
593         }
594
595         return false;
596 }
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         union olsr_sockaddr addr;
602         bool addrSet = false;
603
604         if (rxAllowedSourceIpAddressesCount >= PUD_RX_ALLOWED_SOURCE_IP_MAX) {
605                 pudError(false, "Can't configure more than %u allowed source IP"
606                         " addresses", PUD_RX_ALLOWED_SOURCE_IP_MAX);
607                 return true;
608         }
609
610         if (!readIPAddress(valueName, value, 0, &addr, &addrSet)) {
611                 return true;
612         }
613
614         if (!isRxAllowedSourceIpAddress(&addr)) {
615                 rxAllowedSourceIpAddresses[rxAllowedSourceIpAddressesCount] = addr;
616                 rxAllowedSourceIpAddressesCount++;
617         }
618
619         return false;
620 }
621
622 /*
623  * rxMcAddr + rxMcPort
624  */
625
626 /** The rx multicast address */
627 static union olsr_sockaddr rxMcAddr;
628
629 /** True when the rx multicast address is set */
630 static bool rxMcAddrSet = false;
631
632 /**
633  @return
634  The receive multicast address (in network byte order). Sets both the address
635  and the port to their default values when the address was not yet set.
636  */
637 union olsr_sockaddr * getRxMcAddr(void) {
638         if (!rxMcAddrSet) {
639                 setRxMcAddr((olsr_cnf->ip_version == AF_INET) ? PUD_RX_MC_ADDR_4_DEFAULT : PUD_RX_MC_ADDR_6_DEFAULT,
640                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
641         }
642         return &rxMcAddr;
643 }
644
645 int setRxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
646         static const char * valueName = PUD_RX_MC_ADDR_NAME;
647
648         if (!readIPAddress(valueName, value, PUD_RX_MC_PORT_DEFAULT, &rxMcAddr, &rxMcAddrSet)) {
649                         return true;
650         }
651
652         if (!isMulticast(&rxMcAddr)) {
653                 pudError(false, "Value of parameter %s (%s) is not a multicast address",
654                                 valueName, value);
655                 return true;
656         }
657
658         return false;
659 }
660
661 /**
662  @return
663  The receive multicast port (in network byte order)
664  */
665 unsigned short getRxMcPort(void) {
666         return getOlsrSockaddrPort(getRxMcAddr(), PUD_RX_MC_PORT_DEFAULT);
667 }
668
669 int setRxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
670         static const char * valueName = PUD_RX_MC_PORT_NAME;
671         unsigned short rxMcPortNew;
672
673         if (!readUS(valueName, value, &rxMcPortNew)) {
674                 return true;
675         }
676
677         if (rxMcPortNew < 1) {
678                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, rxMcPortNew);
679                 return true;
680         }
681
682         setOlsrSockaddrPort(getRxMcAddr(), htons((in_port_t) rxMcPortNew));
683
684         return false;
685 }
686
687 /*
688  * positionFile
689  */
690
691 /** The positionFile buffer */
692 static char positionFile[PATH_MAX + 1];
693
694 /** True when the positionFile is set */
695 static bool positionFileSet = false;
696
697 /**
698  @return
699  The positionFile (NULL when not set)
700  */
701 char * getPositionFile(void) {
702         if (!positionFileSet) {
703                 return NULL;
704         }
705
706         return &positionFile[0];
707 }
708
709 int setPositionFile(const char *value, void *data __attribute__ ((unused)),
710                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
711         size_t valueLength;
712
713         assert(value != NULL);
714
715         valueLength = strlen(value);
716         if (valueLength > PATH_MAX) {
717                 pudError(false, "Value of parameter %s is too long, maximum length is"
718                                 " %u, current length is %lu", PUD_POSFILE_NAME, PATH_MAX, (unsigned long) valueLength);
719                 return true;
720         }
721
722         strcpy((char *) &positionFile[0], value);
723         positionFileSet = true;
724
725         return false;
726 }
727
728 /*
729  * positionFilePeriod
730  */
731
732 /** The positionFilePeriod value (milliseconds) */
733 unsigned long long positionFilePeriod = PUD_POSFILEPERIOD_DEFAULT;
734
735 /**
736  @return
737  The positionFilePeriod (in milliseconds)
738  */
739 unsigned long long getPositionFilePeriod(void) {
740         return positionFilePeriod;
741 }
742
743 /**
744  Set the positionFilePeriod
745
746  @param value
747  The positionFilePeriod (a number in string representation)
748  @param data
749  Unused
750  @param addon
751  Unused
752
753  @return
754  - true when an error is detected
755  - false otherwise
756  */
757 int setPositionFilePeriod(const char *value, void *data __attribute__ ((unused)),
758                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
759         static const char * valueName = PUD_POSFILEPERIOD_NAME;
760         unsigned long long positionFilePeriodNew;
761
762         assert(value != NULL);
763
764         if (!readULL(valueName, value, &positionFilePeriodNew, 10)) {
765                 return true;
766         }
767
768         if ((positionFilePeriodNew != 0)
769                         && ((positionFilePeriodNew < PUD_POSFILEPERIOD_MIN) || (positionFilePeriodNew > PUD_POSFILEPERIOD_MAX))) {
770                 pudError(false, "Configured %s (%llu) is outside of"
771                                 " valid range %llu-%llu", valueName, positionFilePeriodNew, PUD_POSFILEPERIOD_MIN, PUD_POSFILEPERIOD_MAX);
772                 return true;
773         }
774
775         positionFilePeriod = positionFilePeriodNew;
776
777         return false;
778 }
779
780 /*
781  * txNonOlsrIf
782  */
783
784 /** The maximum number of tx non-olsr interfaces */
785 #define PUD_TX_NON_OLSR_IF_MAX 32
786
787 /** Array with tx non-olsr interface names */
788 static unsigned char txNonOlsrInterfaceNames[PUD_TX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
789
790 /** The number of tx interface names in the array */
791 static unsigned int txNonOlsrInterfaceCount = 0;
792
793 /**
794  Determine whether a give interface name is configured as a transmit non-OLSR
795  interface.
796
797  @param ifName
798  The interface to check
799
800  @return
801  - true when the given interface name is configured as a transmit non-OLSR
802  interface
803  - false otherwise
804  */
805 bool isTxNonOlsrInterface(const char *ifName) {
806         unsigned int i;
807
808         assert (ifName != NULL);
809
810         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
811                 if (strncmp((char *) &txNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ + 1) == 0) {
812                         return true;
813                 }
814         }
815
816         return false;
817 }
818
819 int addTxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
820                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
821         size_t valueLength;
822
823         assert (value != NULL);
824
825         if (txNonOlsrInterfaceCount >= PUD_TX_NON_OLSR_IF_MAX) {
826                 pudError(false, "Can not configure more than %u transmit interfaces", PUD_TX_NON_OLSR_IF_MAX);
827                 return true;
828         }
829
830         valueLength = strlen(value);
831         if (valueLength > IFNAMSIZ) {
832                 pudError(false, "Value of parameter %s (%s) is too long, maximum length is %u, current length is %lu",
833                                 PUD_TX_NON_OLSR_IF_NAME, value, IFNAMSIZ, (long unsigned int)valueLength);
834                 return true;
835         }
836
837         if (!isTxNonOlsrInterface(value)) {
838                 strcpy((char *) &txNonOlsrInterfaceNames[txNonOlsrInterfaceCount][0], value);
839                 txNonOlsrInterfaceCount++;
840         }
841
842         return false;
843 }
844
845 /**
846  * @return the number of configured non-olsr transmit interfaces
847  */
848 unsigned int getTxNonOlsrInterfaceCount(void) {
849         return txNonOlsrInterfaceCount;
850 }
851
852 /**
853  * @param idx the index of the configured non-olsr transmit interface
854  * @return the index-th interface name
855  */
856 unsigned char * getTxNonOlsrInterfaceName(unsigned int idx) {
857         return &txNonOlsrInterfaceNames[idx][0];
858 }
859
860 /*
861  * txMcAddr + txMcPort
862  */
863
864 /** The tx multicast address */
865 static union olsr_sockaddr txMcAddr;
866
867 /** True when the tx multicast address is set */
868 static bool txMcAddrSet = false;
869
870 /**
871  @return
872  The transmit multicast address (in network byte order). Sets both the address
873  and the port to their default values when the address was not yet set.
874  */
875 union olsr_sockaddr * getTxMcAddr(void) {
876         if (!txMcAddrSet) {
877                 setTxMcAddr((olsr_cnf->ip_version == AF_INET) ? PUD_TX_MC_ADDR_4_DEFAULT : PUD_TX_MC_ADDR_6_DEFAULT,
878                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
879         }
880         return &txMcAddr;
881 }
882
883 int setTxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
884         static const char * valueName = PUD_TX_MC_ADDR_NAME;
885
886         if (!readIPAddress(valueName, value, PUD_TX_MC_PORT_DEFAULT, &txMcAddr, &txMcAddrSet)) {
887                         return true;
888         }
889
890         if (!isMulticast(&txMcAddr)) {
891                 pudError(false, "Value of parameter %s (%s) is not a multicast address",
892                                 valueName, value);
893                 return true;
894         }
895
896         return false;
897 }
898
899 /**
900  @return
901  The transmit multicast port (in network byte order)
902  */
903 unsigned short getTxMcPort(void) {
904         return getOlsrSockaddrPort(getTxMcAddr(), PUD_TX_MC_PORT_DEFAULT);
905 }
906
907 int setTxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
908         static const char * valueName = PUD_TX_MC_PORT_NAME;
909         unsigned short txMcPortNew;
910
911         if (!readUS(valueName, value, &txMcPortNew)) {
912                 return true;
913         }
914
915         if (txMcPortNew < 1) {
916                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, txMcPortNew);
917                 return true;
918         }
919
920         setOlsrSockaddrPort(getTxMcAddr(), htons((in_port_t) txMcPortNew));
921
922         return false;
923 }
924
925 /*
926  * txTtl
927  */
928
929 /** The tx TTL */
930 static unsigned char txTtl = PUD_TX_TTL_DEFAULT;
931
932 /**
933  @return
934  The transmit multicast IP packet time-to-live
935  */
936 unsigned char getTxTtl(void) {
937         return txTtl;
938 }
939
940 int setTxTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
941         static const char * valueName = PUD_TX_TTL_NAME;
942
943         if (!readUC(valueName, value, &txTtl)) {
944                 return true;
945         }
946
947         if ((txTtl < 1) /* || (txTtl > MAX_TTL) */) {
948                 pudError(false, "Value of parameter %s (%u) is outside of"
949                         " valid range 1-%u", valueName, txTtl, MAX_TTL);
950                 return true;
951         }
952
953         return false;
954 }
955
956 /*
957  * txNmeaMessagePrefix
958  */
959
960 /** The exact length of the tx NMEA message prefix */
961 #define PUD_TXNMEAMESSAGEPREFIXLENGTH 4
962
963 /** The tx NMEA message prefix buffer */
964 static unsigned char txNmeaMessagePrefix[PUD_TXNMEAMESSAGEPREFIXLENGTH + 1];
965
966 /** True when the tx NMEA message prefix is set */
967 static bool txNmeaMessagePrefixSet = false;
968
969 /**
970  @return
971  The transmit multicast NMEA message prefix
972  */
973 unsigned char * getTxNmeaMessagePrefix(void) {
974         if (!txNmeaMessagePrefixSet) {
975                 setTxNmeaMessagePrefix(PUD_TX_NMEAMESSAGEPREFIX_DEFAULT, NULL,
976                                 (set_plugin_parameter_addon) {.pc = NULL});
977         }
978         return &txNmeaMessagePrefix[0];
979 }
980
981 int setTxNmeaMessagePrefix(const char *value, void *data __attribute__ ((unused)),
982                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
983         const char * invalidCharName;
984         static const char * valueName = PUD_TX_NMEAMESSAGEPREFIX_NAME;
985         size_t valueLength;
986
987         assert (value != NULL);
988
989         valueLength = strlen(value);
990         if (valueLength != PUD_TXNMEAMESSAGEPREFIXLENGTH) {
991                 pudError(false, "Length of parameter %s (%s) must be exactly %u characters",
992                                 valueName, value, PUD_TXNMEAMESSAGEPREFIXLENGTH);
993                 return true;
994         }
995
996   invalidCharName = nmea_parse_sentence_has_invalid_chars(value, valueLength);
997   if (invalidCharName) {
998     char report[256];
999     snprintf(report, sizeof(report), "Configured %s (%s),"
1000         " contains invalid NMEA characters (%s)", valueName, value, invalidCharName);
1001     pudError(false, "%s", report);
1002     return true;
1003   }
1004
1005         if ((strchr(value, ' ') != NULL) || (strchr(value, '\t') != NULL)) {
1006                 pudError(false, "Value of parameter %s (%s) can not contain whitespace",
1007                                 valueName, value);
1008                 return true;
1009         }
1010
1011         strcpy((char *) &txNmeaMessagePrefix[0], value);
1012         txNmeaMessagePrefixSet = true;
1013         return false;
1014 }
1015
1016 /*
1017  * uplinkAddr + uplinkPort
1018  */
1019
1020 /** The uplink address */
1021 static union olsr_sockaddr uplinkAddr;
1022
1023 /** True when the uplink address is set */
1024 static bool uplinkAddrSet = false;
1025
1026 /**
1027  @return
1028  - true when the uplink address is set
1029  - false otherwise
1030  */
1031 bool isUplinkAddrSet(void) {
1032         return uplinkAddrSet;
1033 }
1034
1035 /**
1036  @return
1037  The uplink address (in network byte order). Sets both the address
1038  and the port to their default values when the address was not yet set.
1039  */
1040 union olsr_sockaddr * getUplinkAddr(void) {
1041         if (!uplinkAddrSet) {
1042                 setUplinkAddr((olsr_cnf->ip_version == AF_INET) ? PUD_UPLINK_ADDR_4_DEFAULT : PUD_UPLINK_ADDR_6_DEFAULT,
1043                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
1044         }
1045         return &uplinkAddr;
1046 }
1047
1048 int setUplinkAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1049         return !readIPAddress(PUD_UPLINK_ADDR_NAME, value, PUD_UPLINK_PORT_DEFAULT, &uplinkAddr, &uplinkAddrSet);
1050 }
1051
1052 /**
1053  @return
1054  The uplink port (in network byte order)
1055  */
1056 unsigned short getUplinkPort(void) {
1057         return getOlsrSockaddrPort(getUplinkAddr(), PUD_UPLINK_PORT_DEFAULT);
1058 }
1059
1060 int setUplinkPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1061         static const char * valueName = PUD_UPLINK_PORT_NAME;
1062         unsigned short uplinkPortNew;
1063
1064         if (!readUS(valueName, value, &uplinkPortNew)) {
1065                 return true;
1066         }
1067
1068         if (uplinkPortNew < 1) {
1069                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, uplinkPortNew);
1070                 return true;
1071         }
1072
1073         setOlsrSockaddrPort(getUplinkAddr(), htons((in_port_t) uplinkPortNew));
1074
1075         return false;
1076 }
1077
1078 /*
1079  * downlinkPort
1080  */
1081
1082 /** the downlink port */
1083 unsigned short downlinkPort = 0;
1084
1085 /** true when the downlinkPort is set */
1086 bool downlinkPortSet = false;
1087
1088 /**
1089  @return
1090  The downlink port (in network byte order)
1091  */
1092 unsigned short getDownlinkPort(void) {
1093         if (!downlinkPortSet) {
1094                 downlinkPort = htons(PUD_DOWNLINK_PORT_DEFAULT);
1095                 downlinkPortSet = true;
1096         }
1097
1098         return downlinkPort;
1099 }
1100
1101 int setDownlinkPort(const char *value, void *data __attribute__ ((unused)),
1102                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1103         static const char * valueName = PUD_DOWNLINK_PORT_NAME;
1104         unsigned short downlinkPortNew;
1105
1106         if (!readUS(valueName, value, &downlinkPortNew)) {
1107                 return true;
1108         }
1109
1110         if (downlinkPortNew < 1) {
1111                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, downlinkPortNew);
1112                 return true;
1113         }
1114
1115         downlinkPort = htons(downlinkPortNew);
1116         downlinkPortSet = true;
1117
1118         return false;
1119 }
1120
1121 /*
1122  * olsrTtl
1123  */
1124
1125 /** The OLSR TTL */
1126 static unsigned char olsrTtl = PUD_OLSR_TTL_DEFAULT;
1127
1128 /**
1129  @return
1130  The OLSR multicast IP packet time-to-live
1131  */
1132 unsigned char getOlsrTtl(void) {
1133         return olsrTtl;
1134 }
1135
1136 int setOlsrTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1137         static const char * valueName = PUD_OLSR_TTL_NAME;
1138
1139         if (!readUC(valueName, value, &olsrTtl)) {
1140                 return true;
1141         }
1142
1143         if ((olsrTtl < 1) /* || (olsrTtl > MAX_TTL) */) {
1144                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-%u",
1145                                 valueName, olsrTtl, MAX_TTL);
1146                 return true;
1147         }
1148
1149         return false;
1150 }
1151
1152 /*
1153  * updateIntervalStationary
1154  */
1155
1156 /** The stationary interval update plugin parameter (in seconds) */
1157 static unsigned long long updateIntervalStationary = PUD_UPDATE_INTERVAL_STATIONARY_DEFAULT;
1158
1159 /**
1160  @return
1161  The stationary interval update plugin parameter (in seconds)
1162  */
1163 unsigned long long getUpdateIntervalStationary(void) {
1164         return updateIntervalStationary;
1165 }
1166
1167 int setUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1168                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1169         static const char * valueName = PUD_UPDATE_INTERVAL_STATIONARY_NAME;
1170
1171         if (!readULL(valueName, value, &updateIntervalStationary, 10)) {
1172                 return true;
1173         }
1174
1175         if (updateIntervalStationary < 1) {
1176                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1177                 return true;
1178         }
1179
1180         return false;
1181 }
1182
1183 /*
1184  * updateIntervalMoving
1185  */
1186
1187 /** The moving interval update plugin parameter (in seconds) */
1188 static unsigned long long updateIntervalMoving = PUD_UPDATE_INTERVAL_MOVING_DEFAULT;
1189
1190 /**
1191  @return
1192  The moving interval update plugin parameter (in seconds)
1193  */
1194 unsigned long long getUpdateIntervalMoving(void) {
1195         return updateIntervalMoving;
1196 }
1197
1198 int setUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1199                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1200         static const char * valueName = PUD_UPDATE_INTERVAL_MOVING_NAME;
1201
1202         if (!readULL(valueName, value, &updateIntervalMoving, 10)) {
1203                 return true;
1204         }
1205
1206         if (updateIntervalMoving < 1) {
1207                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1208                 return true;
1209         }
1210
1211         return false;
1212 }
1213
1214 /*
1215  * uplinkUpdateIntervalStationary
1216  */
1217
1218 /** The uplink stationary interval update plugin parameter (in seconds) */
1219 static unsigned long long uplinkUpdateIntervalStationary = PUD_UPLINK_UPDATE_INTERVAL_STATIONARY_DEFAULT;
1220
1221 /**
1222  @return
1223  The uplink stationary interval update plugin parameter (in seconds)
1224  */
1225 unsigned long long getUplinkUpdateIntervalStationary(void) {
1226         return uplinkUpdateIntervalStationary;
1227 }
1228
1229 int setUplinkUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1230                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1231         static const char * valueName = PUD_UPLINK_UPDATE_INTERVAL_STATIONARY_NAME;
1232
1233         if (!readULL(valueName, value, &uplinkUpdateIntervalStationary, 10)) {
1234                 return true;
1235         }
1236
1237         if (uplinkUpdateIntervalStationary < 1) {
1238                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1239                 return true;
1240         }
1241
1242         return false;
1243 }
1244
1245 /*
1246  * uplinkUpdateIntervalMoving
1247  */
1248
1249 /** The uplink moving interval update plugin parameter (in seconds) */
1250 static unsigned long long uplinkUpdateIntervalMoving = PUD_UPLINK_UPDATE_INTERVAL_MOVING_DEFAULT;
1251
1252 /**
1253  @return
1254  The uplink moving interval update plugin parameter (in seconds)
1255  */
1256 unsigned long long getUplinkUpdateIntervalMoving(void) {
1257         return uplinkUpdateIntervalMoving;
1258 }
1259
1260 int setUplinkUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1261                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1262         static const char * valueName = PUD_UPLINK_UPDATE_INTERVAL_MOVING_NAME;
1263
1264         if (!readULL(valueName, value, &uplinkUpdateIntervalMoving, 10)) {
1265                 return true;
1266         }
1267
1268         if (uplinkUpdateIntervalMoving < 1) {
1269                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1270                 return true;
1271         }
1272
1273         return false;
1274 }
1275
1276 /*
1277  * gatewayDeterminationInterval
1278  */
1279
1280 /** The gateway determination interval plugin parameter (in seconds) */
1281 static unsigned long long gatewayDeterminationInterval = PUD_GATEWAY_DETERMINATION_INTERVAL_DEFAULT;
1282
1283 /**
1284  @return
1285  The gateway determination interval plugin parameter (in seconds)
1286  */
1287 unsigned long long getGatewayDeterminationInterval(void) {
1288         return gatewayDeterminationInterval;
1289 }
1290
1291 int setGatewayDeterminationInterval(const char *value, void *data __attribute__ ((unused)),
1292                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1293         static const char * valueName = PUD_GATEWAY_DETERMINATION_INTERVAL_NAME;
1294
1295         if (!readULL(valueName, value, &gatewayDeterminationInterval, 10)) {
1296                 return true;
1297         }
1298
1299         if (gatewayDeterminationInterval < 1) {
1300                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1301                 return true;
1302         }
1303
1304         return false;
1305 }
1306
1307 /*
1308  * movingSpeedThreshold
1309  */
1310
1311 /** The moving speed threshold plugin parameter (in kph) */
1312 static unsigned long long movingSpeedThreshold = PUD_MOVING_SPEED_THRESHOLD_DEFAULT;
1313
1314 /**
1315  @return
1316  The moving speed threshold plugin parameter (in kph)
1317  */
1318 unsigned long long getMovingSpeedThreshold(void) {
1319         return movingSpeedThreshold;
1320 }
1321
1322 int setMovingSpeedThreshold(const char *value, void *data __attribute__ ((unused)),
1323                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1324         return !readULL(PUD_MOVING_SPEED_THRESHOLD_NAME, value, &movingSpeedThreshold, 10);
1325 }
1326
1327 /*
1328  * movingDistanceThreshold
1329  */
1330
1331 /** The moving distance threshold plugin parameter (in meters) */
1332 static unsigned long long movingDistanceThreshold = PUD_MOVING_DISTANCE_THRESHOLD_DEFAULT;
1333
1334 /**
1335  @return
1336  The moving distance threshold plugin parameter (in meters)
1337  */
1338 unsigned long long getMovingDistanceThreshold(void) {
1339         return movingDistanceThreshold;
1340 }
1341
1342 int setMovingDistanceThreshold(const char *value, void *data __attribute__ ((unused)),
1343                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1344         return !readULL(PUD_MOVING_DISTANCE_THRESHOLD_NAME, value, &movingDistanceThreshold, 10);
1345 }
1346
1347 /*
1348  * dopMultiplier
1349  */
1350
1351 /** The DOP multiplier plugin parameter */
1352 static double dopMultiplier = PUD_DOP_MULTIPLIER_DEFAULT;
1353
1354 /**
1355  @return
1356  The DOP multiplier plugin parameter
1357  */
1358 double getDopMultiplier(void) {
1359         return dopMultiplier;
1360 }
1361
1362 int setDopMultiplier(const char *value, void *data __attribute__ ((unused)),
1363                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1364         return !readDouble(PUD_DOP_MULTIPLIER_NAME, value, &dopMultiplier);
1365 }
1366
1367 /*
1368  * defaultHdop
1369  */
1370
1371 /** The default HDOP plugin parameter (in meters) */
1372 static unsigned long long defaultHdop = PUD_DEFAULT_HDOP_DEFAULT;
1373
1374 /**
1375  @return
1376  The default HDOP plugin parameter (in meters)
1377  */
1378 unsigned long long getDefaultHdop(void) {
1379         return defaultHdop;
1380 }
1381
1382 int setDefaultHdop(const char *value, void *data __attribute__ ((unused)),
1383                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1384         return !readULL(PUD_DEFAULT_HDOP_NAME, value, &defaultHdop, 10);
1385 }
1386
1387 /*
1388  * defaultVdop
1389  */
1390
1391 /** The default VDOP plugin parameter (in meters) */
1392 static unsigned long long defaultVdop = PUD_DEFAULT_VDOP_DEFAULT;
1393
1394 /**
1395  @return
1396  The default VDOP plugin parameter (in meters)
1397  */
1398 unsigned long long getDefaultVdop(void) {
1399         return defaultVdop;
1400 }
1401
1402 int setDefaultVdop(const char *value, void *data __attribute__ ((unused)),
1403                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1404         return !readULL(PUD_DEFAULT_VDOP_NAME, value, &defaultVdop, 10);
1405 }
1406
1407 /*
1408  * averageDepth
1409  */
1410
1411 /** The depth of the average list */
1412 static unsigned long long averageDepth = PUD_AVERAGE_DEPTH_DEFAULT;
1413
1414 /**
1415  @return
1416  The depth of the average list
1417  */
1418 unsigned long long getAverageDepth(void) {
1419         return averageDepth;
1420 }
1421
1422 int setAverageDepth(const char *value, void *data __attribute__ ((unused)),
1423                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1424         static const char * valueName = PUD_AVERAGE_DEPTH_NAME;
1425
1426         if (!readULL(valueName, value, &averageDepth, 10)) {
1427                 return true;
1428         }
1429
1430         if (averageDepth < 1) {
1431                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1432                 return true;
1433         }
1434
1435         return false;
1436 }
1437
1438 /*
1439  * hysteresisCountToStationary
1440  */
1441
1442 /** The hysteresis count for changing state from moving to stationary */
1443 static unsigned long long hysteresisCountToStationary = PUD_HYSTERESIS_COUNT_2STAT_DEFAULT;
1444
1445 /**
1446  @return
1447  The hysteresis count for changing state from moving to stationary
1448  */
1449 unsigned long long getHysteresisCountToStationary(void) {
1450         return hysteresisCountToStationary;
1451 }
1452
1453 int setHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1454                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1455         return !readULL(PUD_HYSTERESIS_COUNT_2STAT_NAME, value, &hysteresisCountToStationary, 10);
1456 }
1457
1458 /*
1459  * hysteresisCountToMoving
1460  */
1461
1462 /** The hysteresis count for changing state from stationary to moving */
1463 static unsigned long long hysteresisCountToMoving = PUD_HYSTERESIS_COUNT_2MOV_DEFAULT;
1464
1465 /**
1466  @return
1467  The hysteresis count for changing state from stationary to moving
1468  */
1469 unsigned long long getHysteresisCountToMoving(void) {
1470         return hysteresisCountToMoving;
1471 }
1472
1473 int setHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1474                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1475         return !readULL(PUD_HYSTERESIS_COUNT_2MOV_NAME, value, &hysteresisCountToMoving, 10);
1476 }
1477
1478 /*
1479  * gatewayHysteresisCountToStationary
1480  */
1481
1482 /** The hysteresis count for changing state from moving to stationary */
1483 static unsigned long long gatewayHysteresisCountToStationary = PUD_GAT_HYSTERESIS_COUNT_2STAT_DEFAULT;
1484
1485 /**
1486  @return
1487  The hysteresis count for changing state from moving to stationary
1488  */
1489 unsigned long long getGatewayHysteresisCountToStationary(void) {
1490         return gatewayHysteresisCountToStationary;
1491 }
1492
1493 int setGatewayHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1494                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1495         return !readULL(PUD_GAT_HYSTERESIS_COUNT_2STAT_NAME, value, &gatewayHysteresisCountToStationary, 10);
1496 }
1497
1498 /*
1499  * gatewayHysteresisCountToMoving
1500  */
1501
1502 /** The hysteresis count for changing state from stationary to moving */
1503 static unsigned long long gatewayHysteresisCountToMoving = PUD_GAT_HYSTERESIS_COUNT_2MOV_DEFAULT;
1504
1505 /**
1506  @return
1507  The hysteresis count for changing state from stationary to moving
1508  */
1509 unsigned long long getGatewayHysteresisCountToMoving(void) {
1510         return gatewayHysteresisCountToMoving;
1511 }
1512
1513 int setGatewayHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1514                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1515         return !readULL(PUD_GAT_HYSTERESIS_COUNT_2MOV_NAME, value, &gatewayHysteresisCountToMoving, 10);
1516 }
1517
1518 /*
1519  * useDeDup
1520  */
1521
1522 /** when true then duplicate message detection is performed */
1523 static bool useDeDup = PUD_USE_DEDUP_DEFAULT;
1524
1525 /**
1526  @return
1527  The duplicate message detection setting
1528  */
1529 bool getUseDeDup(void) {
1530         return useDeDup;
1531 }
1532
1533 int setUseDeDup(const char *value, void *data __attribute__ ((unused)),
1534                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1535         return !readBool(PUD_USE_DEDUP_NAME, value, &useDeDup);
1536 }
1537
1538 /*
1539  * deDupDepth
1540  */
1541
1542 /** The deduplication depth */
1543 static unsigned long long deDupDepth = PUD_DEDUP_DEPTH_DEFAULT;
1544
1545 /**
1546  @return
1547  The deduplication depth
1548  */
1549 unsigned long long getDeDupDepth(void) {
1550         return deDupDepth;
1551 }
1552
1553 int setDeDupDepth(const char *value, void *data __attribute__ ((unused)),
1554                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1555         return !readULL(PUD_DEDUP_DEPTH_NAME, value, &deDupDepth, 10);
1556 }
1557
1558 /*
1559  * useLoopback
1560  */
1561
1562 /** when true then loopback is performed */
1563 static bool useLoopback = PUD_USE_LOOPBACK_DEFAULT;
1564
1565 /**
1566  @return
1567  The loopback usage setting
1568  */
1569 bool getUseLoopback(void) {
1570         return useLoopback;
1571 }
1572
1573 int setUseLoopback(const char *value, void *data __attribute__ ((unused)),
1574                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1575         return !readBool(PUD_USE_LOOPBACK_NAME, value, &useLoopback);
1576 }
1577
1578 /*
1579  * Check Functions
1580  */
1581
1582 /**
1583  Check the configuration for consistency and validity.
1584
1585  @return
1586  - true when the configuration is consistent and valid
1587  - false otherwise
1588  */
1589 unsigned int checkConfig(void) {
1590         int retval = true;
1591
1592         if (rxNonOlsrInterfaceCount == 0) {
1593                 pudError(false, "No receive non-OLSR interfaces configured");
1594                 retval = false;
1595         }
1596
1597         if (txNonOlsrInterfaceCount == 0) {
1598                 pudError(false, "No transmit non-OLSR interfaces configured");
1599                 retval = false;
1600         }
1601
1602         if (updateIntervalMoving > updateIntervalStationary) {
1603                 pudError(false,"The update interval for moving situations must not be"
1604                 " larger than that for stationary situations");
1605                 retval = false;
1606         }
1607
1608         if (uplinkUpdateIntervalMoving > uplinkUpdateIntervalStationary) {
1609                 pudError(false,"The uplink update interval for moving situations must not be"
1610                 " larger than that for stationary situations");
1611                 retval = false;
1612         }
1613
1614         if (isUplinkAddrSet() && (getUplinkPort() == getDownlinkPort())) {
1615                 pudError(false, "The uplink port and the downlink port must not be the same");
1616                 retval = false;
1617         }
1618
1619         return retval;
1620 }
1621
1622 /**
1623  Check the configuration for consistency and validity after everything has been
1624  setup.
1625
1626  @return
1627  - true when the configuration is consistent and valid
1628  - false otherwise
1629  */
1630 unsigned int checkRunSetup(void) {
1631         return true;
1632 }