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