d68207d2f836203a91f9c44e5cc6cdaf4e104a38
[olsrd.git] / lib / pud / src / configuration.c
1 #include "configuration.h"
2
3 /* Plugin includes */
4 #include "pud.h"
5 #include "netTools.h"
6 #include "networkInterfaces.h"
7
8 /* OLSR includes */
9 #include "olsr_types.h"
10 #include "olsr_cfg.h"
11
12 /* System includes */
13 #include <assert.h>
14 #include <errno.h>
15 #include <stdlib.h>
16 #include <stddef.h>
17 #include <string.h>
18 #include <net/if.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
21 #include <sys/socket.h>
22 #include <unistd.h>
23 #include <nmea/util.h>
24
25 /*
26  * Utility functions
27  */
28
29 /**
30  Determine the address of the port in an OLSR socket address
31
32  @param ipVersion
33  The IP version (AF_INET or AF_INET6)
34  @param addr
35  A pointer to OLSR socket address
36  @param port
37  A pointer to the location where the pointer to the port will be stored
38  */
39 static void getOlsrSockaddrPortAddress(int ipVersion,
40                 union olsr_sockaddr * addr, in_port_t ** port) {
41         if (ipVersion == AF_INET) {
42                 *port = &addr->in4.sin_port;
43         } else {
44                 *port = &addr->in6.sin6_port;
45         }
46 }
47
48 /**
49  Get pointers to the IP address and port in an OLSR socket address
50  @param ipVersion
51  The IP version (AF_INET or AF_INET6)
52  @param addr
53  A pointer to OLSR socket address
54  @param ipAddress
55  A pointer to the location where the pointer to the IP address will be stored
56  @param port
57  A pointer to the location where the pointer to the port will be stored
58  */
59 static void getOlsrSockAddrAndPortAddresses(int ipVersion,
60                 union olsr_sockaddr * addr, void ** ipAddress, in_port_t ** port) {
61         if (ipVersion == AF_INET) {
62                 *ipAddress = (void *) &addr->in4.sin_addr;
63                 *port = (void *) &addr->in4.sin_port;
64         } else {
65                 *ipAddress = (void *) &addr->in6.sin6_addr;
66                 *port = (void *) &addr->in6.sin6_port;
67         }
68 }
69
70 /**
71  Read an unsigned long long number from a value string
72
73  @param valueName
74  the name of the value
75  @param value
76  the string to convert to a number
77  @param valueNumber
78  a pointer to the location where to store the number upon successful conversion
79
80  @return
81  - true on success
82  - false otherwise
83  */
84 static bool readULL(const char * valueName, const char * value,
85                 unsigned long long * valueNumber) {
86         char * endPtr = NULL;
87         unsigned long long valueNew;
88
89         errno = 0;
90         valueNew = strtoull(value, &endPtr, 10);
91
92         if (!((endPtr != value) && (*value != '\0') && (*endPtr == '\0'))) {
93                 /* invalid conversion */
94                 pudError(true, "Configured %s (%s) could not be converted to a number",
95                                 valueName, value);
96                 return false;
97         }
98
99         *valueNumber = valueNew;
100
101         return true;
102 }
103
104 /**
105  Read a double number from a value string
106
107  @param valueName
108  the name of the value
109  @param value
110  the string to convert to a number
111  @param valueNumber
112  a pointer to the location where to store the number upon successful conversion
113
114  @return
115  - true on success
116  - false otherwise
117  */
118 static bool readDouble(const char * valueName, const char * value,
119                 double * valueNumber) {
120         char * endPtr = NULL;
121         double valueNew;
122
123         errno = 0;
124         valueNew = strtod(value, &endPtr);
125
126         if (!((endPtr != value) && (*value != '\0') && (*endPtr == '\0'))) {
127                 /* invalid conversion */
128                 pudError(true, "Configured %s (%s) could not be converted to a number",
129                                 valueName, value);
130                 return false;
131         }
132
133         *valueNumber = valueNew;
134
135         return true;
136 }
137
138 /*
139  * nodeIdType
140  */
141
142 /** The nodeIdType */
143 static NodeIdType nodeIdType = PUD_NODE_ID_TYPE_DEFAULT;
144
145 /**
146  @return
147  The node ID type
148  */
149 NodeIdType getNodeIdTypeNumber(void) {
150         return nodeIdType;
151 }
152
153 /**
154  Set the node ID type.
155
156  @param value
157  The value of the node ID type to set (a number in string representation)
158  @param data
159  Unused
160  @param addon
161  Unused
162
163  @return
164  - true when an error is detected
165  - false otherwise
166  */
167 int setNodeIdType(const char *value, void *data __attribute__ ((unused)),
168                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
169         static const char * valueName = PUD_NODE_ID_TYPE_NAME;
170         unsigned long long nodeIdTypeNew;
171
172         assert (value != NULL);
173
174         if (!readULL(valueName, value, &nodeIdTypeNew)) {
175                 return true;
176         }
177
178         if (!isValidNodeIdType(nodeIdTypeNew)) {
179                 pudError(false, "Configured %s (%llu) is reserved", valueName,
180                                 nodeIdTypeNew);
181                 return true;
182         }
183
184         nodeIdType = nodeIdTypeNew;
185
186         return false;
187 }
188
189 /*
190  * nodeId
191  */
192
193 /** The maximum length of a nodeId */
194 #define PUD_NODEIDMAXLENGTH 255
195
196 /**
197  The type that is used to store the nodeId as a binary representation
198  */
199 typedef union _nodeIdBinaryType {
200                 unsigned long long longValue;
201                 unsigned char stringValue[PUD_NODEIDMAXLENGTH + 1];
202                 union olsr_ip_addr ip;
203                 unsigned char mac[PUD_NODEIDTYPE_MAC_BYTES];
204 } nodeIdBinaryType;
205
206 /** The nodeId buffer */
207 static unsigned char nodeId[PUD_NODEIDMAXLENGTH + 1];
208
209 /** The length of the string in the nodeId buffer */
210 static size_t nodeIdLength = 0;
211
212 /** True when the nodeId is set */
213 static bool nodeIdSet = false;
214
215 /** The nodeId as a binary representation */
216 static nodeIdBinaryType nodeIdBinary;
217
218 /** The length of the string in the nodeIdBinary buffer */
219 static size_t nodeIdBinaryLength = 0;
220
221 /** True when the nodeIdBinary is set */
222 static bool nodeIdBinarySet = false;
223
224 /**
225  @return
226  The node ID
227  */
228 unsigned char * getNodeId(void) {
229         return getNodeIdWithLength(NULL);
230 }
231
232 /**
233  Get the nodeId and its length
234
235  @param length
236  a pointer to the variable in which to store the nodeId length (allowed to be
237  NULL, in which case the length is not stored)
238
239  @return
240  The node ID
241  */
242 unsigned char * getNodeIdWithLength(size_t *length) {
243         if (!nodeIdSet) {
244                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
245         }
246
247         if (length != NULL) {
248                 *length = nodeIdLength;
249         }
250
251         return &nodeId[0];
252 }
253
254 /**
255  Get the nodeIdBinary and its length
256
257  @param length
258  a pointer to the variable in which to store the nodeIdBinary length (allowed to be
259  NULL, in which case the length is not stored)
260
261  @return
262  The node ID in binary representation
263  */
264 unsigned char * getNodeIdBinaryWithLength(size_t *length) {
265         if (!nodeIdBinarySet) {
266                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
267         }
268
269         if (length != NULL) {
270                 *length = nodeIdBinaryLength;
271         }
272
273         return (unsigned char *)&nodeIdBinary;
274 }
275
276 /**
277  Set the node ID.
278
279  @param value
280  The value of the node ID to set (in string representation)
281  @param data
282  Unused
283  @param addon
284  Unused
285
286  @return
287  - true when an error is detected
288  - false otherwise
289  */
290 int setNodeId(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
291         static const char * valueName = PUD_NODE_ID_NAME;
292         size_t valueLength;
293
294         assert (value != NULL);
295
296         valueLength = strlen(value);
297         if (valueLength > PUD_NODEIDMAXLENGTH) {
298                 pudError(false, "Configured %s is too long, maximum length is"
299                         " %u, current length is %lu", valueName, PUD_NODEIDMAXLENGTH,
300                                 (unsigned long) valueLength);
301                 return true;
302         }
303
304         strcpy((char *) &nodeId[0], value);
305         nodeIdLength = valueLength;
306         nodeIdSet = true;
307
308         return false;
309 }
310
311 /*
312  * nodeId Validation
313  */
314
315 /**
316  Validate whether the configured nodeId is valid w.r.t. the configured
317  nodeIdType, for types that are MAC addresses
318
319  @return
320  - true when ok
321  - false on failure
322  */
323 static bool setupNodeIdBinaryMAC(void) {
324         unsigned char * mac = getMainIpMacAddress();
325         if (!mac) {
326                 return false;
327         }
328
329         memcpy(&nodeIdBinary.mac, mac, PUD_NODEIDTYPE_MAC_BYTES);
330         nodeIdBinaryLength = PUD_NODEIDTYPE_MAC_BYTES;
331         nodeIdBinarySet = true;
332
333         if (setupNodeIdBinaryBufferForOlsrCache(mac, PUD_NODEIDTYPE_MAC_BYTES)) {
334                 return true;
335         }
336
337         pudError(false, "%s value \"MAC address\" could not be setup", PUD_NODE_ID_NAME);
338         return false;
339 }
340
341 /**
342  Validate whether the configured nodeId is valid w.r.t. the configured
343  nodeIdType, for types that fit in an unsigned long long (64 bits)
344
345  @param min
346  the minimum value
347  @param max
348  the maximum value
349  @param bytes
350  the number of bytes in the buffer
351
352  @return
353  - true when ok
354  - false on failure
355  */
356 static bool setupNodeIdBinaryLongLong(unsigned long long min,
357                 unsigned long long max, unsigned int bytes) {
358         unsigned long long longValue = 0;
359         int i = bytes - 1;
360
361         if (!readULL(PUD_NODE_ID_NAME, (char *) getNodeId(), &longValue)) {
362                 return false;
363         }
364
365         if ((longValue < min) || (longValue > max)) {
366                 pudError(false, "%s value %llu is out of range [%llu,%llu]",
367                                 PUD_NODE_ID_NAME, longValue, min, max);
368                 return false;
369         }
370
371         while (i >= 0) {
372                 ((unsigned char *)&nodeIdBinary.longValue)[i] = longValue & 0xff;
373                 longValue >>= 8;
374                 i--;
375         }
376
377         assert(longValue == 0);
378
379         nodeIdBinaryLength = bytes;
380         nodeIdBinarySet = true;
381
382         if (setupNodeIdBinaryLongForOlsrCache(nodeIdBinary.longValue, bytes)) {
383                 return true;
384         }
385
386         return false;
387 }
388
389 /**
390  Validate whether the configured nodeId is valid w.r.t. the configured
391  nodeIdType, for types that are strings
392
393  @return
394  - true when ok
395  - false on failure
396  */
397 static bool setupNodeIdBinaryString(void) {
398         bool invalidChars;
399         char report[256];
400         size_t nodeidlength;
401         char * nodeid = (char *)getNodeIdWithLength(&nodeidlength);
402
403         invalidChars = nmea_string_has_invalid_chars(nodeid,
404                         PUD_NODE_ID_NAME, &report[0], sizeof(report));
405         if (invalidChars) {
406                 pudError(false, &report[0]);
407                 return false;
408         }
409
410         if (nodeidlength > PUD_NODEIDMAXLENGTH) {
411                 pudError(false, "%s value \"%s\" is too long", PUD_NODE_ID_NAME, &nodeid[0]);
412                 return false;
413         }
414
415         /* including trailing \0 */
416         memcpy(&nodeIdBinary.stringValue[0], &nodeid[0], nodeidlength + 1);
417         nodeIdBinaryLength = nodeIdLength + 1;
418         nodeIdBinarySet = true;
419
420         /* including trailing \0 */
421         if (setupNodeIdBinaryBufferForOlsrCache(&nodeid[0], nodeidlength + 1)) {
422                 return true;
423         }
424
425         pudError(false, "%s value \"%s\" is too long", PUD_NODE_ID_NAME, &nodeid[0]);
426         return false;
427 }
428
429 /**
430  Validate whether the configured nodeId is valid w.r.t. the configured
431  nodeIdType, for types that are IP addresses
432
433  @return
434  - true when ok
435  - false on failure
436  */
437 static bool setupNodeIdBinaryIp(void) {
438         void * src;
439         size_t length;
440         if (olsr_cnf->ip_version == AF_INET) {
441                 src = &olsr_cnf->main_addr.v4;
442                 length = sizeof(struct in_addr);
443         } else {
444                 src = &olsr_cnf->main_addr.v6;
445                 length = sizeof(struct in6_addr);
446         }
447
448         memcpy(&nodeIdBinary.ip, src, length);
449         nodeIdBinaryLength = length;
450         nodeIdBinarySet = true;
451
452         if (setupNodeIdBinaryBufferForOlsrCache(src, length)) {
453                 return true;
454         }
455
456         pudError(false, "%s value \"OLSRd main IP address\" could not be setup", PUD_NODE_ID_NAME);
457         return false;
458 }
459
460 /**
461  Validate whether the configured nodeId is valid w.r.t. the configured
462  nodeIdType
463
464  @return
465  - true when ok
466  - false on failure
467  */
468 static bool setupNodeIdBinaryAndValidate(NodeIdType nodeIdTypeNumber) {
469         switch (nodeIdTypeNumber) {
470                 case PUD_NODEIDTYPE_MAC: /* hardware address */
471                         return setupNodeIdBinaryMAC();
472
473                 case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
474                         return setupNodeIdBinaryLongLong(PUD_NODEIDTYPE_MSISDN_MIN,
475                                 PUD_NODEIDTYPE_MSISDN_MAX, PUD_NODEIDTYPE_MSISDN_BYTES);
476
477                 case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
478                         return setupNodeIdBinaryLongLong(PUD_NODEIDTYPE_TETRA_MIN,
479                                 PUD_NODEIDTYPE_TETRA_MAX, PUD_NODEIDTYPE_TETRA_BYTES);
480
481                 case PUD_NODEIDTYPE_DNS: /* DNS name */
482                         return setupNodeIdBinaryString();
483
484                 case PUD_NODEIDTYPE_MMSI: /* an AIS MMSI number */
485                         return setupNodeIdBinaryLongLong(PUD_NODEIDTYPE_MMSI_MIN,
486                                 PUD_NODEIDTYPE_MMSI_MAX, PUD_NODEIDTYPE_MMSI_BYTES);
487
488                 case PUD_NODEIDTYPE_URN: /* a URN number */
489                         return setupNodeIdBinaryLongLong(PUD_NODEIDTYPE_URN_MIN,
490                                 PUD_NODEIDTYPE_URN_MAX, PUD_NODEIDTYPE_URN_BYTES);
491
492                 case PUD_NODEIDTYPE_192:
493                         return setupNodeIdBinaryLongLong(PUD_NODEIDTYPE_192_MIN,
494                                 PUD_NODEIDTYPE_192_MAX, PUD_NODEIDTYPE_192_BYTES);
495
496                 case PUD_NODEIDTYPE_193:
497                         return setupNodeIdBinaryLongLong(PUD_NODEIDTYPE_193_MIN,
498                                 PUD_NODEIDTYPE_193_MAX, PUD_NODEIDTYPE_193_BYTES);
499
500                 case PUD_NODEIDTYPE_194:
501                         return setupNodeIdBinaryLongLong(PUD_NODEIDTYPE_194_MIN,
502                                 PUD_NODEIDTYPE_194_MAX, PUD_NODEIDTYPE_194_BYTES);
503
504                 case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
505                 case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
506                 default: /* unsupported */
507                         return setupNodeIdBinaryIp();
508         }
509
510         return false;
511 }
512
513 /*
514  * rxNonOlsrIf
515  */
516
517 /** The maximum number of RX non-OLSR interfaces */
518 #define PUD_RX_NON_OLSR_IF_MAX 32
519
520 /** Array with RX non-OLSR interface names */
521 static unsigned char rxNonOlsrInterfaceNames[PUD_RX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
522
523 /** The number of RX non-OLSR interface names in the array */
524 static unsigned int rxNonOlsrInterfaceCount = 0;
525
526 /**
527  Determine whether a give interface name is configured as a receive non-OLSR
528  interface.
529
530  @param ifName
531  The interface name to check
532
533  @return
534  - true when the given interface name is configured as a receive non-OLSR
535  interface
536  - false otherwise
537  */
538 bool isRxNonOlsrInterface(const char *ifName) {
539         unsigned int i;
540
541         assert (ifName != NULL);
542
543         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
544                 if (strncmp((char *) &rxNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
545                                 + 1) == 0) {
546                         return true;
547                 }
548         }
549
550         return false;
551 }
552
553 /**
554  Add a receive non-OLSR interface
555
556  @param value
557  The name of the non-OLSR interface to add
558  @param data
559  Unused
560  @param addon
561  Unused
562
563  @return
564  - true when an error is detected
565  - false otherwise
566  */
567 int addRxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
568                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
569         unsigned long valueLength;
570
571         assert (value != NULL);
572
573         valueLength = strlen(value);
574         if (valueLength > IFNAMSIZ) {
575                 pudError(false, "Configured %s (%s) is too long,"
576                         " maximum length is %u, current length is %lu",
577                                 PUD_RX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
578                 return true;
579         }
580
581         if (!isRxNonOlsrInterface(value)) {
582                 if (rxNonOlsrInterfaceCount >= PUD_RX_NON_OLSR_IF_MAX) {
583                         pudError(false, "Can't configure more than %u receive interfaces",
584                                         PUD_RX_NON_OLSR_IF_MAX);
585                         return true;
586                 }
587
588                 strcpy((char *) &rxNonOlsrInterfaceNames[rxNonOlsrInterfaceCount][0],
589                                 value);
590                 rxNonOlsrInterfaceCount++;
591         }
592
593         return false;
594 }
595
596 /*
597  * rxAllowedSourceIpAddress
598  */
599
600 /** The maximum number of RX allowed source IP addresses */
601 #define PUD_RX_ALLOWED_SOURCE_IP_MAX 32
602
603 /** Array with RX allowed source IP addresses */
604 static struct sockaddr rxAllowedSourceIpAddresses[PUD_RX_ALLOWED_SOURCE_IP_MAX];
605
606 /** The number of RX allowed source IP addresses in the array */
607 static unsigned int rxAllowedSourceIpAddressesCount = 0;
608
609 /**
610  Determine whether a give IP address is configured as an allowed source IP
611  address.
612
613  @param sender
614  The IP address to check
615
616  @return
617  - true when the given IP address is configured as an allowed source IP
618  address
619  - false otherwise
620  */
621 bool isRxAllowedSourceIpAddress(struct sockaddr * sender) {
622         void * addr;
623         unsigned int addrSize;
624         unsigned int i;
625
626         if (rxAllowedSourceIpAddressesCount == 0) {
627                 return true;
628         }
629
630         if (sender == NULL) {
631                 return false;
632         }
633
634         if (sender->sa_family == AF_INET) {
635                 addr = (void *) (&((struct sockaddr_in *) sender)->sin_addr);
636                 addrSize = sizeof(struct in_addr);
637         } else {
638                 addr = (void *) (&((struct sockaddr_in6 *) sender)->sin6_addr);
639                 addrSize = sizeof(struct in6_addr);
640         }
641
642         for (i = 0; i < rxAllowedSourceIpAddressesCount; i++) {
643                 if ((rxAllowedSourceIpAddresses[i].sa_family == sender->sa_family)
644                                 && (memcmp(&rxAllowedSourceIpAddresses[i].sa_data, addr,
645                                                 addrSize) == 0)) {
646                         return true;
647                 }
648         }
649
650         return false;
651 }
652
653 /**
654  Set the RX allowed source IP addresses.
655
656  @param value
657  The RX allowed source IP address (in string representation)
658  @param data
659  Unused
660  @param addon
661  Unused
662
663  @return
664  - true when an error is detected
665  - false otherwise
666  */
667 int addRxAllowedSourceIpAddress(const char *value, void *data __attribute__ ((unused)),
668                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
669         static const char * valueName = PUD_RX_ALLOWED_SOURCE_IP_NAME;
670         const char * valueInternal = value;
671         int conversion;
672         struct sockaddr addr;
673
674         assert (value != NULL);
675
676         memset(&addr, 0, sizeof(addr));
677
678         addr.sa_family = olsr_cnf->ip_version;
679         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, &addr.sa_data);
680         if (conversion != 1) {
681                 pudError((conversion == -1) ? true : false,
682                                 "Configured %s (%s) is not an IP address", valueName,
683                                 valueInternal);
684                 return true;
685         }
686
687         if ((rxAllowedSourceIpAddressesCount == 0) || !isRxAllowedSourceIpAddress(&addr)) {
688                 if (rxAllowedSourceIpAddressesCount >= PUD_RX_ALLOWED_SOURCE_IP_MAX) {
689                         pudError(false, "Can't configure more than %u allowed source IP"
690                                 " addresses", PUD_RX_ALLOWED_SOURCE_IP_MAX);
691                         return true;
692                 }
693
694                 memcpy(&rxAllowedSourceIpAddresses[rxAllowedSourceIpAddressesCount],
695                                 &addr, sizeof(addr));
696                 rxAllowedSourceIpAddressesCount++;
697         }
698
699         return false;
700 }
701
702 /*
703  * rxMcAddr
704  */
705
706 /** The rx multicast address */
707 static union olsr_sockaddr rxMcAddr;
708
709 /** True when the rx multicast address is set */
710 static bool rxMcAddrSet = false;
711
712 /**
713  @return
714  The receive multicast address (in network byte order). Sets both the address
715  and the port to their default values when the address was not yet set.
716  */
717 union olsr_sockaddr * getRxMcAddr(void) {
718         if (!rxMcAddrSet) {
719                 setRxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
720         }
721         return &rxMcAddr;
722 }
723
724 /**
725  Set the receive multicast address. Sets the address to its default value when
726  the value is NULL. Also sets the port to its default value when the address
727  was not yet set.
728
729  @param value
730  The receive multicast address (in string representation)
731  @param data
732  Unused
733  @param addon
734  Unused
735
736  @return
737  - true when an error is detected
738  - false otherwise
739  */
740 int setRxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
741         static const char * valueName = PUD_RX_MC_ADDR_NAME;
742         void * ipAddress;
743         in_port_t * port;
744         const char * valueInternal = value;
745         int conversion;
746
747         getOlsrSockAddrAndPortAddresses(olsr_cnf->ip_version, &rxMcAddr, &ipAddress,
748                         &port);
749         if (olsr_cnf->ip_version == AF_INET) {
750                 rxMcAddr.in4.sin_family = olsr_cnf->ip_version;
751                 if (valueInternal == NULL) {
752                         valueInternal = PUD_RX_MC_ADDR_4_DEFAULT;
753                 }
754         } else {
755                 rxMcAddr.in6.sin6_family = olsr_cnf->ip_version;
756                 if (valueInternal == NULL) {
757                         valueInternal = PUD_RX_MC_ADDR_6_DEFAULT;
758                 }
759         }
760
761         if (!rxMcAddrSet) {
762                 *port = htons(PUD_RX_MC_PORT_DEFAULT);
763         }
764
765         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
766         if (conversion != 1) {
767                 pudError((conversion == -1) ? true : false,
768                                 "Configured %s (%s) is not an IP address", valueName,
769                                 valueInternal);
770                 return true;
771         }
772
773         if (!isMulticast(olsr_cnf->ip_version, &rxMcAddr)) {
774                 pudError(false, "Configured %s (%s) is not a multicast address",
775                                 valueName, valueInternal);
776                 return true;
777         }
778
779         rxMcAddrSet = true;
780         return false;
781 }
782
783 /*
784  * rxMcPort
785  */
786
787 /**
788  @return
789  The receive multicast port (in network byte order)
790  */
791 unsigned short getRxMcPort(void) {
792         in_port_t * port;
793         getOlsrSockaddrPortAddress(olsr_cnf->ip_version, getRxMcAddr(), &port);
794         return *port;
795 }
796
797 /**
798  Set the receive multicast port
799
800  @param value
801  The receive multicast port (a number in string representation)
802  @param data
803  Unused
804  @param addon
805  Unused
806
807  @return
808  - true when an error is detected
809  - false otherwise
810  */
811 int setRxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
812         static const char * valueName = PUD_RX_MC_PORT_NAME;
813         unsigned long long rxMcPortNew;
814         in_port_t * port;
815         union olsr_sockaddr * addr = getRxMcAddr();
816
817         assert (value != NULL);
818
819         if (!readULL(valueName, value, &rxMcPortNew)) {
820                 return true;
821         }
822
823         if ((rxMcPortNew < 1) || (rxMcPortNew > 65535)) {
824                 pudError(false, "Configured %s (%llu) is outside of"
825                         " valid range 1-65535", valueName, rxMcPortNew);
826                 return true;
827         }
828
829         getOlsrSockaddrPortAddress(olsr_cnf->ip_version, addr, &port);
830         *port = htons((uint16_t) rxMcPortNew);
831
832         return false;
833 }
834
835 /*
836  * txNonOlsrIf
837  */
838
839 /** The maximum number of rx non-olsr interfaces */
840 #define PUD_TX_NON_OLSR_IF_MAX 32
841
842 /** Array with tx non-olsr interface names */
843 static unsigned char txNonOlsrInterfaceNames[PUD_TX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
844
845 /** The number of tx interface names in the array */
846 static unsigned int txNonOlsrInterfaceCount = 0;
847
848 /**
849  Determine whether a give interface name is configured as a transmit non-OLSR
850  interface.
851
852  @param ifName
853  The interface to check
854
855  @return
856  - true when the given interface name is configured as a transmit non-OLSR
857  interface
858  - false otherwise
859  */
860 bool isTxNonOlsrInterface(const char *ifName) {
861         unsigned int i;
862
863         assert (ifName != NULL);
864
865         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
866                 if (strncmp((char *) &txNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
867                                 + 1) == 0) {
868                         return true;
869                 }
870         }
871
872         return false;
873 }
874
875 /**
876  Add a transmit non-OLSR interface
877
878  @param value
879  The name of the non-OLSR interface to add
880  @param data
881  Unused
882  @param addon
883  Unused
884
885  @return
886  - true when an error is detected
887  - false otherwise
888  */
889 int addTxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
890                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
891         unsigned long valueLength;
892
893         assert (value != NULL);
894
895         valueLength = strlen(value);
896         if (valueLength > IFNAMSIZ) {
897                 pudError(false, "Configured %s (%s) is too long,"
898                         " maximum length is %u, current length is %lu",
899                                 PUD_TX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
900                 return true;
901         }
902
903         if (!isTxNonOlsrInterface(value)) {
904                 if (txNonOlsrInterfaceCount >= PUD_TX_NON_OLSR_IF_MAX) {
905                         pudError(false, "Can not configure more than %u transmit"
906                                 " interfaces", PUD_TX_NON_OLSR_IF_MAX);
907                         return true;
908                 }
909
910                 strcpy((char *) &txNonOlsrInterfaceNames[txNonOlsrInterfaceCount][0],
911                                 value);
912                 txNonOlsrInterfaceCount++;
913         }
914
915         return false;
916 }
917
918 /*
919  * txMcAddr
920  */
921
922 /** The tx multicast address */
923 static union olsr_sockaddr txMcAddr;
924
925 /** True when the tx multicast address is set */
926 static bool txMcAddrSet = false;
927
928 /**
929  @return
930  The transmit multicast address (in network byte order). Sets both the address
931  and the port to their default values when the address was not yet set.
932  */
933 union olsr_sockaddr * getTxMcAddr(void) {
934         if (!txMcAddrSet) {
935                 setTxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
936         }
937         return &txMcAddr;
938 }
939
940 /**
941  Set the transmit multicast address. Sets the address to its default value when
942  the value is NULL. Also sets the port to its default value when the address
943  was not yet set.
944
945  @param value
946  The transmit multicast address (in string representation)
947  @param data
948  Unused
949  @param addon
950  Unused
951
952  @return
953  - true when an error is detected
954  - false otherwise
955  */
956 int setTxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
957         static const char * valueName = PUD_TX_MC_ADDR_NAME;
958         void * ipAddress;
959         in_port_t * port;
960         const char * valueInternal = value;
961         int conversion;
962
963         getOlsrSockAddrAndPortAddresses(olsr_cnf->ip_version, &txMcAddr, &ipAddress,
964                         &port);
965         if (olsr_cnf->ip_version == AF_INET) {
966                 txMcAddr.in4.sin_family = olsr_cnf->ip_version;
967                 if (valueInternal == NULL) {
968                         valueInternal = PUD_TX_MC_ADDR_4_DEFAULT;
969                 }
970         } else {
971                 txMcAddr.in6.sin6_family = olsr_cnf->ip_version;
972                 if (valueInternal == NULL) {
973                         valueInternal = PUD_TX_MC_ADDR_6_DEFAULT;
974                 }
975         }
976
977         if (!txMcAddrSet) {
978                 *port = htons(PUD_TX_MC_PORT_DEFAULT);
979         }
980
981         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
982         if (conversion != 1) {
983                 pudError((conversion == -1) ? true : false,
984                                 "Configured %s (%s) is not an IP address", valueName,
985                                 valueInternal);
986                 return true;
987         }
988
989         if (!isMulticast(olsr_cnf->ip_version, &txMcAddr)) {
990                 pudError(false, "Configured %s (%s) is not a multicast address",
991                                 valueName, valueInternal);
992                 return true;
993         }
994
995         txMcAddrSet = true;
996         return false;
997 }
998
999 /*
1000  * txMcPort
1001  */
1002
1003 /**
1004  @return
1005  The transmit multicast port (in network byte order)
1006  */
1007 unsigned short getTxMcPort(void) {
1008         in_port_t * port;
1009         getOlsrSockaddrPortAddress(olsr_cnf->ip_version, getTxMcAddr(), &port);
1010         return *port;
1011 }
1012
1013 /**
1014  Set the transmit multicast port
1015
1016  @param value
1017  The transmit multicast port (a number in string representation)
1018  @param data
1019  Unused
1020  @param addon
1021  Unused
1022
1023  @return
1024  - true when an error is detected
1025  - false otherwise
1026  */
1027 int setTxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1028         static const char * valueName = PUD_TX_MC_PORT_NAME;
1029         unsigned long long txMcPortNew;
1030         in_port_t * port;
1031         union olsr_sockaddr * addr = getTxMcAddr();
1032
1033         assert (value != NULL);
1034
1035         if (!readULL(valueName, value, &txMcPortNew)) {
1036                 return true;
1037         }
1038
1039         if ((txMcPortNew < 1) || (txMcPortNew > 65535)) {
1040                 pudError(false, "Configured %s (%llu) is outside of"
1041                         " valid range 1-65535", valueName, txMcPortNew);
1042                 return true;
1043         }
1044
1045         getOlsrSockaddrPortAddress(olsr_cnf->ip_version, addr, &port);
1046         *port = htons((uint16_t) txMcPortNew);
1047
1048         return false;
1049 }
1050
1051 /*
1052  * uplinkAddr
1053  */
1054
1055 /** The uplink address */
1056 static union olsr_sockaddr uplinkAddr;
1057
1058 /** True when the uplink address is set */
1059 static bool uplinkAddrSet = false;
1060
1061 /** True when the uplink address is set */
1062 static bool uplinkPortSet = false;
1063
1064 /**
1065  @return
1066  - true when the uplink address is set
1067  - false otherwise
1068  */
1069 bool isUplinkAddrSet(void) {
1070         return uplinkAddrSet;
1071 }
1072
1073 /**
1074  @return
1075  The uplink address (in network byte order). Sets both the address
1076  and the port to their default values when the address was not yet set.
1077  */
1078 union olsr_sockaddr * getUplinkAddr(void) {
1079         if (!uplinkAddrSet) {
1080                 setUplinkAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
1081         }
1082         return &uplinkAddr;
1083 }
1084
1085 /**
1086  Set the uplink address. Sets the address to its default value when
1087  the value is NULL. Also sets the port to its default value when the address
1088  was not yet set.
1089
1090  @param value
1091  The uplink address (in string representation)
1092  @param data
1093  Unused
1094  @param addon
1095  Unused
1096
1097  @return
1098  - true when an error is detected
1099  - false otherwise
1100  */
1101 int setUplinkAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1102         static const char * valueName = PUD_UPLINK_ADDR_NAME;
1103         void * ipAddress;
1104         in_port_t * port;
1105         const char * valueInternal = value;
1106         int conversion;
1107         bool defaultValue = false;
1108
1109         getOlsrSockAddrAndPortAddresses(olsr_cnf->ip_version, &uplinkAddr,
1110                         &ipAddress, &port);
1111         if (olsr_cnf->ip_version == AF_INET) {
1112                 uplinkAddr.in4.sin_family = olsr_cnf->ip_version;
1113                 if (valueInternal == NULL) {
1114                         valueInternal = PUD_UPLINK_ADDR_4_DEFAULT;
1115                         defaultValue = true;
1116                 }
1117         } else {
1118                 uplinkAddr.in6.sin6_family = olsr_cnf->ip_version;
1119                 if (valueInternal == NULL) {
1120                         valueInternal = PUD_UPLINK_ADDR_6_DEFAULT;
1121                         defaultValue = true;
1122                 }
1123         }
1124
1125         if (!uplinkPortSet) {
1126                 *port = htons(PUD_UPLINK_PORT_DEFAULT);
1127                 uplinkPortSet = true;
1128         }
1129
1130         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
1131         if (conversion != 1) {
1132                 pudError((conversion == -1) ? true : false,
1133                                 "Configured %s (%s) is not an IP address", valueName,
1134                                 valueInternal);
1135                 return true;
1136         }
1137
1138         if (!defaultValue) {
1139                 uplinkAddrSet = true;
1140         }
1141
1142         return false;
1143 }
1144
1145 /*
1146  * uplinkPort
1147  */
1148
1149 /**
1150  @return
1151  The uplink port (in network byte order)
1152  */
1153 unsigned short getUplinkPort(void) {
1154         in_port_t * port;
1155         getOlsrSockaddrPortAddress(olsr_cnf->ip_version, getUplinkAddr(), &port);
1156         return *port;
1157 }
1158
1159 /**
1160  Set the uplink port
1161
1162  @param value
1163  The uplink port (a number in string representation)
1164  @param data
1165  Unused
1166  @param addon
1167  Unused
1168
1169  @return
1170  - true when an error is detected
1171  - false otherwise
1172  */
1173 int setUplinkPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1174         static const char * valueName = PUD_UPLINK_PORT_NAME;
1175         unsigned long long uplinkPortNew;
1176         in_port_t * port;
1177         union olsr_sockaddr * addr = getUplinkAddr();
1178
1179         assert (value != NULL);
1180
1181         if (!readULL(valueName, value, &uplinkPortNew)) {
1182                 return true;
1183         }
1184
1185         if ((uplinkPortNew < 1) || (uplinkPortNew > 65535)) {
1186                 pudError(false, "Configured %s (%llu) is outside of"
1187                         " valid range 1-65535", valueName, uplinkPortNew);
1188                 return true;
1189         }
1190
1191         getOlsrSockaddrPortAddress(olsr_cnf->ip_version, addr, &port);
1192         *port = htons((uint16_t) uplinkPortNew);
1193         uplinkPortSet = true;
1194
1195         return false;
1196 }
1197
1198
1199 /*
1200  * downlinkPort
1201  */
1202
1203 /** the downlink port */
1204 unsigned short downlinkPort = 0;
1205
1206 /** true when the downlinkPort is set */
1207 bool downlinkPortSet = false;
1208
1209 /**
1210  @return
1211  The downlink port (in network byte order)
1212  */
1213 unsigned short getDownlinkPort(void) {
1214         if (!downlinkPortSet) {
1215                 downlinkPort = htons(PUD_DOWNLINK_PORT_DEFAULT);
1216                 downlinkPortSet = true;
1217         }
1218
1219         return downlinkPort;
1220 }
1221
1222 /**
1223  Set the downlink port
1224
1225  @param value
1226  The downlink port (a number in string representation)
1227  @param data
1228  Unused
1229  @param addon
1230  Unused
1231
1232  @return
1233  - true when an error is detected
1234  - false otherwise
1235  */
1236 int setDownlinkPort(const char *value, void *data __attribute__ ((unused)),
1237                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1238         static const char * valueName = PUD_DOWNLINK_PORT_NAME;
1239         unsigned long long downlinkPortNew;
1240
1241         assert(value != NULL);
1242
1243         if (!readULL(valueName, value, &downlinkPortNew)) {
1244                 return true;
1245         }
1246
1247         if ((downlinkPortNew < 1) || (downlinkPortNew > 65535)) {
1248                 pudError(false, "Configured %s (%llu) is outside of"
1249                                 " valid range 1-65535", valueName, downlinkPortNew);
1250                 return true;
1251         }
1252
1253         downlinkPort = htons(downlinkPortNew);
1254         downlinkPortSet = true;
1255
1256         return false;
1257 }
1258
1259 /*
1260  * txTtl
1261  */
1262
1263 /** The tx TTL */
1264 static unsigned char txTtl = PUD_TX_TTL_DEFAULT;
1265
1266 /**
1267  @return
1268  The transmit multicast IP packet time-to-live
1269  */
1270 unsigned char getTxTtl(void) {
1271         return txTtl;
1272 }
1273
1274 /**
1275  Set the transmit multicast IP packet time-to-live
1276
1277  @param value
1278  The transmit multicast IP packet time-to-live (a number in string representation)
1279  @param data
1280  Unused
1281  @param addon
1282  Unused
1283
1284  @return
1285  - true when an error is detected
1286  - false otherwise
1287  */
1288 int setTxTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1289         static const char * valueName = PUD_TX_TTL_NAME;
1290         unsigned long long txTtlNew;
1291
1292         assert (value != NULL);
1293
1294         if (!readULL(valueName, value, &txTtlNew)) {
1295                 return true;
1296         }
1297
1298         if ((txTtlNew < 1) || (txTtlNew > MAX_TTL)) {
1299                 pudError(false, "Configured %s (%llu) is outside of"
1300                         " valid range 1-%u", valueName, txTtlNew, MAX_TTL);
1301                 return true;
1302         }
1303
1304         txTtl = txTtlNew;
1305
1306         return false;
1307 }
1308
1309 /*
1310  * txNmeaMessagePrefix
1311  */
1312
1313 /** The exact length of the tx NMEA message prefix */
1314 #define PUD_TXNMEAMESSAGEPREFIXLENGTH 4
1315
1316 /** The tx NMEA message prefix buffer */
1317 static unsigned char txNmeaMessagePrefix[PUD_TXNMEAMESSAGEPREFIXLENGTH + 1];
1318
1319 /** True when the tx NMEA message prefix is set */
1320 static bool txNmeaMessagePrefixSet = false;
1321
1322 /**
1323  @return
1324  The transmit multicast NMEA message prefix
1325  */
1326 unsigned char * getTxNmeaMessagePrefix(void) {
1327         if (!txNmeaMessagePrefixSet) {
1328                 setTxNmeaMessagePrefix(PUD_TX_NMEAMESSAGEPREFIX_DEFAULT, NULL,
1329                                 (set_plugin_parameter_addon) {.pc = NULL});
1330         }
1331         return &txNmeaMessagePrefix[0];
1332 }
1333
1334 /**
1335  Set the transmit multicast NMEA message prefix
1336
1337  @param value
1338  The transmit multicast NMEA message prefix (in string representation)
1339  @param data
1340  Unused
1341  @param addon
1342  Unused
1343
1344  @return
1345  - true when an error is detected
1346  - false otherwise
1347  */
1348 int setTxNmeaMessagePrefix(const char *value, void *data __attribute__ ((unused)),
1349                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1350         static const char * valueName = PUD_TX_NMEAMESSAGEPREFIX_NAME;
1351         size_t valueLength;
1352         bool invalidChars;
1353         char report[256];
1354
1355         assert (value != NULL);
1356
1357         valueLength = strlen(value);
1358         if (valueLength != PUD_TXNMEAMESSAGEPREFIXLENGTH) {
1359                 pudError(false, "Configured %s (%s) must be %u exactly characters",
1360                                 valueName, value, PUD_TXNMEAMESSAGEPREFIXLENGTH);
1361                 return true;
1362         }
1363
1364         invalidChars = nmea_string_has_invalid_chars(value, valueName, &report[0],
1365                         sizeof(report));
1366         if (invalidChars) {
1367                 pudError(false, &report[0]);
1368                 return true;
1369         }
1370
1371         if ((strchr(value, ' ') != NULL) || (strchr(value, '\t') != NULL)) {
1372                 pudError(false, "Configured %s (%s) can not contain whitespace",
1373                                 valueName, value);
1374                 return true;
1375         }
1376
1377         strcpy((char *) &txNmeaMessagePrefix[0], value);
1378         txNmeaMessagePrefixSet = true;
1379         return false;
1380 }
1381
1382 /*
1383  * olsrTtl
1384  */
1385
1386 /** The OLSR TTL */
1387 static unsigned char olsrTtl = PUD_OLSR_TTL_DEFAULT;
1388
1389 /**
1390  @return
1391  The OLSR multicast IP packet time-to-live
1392  */
1393 unsigned char getOlsrTtl(void) {
1394         return olsrTtl;
1395 }
1396
1397 /**
1398  Set the OLSR multicast IP packet time-to-live
1399
1400  @param value
1401  The OLSR multicast IP packet time-to-live (a number in string representation)
1402  @param data
1403  Unused
1404  @param addon
1405  Unused
1406
1407  @return
1408  - true when an error is detected
1409  - false otherwise
1410  */
1411 int setOlsrTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1412         static const char * valueName = PUD_OLSR_TTL_NAME;
1413         unsigned long long olsrTtlNew;
1414
1415         assert (value != NULL);
1416
1417         if (!readULL(valueName, value, &olsrTtlNew)) {
1418                 return true;
1419         }
1420
1421         if ((olsrTtlNew < 1) || (olsrTtlNew > MAX_TTL)) {
1422                 pudError(false, "Configured %s (%llu) is outside of valid range 1-%u",
1423                                 valueName, olsrTtlNew, MAX_TTL);
1424                 return true;
1425         }
1426
1427         olsrTtl = olsrTtlNew;
1428
1429         return false;
1430 }
1431
1432 /*
1433  * updateIntervalStationary
1434  */
1435
1436 /** The stationary interval update plugin parameter (in seconds) */
1437 static unsigned long long updateIntervalStationary = PUD_UPDATE_INTERVAL_STATIONARY_DEFAULT;
1438
1439 /**
1440  @return
1441  The stationary interval update plugin parameter (in seconds)
1442  */
1443 unsigned long long getUpdateIntervalStationary(void) {
1444         return updateIntervalStationary;
1445 }
1446
1447 /**
1448  Set stationary interval update plugin parameter
1449
1450  @param value
1451  The stationary interval update plugin parameter (in seconds)
1452  @param data
1453  Unused
1454  @param addon
1455  Unused
1456
1457  @return
1458  - true when an error is detected
1459  - false otherwise
1460  */
1461 int setUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1462                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1463         static const char * valueName = PUD_UPDATE_INTERVAL_STATIONARY_NAME;
1464         unsigned long long updateIntervalStationaryNew;
1465
1466         assert (value != NULL);
1467
1468         if (!readULL(valueName, value, &updateIntervalStationaryNew)) {
1469                 return true;
1470         }
1471
1472         if (updateIntervalStationaryNew < 1) {
1473                 pudError(false, "Configured %s must be at least 1", valueName);
1474                 return true;
1475         }
1476
1477         updateIntervalStationary = updateIntervalStationaryNew;
1478
1479         return false;
1480 }
1481
1482 /*
1483  * updateIntervalMoving
1484  */
1485
1486 /** The moving interval update plugin parameter (in seconds) */
1487 static unsigned long long updateIntervalMoving = PUD_UPDATE_INTERVAL_MOVING_DEFAULT;
1488
1489 /**
1490  @return
1491  The moving interval update plugin parameter (in seconds)
1492  */
1493 unsigned long long getUpdateIntervalMoving(void) {
1494         return updateIntervalMoving;
1495 }
1496
1497 /**
1498  Set moving interval update plugin parameter
1499
1500  @param value
1501  The moving interval update plugin parameter (in seconds)
1502  @param data
1503  Unused
1504  @param addon
1505  Unused
1506
1507  @return
1508  - true when an error is detected
1509  - false otherwise
1510  */
1511 int setUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1512                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1513         static const char * valueName = PUD_UPDATE_INTERVAL_MOVING_NAME;
1514         unsigned long long updateIntervalMovingNew;
1515
1516         assert (value != NULL);
1517
1518         if (!readULL(valueName, value, &updateIntervalMovingNew)) {
1519                 return true;
1520         }
1521
1522         if (updateIntervalMovingNew < 1) {
1523                 pudError(false, "Configured %s must be at least 1", valueName);
1524                 return true;
1525         }
1526
1527         updateIntervalMoving = updateIntervalMovingNew;
1528
1529         return false;
1530 }
1531
1532 /*
1533  * uplinkUpdateIntervalStationary
1534  */
1535
1536 /** The uplink stationary interval update plugin parameter (in seconds) */
1537 static unsigned long long uplinkUpdateIntervalStationary = PUD_UPLINK_UPDATE_INTERVAL_STATIONARY_DEFAULT;
1538
1539 /**
1540  @return
1541  The uplink stationary interval update plugin parameter (in seconds)
1542  */
1543 unsigned long long getUplinkUpdateIntervalStationary(void) {
1544         return uplinkUpdateIntervalStationary;
1545 }
1546
1547 /**
1548  Set uplink stationary interval update plugin parameter
1549
1550  @param value
1551  The uplink stationary interval update plugin parameter (in seconds)
1552  @param data
1553  Unused
1554  @param addon
1555  Unused
1556
1557  @return
1558  - true when an error is detected
1559  - false otherwise
1560  */
1561 int setUplinkUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1562                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1563         static const char * valueName = PUD_UPLINK_UPDATE_INTERVAL_STATIONARY_NAME;
1564         unsigned long long uplinkUpdateIntervalStationaryNew;
1565
1566         assert (value != NULL);
1567
1568         if (!readULL(valueName, value, &uplinkUpdateIntervalStationaryNew)) {
1569                 return true;
1570         }
1571
1572         if (uplinkUpdateIntervalStationaryNew < 1) {
1573                 pudError(false, "Configured %s must be at least 1", valueName);
1574                 return true;
1575         }
1576
1577         uplinkUpdateIntervalStationary = uplinkUpdateIntervalStationaryNew;
1578
1579         return false;
1580 }
1581
1582 /*
1583  * uplinkUpdateIntervalMoving
1584  */
1585
1586 /** The uplink moving interval update plugin parameter (in seconds) */
1587 static unsigned long long uplinkUpdateIntervalMoving = PUD_UPLINK_UPDATE_INTERVAL_MOVING_DEFAULT;
1588
1589 /**
1590  @return
1591  The uplink moving interval update plugin parameter (in seconds)
1592  */
1593 unsigned long long getUplinkUpdateIntervalMoving(void) {
1594         return uplinkUpdateIntervalMoving;
1595 }
1596
1597 /**
1598  Set uplink moving interval update plugin parameter
1599
1600  @param value
1601  The uplink moving interval update plugin parameter (in seconds)
1602  @param data
1603  Unused
1604  @param addon
1605  Unused
1606
1607  @return
1608  - true when an error is detected
1609  - false otherwise
1610  */
1611 int setUplinkUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1612                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1613         static const char * valueName = PUD_UPLINK_UPDATE_INTERVAL_MOVING_NAME;
1614         unsigned long long uplinkUpdateIntervalMovingNew;
1615
1616         assert (value != NULL);
1617
1618         if (!readULL(valueName, value, &uplinkUpdateIntervalMovingNew)) {
1619                 return true;
1620         }
1621
1622         if (uplinkUpdateIntervalMovingNew < 1) {
1623                 pudError(false, "Configured %s must be at least 1", valueName);
1624                 return true;
1625         }
1626
1627         uplinkUpdateIntervalMoving = uplinkUpdateIntervalMovingNew;
1628
1629         return false;
1630 }
1631
1632 /*
1633  * movingSpeedThreshold
1634  */
1635
1636 /** The moving speed threshold plugin parameter (in kph) */
1637 static unsigned long long movingSpeedThreshold = PUD_MOVING_SPEED_THRESHOLD_DEFAULT;
1638
1639 /**
1640  @return
1641  The moving speed threshold plugin parameter (in kph)
1642  */
1643 unsigned long long getMovingSpeedThreshold(void) {
1644         return movingSpeedThreshold;
1645 }
1646
1647 /**
1648  Set moving speed threshold plugin parameter
1649
1650  @param value
1651  The moving speed threshold plugin parameter (in kph)
1652  @param data
1653  Unused
1654  @param addon
1655  Unused
1656
1657  @return
1658  - true when an error is detected
1659  - false otherwise
1660  */
1661 int setMovingSpeedThreshold(const char *value, void *data __attribute__ ((unused)),
1662                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1663         static const char * valueName = PUD_MOVING_SPEED_THRESHOLD_NAME;
1664         unsigned long long movingSpeedThresholdNew;
1665
1666         assert (value != NULL);
1667
1668         if (!readULL(valueName, value, &movingSpeedThresholdNew)) {
1669                 return true;
1670         }
1671
1672         movingSpeedThreshold = movingSpeedThresholdNew;
1673
1674         return false;
1675 }
1676
1677 /*
1678  * movingDistanceThreshold
1679  */
1680
1681 /** The moving distance threshold plugin parameter (in meters) */
1682 static unsigned long long movingDistanceThreshold = PUD_MOVING_DISTANCE_THRESHOLD_DEFAULT;
1683
1684 /**
1685  @return
1686  The moving distance threshold plugin parameter (in meters)
1687  */
1688 unsigned long long getMovingDistanceThreshold(void) {
1689         return movingDistanceThreshold;
1690 }
1691
1692 /**
1693  Set moving distance threshold plugin parameter
1694
1695  @param value
1696  The moving distance threshold plugin parameter (in meter)
1697  @param data
1698  Unused
1699  @param addon
1700  Unused
1701
1702  @return
1703  - true when an error is detected
1704  - false otherwise
1705  */
1706 int setMovingDistanceThreshold(const char *value, void *data __attribute__ ((unused)),
1707                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1708         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1709         unsigned long long movingDistanceThresholdNew;
1710
1711         assert (value != NULL);
1712
1713         if (!readULL(valueName, value, &movingDistanceThresholdNew)) {
1714                 return true;
1715         }
1716
1717         movingDistanceThreshold = movingDistanceThresholdNew;
1718
1719         return false;
1720 }
1721
1722 /*
1723  * dopMultiplier
1724  */
1725
1726 /* The DOP multiplier plugin parameter */
1727 static double dopMultiplier = PUD_DOP_MULTIPLIER_DEFAULT;
1728
1729 /**
1730  @return
1731  The DOP multiplier plugin parameter
1732  */
1733 double getDopMultiplier(void) {
1734         return dopMultiplier;
1735 }
1736
1737 /**
1738  Set DOP multiplier plugin parameter
1739
1740  @param value
1741  The DOP multiplier plugin parameter
1742  @param data
1743  Unused
1744  @param addon
1745  Unused
1746
1747  @return
1748  - true when an error is detected
1749  - false otherwise
1750  */
1751 int setDopMultiplier(const char *value, void *data __attribute__ ((unused)),
1752                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1753         static const char * valueName = PUD_DOP_MULTIPLIER_NAME;
1754         double dopMultiplierNew;
1755
1756         assert (value != NULL);
1757
1758         if (!readDouble(valueName, value, &dopMultiplierNew)) {
1759                 return true;
1760         }
1761
1762         dopMultiplier = dopMultiplierNew;
1763
1764         return false;
1765 }
1766
1767 /*
1768  * defaultHdop
1769  */
1770
1771 /** The default HDOP plugin parameter (in meters) */
1772 static unsigned long long defaultHdop = PUD_DEFAULT_HDOP_DEFAULT;
1773
1774 /**
1775  @return
1776  The default HDOP plugin parameter (in meters)
1777  */
1778 unsigned long long getDefaultHdop(void) {
1779         return defaultHdop;
1780 }
1781
1782 /**
1783  Set default HDOP plugin parameter
1784
1785  @param value
1786  The default HDOP plugin parameter (in meters)
1787  @param data
1788  Unused
1789  @param addon
1790  Unused
1791
1792  @return
1793  - true when an error is detected
1794  - false otherwise
1795  */
1796 int setDefaultHdop(const char *value, void *data __attribute__ ((unused)),
1797                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1798         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1799         unsigned long long defaultHdopNew;
1800
1801         assert (value != NULL);
1802
1803         if (!readULL(valueName, value, &defaultHdopNew)) {
1804                 return true;
1805         }
1806
1807         defaultHdop = defaultHdopNew;
1808
1809         return false;
1810 }
1811
1812 /*
1813  * defaultVdop
1814  */
1815
1816 /** The default VDOP plugin parameter (in meters) */
1817 static unsigned long long defaultVdop = PUD_DEFAULT_VDOP_DEFAULT;
1818
1819 /**
1820  @return
1821  The default VDOP plugin parameter (in meters)
1822  */
1823 unsigned long long getDefaultVdop(void) {
1824         return defaultVdop;
1825 }
1826
1827 /**
1828  Set default VDOP plugin parameter
1829
1830  @param value
1831  The default VDOP plugin parameter (in meters)
1832  @param data
1833  Unused
1834  @param addon
1835  Unused
1836
1837  @return
1838  - true when an error is detected
1839  - false otherwise
1840  */
1841 int setDefaultVdop(const char *value, void *data __attribute__ ((unused)),
1842                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1843         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1844         unsigned long long defaultVdopNew;
1845
1846         assert (value != NULL);
1847
1848         if (!readULL(valueName, value, &defaultVdopNew)) {
1849                 return true;
1850         }
1851
1852         defaultVdop = defaultVdopNew;
1853
1854         return false;
1855 }
1856
1857 /*
1858  * averageDepth
1859  */
1860
1861 /** The depth of the average list */
1862 static unsigned long long averageDepth = PUD_AVERAGE_DEPTH_DEFAULT;
1863
1864 /**
1865  @return
1866  The depth of the average list
1867  */
1868 unsigned long long getAverageDepth(void) {
1869         return averageDepth;
1870 }
1871
1872 /**
1873  Set average depth plugin parameter
1874
1875  @param value
1876  The average depth plugin parameter
1877  @param data
1878  Unused
1879  @param addon
1880  Unused
1881
1882  @return
1883  - true when an error is detected
1884  - false otherwise
1885  */
1886 int setAverageDepth(const char *value, void *data __attribute__ ((unused)),
1887                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1888         static const char * valueName = PUD_AVERAGE_DEPTH_NAME;
1889         unsigned long long averageDepthNew;
1890
1891         assert (value != NULL);
1892
1893         if (!readULL(valueName, value, &averageDepthNew)) {
1894                 return true;
1895         }
1896
1897         if (averageDepthNew < 1) {
1898                 pudError(false, "Configured %s must be at least 1", valueName);
1899                 return true;
1900         }
1901
1902         averageDepth = averageDepthNew;
1903
1904         return false;
1905 }
1906
1907 /*
1908  * hysteresisCountToStationary
1909  */
1910
1911 /** The hysteresis count for changing state from moving to stationary */
1912 static unsigned long long hysteresisCountToStationary = PUD_HYSTERESIS_COUNT_2STAT_DEFAULT;
1913
1914 /**
1915  @return
1916  The hysteresis count for changing state from moving to stationary
1917  */
1918 unsigned long long getHysteresisCountToStationary(void) {
1919         return hysteresisCountToStationary;
1920 }
1921
1922 /**
1923  Set hysteresis count plugin parameter
1924
1925  @param value
1926  The hysteresis count plugin parameter
1927  @param data
1928  Unused
1929  @param addon
1930  Unused
1931
1932  @return
1933  - true when an error is detected
1934  - false otherwise
1935  */
1936 int setHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1937                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1938         static const char * valueName = PUD_HYSTERESIS_COUNT_2STAT_NAME;
1939         unsigned long long hysteresisCountNew;
1940
1941         assert (value != NULL);
1942
1943         if (!readULL(valueName, value, &hysteresisCountNew)) {
1944                 return true;
1945         }
1946
1947         hysteresisCountToStationary = hysteresisCountNew;
1948
1949         return false;
1950 }
1951
1952 /*
1953  * hysteresisCountToMoving
1954  */
1955
1956 /** The hysteresis count for changing state from stationary to moving */
1957 static unsigned long long hysteresisCountToMoving = PUD_HYSTERESIS_COUNT_2MOV_DEFAULT;
1958
1959 /**
1960  @return
1961  The hysteresis count for changing state from stationary to moving
1962  */
1963 unsigned long long getHysteresisCountToMoving(void) {
1964         return hysteresisCountToMoving;
1965 }
1966
1967 /**
1968  Set hysteresis count plugin parameter
1969
1970  @param value
1971  The hysteresis count plugin parameter
1972  @param data
1973  Unused
1974  @param addon
1975  Unused
1976
1977  @return
1978  - true when an error is detected
1979  - false otherwise
1980  */
1981 int setHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1982                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1983         static const char * valueName = PUD_HYSTERESIS_COUNT_2MOV_NAME;
1984         unsigned long long hysteresisCountNew;
1985
1986         assert (value != NULL);
1987
1988         if (!readULL(valueName, value, &hysteresisCountNew)) {
1989                 return true;
1990         }
1991
1992         hysteresisCountToMoving = hysteresisCountNew;
1993
1994         return false;
1995 }
1996
1997 /*
1998  * useDeDup
1999  */
2000
2001 /* when true then duplicate message detection is performed */
2002 static bool useDeDup = PUD_USE_DEDUP_DEFAULT;
2003
2004 /**
2005  @return
2006  The duplicate message detection setting
2007  */
2008 bool getUseDeDup(void) {
2009         return useDeDup;
2010 }
2011
2012 /**
2013  Set duplicate message detection setting plugin parameter
2014
2015  @param value
2016  The duplicate message detection setting plugin parameter
2017  @param data
2018  Unused
2019  @param addon
2020  Unused
2021
2022  @return
2023  - true when an error is detected
2024  - false otherwise
2025  */
2026 int setUseDeDup(const char *value, void *data __attribute__ ((unused)),
2027                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
2028         static const char * valueName = PUD_USE_DEDUP_NAME;
2029         unsigned long long useDeDupNew;
2030
2031         assert (value != NULL);
2032
2033         if (!readULL(valueName, value, &useDeDupNew)) {
2034                 return true;
2035         }
2036
2037         if ((useDeDupNew != 0) && (useDeDupNew != 1)) {
2038                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
2039                                 valueName);
2040                 return true;
2041         }
2042
2043         useDeDup = (useDeDupNew == 1);
2044
2045         return false;
2046 }
2047
2048 /*
2049  * deDupDepth
2050  */
2051
2052 /** The hysteresis count for changing state from stationary to moving */
2053 static unsigned long long deDupDepth = PUD_DEDUP_DEPTH_DEFAULT;
2054
2055 /**
2056  @return
2057  The hysteresis count for changing state from stationary to moving
2058  */
2059 unsigned long long getDeDupDepth(void) {
2060         return deDupDepth;
2061 }
2062
2063 /**
2064  Set de-duplication depth plugin parameter
2065
2066  @param value
2067  The de-duplication depth plugin parameter
2068  @param data
2069  Unused
2070  @param addon
2071  Unused
2072
2073  @return
2074  - true when an error is detected
2075  - false otherwise
2076  */
2077 int setDeDupDepth(const char *value, void *data __attribute__ ((unused)),
2078                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
2079         static const char * valueName = PUD_DEDUP_DEPTH_NAME;
2080         unsigned long long deDupDepthNew;
2081
2082         assert (value != NULL);
2083
2084         if (!readULL(valueName, value, &deDupDepthNew)) {
2085                 return true;
2086         }
2087
2088         deDupDepth = deDupDepthNew;
2089
2090         return false;
2091 }
2092
2093 /*
2094  * useLoopback
2095  */
2096
2097 /* when true then loopback is performed */
2098 static bool useLoopback = PUD_USE_LOOPBACK_DEFAULT;
2099
2100 /**
2101  @return
2102  The loopback usage setting
2103  */
2104 bool getUseLoopback(void) {
2105         return useLoopback;
2106 }
2107
2108 /**
2109  Set loopback usage plugin parameter
2110
2111  @param value
2112  The loopback usage plugin parameter
2113  @param data
2114  Unused
2115  @param addon
2116  Unused
2117
2118  @return
2119  - true when an error is detected
2120  - false otherwise
2121  */
2122 int setUseLoopback(const char *value, void *data __attribute__ ((unused)),
2123                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
2124         static const char * valueName = PUD_USE_LOOPBACK_NAME;
2125         unsigned long long useLoopbackNew;
2126
2127         assert (value != NULL);
2128
2129         if (!readULL(valueName, value, &useLoopbackNew)) {
2130                 return true;
2131         }
2132
2133         if ((useLoopbackNew != 0) && (useLoopbackNew != 1)) {
2134                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
2135                                 valueName);
2136                 return true;
2137         }
2138
2139         useLoopback = (useLoopbackNew == 1);
2140
2141         return false;
2142 }
2143
2144 /*
2145  * Check Functions
2146  */
2147
2148 /**
2149  Check the configuration for consistency and validity.
2150
2151  @return
2152  - true when the configuration is consistent and valid
2153  - false otherwise
2154  */
2155 unsigned int checkConfig(void) {
2156         int retval = true;
2157
2158         if (!olsr_cnf->smart_gw_active) {
2159                 pudError(false, "Smart Gateway must be active");
2160                 retval = false;
2161         }
2162
2163         if (rxNonOlsrInterfaceCount == 0) {
2164                 pudError(false, "No receive non-OLSR interfaces configured");
2165                 retval = false;
2166         }
2167
2168         if (txNonOlsrInterfaceCount == 0) {
2169                 pudError(false, "No transmit non-OLSR interfaces configured");
2170                 retval = false;
2171         }
2172
2173         if (!nodeIdSet) {
2174                 if (nodeIdType == PUD_NODEIDTYPE_DNS) {
2175                         char name[PUD_NODEIDMAXLENGTH + 1];
2176
2177                         errno = 0;
2178                         if (gethostname(&name[0], sizeof(name)) < 0) {
2179                                 pudError(true, "Could not get the host name");
2180                                 retval = false;
2181                         } else {
2182                                 setNodeId(&name[0], NULL,
2183                                                 (set_plugin_parameter_addon) {.pc = NULL});
2184                         }
2185                 } else if ((nodeIdType != PUD_NODEIDTYPE_MAC) && (nodeIdType
2186                                 != PUD_NODEIDTYPE_IPV4) && (nodeIdType != PUD_NODEIDTYPE_IPV6)) {
2187                         pudError(false, "No node ID set while one is required for"
2188                                 " node type %u", nodeIdType);
2189                         retval = false;
2190                 }
2191         }
2192
2193         if (!setupNodeIdBinaryAndValidate(nodeIdType)) {
2194                 retval = false;
2195         }
2196
2197         if (updateIntervalMoving > updateIntervalStationary) {
2198                 pudError(false,"The update interval for moving situations must not be"
2199                 " larger than that for stationary situations");
2200                 retval = false;
2201         }
2202
2203         if (uplinkUpdateIntervalMoving > uplinkUpdateIntervalStationary) {
2204                 pudError(false,"The uplink update interval for moving situations must not be"
2205                 " larger than that for stationary situations");
2206                 retval = false;
2207         }
2208
2209         if (getUplinkPort() == getDownlinkPort()) {
2210                 pudError(false, "The uplink port and the downlink port must not be the same");
2211                 retval = false;
2212         }
2213
2214         return retval;
2215 }
2216
2217 /**
2218  Check the configuration for consistency and validity after everything has been
2219  setup.
2220
2221  @return
2222  - true when the configuration is consistent and valid
2223  - false otherwise
2224  */
2225 unsigned int checkRunSetup(void) {
2226         int retval = true;
2227         unsigned int i;
2228
2229         /* any receive interface name that is configured but is not the name of an
2230          * actual receive interface is not a valid interface name */
2231         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
2232                 unsigned char * nonOlsrInterfaceName = &rxNonOlsrInterfaceNames[i][0];
2233
2234                 TRxTxNetworkInterface * interfaceObject = getRxNetworkInterfaces();
2235                 bool found = false;
2236                 while (interfaceObject != NULL) {
2237                         if (strncmp((char *) nonOlsrInterfaceName,
2238                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
2239                                 found = true;
2240                                 break;
2241                         }
2242                         interfaceObject = interfaceObject->next;
2243                 }
2244                 if (!found) {
2245                         pudError(false, "Configured receive non-OLSR interface %s is not"
2246                                 " a known interface name", nonOlsrInterfaceName);
2247                         retval = false;
2248                 }
2249         }
2250
2251         /* any transmit interface name that is configured but is not the name of an
2252          * actual transmit interface is not a valid interface name */
2253         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
2254                 unsigned char * nonOlsrInterfaceName = &txNonOlsrInterfaceNames[i][0];
2255
2256                 TRxTxNetworkInterface * interfaceObject = getTxNetworkInterfaces();
2257                 bool found = false;
2258                 while (interfaceObject != NULL) {
2259                         if (strncmp((char *) nonOlsrInterfaceName,
2260                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
2261                                 found = true;
2262                                 break;
2263                         }
2264                         interfaceObject = interfaceObject->next;
2265                 }
2266                 if (!found) {
2267                         pudError(false, "Configured transmit non-OLSR interface %s is not"
2268                                 " a known interface name", nonOlsrInterfaceName);
2269                         retval = false;
2270                 }
2271         }
2272
2273         return retval;
2274 }