b878785b2cfde7ea5f3474fb3051ce95d14324e8
[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 "nmeaTools.h"
7 #include "nodeIdConversion.h"
8 #include "networkInterfaces.h"
9
10 /* OLSR includes */
11 #include "olsr_types.h"
12 #include "olsr_protocol.h"
13 #include "cfgparser/olsrd_conf.h"
14
15 /* System includes */
16 #include <assert.h>
17 #include <errno.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <net/if.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <sys/socket.h>
24 #include <unistd.h>
25 #include <stdint.h>
26
27 /*
28  * Utility functions
29  */
30
31 /**
32  Read an unsigned long long number from a value string
33
34  @param valueName
35  the name of the value
36  @param value
37  the string to convert to a number
38  @param valueNumber
39  a pointer to the location where to store the number upon successful conversion
40
41  @return
42  - true on success
43  - false otherwise
44  */
45 bool readULL(const char * valueName, const char * value,
46                 unsigned long long * valueNumber) {
47         char * endPtr = NULL;
48         unsigned long long valueNew;
49
50         errno = 0;
51         valueNew = strtoull(value, &endPtr, 10);
52
53         if (!((endPtr != value) && (*value != '\0') && (*endPtr == '\0'))) {
54                 /* invalid conversion */
55                 pudError(true, "Configured %s (%s) could not be converted to a number",
56                                 valueName, value);
57                 return false;
58         }
59
60         *valueNumber = valueNew;
61
62         return true;
63 }
64
65 /*
66  * nodeIdType
67  */
68
69 /** The nodeIdType */
70 NodeIdType nodeIdType = PUD_NODE_ID_TYPE_DEFAULT;
71
72 /**
73  @return
74  The node ID type
75  */
76 NodeIdType getNodeIdTypeNumber(void) {
77         return nodeIdType;
78 }
79
80 /**
81  Set the node ID type.
82
83  @param value
84  The value of the node ID type to set (a number in string representation)
85  @param data
86  Unused
87  @param addon
88  Unused
89
90  @return
91  - true when an error is detected
92  - false otherwise
93  */
94 int setNodeIdType(const char *value, void *data __attribute__ ((unused)),
95                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
96         static const char * valueName = PUD_NODE_ID_TYPE_NAME;
97         unsigned long long nodeIdTypeNew;
98
99         assert (value != NULL);
100
101         if (!readULL(valueName, value, &nodeIdTypeNew)) {
102                 return true;
103         }
104
105         if (nodeIdTypeNew > PUD_NODE_ID_TYPE_MAX) {
106                 pudError(false, "Configured %s (%llu) is out of range 0-%u", valueName,
107                                 nodeIdTypeNew, PUD_NODE_ID_TYPE_MAX);
108                 return true;
109         }
110
111         switch (nodeIdTypeNew) {
112                 case PUD_NODEIDTYPE_MAC:
113                 case PUD_NODEIDTYPE_MSISDN:
114                 case PUD_NODEIDTYPE_TETRA:
115                 case PUD_NODEIDTYPE_DNS:
116                 case PUD_NODEIDTYPE_IPV4:
117                 case PUD_NODEIDTYPE_IPV6:
118                 case PUD_NODEIDTYPE_192:
119                 case PUD_NODEIDTYPE_193:
120                 case PUD_NODEIDTYPE_194:
121                         break;
122
123                 default:
124                         pudError(false, "Configured %s (%llu) is reserved", valueName,
125                                         nodeIdTypeNew);
126                         return true;
127         }
128
129         nodeIdType = nodeIdTypeNew;
130
131         return false;
132 }
133
134 /*
135  * nodeId
136  */
137
138 /** The maximum length of a nodeId */
139 #define PUD_NODEIDMAXLENGTH 255
140
141 /** The nodeId buffer */
142 unsigned char nodeId[PUD_NODEIDMAXLENGTH + 1];
143
144 /** The length of the string in the nodeId buffer */
145 size_t nodeIdLength = 0;
146
147 /** True when the nodeId is set */
148 bool nodeIdSet = false;
149
150 /**
151  @return
152  The node ID
153  */
154 unsigned char * getNodeId(void) {
155         return getNodeIdWithLength(NULL);
156 }
157
158 /**
159  Get the nodeId and its length
160
161  @param length
162  a pointer to the variable in which to store the nodeId length (allowed to be
163  NULL, in which case the length is not stored)
164
165  @return
166  The node ID
167  */
168 unsigned char * getNodeIdWithLength(size_t *length) {
169         if (!nodeIdSet) {
170                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
171         }
172
173         if (length != NULL) {
174                 *length = nodeIdLength;
175         }
176
177         return &nodeId[0];
178 }
179
180 /**
181  Set the node ID.
182
183  @param value
184  The value of the node ID to set (in string representation)
185  @param data
186  Unused
187  @param addon
188  Unused
189
190  @return
191  - true when an error is detected
192  - false otherwise
193  */
194 int setNodeId(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
195         static const char * valueName = PUD_NODE_ID_NAME;
196         size_t valueLength;
197
198         assert (value != NULL);
199
200         valueLength = strlen(value);
201         if (valueLength > PUD_NODEIDMAXLENGTH) {
202                 pudError(false, "Configured %s is too long, maximum length is"
203                         " %u, current length is %lu", valueName, PUD_NODEIDMAXLENGTH,
204                                 (unsigned long) valueLength);
205                 return true;
206         }
207
208         strcpy((char *) &nodeId[0], value);
209         nodeIdLength = valueLength;
210         nodeIdSet = true;
211
212         return false;
213 }
214
215 /*
216  * rxNonOlsrIf
217  */
218
219 /** The maximum number of RX non-OLSR interfaces */
220 #define PUD_RX_NON_OLSR_IF_MAX 32
221
222 /** Array with RX non-OLSR interface names */
223 unsigned char rxNonOlsrInterfaceNames[PUD_RX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
224
225 /** The number of RX non-OLSR interface names in the array */
226 unsigned int rxNonOlsrInterfaceCount = 0;
227
228 /**
229  Determine whether a give interface name is configured as a receive non-OLSR
230  interface.
231
232  @param ifName
233  The interface name to check
234
235  @return
236  - true when the given interface name is configured as a receive non-OLSR
237  interface
238  - false otherwise
239  */
240 bool isRxNonOlsrInterface(const char *ifName) {
241         unsigned int i;
242
243         assert (ifName != NULL);
244
245         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
246                 if (strncmp((char *) &rxNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
247                                 + 1) == 0) {
248                         return true;
249                 }
250         }
251
252         return false;
253 }
254
255 /**
256  Add a receive non-OLSR interface
257
258  @param value
259  The name of the non-OLSR interface to add
260  @param data
261  Unused
262  @param addon
263  Unused
264
265  @return
266  - true when an error is detected
267  - false otherwise
268  */
269 int addRxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
270                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
271         unsigned long valueLength;
272
273         assert (value != NULL);
274
275         valueLength = strlen(value);
276         if (valueLength > IFNAMSIZ) {
277                 pudError(false, "Configured %s (%s) is too long,"
278                         " maximum length is %u, current length is %lu",
279                                 PUD_RX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
280                 return true;
281         }
282
283         if (!isRxNonOlsrInterface(value)) {
284                 if (rxNonOlsrInterfaceCount >= PUD_RX_NON_OLSR_IF_MAX) {
285                         pudError(false, "Can't configure more than %u receive interfaces",
286                                         PUD_RX_NON_OLSR_IF_MAX);
287                         return true;
288                 }
289
290                 strcpy((char *) &rxNonOlsrInterfaceNames[rxNonOlsrInterfaceCount][0],
291                                 value);
292                 rxNonOlsrInterfaceCount++;
293         }
294
295         return false;
296 }
297
298 /*
299  * rxAllowedSourceIpAddress
300  */
301
302 /** The maximum number of RX allowed source IP addresses */
303 #define PUD_RX_ALLOWED_SOURCE_IP_MAX 32
304
305 /** Array with RX allowed source IP addresses */
306 struct sockaddr rxAllowedSourceIpAddresses[PUD_RX_ALLOWED_SOURCE_IP_MAX];
307
308 /** The number of RX allowed source IP addresses in the array */
309 unsigned int rxAllowedSourceIpAddressesCount = 0;
310
311 /**
312  Determine whether a give IP address is configured as an allowed source IP
313  address.
314
315  @param sender
316  The IP address to check
317
318  @return
319  - true when the given IP address is configured as an allowed source IP
320  address
321  - false otherwise
322  */
323 bool isRxAllowedSourceIpAddress(struct sockaddr * sender) {
324         void * addr;
325         unsigned int addrSize;
326         unsigned int i;
327
328         if (rxAllowedSourceIpAddressesCount == 0) {
329                 return true;
330         }
331
332         if (sender == NULL) {
333                 return false;
334         }
335
336         if (sender->sa_family == AF_INET) {
337                 addr = (void *) (&((struct sockaddr_in *) sender)->sin_addr);
338                 addrSize = sizeof(struct in_addr);
339         } else {
340                 addr = (void *) (&((struct sockaddr_in6 *) sender)->sin6_addr);
341                 addrSize = sizeof(struct in6_addr);
342         }
343
344         for (i = 0; i < rxAllowedSourceIpAddressesCount; i++) {
345                 if ((rxAllowedSourceIpAddresses[i].sa_family == sender->sa_family)
346                                 && (memcmp(&rxAllowedSourceIpAddresses[i].sa_data, addr,
347                                                 addrSize) == 0)) {
348                         return true;
349                 }
350         }
351
352         return false;
353 }
354
355 /**
356  Set the RX allowed source IP addresses.
357
358  @param value
359  The RX allowed source IP address (in string representation)
360  @param data
361  Unused
362  @param addon
363  Unused
364
365  @return
366  - true when an error is detected
367  - false otherwise
368  */
369 int addRxAllowedSourceIpAddress(const char *value, void *data __attribute__ ((unused)),
370                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
371         static const char * valueName = PUD_RX_ALLOWED_SOURCE_IP_NAME;
372         const char * valueInternal = value;
373         int conversion;
374         struct sockaddr addr;
375
376         assert (value != NULL);
377
378         memset(&addr, 0, sizeof(addr));
379
380         addr.sa_family = olsr_cnf->ip_version;
381         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, &addr.sa_data);
382         if (conversion != 1) {
383                 pudError((conversion == -1) ? true : false,
384                                 "Configured %s (%s) is not an IP address", valueName,
385                                 valueInternal);
386                 return true;
387         }
388
389         if ((rxAllowedSourceIpAddressesCount == 0) || !isRxAllowedSourceIpAddress(&addr)) {
390                 if (rxAllowedSourceIpAddressesCount >= PUD_RX_ALLOWED_SOURCE_IP_MAX) {
391                         pudError(false, "Can't configure more than %u allowed source IP"
392                                 " addresses", PUD_RX_ALLOWED_SOURCE_IP_MAX);
393                         return true;
394                 }
395
396                 memcpy(&rxAllowedSourceIpAddresses[rxAllowedSourceIpAddressesCount],
397                                 &addr, sizeof(addr));
398                 rxAllowedSourceIpAddressesCount++;
399         }
400
401         return false;
402 }
403
404 /*
405  * rxMcAddr
406  */
407
408 /** The rx multicast address */
409 union olsr_sockaddr rxMcAddr;
410
411 /** True when the rx multicast address is set */
412 bool rxMcAddrSet = false;
413
414 /**
415  @return
416  The receive multicast address (in network byte order). Sets both the address
417  and the port to their default values when the address was not yet set.
418  */
419 union olsr_sockaddr * getRxMcAddr(void) {
420         if (!rxMcAddrSet) {
421                 setRxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
422         }
423         return &rxMcAddr;
424 }
425
426 /**
427  Set the receive multicast address. Sets the address to its default value when
428  the value is NULL. Also sets the port to its default value when the address
429  was not yet set.
430
431  @param value
432  The receive multicast address (in string representation)
433  @param data
434  Unused
435  @param addon
436  Unused
437
438  @return
439  - true when an error is detected
440  - false otherwise
441  */
442 int setRxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
443         static const char * valueName = PUD_RX_MC_ADDR_NAME;
444         void * ipAddress;
445         in_port_t * port;
446         const char * valueInternal = value;
447         int conversion;
448
449         if (olsr_cnf->ip_version == AF_INET) {
450                 rxMcAddr.in4.sin_family = olsr_cnf->ip_version;
451                 ipAddress = (void *) &rxMcAddr.in4.sin_addr;
452                 port = (void *) &rxMcAddr.in4.sin_port;
453                 if (valueInternal == NULL) {
454                         valueInternal = PUD_RX_MC_ADDR_4_DEFAULT;
455                 }
456         } else {
457                 rxMcAddr.in6.sin6_family = olsr_cnf->ip_version;
458                 ipAddress = (void *) &rxMcAddr.in6.sin6_addr;
459                 port = (void *) &rxMcAddr.in6.sin6_port;
460                 if (valueInternal == NULL) {
461                         valueInternal = PUD_RX_MC_ADDR_6_DEFAULT;
462                 }
463         }
464
465         if (!rxMcAddrSet) {
466                 *port = htons(PUD_RX_MC_PORT_DEFAULT);
467         }
468
469         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
470         if (conversion != 1) {
471                 pudError((conversion == -1) ? true : false,
472                                 "Configured %s (%s) is not an IP address", valueName,
473                                 valueInternal);
474                 return true;
475         }
476
477         if (!isMulticast(olsr_cnf->ip_version, &rxMcAddr)) {
478                 pudError(false, "Configured %s (%s) is not a multicast address",
479                                 valueName, valueInternal);
480                 return true;
481         }
482
483         rxMcAddrSet = true;
484         return false;
485 }
486
487 /*
488  * rxMcPort
489  */
490
491 /**
492  @return
493  The receive multicast port (in network byte order)
494  */
495 unsigned short getRxMcPort(void) {
496         in_port_t * port;
497         union olsr_sockaddr * addr = getRxMcAddr();
498
499         if (olsr_cnf->ip_version == AF_INET) {
500                 port = (void *) &addr->in4.sin_port;
501         } else {
502                 port = (void *) &addr->in6.sin6_port;
503         }
504
505         return *port;
506 }
507
508 /**
509  Set the receive multicast port
510
511  @param value
512  The receive multicast port (a number in string representation)
513  @param data
514  Unused
515  @param addon
516  Unused
517
518  @return
519  - true when an error is detected
520  - false otherwise
521  */
522 int setRxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
523         static const char * valueName = PUD_RX_MC_PORT_NAME;
524         unsigned long long rxMcPortNew;
525         in_port_t * port;
526         union olsr_sockaddr * addr = getRxMcAddr();
527
528         assert (value != NULL);
529
530         if (!readULL(valueName, value, &rxMcPortNew)) {
531                 return true;
532         }
533
534         if ((rxMcPortNew < 1) || (rxMcPortNew > 65535)) {
535                 pudError(false, "Configured %s (%llu) is outside of"
536                         " valid range 1-65535", valueName, rxMcPortNew);
537                 return true;
538         }
539
540         if (olsr_cnf->ip_version == AF_INET) {
541                 port = (void *) &addr->in4.sin_port;
542         } else {
543                 port = (void *) &addr->in6.sin6_port;
544         }
545
546         *port = htons((uint16_t) rxMcPortNew);
547
548         return false;
549 }
550
551 /*
552  * txNonOlsrIf
553  */
554
555 /** The maximum number of rx non-olsr interfaces */
556 #define PUD_TX_NON_OLSR_IF_MAX 32
557
558 /** Array with tx non-olsr interface names */
559 unsigned char txNonOlsrInterfaceNames[PUD_TX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
560
561 /** The number of tx interface names in the array */
562 unsigned int txNonOlsrInterfaceCount = 0;
563
564 /**
565  Determine whether a give interface name is configured as a transmit non-OLSR
566  interface.
567
568  @param ifName
569  The interface to check
570
571  @return
572  - true when the given interface name is configured as a transmit non-OLSR
573  interface
574  - false otherwise
575  */
576 bool isTxNonOlsrInterface(const char *ifName) {
577         unsigned int i;
578
579         assert (ifName != NULL);
580
581         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
582                 if (strncmp((char *) &txNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
583                                 + 1) == 0) {
584                         return true;
585                 }
586         }
587
588         return false;
589 }
590
591 /**
592  Add a transmit non-OLSR interface
593
594  @param value
595  The name of the non-OLSR interface to add
596  @param data
597  Unused
598  @param addon
599  Unused
600
601  @return
602  - true when an error is detected
603  - false otherwise
604  */
605 int addTxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
606                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
607         unsigned long valueLength;
608
609         assert (value != NULL);
610
611         valueLength = strlen(value);
612         if (valueLength > IFNAMSIZ) {
613                 pudError(false, "Configured %s (%s) is too long,"
614                         " maximum length is %u, current length is %lu",
615                                 PUD_TX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
616                 return true;
617         }
618
619         if (!isTxNonOlsrInterface(value)) {
620                 if (txNonOlsrInterfaceCount >= PUD_TX_NON_OLSR_IF_MAX) {
621                         pudError(false, "Can not configure more than %u transmit"
622                                 " interfaces", PUD_TX_NON_OLSR_IF_MAX);
623                         return true;
624                 }
625
626                 strcpy((char *) &txNonOlsrInterfaceNames[txNonOlsrInterfaceCount][0],
627                                 value);
628                 txNonOlsrInterfaceCount++;
629         }
630
631         return false;
632 }
633
634 /*
635  * txMcAddr
636  */
637
638 /** The tx multicast address */
639 union olsr_sockaddr txMcAddr;
640
641 /** True when the tx multicast address is set */
642 bool txMcAddrSet = false;
643
644 /**
645  @return
646  The transmit multicast address (in network byte order). Sets both the address
647  and the port to their default values when the address was not yet set.
648  */
649 union olsr_sockaddr * getTxMcAddr(void) {
650         if (!txMcAddrSet) {
651                 setTxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
652         }
653         return &txMcAddr;
654 }
655
656 /**
657  Set the transmit multicast address. Sets the address to its default value when
658  the value is NULL. Also sets the port to its default value when the address
659  was not yet set.
660
661  @param value
662  The transmit multicast address (in string representation)
663  @param data
664  Unused
665  @param addon
666  Unused
667
668  @return
669  - true when an error is detected
670  - false otherwise
671  */
672 int setTxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
673         static const char * valueName = PUD_TX_MC_ADDR_NAME;
674         void * ipAddress;
675         in_port_t * port;
676         const char * valueInternal = value;
677         int conversion;
678
679         if (olsr_cnf->ip_version == AF_INET) {
680                 txMcAddr.in4.sin_family = olsr_cnf->ip_version;
681                 ipAddress = (void *) &txMcAddr.in4.sin_addr;
682                 port = (void *) &txMcAddr.in4.sin_port;
683                 if (valueInternal == NULL) {
684                         valueInternal = PUD_TX_MC_ADDR_4_DEFAULT;
685                 }
686         } else {
687                 txMcAddr.in6.sin6_family = olsr_cnf->ip_version;
688                 ipAddress = (void *) &txMcAddr.in6.sin6_addr;
689                 port = (void *) &txMcAddr.in6.sin6_port;
690                 if (valueInternal == NULL) {
691                         valueInternal = PUD_TX_MC_ADDR_6_DEFAULT;
692                 }
693         }
694
695         if (!txMcAddrSet) {
696                 *port = htons(PUD_TX_MC_PORT_DEFAULT);
697         }
698
699         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
700         if (conversion != 1) {
701                 pudError((conversion == -1) ? true : false,
702                                 "Configured %s (%s) is not an IP address", valueName,
703                                 valueInternal);
704                 return true;
705         }
706
707         if (!isMulticast(olsr_cnf->ip_version, &txMcAddr)) {
708                 pudError(false, "Configured %s (%s) is not a multicast address",
709                                 valueName, valueInternal);
710                 return true;
711         }
712
713         txMcAddrSet = true;
714         return false;
715 }
716
717 /*
718  * txMcPort
719  */
720
721 /**
722  @return
723  The transmit multicast port (in network byte order)
724  */
725 unsigned short getTxMcPort(void) {
726         in_port_t * port;
727         union olsr_sockaddr * addr = getTxMcAddr();
728
729         if (olsr_cnf->ip_version == AF_INET) {
730                 port = (void *) &addr->in4.sin_port;
731         } else {
732                 port = (void *) &addr->in6.sin6_port;
733         }
734
735         return *port;
736 }
737
738 /**
739  Set the transmit multicast port
740
741  @param value
742  The transmit multicast port (a number in string representation)
743  @param data
744  Unused
745  @param addon
746  Unused
747
748  @return
749  - true when an error is detected
750  - false otherwise
751  */
752 int setTxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
753         static const char * valueName = PUD_TX_MC_PORT_NAME;
754         unsigned long long txMcPortNew;
755         in_port_t * port;
756         union olsr_sockaddr * addr = getTxMcAddr();
757
758         assert (value != NULL);
759
760         if (!readULL(valueName, value, &txMcPortNew)) {
761                 return true;
762         }
763
764         if ((txMcPortNew < 1) || (txMcPortNew > 65535)) {
765                 pudError(false, "Configured %s (%llu) is outside of"
766                         " valid range 1-65535", valueName, txMcPortNew);
767                 return true;
768         }
769
770         if (olsr_cnf->ip_version == AF_INET) {
771                 port = (void *) &addr->in4.sin_port;
772         } else {
773                 port = (void *) &addr->in6.sin6_port;
774         }
775
776         *port = htons((uint16_t) txMcPortNew);
777
778         return false;
779 }
780
781 /*
782  * txTtl
783  */
784
785 /** The tx TTL */
786 unsigned char txTtl = PUD_TX_TTL_DEFAULT;
787
788 /**
789  @return
790  The transmit multicast IP packet time-to-live
791  */
792 unsigned char getTxTtl(void) {
793         return txTtl;
794 }
795
796 /**
797  Set the transmit multicast IP packet time-to-live
798
799  @param value
800  The transmit multicast IP packet time-to-live (a number in string representation)
801  @param data
802  Unused
803  @param addon
804  Unused
805
806  @return
807  - true when an error is detected
808  - false otherwise
809  */
810 int setTxTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
811         static const char * valueName = PUD_TX_TTL_NAME;
812         unsigned long long txTtlNew;
813
814         assert (value != NULL);
815
816         if (!readULL(valueName, value, &txTtlNew)) {
817                 return true;
818         }
819
820         if ((txTtlNew < 1) || (txTtlNew > MAX_TTL)) {
821                 pudError(false, "Configured %s (%llu) is outside of"
822                         " valid range 1-%u", valueName, txTtlNew, MAX_TTL);
823                 return true;
824         }
825
826         txTtl = txTtlNew;
827
828         return false;
829 }
830
831 /*
832  * txNmeaMessagePrefix
833  */
834
835 /** The exact length of the tx NMEA message prefix */
836 #define PUD_TXNMEAMESSAGEPREFIXLENGTH 4
837
838 /** The tx NMEA message prefix buffer */
839 unsigned char txNmeaMessagePrefix[PUD_TXNMEAMESSAGEPREFIXLENGTH + 1];
840
841 /** True when the tx NMEA message prefix is set */
842 bool txNmeaMessagePrefixSet = false;
843
844 /**
845  @return
846  The transmit multicast NMEA message prefix
847  */
848 unsigned char * getTxNmeaMessagePrefix(void) {
849         if (!txNmeaMessagePrefixSet) {
850                 setTxNmeaMessagePrefix(PUD_TX_NMEAMESSAGEPREFIX_DEFAULT, NULL,
851                                 (set_plugin_parameter_addon) {.pc = NULL});
852         }
853         return &txNmeaMessagePrefix[0];
854 }
855
856 /**
857  Set the transmit multicast NMEA message prefix
858
859  @param value
860  The transmit multicast NMEA message prefix (in string representation)
861  @param data
862  Unused
863  @param addon
864  Unused
865
866  @return
867  - true when an error is detected
868  - false otherwise
869  */
870 int setTxNmeaMessagePrefix(const char *value, void *data __attribute__ ((unused)),
871                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
872         static const char * valueName = PUD_TX_NMEAMESSAGEPREFIX_NAME;
873         size_t valueLength;
874
875         assert (value != NULL);
876
877         valueLength = strlen(value);
878         if (valueLength != PUD_TXNMEAMESSAGEPREFIXLENGTH) {
879                 pudError(false, "Configured %s (%s) must be %u exactly characters",
880                                 valueName, value, PUD_TXNMEAMESSAGEPREFIXLENGTH);
881                 return true;
882         }
883
884         if (hasInvalidNmeaChars(value, valueName)) {
885                 return true;
886         }
887
888         if ((strchr(value, ' ') != NULL) || (strchr(value, '\t') != NULL)) {
889                 pudError(false, "Configured %s (%s) can not contain whitespace",
890                                 valueName, value);
891                 return true;
892         }
893
894         strcpy((char *) &txNmeaMessagePrefix[0], value);
895         txNmeaMessagePrefixSet = true;
896         return false;
897 }
898
899 /*
900  * olsrTtl
901  */
902
903 /** The OLSR TTL */
904 unsigned char olsrTtl = PUD_OLSR_TTL_DEFAULT;
905
906 /**
907  @return
908  The OLSR multicast IP packet time-to-live
909  */
910 unsigned char getOlsrTtl(void) {
911         return olsrTtl;
912 }
913
914 /**
915  Set the OLSR multicast IP packet time-to-live
916
917  @param value
918  The OLSR multicast IP packet time-to-live (a number in string representation)
919  @param data
920  Unused
921  @param addon
922  Unused
923
924  @return
925  - true when an error is detected
926  - false otherwise
927  */
928 int setOlsrTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
929         static const char * valueName = PUD_OLSR_TTL_NAME;
930         unsigned long long olsrTtlNew;
931
932         assert (value != NULL);
933
934         if (!readULL(valueName, value, &olsrTtlNew)) {
935                 return true;
936         }
937
938         if ((olsrTtlNew < 1) || (olsrTtlNew > MAX_TTL)) {
939                 pudError(false, "Configured %s (%llu) is outside of valid range 1-%u",
940                                 valueName, olsrTtlNew, MAX_TTL);
941                 return true;
942         }
943
944         olsrTtl = olsrTtlNew;
945
946         return false;
947 }
948
949 /*
950  * updateIntervalStationary
951  */
952
953 /** The stationary interval update plugin parameter (in seconds) */
954 unsigned long long updateIntervalStationary = PUD_UPDATE_INTERVAL_STATIONARY_DEFAULT;
955
956 /**
957  @return
958  The stationary interval update plugin parameter (in seconds)
959  */
960 unsigned long long getUpdateIntervalStationary(void) {
961         return updateIntervalStationary;
962 }
963
964 /**
965  Set stationary interval update plugin parameter
966
967  @param value
968  The stationary interval update plugin parameter (in seconds)
969  @param data
970  Unused
971  @param addon
972  Unused
973
974  @return
975  - true when an error is detected
976  - false otherwise
977  */
978 int setUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
979                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
980         static const char * valueName = PUD_UPDATE_INTERVAL_STATIONARY_NAME;
981         unsigned long long updateIntervalStationaryNew;
982
983         assert (value != NULL);
984
985         if (!readULL(valueName, value, &updateIntervalStationaryNew)) {
986                 return true;
987         }
988
989         if (updateIntervalStationaryNew < 1) {
990                 pudError(false, "Configured %s must be at least 1", valueName);
991                 return true;
992         }
993
994         updateIntervalStationary = updateIntervalStationaryNew;
995
996         return false;
997 }
998
999 /*
1000  * updateIntervalMoving
1001  */
1002
1003 /** The moving interval update plugin parameter (in seconds) */
1004 unsigned long long updateIntervalMoving = PUD_UPDATE_INTERVAL_MOVING_DEFAULT;
1005
1006 /**
1007  @return
1008  The moving interval update plugin parameter (in seconds)
1009  */
1010 unsigned long long getUpdateIntervalMoving(void) {
1011         return updateIntervalMoving;
1012 }
1013
1014 /**
1015  Set moving interval update plugin parameter
1016
1017  @param value
1018  The moving interval update plugin parameter (in seconds)
1019  @param data
1020  Unused
1021  @param addon
1022  Unused
1023
1024  @return
1025  - true when an error is detected
1026  - false otherwise
1027  */
1028 int setUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1029                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1030         static const char * valueName = PUD_UPDATE_INTERVAL_MOVING_NAME;
1031         unsigned long long updateIntervalMovingNew;
1032
1033         assert (value != NULL);
1034
1035         if (!readULL(valueName, value, &updateIntervalMovingNew)) {
1036                 return true;
1037         }
1038
1039         if (updateIntervalMovingNew < 1) {
1040                 pudError(false, "Configured %s must be at least 1", valueName);
1041                 return true;
1042         }
1043
1044         updateIntervalMoving = updateIntervalMovingNew;
1045
1046         return false;
1047 }
1048
1049 /*
1050  * movingSpeedThreshold
1051  */
1052
1053 /** The moving speed threshold plugin parameter (in kph) */
1054 unsigned long long movingSpeedThreshold = PUD_MOVING_SPEED_THRESHOLD_DEFAULT;
1055
1056 /**
1057  @return
1058  The moving speed threshold plugin parameter (in kph)
1059  */
1060 unsigned long long getMovingSpeedThreshold(void) {
1061         return movingSpeedThreshold;
1062 }
1063
1064 /**
1065  Set moving speed threshold plugin parameter
1066
1067  @param value
1068  The moving speed threshold plugin parameter (in kph)
1069  @param data
1070  Unused
1071  @param addon
1072  Unused
1073
1074  @return
1075  - true when an error is detected
1076  - false otherwise
1077  */
1078 int setMovingSpeedThreshold(const char *value, void *data __attribute__ ((unused)),
1079                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1080         static const char * valueName = PUD_MOVING_SPEED_THRESHOLD_NAME;
1081         unsigned long long movingSpeedThresholdNew;
1082
1083         assert (value != NULL);
1084
1085         if (!readULL(valueName, value, &movingSpeedThresholdNew)) {
1086                 return true;
1087         }
1088
1089         movingSpeedThreshold = movingSpeedThresholdNew;
1090
1091         return false;
1092 }
1093
1094 /*
1095  * movingDistanceThreshold
1096  */
1097
1098 /** The moving distance threshold plugin parameter (in meters) */
1099 unsigned long long movingDistanceThreshold = PUD_MOVING_DISTANCE_THRESHOLD_DEFAULT;
1100
1101 /**
1102  @return
1103  The moving distance threshold plugin parameter (in meters)
1104  */
1105 unsigned long long getMovingDistanceThreshold(void) {
1106         return movingDistanceThreshold;
1107 }
1108
1109 /**
1110  Set moving distance threshold plugin parameter
1111
1112  @param value
1113  The moving distance threshold plugin parameter (in meter)
1114  @param data
1115  Unused
1116  @param addon
1117  Unused
1118
1119  @return
1120  - true when an error is detected
1121  - false otherwise
1122  */
1123 int setMovingDistanceThreshold(const char *value, void *data __attribute__ ((unused)),
1124                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1125         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1126         unsigned long long movingDistanceThresholdNew;
1127
1128         assert (value != NULL);
1129
1130         if (!readULL(valueName, value, &movingDistanceThresholdNew)) {
1131                 return true;
1132         }
1133
1134         movingDistanceThreshold = movingDistanceThresholdNew;
1135
1136         return false;
1137 }
1138
1139 /*
1140  * defaultHdop
1141  */
1142
1143 /** The default HDOP plugin parameter (in meters) */
1144 unsigned long long defaultHdop = PUD_DEFAULT_HDOP_DEFAULT;
1145
1146 /**
1147  @return
1148  The default HDOP plugin parameter (in meters)
1149  */
1150 unsigned long long getDefaultHdop(void) {
1151         return defaultHdop;
1152 }
1153
1154 /**
1155  Set default HDOP plugin parameter
1156
1157  @param value
1158  The default HDOP plugin parameter (in meters)
1159  @param data
1160  Unused
1161  @param addon
1162  Unused
1163
1164  @return
1165  - true when an error is detected
1166  - false otherwise
1167  */
1168 int setDefaultHdop(const char *value, void *data __attribute__ ((unused)),
1169                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1170         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1171         unsigned long long defaultHdopNew;
1172
1173         assert (value != NULL);
1174
1175         if (!readULL(valueName, value, &defaultHdopNew)) {
1176                 return true;
1177         }
1178
1179         defaultHdop = defaultHdopNew;
1180
1181         return false;
1182 }
1183
1184 /*
1185  * defaultVdop
1186  */
1187
1188 /** The default VDOP plugin parameter (in meters) */
1189 unsigned long long defaultVdop = PUD_DEFAULT_VDOP_DEFAULT;
1190
1191 /**
1192  @return
1193  The default VDOP plugin parameter (in meters)
1194  */
1195 unsigned long long getDefaultVdop(void) {
1196         return defaultVdop;
1197 }
1198
1199 /**
1200  Set default VDOP plugin parameter
1201
1202  @param value
1203  The default VDOP plugin parameter (in meters)
1204  @param data
1205  Unused
1206  @param addon
1207  Unused
1208
1209  @return
1210  - true when an error is detected
1211  - false otherwise
1212  */
1213 int setDefaultVdop(const char *value, void *data __attribute__ ((unused)),
1214                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1215         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1216         unsigned long long defaultVdopNew;
1217
1218         assert (value != NULL);
1219
1220         if (!readULL(valueName, value, &defaultVdopNew)) {
1221                 return true;
1222         }
1223
1224         defaultVdop = defaultVdopNew;
1225
1226         return false;
1227 }
1228
1229 /*
1230  * averageDepth
1231  */
1232
1233 /** The depth of the average list */
1234 unsigned long long averageDepth = PUD_AVERAGE_DEPTH_DEFAULT;
1235
1236 /**
1237  @return
1238  The depth of the average list
1239  */
1240 unsigned long long getAverageDepth(void) {
1241         return averageDepth;
1242 }
1243
1244 /**
1245  Set average depth plugin parameter
1246
1247  @param value
1248  The average depth plugin parameter
1249  @param data
1250  Unused
1251  @param addon
1252  Unused
1253
1254  @return
1255  - true when an error is detected
1256  - false otherwise
1257  */
1258 int setAverageDepth(const char *value, void *data __attribute__ ((unused)),
1259                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1260         static const char * valueName = PUD_AVERAGE_DEPTH_NAME;
1261         unsigned long long averageDepthNew;
1262
1263         assert (value != NULL);
1264
1265         if (!readULL(valueName, value, &averageDepthNew)) {
1266                 return true;
1267         }
1268
1269         if (averageDepthNew < 1) {
1270                 pudError(false, "Configured %s must be at least 1", valueName);
1271                 return true;
1272         }
1273
1274         averageDepth = averageDepthNew;
1275
1276         return false;
1277 }
1278
1279 /*
1280  * hysteresisCountToStationary
1281  */
1282
1283 /** The hysteresis count for changing state from moving to stationary */
1284 unsigned long long hysteresisCountToStationary = PUD_HYSTERESIS_COUNT_2STAT_DEFAULT;
1285
1286 /**
1287  @return
1288  The hysteresis count for changing state from moving to stationary
1289  */
1290 unsigned long long getHysteresisCountToStationary(void) {
1291         return hysteresisCountToStationary;
1292 }
1293
1294 /**
1295  Set hysteresis count plugin parameter
1296
1297  @param value
1298  The hysteresis count plugin parameter
1299  @param data
1300  Unused
1301  @param addon
1302  Unused
1303
1304  @return
1305  - true when an error is detected
1306  - false otherwise
1307  */
1308 int setHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1309                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1310         static const char * valueName = PUD_HYSTERESIS_COUNT_2STAT_NAME;
1311         unsigned long long hysteresisCountNew;
1312
1313         assert (value != NULL);
1314
1315         if (!readULL(valueName, value, &hysteresisCountNew)) {
1316                 return true;
1317         }
1318
1319         hysteresisCountToStationary = hysteresisCountNew;
1320
1321         return false;
1322 }
1323
1324 /*
1325  * hysteresisCountToMoving
1326  */
1327
1328 /** The hysteresis count for changing state from stationary to moving */
1329 unsigned long long hysteresisCountToMoving = PUD_HYSTERESIS_COUNT_2MOV_DEFAULT;
1330
1331 /**
1332  @return
1333  The hysteresis count for changing state from stationary to moving
1334  */
1335 unsigned long long getHysteresisCountToMoving(void) {
1336         return hysteresisCountToMoving;
1337 }
1338
1339 /**
1340  Set hysteresis count plugin parameter
1341
1342  @param value
1343  The hysteresis count plugin parameter
1344  @param data
1345  Unused
1346  @param addon
1347  Unused
1348
1349  @return
1350  - true when an error is detected
1351  - false otherwise
1352  */
1353 int setHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1354                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1355         static const char * valueName = PUD_HYSTERESIS_COUNT_2MOV_NAME;
1356         unsigned long long hysteresisCountNew;
1357
1358         assert (value != NULL);
1359
1360         if (!readULL(valueName, value, &hysteresisCountNew)) {
1361                 return true;
1362         }
1363
1364         hysteresisCountToMoving = hysteresisCountNew;
1365
1366         return false;
1367 }
1368
1369 /*
1370  * useDeDup
1371  */
1372
1373 /* when true then duplicate message detection is performed */
1374 bool useDeDup = PUD_USE_DEDUP_DEFAULT;
1375
1376 /**
1377  @return
1378  The duplicate message detection setting
1379  */
1380 bool getUseDeDup(void) {
1381         return useDeDup;
1382 }
1383
1384 /**
1385  Set duplicate message detection setting plugin parameter
1386
1387  @param value
1388  The duplicate message detection setting plugin parameter
1389  @param data
1390  Unused
1391  @param addon
1392  Unused
1393
1394  @return
1395  - true when an error is detected
1396  - false otherwise
1397  */
1398 int setUseDeDup(const char *value, void *data __attribute__ ((unused)),
1399                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1400         static const char * valueName = PUD_USE_DEDUP_NAME;
1401         unsigned long long useDeDupNew;
1402
1403         assert (value != NULL);
1404
1405         if (!readULL(valueName, value, &useDeDupNew)) {
1406                 return true;
1407         }
1408
1409         if ((useDeDupNew != 0) && (useDeDupNew != 1)) {
1410                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
1411                                 valueName);
1412                 return true;
1413         }
1414
1415         useDeDup = (useDeDupNew == 1);
1416
1417         return false;
1418 }
1419
1420 /*
1421  * deDupDepth
1422  */
1423
1424 /** The hysteresis count for changing state from stationary to moving */
1425 unsigned long long deDupDepth = PUD_DEDUP_DEPTH_DEFAULT;
1426
1427 /**
1428  @return
1429  The hysteresis count for changing state from stationary to moving
1430  */
1431 unsigned long long getDeDupDepth(void) {
1432         return deDupDepth;
1433 }
1434
1435 /**
1436  Set de-duplication depth plugin parameter
1437
1438  @param value
1439  The de-duplication depth plugin parameter
1440  @param data
1441  Unused
1442  @param addon
1443  Unused
1444
1445  @return
1446  - true when an error is detected
1447  - false otherwise
1448  */
1449 int setDeDupDepth(const char *value, void *data __attribute__ ((unused)),
1450                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1451         static const char * valueName = PUD_DEDUP_DEPTH_NAME;
1452         unsigned long long deDupDepthNew;
1453
1454         assert (value != NULL);
1455
1456         if (!readULL(valueName, value, &deDupDepthNew)) {
1457                 return true;
1458         }
1459
1460         deDupDepth = deDupDepthNew;
1461
1462         return false;
1463 }
1464
1465 /*
1466  * useLoopback
1467  */
1468
1469 /* when true then loopback is performed */
1470 bool useLoopback = PUD_USE_LOOPBACK_DEFAULT;
1471
1472 /**
1473  @return
1474  The loopback usage setting
1475  */
1476 bool getUseLoopback(void) {
1477         return useLoopback;
1478 }
1479
1480 /**
1481  Set loopback usage plugin parameter
1482
1483  @param value
1484  The loopback usage plugin parameter
1485  @param data
1486  Unused
1487  @param addon
1488  Unused
1489
1490  @return
1491  - true when an error is detected
1492  - false otherwise
1493  */
1494 int setUseLoopback(const char *value, void *data __attribute__ ((unused)),
1495                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1496         static const char * valueName = PUD_USE_LOOPBACK_NAME;
1497         unsigned long long useLoopbackNew;
1498
1499         assert (value != NULL);
1500
1501         if (!readULL(valueName, value, &useLoopbackNew)) {
1502                 return true;
1503         }
1504
1505         if ((useLoopbackNew != 0) && (useLoopbackNew != 1)) {
1506                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
1507                                 valueName);
1508                 return true;
1509         }
1510
1511         useLoopback = (useLoopbackNew == 1);
1512
1513         return false;
1514 }
1515
1516 /*
1517  * Check Functions
1518  */
1519
1520 /**
1521  Check the configuration for consistency and validity.
1522
1523  @return
1524  - true when the configuration is consistent and valid
1525  - false otherwise
1526  */
1527 unsigned int checkConfig(void) {
1528         int retval = true;
1529
1530         if (rxNonOlsrInterfaceCount == 0) {
1531                 pudError(false, "No receive non-OLSR interfaces configured");
1532                 retval = false;
1533         }
1534
1535         if (txNonOlsrInterfaceCount == 0) {
1536                 pudError(false, "No transmit non-OLSR interfaces configured");
1537                 retval = false;
1538         }
1539
1540         if (!nodeIdSet) {
1541                 if (nodeIdType == PUD_NODEIDTYPE_DNS) {
1542                         char name[PUD_NODEIDMAXLENGTH + 1];
1543
1544                         errno = 0;
1545                         if (gethostname(&name[0], sizeof(name)) < 0) {
1546                                 pudError(true, "Could not get the host name");
1547                                 retval = false;
1548                         } else {
1549                                 setNodeId(&name[0], NULL,
1550                                                 (set_plugin_parameter_addon) {.pc = NULL});
1551                         }
1552                 } else if ((nodeIdType != PUD_NODEIDTYPE_MAC) && (nodeIdType
1553                                 != PUD_NODEIDTYPE_IPV4) && (nodeIdType != PUD_NODEIDTYPE_IPV6)) {
1554                         pudError(false, "No node ID set while one is required for"
1555                                 " node type %u", nodeIdType);
1556                         retval = false;
1557                 }
1558         }
1559
1560         if (!validateNodeId(nodeIdType)) {
1561                 retval = false;
1562         }
1563
1564         if (updateIntervalMoving > updateIntervalStationary) {
1565                 pudError(false,"The update interval for moving situations must not be"
1566                 " larger than that for stationary situations");
1567                 retval = false;
1568         }
1569
1570         return retval;
1571 }
1572
1573 /**
1574  Check the configuration for consistency and validity after everything has been
1575  setup.
1576
1577  @return
1578  - true when the configuration is consistent and valid
1579  - false otherwise
1580  */
1581 unsigned int checkRunSetup(void) {
1582         int retval = true;
1583         unsigned int i;
1584
1585         /* any receive interface name that is configured but is not the name of an
1586          * actual receive interface is not a valid interface name */
1587         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
1588                 unsigned char * nonOlsrInterfaceName = &rxNonOlsrInterfaceNames[i][0];
1589
1590                 TRxTxNetworkInterface * interfaceObject = getRxNetworkInterfaces();
1591                 bool found = false;
1592                 while (interfaceObject != NULL) {
1593                         if (strncmp((char *) nonOlsrInterfaceName,
1594                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
1595                                 found = true;
1596                                 break;
1597                         }
1598                         interfaceObject = interfaceObject->next;
1599                 }
1600                 if (!found) {
1601                         pudError(false, "Configured receive non-OLSR interface %s is not"
1602                                 " a known interface name", nonOlsrInterfaceName);
1603                         retval = false;
1604                 }
1605         }
1606
1607         /* any transmit interface name that is configured but is not the name of an
1608          * actual transmit interface is not a valid interface name */
1609         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
1610                 unsigned char * nonOlsrInterfaceName = &txNonOlsrInterfaceNames[i][0];
1611
1612                 TRxTxNetworkInterface * interfaceObject = getTxNetworkInterfaces();
1613                 bool found = false;
1614                 while (interfaceObject != NULL) {
1615                         if (strncmp((char *) nonOlsrInterfaceName,
1616                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
1617                                 found = true;
1618                                 break;
1619                         }
1620                         interfaceObject = interfaceObject->next;
1621                 }
1622                 if (!found) {
1623                         pudError(false, "Configured transmit non-OLSR interface %s is not"
1624                                 " a known interface name", nonOlsrInterfaceName);
1625                         retval = false;
1626                 }
1627         }
1628
1629         return retval;
1630 }