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