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