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