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