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