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