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