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