7640fb8b1cded54dffd7fc5a9c1c19c7b7344f82
[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 #include "posFile.h"
8 #include "configTools.h"
9
10 /* OLSR includes */
11 #include <olsr_protocol.h>
12
13 /* System includes */
14 #include <unistd.h>
15 #include <nmea/util.h>
16 #include <OlsrdPudWireFormat/nodeIdConversion.h>
17 #include <limits.h>
18
19 /*
20  * Note:
21  * Setters must return true when an error is detected, false otherwise
22  */
23
24 /*
25  * nodeIdType
26  */
27
28 /** The nodeIdType */
29 static NodeIdType nodeIdType = PUD_NODE_ID_TYPE_DEFAULT;
30
31 /**
32  @return
33  The node ID type
34  */
35 NodeIdType getNodeIdTypeNumber(void) {
36         return nodeIdType;
37 }
38
39 int setNodeIdType(const char *value, void *data __attribute__ ((unused)),
40                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
41         static const char * valueName = PUD_NODE_ID_TYPE_NAME;
42         unsigned long long nodeIdTypeNew;
43
44         if (!readULL(valueName, value, &nodeIdTypeNew)) {
45                 return true;
46         }
47
48         if (!isValidNodeIdType(nodeIdTypeNew)) {
49                 pudError(false, "Value of parameter %s (%llu) is reserved", valueName,
50                                 nodeIdTypeNew);
51                 return true;
52         }
53
54         nodeIdType = nodeIdTypeNew;
55
56         return false;
57 }
58
59 /*
60  * nodeId
61  */
62
63 /** The nodeId buffer */
64 static unsigned char nodeId[PUD_TX_NODEID_BUFFERSIZE + 1];
65
66 /** The length of the string in the nodeId buffer */
67 static size_t nodeIdLength = 0;
68
69 /** True when the nodeId is set */
70 static bool nodeIdSet = false;
71
72 /** The nodeId as a binary representation, with status */
73 static nodeIdBinaryType nodeIdBinary;
74
75 /**
76  @return
77  The node ID
78  */
79 unsigned char * getNodeId(void) {
80         return getNodeIdWithLength(NULL);
81 }
82
83 /**
84  Get the nodeId and its length
85
86  @param length
87  a pointer to the variable in which to store the nodeId length (allowed to be
88  NULL, in which case the length is not stored)
89
90  @return
91  The node ID
92  */
93 unsigned char * getNodeIdWithLength(size_t *length) {
94         if (!nodeIdSet) {
95                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
96         }
97
98         if (length != NULL) {
99                 *length = nodeIdLength;
100         }
101
102         return &nodeId[0];
103 }
104
105 /**
106  Get the nodeIdBinary
107
108  @return
109  The node ID in binary representation
110  */
111 nodeIdBinaryType * getNodeIdBinary(void) {
112         if (!nodeIdBinary.set) {
113                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
114         }
115
116         return &nodeIdBinary;
117 }
118
119 int setNodeId(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
120         size_t valueLength;
121
122         assert (value != NULL);
123
124         valueLength = strlen(value);
125         if (valueLength > PUD_TX_NODEID_BUFFERSIZE) {
126                 pudError(false, "Value of parameter %s is too long, maximum length is"
127                         " %u, current length is %lu", PUD_NODE_ID_NAME, PUD_TX_NODEID_BUFFERSIZE,
128                                 (unsigned long) valueLength);
129                 return true;
130         }
131
132         strcpy((char *) &nodeId[0], value);
133         nodeIdLength = valueLength;
134         nodeIdSet = true;
135         nodeIdBinary.set = false;
136
137         return false;
138 }
139
140 /*
141  * nodeId Validation
142  */
143
144 /**
145  Validate whether the configured nodeId is valid w.r.t. the configured
146  nodeIdType, for types that are MAC addresses
147
148  @return
149  - true when ok
150  - false on failure
151  */
152 static bool intSetupNodeIdBinaryMAC(void) {
153         unsigned char * mac = getMainIpMacAddress();
154         if (!mac) {
155                 return false;
156         }
157
158         return setupNodeIdBinaryMAC(&nodeIdBinary, mac);
159 }
160
161 /**
162  Validate whether the configured nodeId is valid w.r.t. the configured
163  nodeIdType, for types that fit in an unsigned long long (64 bits)
164
165  @param min
166  the minimum value
167  @param max
168  the maximum value
169  @param bytes
170  the number of bytes in the buffer
171
172  @return
173  - true when ok
174  - false on failure
175  */
176 static bool intSetupNodeIdBinaryLongLong(unsigned long long min,
177                 unsigned long long max, unsigned int bytes) {
178         unsigned long long longValue = 0;
179         if (!readULL(PUD_NODE_ID_NAME, (char *) getNodeId(), &longValue)) {
180                 return false;
181         }
182
183         if ((longValue < min) || (longValue > max)) {
184                 pudError(false, "%s value %llu is out of range [%llu,%llu]",
185                                 PUD_NODE_ID_NAME, longValue, min, max);
186                 return false;
187         }
188
189         return setupNodeIdBinaryLongLong(&nodeIdBinary, longValue, bytes);
190 }
191
192 /**
193  Validate whether the configured nodeId is valid w.r.t. the configured
194  nodeIdType, for types that are strings
195
196  @return
197  - true when ok
198  - false on failure
199  */
200 static bool intSetupNodeIdBinaryString(void) {
201         char report[256];
202         size_t nodeidlength;
203         char * nodeid = (char *)getNodeIdWithLength(&nodeidlength);
204
205         if (nmea_string_has_invalid_chars(nodeid, PUD_NODE_ID_NAME, &report[0], sizeof(report))) {
206                 pudError(false, "%s", &report[0]);
207                 return false;
208         }
209
210         if (nodeidlength > PUD_TX_NODEID_BUFFERSIZE) {
211                 pudError(false, "Length of parameter %s (%s) is too great", PUD_NODE_ID_NAME, &nodeid[0]);
212                 return false;
213         }
214
215         return setupNodeIdBinaryString(&nodeIdBinary, nodeid, nodeidlength);
216 }
217
218 /**
219  Validate whether the configured nodeId is valid w.r.t. the configured
220  nodeIdType, for types that are IP addresses
221
222  @return
223  - true when ok
224  - false on failure
225  */
226 static bool intSetupNodeIdBinaryIp(void) {
227         void * src;
228         size_t length;
229         if (olsr_cnf->ip_version == AF_INET) {
230                 src = &olsr_cnf->main_addr.v4;
231                 length = sizeof(struct in_addr);
232         } else {
233                 src = &olsr_cnf->main_addr.v6;
234                 length = sizeof(struct in6_addr);
235         }
236
237         return setupNodeIdBinaryIp(&nodeIdBinary, src, length);
238 }
239
240 /**
241  Validate whether the configured nodeId is valid w.r.t. the configured
242  nodeIdType and setup the binary value
243
244  @return
245  - true when ok
246  - false on failure
247  */
248 static bool setupNodeIdBinaryAndValidate(NodeIdType nodeIdTypeNumber) {
249         switch (nodeIdTypeNumber) {
250                 case PUD_NODEIDTYPE_MAC: /* hardware address */
251                         return intSetupNodeIdBinaryMAC();
252
253                 case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
254                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_MSISDN_MIN,
255                                 PUD_NODEIDTYPE_MSISDN_MAX, PUD_NODEIDTYPE_MSISDN_BYTES);
256
257                 case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
258                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_TETRA_MIN,
259                                 PUD_NODEIDTYPE_TETRA_MAX, PUD_NODEIDTYPE_TETRA_BYTES);
260
261                 case PUD_NODEIDTYPE_DNS: /* DNS name */
262                         return intSetupNodeIdBinaryString();
263
264                 case PUD_NODEIDTYPE_MMSI: /* an AIS MMSI number */
265                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_MMSI_MIN,
266                                 PUD_NODEIDTYPE_MMSI_MAX, PUD_NODEIDTYPE_MMSI_BYTES);
267
268                 case PUD_NODEIDTYPE_URN: /* a URN number */
269                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_URN_MIN,
270                                 PUD_NODEIDTYPE_URN_MAX, PUD_NODEIDTYPE_URN_BYTES);
271
272                 case PUD_NODEIDTYPE_192:
273                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_192_MIN,
274                                 PUD_NODEIDTYPE_192_MAX, PUD_NODEIDTYPE_192_BYTES);
275
276                 case PUD_NODEIDTYPE_193:
277                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_193_MIN,
278                                 PUD_NODEIDTYPE_193_MAX, PUD_NODEIDTYPE_193_BYTES);
279
280                 case PUD_NODEIDTYPE_194:
281                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_194_MIN,
282                                 PUD_NODEIDTYPE_194_MAX, PUD_NODEIDTYPE_194_BYTES);
283
284                 case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
285                 case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
286                 default: /* unsupported */
287                         return intSetupNodeIdBinaryIp();
288         }
289
290         return false;
291 }
292
293 /*
294  * rxNonOlsrIf
295  */
296
297 /** The maximum number of RX non-OLSR interfaces */
298 #define PUD_RX_NON_OLSR_IF_MAX 32
299
300 /** Array with RX non-OLSR interface names */
301 static unsigned char rxNonOlsrInterfaceNames[PUD_RX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
302
303 /** The number of RX non-OLSR interface names in the array */
304 static unsigned int rxNonOlsrInterfaceCount = 0;
305
306 /**
307  Determine whether a give interface name is configured as a receive non-OLSR
308  interface.
309
310  @param ifName
311  The interface name to check
312
313  @return
314  - true when the given interface name is configured as a receive non-OLSR
315  interface
316  - false otherwise
317  */
318 bool isRxNonOlsrInterface(const char *ifName) {
319         unsigned int i;
320
321         assert (ifName != NULL);
322
323         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
324                 if (strncmp((char *) &rxNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
325                                 + 1) == 0) {
326                         return true;
327                 }
328         }
329
330         return false;
331 }
332
333 int addRxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
334                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
335         size_t valueLength;
336
337         if (rxNonOlsrInterfaceCount >= PUD_RX_NON_OLSR_IF_MAX) {
338                 pudError(false, "Can't configure more than %u receive interfaces",
339                                 PUD_RX_NON_OLSR_IF_MAX);
340                 return true;
341         }
342
343         assert (value != NULL);
344
345         valueLength = strlen(value);
346         if (valueLength > IFNAMSIZ) {
347                 pudError(false, "Value of parameter %s (%s) is too long,"
348                         " maximum length is %u, current length is %lu",
349                                 PUD_RX_NON_OLSR_IF_NAME, value, IFNAMSIZ, (long unsigned int)valueLength);
350                 return true;
351         }
352
353         if (!isRxNonOlsrInterface(value)) {
354                 strcpy((char *) &rxNonOlsrInterfaceNames[rxNonOlsrInterfaceCount][0],
355                                 value);
356                 rxNonOlsrInterfaceCount++;
357         }
358
359         return false;
360 }
361
362 /*
363  * rxAllowedSourceIpAddress
364  */
365
366 /** The maximum number of RX allowed source IP addresses */
367 #define PUD_RX_ALLOWED_SOURCE_IP_MAX 32
368
369 /** Array with RX allowed source IP addresses */
370 static union olsr_sockaddr rxAllowedSourceIpAddresses[PUD_RX_ALLOWED_SOURCE_IP_MAX];
371
372 /** The number of RX allowed source IP addresses in the array */
373 static unsigned int rxAllowedSourceIpAddressesCount = 0;
374
375 /**
376  Determine whether a give IP address is configured as an allowed source IP
377  address.
378
379  @param sender
380  The IP address to check
381
382  @return
383  - true when the given IP address is configured as an allowed source IP
384  address
385  - false otherwise
386  */
387 bool isRxAllowedSourceIpAddress(union olsr_sockaddr * sender) {
388         unsigned int i;
389
390         if (rxAllowedSourceIpAddressesCount == 0) {
391                 return true;
392         }
393
394         if (sender == NULL) {
395                 return false;
396         }
397
398         for (i = 0; i < rxAllowedSourceIpAddressesCount; i++) {
399                 if (sender->in.sa_family != rxAllowedSourceIpAddresses[i].in.sa_family) {
400                         continue;
401                 }
402
403                 if (sender->in.sa_family == AF_INET) {
404                         if (memcmp(&rxAllowedSourceIpAddresses[i].in4.sin_addr, &sender->in4.sin_addr, sizeof(struct in_addr))
405                                         == 0) {
406                                 return true;
407                         }
408                 } else {
409                         if (memcmp(&rxAllowedSourceIpAddresses[i].in6.sin6_addr, &sender->in6.sin6_addr, sizeof(struct in6_addr))
410                                         == 0) {
411                                 return true;
412                         }
413                 }
414         }
415
416         return false;
417 }
418
419 int addRxAllowedSourceIpAddress(const char *value, void *data __attribute__ ((unused)),
420                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
421         static const char * valueName = PUD_RX_ALLOWED_SOURCE_IP_NAME;
422         union olsr_sockaddr addr;
423         bool addrSet = false;
424
425         if (rxAllowedSourceIpAddressesCount >= PUD_RX_ALLOWED_SOURCE_IP_MAX) {
426                 pudError(false, "Can't configure more than %u allowed source IP"
427                         " addresses", PUD_RX_ALLOWED_SOURCE_IP_MAX);
428                 return true;
429         }
430
431         if (!readIPAddress(valueName, value, 0, &addr, &addrSet)) {
432                 return true;
433         }
434
435         if (!isRxAllowedSourceIpAddress(&addr)) {
436                 rxAllowedSourceIpAddresses[rxAllowedSourceIpAddressesCount] = addr;
437                 rxAllowedSourceIpAddressesCount++;
438         }
439
440         return false;
441 }
442
443 /*
444  * rxMcAddr + rxMcPort
445  */
446
447 /** The rx multicast address */
448 static union olsr_sockaddr rxMcAddr;
449
450 /** True when the rx multicast address is set */
451 static bool rxMcAddrSet = false;
452
453 /**
454  @return
455  The receive multicast address (in network byte order). Sets both the address
456  and the port to their default values when the address was not yet set.
457  */
458 union olsr_sockaddr * getRxMcAddr(void) {
459         if (!rxMcAddrSet) {
460                 setRxMcAddr((olsr_cnf->ip_version == AF_INET) ? PUD_RX_MC_ADDR_4_DEFAULT : PUD_RX_MC_ADDR_6_DEFAULT,
461                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
462         }
463         return &rxMcAddr;
464 }
465
466 int setRxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
467         static const char * valueName = PUD_RX_MC_ADDR_NAME;
468
469         if (!readIPAddress(valueName, value, PUD_RX_MC_PORT_DEFAULT, &rxMcAddr, &rxMcAddrSet)) {
470                         return true;
471         }
472
473         if (!isMulticast(&rxMcAddr)) {
474                 pudError(false, "Value of parameter %s (%s) is not a multicast address",
475                                 valueName, value);
476                 return true;
477         }
478
479         return false;
480 }
481
482 /**
483  @return
484  The receive multicast port (in network byte order)
485  */
486 unsigned short getRxMcPort(void) {
487         return getOlsrSockaddrPort(getRxMcAddr(), PUD_RX_MC_PORT_DEFAULT);
488 }
489
490 int setRxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
491         static const char * valueName = PUD_RX_MC_PORT_NAME;
492         unsigned short rxMcPortNew;
493
494         if (!readUS(valueName, value, &rxMcPortNew)) {
495                 return true;
496         }
497
498         if (rxMcPortNew < 1) {
499                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, rxMcPortNew);
500                 return true;
501         }
502
503         setOlsrSockaddrPort(getRxMcAddr(), htons((in_port_t) rxMcPortNew));
504
505         return false;
506 }
507
508 /*
509  * positionFile
510  */
511
512 /** The positionFile buffer */
513 static char positionFile[PATH_MAX + 1];
514
515 /** True when the positionFile is set */
516 static bool positionFileSet = false;
517
518 /**
519  @return
520  The positionFile (NULL when not set)
521  */
522 char * getPositionFile(void) {
523         if (!positionFileSet) {
524                 return NULL;
525         }
526
527         return &positionFile[0];
528 }
529
530 int setPositionFile(const char *value, void *data __attribute__ ((unused)),
531                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
532         size_t valueLength;
533
534         assert(value != NULL);
535
536         if (!startPositionFile()) {
537                 stopPositionFile();
538                 return true;
539         }
540
541         valueLength = strlen(value);
542         if (valueLength > PATH_MAX) {
543                 pudError(false, "Value of parameter %s is too long, maximum length is"
544                                 " %u, current length is %lu", PUD_POSFILE_NAME, PATH_MAX, (unsigned long) valueLength);
545                 return true;
546         }
547
548         strcpy((char *) &positionFile[0], value);
549         positionFileSet = true;
550
551         return false;
552 }
553
554 /*
555  * txNonOlsrIf
556  */
557
558 /** The maximum number of tx non-olsr interfaces */
559 #define PUD_TX_NON_OLSR_IF_MAX 32
560
561 /** Array with tx non-olsr interface names */
562 static unsigned char txNonOlsrInterfaceNames[PUD_TX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
563
564 /** The number of tx interface names in the array */
565 static unsigned int txNonOlsrInterfaceCount = 0;
566
567 /**
568  Determine whether a give interface name is configured as a transmit non-OLSR
569  interface.
570
571  @param ifName
572  The interface to check
573
574  @return
575  - true when the given interface name is configured as a transmit non-OLSR
576  interface
577  - false otherwise
578  */
579 bool isTxNonOlsrInterface(const char *ifName) {
580         unsigned int i;
581
582         assert (ifName != NULL);
583
584         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
585                 if (strncmp((char *) &txNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ + 1) == 0) {
586                         return true;
587                 }
588         }
589
590         return false;
591 }
592
593 int addTxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
594                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
595         size_t valueLength;
596
597         assert (value != NULL);
598
599         if (txNonOlsrInterfaceCount >= PUD_TX_NON_OLSR_IF_MAX) {
600                 pudError(false, "Can not configure more than %u transmit interfaces", PUD_TX_NON_OLSR_IF_MAX);
601                 return true;
602         }
603
604         valueLength = strlen(value);
605         if (valueLength > IFNAMSIZ) {
606                 pudError(false, "Value of parameter %s (%s) is too long, maximum length is %u, current length is %lu",
607                                 PUD_TX_NON_OLSR_IF_NAME, value, IFNAMSIZ, (long unsigned int)valueLength);
608                 return true;
609         }
610
611         if (!isTxNonOlsrInterface(value)) {
612                 strcpy((char *) &txNonOlsrInterfaceNames[txNonOlsrInterfaceCount][0], value);
613                 txNonOlsrInterfaceCount++;
614         }
615
616         return false;
617 }
618
619 /*
620  * txMcAddr + txMcPort
621  */
622
623 /** The tx multicast address */
624 static union olsr_sockaddr txMcAddr;
625
626 /** True when the tx multicast address is set */
627 static bool txMcAddrSet = false;
628
629 /**
630  @return
631  The transmit multicast address (in network byte order). Sets both the address
632  and the port to their default values when the address was not yet set.
633  */
634 union olsr_sockaddr * getTxMcAddr(void) {
635         if (!txMcAddrSet) {
636                 setTxMcAddr((olsr_cnf->ip_version == AF_INET) ? PUD_TX_MC_ADDR_4_DEFAULT : PUD_TX_MC_ADDR_6_DEFAULT,
637                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
638         }
639         return &txMcAddr;
640 }
641
642 int setTxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
643         static const char * valueName = PUD_TX_MC_ADDR_NAME;
644
645         if (!readIPAddress(valueName, value, PUD_TX_MC_PORT_DEFAULT, &txMcAddr, &txMcAddrSet)) {
646                         return true;
647         }
648
649         if (!isMulticast(&txMcAddr)) {
650                 pudError(false, "Value of parameter %s (%s) is not a multicast address",
651                                 valueName, value);
652                 return true;
653         }
654
655         return false;
656 }
657
658 /**
659  @return
660  The transmit multicast port (in network byte order)
661  */
662 unsigned short getTxMcPort(void) {
663         return getOlsrSockaddrPort(getTxMcAddr(), PUD_TX_MC_PORT_DEFAULT);
664 }
665
666 int setTxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
667         static const char * valueName = PUD_TX_MC_PORT_NAME;
668         unsigned short txMcPortNew;
669
670         if (!readUS(valueName, value, &txMcPortNew)) {
671                 return true;
672         }
673
674         if (txMcPortNew < 1) {
675                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, txMcPortNew);
676                 return true;
677         }
678
679         setOlsrSockaddrPort(getTxMcAddr(), htons((in_port_t) txMcPortNew));
680
681         return false;
682 }
683
684 /*
685  * txTtl
686  */
687
688 /** The tx TTL */
689 static unsigned char txTtl = PUD_TX_TTL_DEFAULT;
690
691 /**
692  @return
693  The transmit multicast IP packet time-to-live
694  */
695 unsigned char getTxTtl(void) {
696         return txTtl;
697 }
698
699 int setTxTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
700         static const char * valueName = PUD_TX_TTL_NAME;
701
702         if (!readUC(valueName, value, &txTtl)) {
703                 return true;
704         }
705
706         if ((txTtl < 1) /* || (txTtl > MAX_TTL) */) {
707                 pudError(false, "Value of parameter %s (%u) is outside of"
708                         " valid range 1-%u", valueName, txTtl, MAX_TTL);
709                 return true;
710         }
711
712         return false;
713 }
714
715 /*
716  * txNmeaMessagePrefix
717  */
718
719 /** The exact length of the tx NMEA message prefix */
720 #define PUD_TXNMEAMESSAGEPREFIXLENGTH 4
721
722 /** The tx NMEA message prefix buffer */
723 static unsigned char txNmeaMessagePrefix[PUD_TXNMEAMESSAGEPREFIXLENGTH + 1];
724
725 /** True when the tx NMEA message prefix is set */
726 static bool txNmeaMessagePrefixSet = false;
727
728 /**
729  @return
730  The transmit multicast NMEA message prefix
731  */
732 unsigned char * getTxNmeaMessagePrefix(void) {
733         if (!txNmeaMessagePrefixSet) {
734                 setTxNmeaMessagePrefix(PUD_TX_NMEAMESSAGEPREFIX_DEFAULT, NULL,
735                                 (set_plugin_parameter_addon) {.pc = NULL});
736         }
737         return &txNmeaMessagePrefix[0];
738 }
739
740 int setTxNmeaMessagePrefix(const char *value, void *data __attribute__ ((unused)),
741                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
742         static const char * valueName = PUD_TX_NMEAMESSAGEPREFIX_NAME;
743         size_t valueLength;
744         char report[256];
745
746         assert (value != NULL);
747
748         valueLength = strlen(value);
749         if (valueLength != PUD_TXNMEAMESSAGEPREFIXLENGTH) {
750                 pudError(false, "Length of parameter %s (%s) must be exactly %u characters",
751                                 valueName, value, PUD_TXNMEAMESSAGEPREFIXLENGTH);
752                 return true;
753         }
754
755         if (nmea_string_has_invalid_chars(value, valueName, &report[0], sizeof(report))) {
756                 pudError(false, "%s", &report[0]);
757                 return true;
758         }
759
760         if ((strchr(value, ' ') != NULL) || (strchr(value, '\t') != NULL)) {
761                 pudError(false, "Value of parameter %s (%s) can not contain whitespace",
762                                 valueName, value);
763                 return true;
764         }
765
766         strcpy((char *) &txNmeaMessagePrefix[0], value);
767         txNmeaMessagePrefixSet = true;
768         return false;
769 }
770
771 /*
772  * uplinkAddr + uplinkPort
773  */
774
775 /** The uplink address */
776 static union olsr_sockaddr uplinkAddr;
777
778 /** True when the uplink address is set */
779 static bool uplinkAddrSet = false;
780
781 /**
782  @return
783  - true when the uplink address is set
784  - false otherwise
785  */
786 bool isUplinkAddrSet(void) {
787         return uplinkAddrSet;
788 }
789
790 /**
791  @return
792  The uplink address (in network byte order). Sets both the address
793  and the port to their default values when the address was not yet set.
794  */
795 union olsr_sockaddr * getUplinkAddr(void) {
796         if (!uplinkAddrSet) {
797                 setUplinkAddr((olsr_cnf->ip_version == AF_INET) ? PUD_UPLINK_ADDR_4_DEFAULT : PUD_UPLINK_ADDR_6_DEFAULT,
798                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
799         }
800         return &uplinkAddr;
801 }
802
803 int setUplinkAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
804         return !readIPAddress(PUD_UPLINK_ADDR_NAME, value, PUD_UPLINK_PORT_DEFAULT, &uplinkAddr, &uplinkAddrSet);
805 }
806
807 /**
808  @return
809  The uplink port (in network byte order)
810  */
811 unsigned short getUplinkPort(void) {
812         return getOlsrSockaddrPort(getUplinkAddr(), PUD_UPLINK_PORT_DEFAULT);
813 }
814
815 int setUplinkPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
816         static const char * valueName = PUD_UPLINK_PORT_NAME;
817         unsigned short uplinkPortNew;
818
819         if (!readUS(valueName, value, &uplinkPortNew)) {
820                 return true;
821         }
822
823         if (uplinkPortNew < 1) {
824                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, uplinkPortNew);
825                 return true;
826         }
827
828         setOlsrSockaddrPort(getUplinkAddr(), htons((in_port_t) uplinkPortNew));
829
830         return false;
831 }
832
833 /*
834  * downlinkPort
835  */
836
837 /** the downlink port */
838 unsigned short downlinkPort = 0;
839
840 /** true when the downlinkPort is set */
841 bool downlinkPortSet = false;
842
843 /**
844  @return
845  The downlink port (in network byte order)
846  */
847 unsigned short getDownlinkPort(void) {
848         if (!downlinkPortSet) {
849                 downlinkPort = htons(PUD_DOWNLINK_PORT_DEFAULT);
850                 downlinkPortSet = true;
851         }
852
853         return downlinkPort;
854 }
855
856 int setDownlinkPort(const char *value, void *data __attribute__ ((unused)),
857                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
858         static const char * valueName = PUD_DOWNLINK_PORT_NAME;
859         unsigned short downlinkPortNew;
860
861         if (!readUS(valueName, value, &downlinkPortNew)) {
862                 return true;
863         }
864
865         if (downlinkPortNew < 1) {
866                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, downlinkPortNew);
867                 return true;
868         }
869
870         downlinkPort = htons(downlinkPortNew);
871         downlinkPortSet = true;
872
873         return false;
874 }
875
876 /*
877  * olsrTtl
878  */
879
880 /** The OLSR TTL */
881 static unsigned char olsrTtl = PUD_OLSR_TTL_DEFAULT;
882
883 /**
884  @return
885  The OLSR multicast IP packet time-to-live
886  */
887 unsigned char getOlsrTtl(void) {
888         return olsrTtl;
889 }
890
891 int setOlsrTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
892         static const char * valueName = PUD_OLSR_TTL_NAME;
893
894         if (!readUC(valueName, value, &olsrTtl)) {
895                 return true;
896         }
897
898         if ((olsrTtl < 1) /* || (olsrTtl > MAX_TTL) */) {
899                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-%u",
900                                 valueName, olsrTtl, MAX_TTL);
901                 return true;
902         }
903
904         return false;
905 }
906
907 /*
908  * updateIntervalStationary
909  */
910
911 /** The stationary interval update plugin parameter (in seconds) */
912 static unsigned long long updateIntervalStationary = PUD_UPDATE_INTERVAL_STATIONARY_DEFAULT;
913
914 /**
915  @return
916  The stationary interval update plugin parameter (in seconds)
917  */
918 unsigned long long getUpdateIntervalStationary(void) {
919         return updateIntervalStationary;
920 }
921
922 int setUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
923                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
924         static const char * valueName = PUD_UPDATE_INTERVAL_STATIONARY_NAME;
925
926         if (!readULL(valueName, value, &updateIntervalStationary)) {
927                 return true;
928         }
929
930         if (updateIntervalStationary < 1) {
931                 pudError(false, "Value of parameter %s must be at least 1", valueName);
932                 return true;
933         }
934
935         return false;
936 }
937
938 /*
939  * updateIntervalMoving
940  */
941
942 /** The moving interval update plugin parameter (in seconds) */
943 static unsigned long long updateIntervalMoving = PUD_UPDATE_INTERVAL_MOVING_DEFAULT;
944
945 /**
946  @return
947  The moving interval update plugin parameter (in seconds)
948  */
949 unsigned long long getUpdateIntervalMoving(void) {
950         return updateIntervalMoving;
951 }
952
953 int setUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
954                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
955         static const char * valueName = PUD_UPDATE_INTERVAL_MOVING_NAME;
956
957         if (!readULL(valueName, value, &updateIntervalMoving)) {
958                 return true;
959         }
960
961         if (updateIntervalMoving < 1) {
962                 pudError(false, "Value of parameter %s must be at least 1", valueName);
963                 return true;
964         }
965
966         return false;
967 }
968
969 /*
970  * uplinkUpdateIntervalStationary
971  */
972
973 /** The uplink stationary interval update plugin parameter (in seconds) */
974 static unsigned long long uplinkUpdateIntervalStationary = PUD_UPLINK_UPDATE_INTERVAL_STATIONARY_DEFAULT;
975
976 /**
977  @return
978  The uplink stationary interval update plugin parameter (in seconds)
979  */
980 unsigned long long getUplinkUpdateIntervalStationary(void) {
981         return uplinkUpdateIntervalStationary;
982 }
983
984 int setUplinkUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
985                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
986         static const char * valueName = PUD_UPLINK_UPDATE_INTERVAL_STATIONARY_NAME;
987
988         if (!readULL(valueName, value, &uplinkUpdateIntervalStationary)) {
989                 return true;
990         }
991
992         if (uplinkUpdateIntervalStationary < 1) {
993                 pudError(false, "Value of parameter %s must be at least 1", valueName);
994                 return true;
995         }
996
997         return false;
998 }
999
1000 /*
1001  * uplinkUpdateIntervalMoving
1002  */
1003
1004 /** The uplink moving interval update plugin parameter (in seconds) */
1005 static unsigned long long uplinkUpdateIntervalMoving = PUD_UPLINK_UPDATE_INTERVAL_MOVING_DEFAULT;
1006
1007 /**
1008  @return
1009  The uplink moving interval update plugin parameter (in seconds)
1010  */
1011 unsigned long long getUplinkUpdateIntervalMoving(void) {
1012         return uplinkUpdateIntervalMoving;
1013 }
1014
1015 int setUplinkUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1016                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1017         static const char * valueName = PUD_UPLINK_UPDATE_INTERVAL_MOVING_NAME;
1018
1019         if (!readULL(valueName, value, &uplinkUpdateIntervalMoving)) {
1020                 return true;
1021         }
1022
1023         if (uplinkUpdateIntervalMoving < 1) {
1024                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1025                 return true;
1026         }
1027
1028         return false;
1029 }
1030
1031 /*
1032  * gatewayDeterminationInterval
1033  */
1034
1035 /** The gateway determination interval plugin parameter (in seconds) */
1036 static unsigned long long gatewayDeterminationInterval = PUD_GATEWAY_DETERMINATION_INTERVAL_DEFAULT;
1037
1038 /**
1039  @return
1040  The gateway determination interval plugin parameter (in seconds)
1041  */
1042 unsigned long long getGatewayDeterminationInterval(void) {
1043         return gatewayDeterminationInterval;
1044 }
1045
1046 int setGatewayDeterminationInterval(const char *value, void *data __attribute__ ((unused)),
1047                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1048         static const char * valueName = PUD_GATEWAY_DETERMINATION_INTERVAL_NAME;
1049
1050         if (!readULL(valueName, value, &gatewayDeterminationInterval)) {
1051                 return true;
1052         }
1053
1054         if (gatewayDeterminationInterval < 1) {
1055                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1056                 return true;
1057         }
1058
1059         return false;
1060 }
1061
1062 /*
1063  * movingSpeedThreshold
1064  */
1065
1066 /** The moving speed threshold plugin parameter (in kph) */
1067 static unsigned long long movingSpeedThreshold = PUD_MOVING_SPEED_THRESHOLD_DEFAULT;
1068
1069 /**
1070  @return
1071  The moving speed threshold plugin parameter (in kph)
1072  */
1073 unsigned long long getMovingSpeedThreshold(void) {
1074         return movingSpeedThreshold;
1075 }
1076
1077 int setMovingSpeedThreshold(const char *value, void *data __attribute__ ((unused)),
1078                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1079         return !readULL(PUD_MOVING_SPEED_THRESHOLD_NAME, value, &movingSpeedThreshold);
1080 }
1081
1082 /*
1083  * movingDistanceThreshold
1084  */
1085
1086 /** The moving distance threshold plugin parameter (in meters) */
1087 static unsigned long long movingDistanceThreshold = PUD_MOVING_DISTANCE_THRESHOLD_DEFAULT;
1088
1089 /**
1090  @return
1091  The moving distance threshold plugin parameter (in meters)
1092  */
1093 unsigned long long getMovingDistanceThreshold(void) {
1094         return movingDistanceThreshold;
1095 }
1096
1097 int setMovingDistanceThreshold(const char *value, void *data __attribute__ ((unused)),
1098                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1099         return !readULL(PUD_MOVING_DISTANCE_THRESHOLD_NAME, value, &movingDistanceThreshold);
1100 }
1101
1102 /*
1103  * dopMultiplier
1104  */
1105
1106 /** The DOP multiplier plugin parameter */
1107 static double dopMultiplier = PUD_DOP_MULTIPLIER_DEFAULT;
1108
1109 /**
1110  @return
1111  The DOP multiplier plugin parameter
1112  */
1113 double getDopMultiplier(void) {
1114         return dopMultiplier;
1115 }
1116
1117 int setDopMultiplier(const char *value, void *data __attribute__ ((unused)),
1118                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1119         return !readDouble(PUD_DOP_MULTIPLIER_NAME, value, &dopMultiplier);
1120 }
1121
1122 /*
1123  * defaultHdop
1124  */
1125
1126 /** The default HDOP plugin parameter (in meters) */
1127 static unsigned long long defaultHdop = PUD_DEFAULT_HDOP_DEFAULT;
1128
1129 /**
1130  @return
1131  The default HDOP plugin parameter (in meters)
1132  */
1133 unsigned long long getDefaultHdop(void) {
1134         return defaultHdop;
1135 }
1136
1137 int setDefaultHdop(const char *value, void *data __attribute__ ((unused)),
1138                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1139         return !readULL(PUD_DEFAULT_HDOP_NAME, value, &defaultHdop);
1140 }
1141
1142 /*
1143  * defaultVdop
1144  */
1145
1146 /** The default VDOP plugin parameter (in meters) */
1147 static unsigned long long defaultVdop = PUD_DEFAULT_VDOP_DEFAULT;
1148
1149 /**
1150  @return
1151  The default VDOP plugin parameter (in meters)
1152  */
1153 unsigned long long getDefaultVdop(void) {
1154         return defaultVdop;
1155 }
1156
1157 int setDefaultVdop(const char *value, void *data __attribute__ ((unused)),
1158                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1159         return !readULL(PUD_DEFAULT_VDOP_NAME, value, &defaultVdop);
1160 }
1161
1162 /*
1163  * averageDepth
1164  */
1165
1166 /** The depth of the average list */
1167 static unsigned long long averageDepth = PUD_AVERAGE_DEPTH_DEFAULT;
1168
1169 /**
1170  @return
1171  The depth of the average list
1172  */
1173 unsigned long long getAverageDepth(void) {
1174         return averageDepth;
1175 }
1176
1177 int setAverageDepth(const char *value, void *data __attribute__ ((unused)),
1178                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1179         static const char * valueName = PUD_AVERAGE_DEPTH_NAME;
1180
1181         if (!readULL(valueName, value, &averageDepth)) {
1182                 return true;
1183         }
1184
1185         if (averageDepth < 1) {
1186                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1187                 return true;
1188         }
1189
1190         return false;
1191 }
1192
1193 /*
1194  * hysteresisCountToStationary
1195  */
1196
1197 /** The hysteresis count for changing state from moving to stationary */
1198 static unsigned long long hysteresisCountToStationary = PUD_HYSTERESIS_COUNT_2STAT_DEFAULT;
1199
1200 /**
1201  @return
1202  The hysteresis count for changing state from moving to stationary
1203  */
1204 unsigned long long getHysteresisCountToStationary(void) {
1205         return hysteresisCountToStationary;
1206 }
1207
1208 int setHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1209                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1210         return !readULL(PUD_HYSTERESIS_COUNT_2STAT_NAME, value, &hysteresisCountToStationary);
1211 }
1212
1213 /*
1214  * hysteresisCountToMoving
1215  */
1216
1217 /** The hysteresis count for changing state from stationary to moving */
1218 static unsigned long long hysteresisCountToMoving = PUD_HYSTERESIS_COUNT_2MOV_DEFAULT;
1219
1220 /**
1221  @return
1222  The hysteresis count for changing state from stationary to moving
1223  */
1224 unsigned long long getHysteresisCountToMoving(void) {
1225         return hysteresisCountToMoving;
1226 }
1227
1228 int setHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1229                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1230         return !readULL(PUD_HYSTERESIS_COUNT_2MOV_NAME, value, &hysteresisCountToMoving);
1231 }
1232
1233 /*
1234  * gatewayHysteresisCountToStationary
1235  */
1236
1237 /** The hysteresis count for changing state from moving to stationary */
1238 static unsigned long long gatewayHysteresisCountToStationary = PUD_GAT_HYSTERESIS_COUNT_2STAT_DEFAULT;
1239
1240 /**
1241  @return
1242  The hysteresis count for changing state from moving to stationary
1243  */
1244 unsigned long long getGatewayHysteresisCountToStationary(void) {
1245         return gatewayHysteresisCountToStationary;
1246 }
1247
1248 int setGatewayHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1249                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1250         return !readULL(PUD_GAT_HYSTERESIS_COUNT_2STAT_NAME, value, &gatewayHysteresisCountToStationary);
1251 }
1252
1253 /*
1254  * gatewayHysteresisCountToMoving
1255  */
1256
1257 /** The hysteresis count for changing state from stationary to moving */
1258 static unsigned long long gatewayHysteresisCountToMoving = PUD_GAT_HYSTERESIS_COUNT_2MOV_DEFAULT;
1259
1260 /**
1261  @return
1262  The hysteresis count for changing state from stationary to moving
1263  */
1264 unsigned long long getGatewayHysteresisCountToMoving(void) {
1265         return gatewayHysteresisCountToMoving;
1266 }
1267
1268 int setGatewayHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1269                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1270         return !readULL(PUD_GAT_HYSTERESIS_COUNT_2MOV_NAME, value, &gatewayHysteresisCountToMoving);
1271 }
1272
1273 /*
1274  * useDeDup
1275  */
1276
1277 /** when true then duplicate message detection is performed */
1278 static bool useDeDup = PUD_USE_DEDUP_DEFAULT;
1279
1280 /**
1281  @return
1282  The duplicate message detection setting
1283  */
1284 bool getUseDeDup(void) {
1285         return useDeDup;
1286 }
1287
1288 int setUseDeDup(const char *value, void *data __attribute__ ((unused)),
1289                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1290         return !readBool(PUD_USE_DEDUP_NAME, value, &useDeDup);
1291 }
1292
1293 /*
1294  * deDupDepth
1295  */
1296
1297 /** The deduplication depth */
1298 static unsigned long long deDupDepth = PUD_DEDUP_DEPTH_DEFAULT;
1299
1300 /**
1301  @return
1302  The deduplication depth
1303  */
1304 unsigned long long getDeDupDepth(void) {
1305         return deDupDepth;
1306 }
1307
1308 int setDeDupDepth(const char *value, void *data __attribute__ ((unused)),
1309                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1310         return !readULL(PUD_DEDUP_DEPTH_NAME, value, &deDupDepth);
1311 }
1312
1313 /*
1314  * useLoopback
1315  */
1316
1317 /** when true then loopback is performed */
1318 static bool useLoopback = PUD_USE_LOOPBACK_DEFAULT;
1319
1320 /**
1321  @return
1322  The loopback usage setting
1323  */
1324 bool getUseLoopback(void) {
1325         return useLoopback;
1326 }
1327
1328 int setUseLoopback(const char *value, void *data __attribute__ ((unused)),
1329                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1330         return !readBool(PUD_USE_LOOPBACK_NAME, value, &useLoopback);
1331 }
1332
1333 /*
1334  * Check Functions
1335  */
1336
1337 /**
1338  Check the configuration for consistency and validity.
1339
1340  @return
1341  - true when the configuration is consistent and valid
1342  - false otherwise
1343  */
1344 unsigned int checkConfig(void) {
1345         int retval = true;
1346
1347         if (!olsr_cnf->smart_gw_active) {
1348                 pudError(false, "Smart Gateway must be active");
1349                 retval = false;
1350         }
1351
1352         if (rxNonOlsrInterfaceCount == 0) {
1353                 pudError(false, "No receive non-OLSR interfaces configured");
1354                 retval = false;
1355         }
1356
1357         if (txNonOlsrInterfaceCount == 0) {
1358                 pudError(false, "No transmit non-OLSR interfaces configured");
1359                 retval = false;
1360         }
1361
1362         if (!nodeIdSet) {
1363                 if (nodeIdType == PUD_NODEIDTYPE_DNS) {
1364                         char name[PUD_TX_NODEID_BUFFERSIZE + 1];
1365
1366                         errno = 0;
1367                         if (gethostname(&name[0], sizeof(name)) < 0) {
1368                                 pudError(true, "Could not get the host name");
1369                                 retval = false;
1370                         } else {
1371                                 setNodeId(&name[0], NULL,
1372                                                 (set_plugin_parameter_addon) {.pc = NULL});
1373                         }
1374                 } else if ((nodeIdType != PUD_NODEIDTYPE_MAC) && (nodeIdType
1375                                 != PUD_NODEIDTYPE_IPV4) && (nodeIdType != PUD_NODEIDTYPE_IPV6)) {
1376                         pudError(false, "No node ID set while one is required for"
1377                                 " node type %u", nodeIdType);
1378                         retval = false;
1379                 }
1380         }
1381
1382         if (!setupNodeIdBinaryAndValidate(nodeIdType)) {
1383                 retval = false;
1384         }
1385
1386         if (updateIntervalMoving > updateIntervalStationary) {
1387                 pudError(false,"The update interval for moving situations must not be"
1388                 " larger than that for stationary situations");
1389                 retval = false;
1390         }
1391
1392         if (uplinkUpdateIntervalMoving > uplinkUpdateIntervalStationary) {
1393                 pudError(false,"The uplink update interval for moving situations must not be"
1394                 " larger than that for stationary situations");
1395                 retval = false;
1396         }
1397
1398         if (isUplinkAddrSet() && (getUplinkPort() == getDownlinkPort())) {
1399                 pudError(false, "The uplink port and the downlink port must not be the same");
1400                 retval = false;
1401         }
1402
1403         return retval;
1404 }
1405
1406 /**
1407  Check the configuration for consistency and validity after everything has been
1408  setup.
1409
1410  @return
1411  - true when the configuration is consistent and valid
1412  - false otherwise
1413  */
1414 unsigned int checkRunSetup(void) {
1415         return true;
1416 }