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