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