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