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