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