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