PUD: introduce dopMultiplier plugin parameter
[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 "nmeaTools.h"
7 #include "nodeIdConversion.h"
8 #include "networkInterfaces.h"
9
10 /* OLSR includes */
11 #include "olsr_types.h"
12 #include "olsr_protocol.h"
13 #include "cfgparser/olsrd_conf.h"
14
15 /* System includes */
16 #include <assert.h>
17 #include <errno.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <net/if.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <sys/socket.h>
24 #include <unistd.h>
25 #include <stdint.h>
26
27 /*
28  * Utility functions
29  */
30
31 /**
32  Read an unsigned long long number from a value string
33
34  @param valueName
35  the name of the value
36  @param value
37  the string to convert to a number
38  @param valueNumber
39  a pointer to the location where to store the number upon successful conversion
40
41  @return
42  - true on success
43  - false otherwise
44  */
45 bool readULL(const char * valueName, const char * value,
46                 unsigned long long * valueNumber) {
47         char * endPtr = NULL;
48         unsigned long long valueNew;
49
50         errno = 0;
51         valueNew = strtoull(value, &endPtr, 10);
52
53         if (!((endPtr != value) && (*value != '\0') && (*endPtr == '\0'))) {
54                 /* invalid conversion */
55                 pudError(true, "Configured %s (%s) could not be converted to a number",
56                                 valueName, value);
57                 return false;
58         }
59
60         *valueNumber = valueNew;
61
62         return true;
63 }
64
65 /**
66  Read a double number from a value string
67
68  @param valueName
69  the name of the value
70  @param value
71  the string to convert to a number
72  @param valueNumber
73  a pointer to the location where to store the number upon successful conversion
74
75  @return
76  - true on success
77  - false otherwise
78  */
79 bool readDouble(const char * valueName, const char * value,
80                 double * valueNumber) {
81         char * endPtr = NULL;
82         double valueNew;
83
84         errno = 0;
85         valueNew = strtod(value, &endPtr);
86
87         if (!((endPtr != value) && (*value != '\0') && (*endPtr == '\0'))) {
88                 /* invalid conversion */
89                 pudError(true, "Configured %s (%s) could not be converted to a number",
90                                 valueName, value);
91                 return false;
92         }
93
94         *valueNumber = valueNew;
95
96         return true;
97 }
98
99 /*
100  * nodeIdType
101  */
102
103 /** The nodeIdType */
104 NodeIdType nodeIdType = PUD_NODE_ID_TYPE_DEFAULT;
105
106 /**
107  @return
108  The node ID type
109  */
110 NodeIdType getNodeIdTypeNumber(void) {
111         return nodeIdType;
112 }
113
114 /**
115  Set the node ID type.
116
117  @param value
118  The value of the node ID type to set (a number in string representation)
119  @param data
120  Unused
121  @param addon
122  Unused
123
124  @return
125  - true when an error is detected
126  - false otherwise
127  */
128 int setNodeIdType(const char *value, void *data __attribute__ ((unused)),
129                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
130         static const char * valueName = PUD_NODE_ID_TYPE_NAME;
131         unsigned long long nodeIdTypeNew;
132
133         assert (value != NULL);
134
135         if (!readULL(valueName, value, &nodeIdTypeNew)) {
136                 return true;
137         }
138
139         if (nodeIdTypeNew > PUD_NODE_ID_TYPE_MAX) {
140                 pudError(false, "Configured %s (%llu) is out of range 0-%u", valueName,
141                                 nodeIdTypeNew, PUD_NODE_ID_TYPE_MAX);
142                 return true;
143         }
144
145         switch (nodeIdTypeNew) {
146                 case PUD_NODEIDTYPE_MAC:
147                 case PUD_NODEIDTYPE_MSISDN:
148                 case PUD_NODEIDTYPE_TETRA:
149                 case PUD_NODEIDTYPE_DNS:
150                 case PUD_NODEIDTYPE_IPV4:
151                 case PUD_NODEIDTYPE_IPV6:
152                 case PUD_NODEIDTYPE_192:
153                 case PUD_NODEIDTYPE_193:
154                 case PUD_NODEIDTYPE_194:
155                         break;
156
157                 default:
158                         pudError(false, "Configured %s (%llu) is reserved", valueName,
159                                         nodeIdTypeNew);
160                         return true;
161         }
162
163         nodeIdType = nodeIdTypeNew;
164
165         return false;
166 }
167
168 /*
169  * nodeId
170  */
171
172 /** The maximum length of a nodeId */
173 #define PUD_NODEIDMAXLENGTH 255
174
175 /** The nodeId buffer */
176 unsigned char nodeId[PUD_NODEIDMAXLENGTH + 1];
177
178 /** The length of the string in the nodeId buffer */
179 size_t nodeIdLength = 0;
180
181 /** True when the nodeId is set */
182 bool nodeIdSet = false;
183
184 /**
185  @return
186  The node ID
187  */
188 unsigned char * getNodeId(void) {
189         return getNodeIdWithLength(NULL);
190 }
191
192 /**
193  Get the nodeId and its length
194
195  @param length
196  a pointer to the variable in which to store the nodeId length (allowed to be
197  NULL, in which case the length is not stored)
198
199  @return
200  The node ID
201  */
202 unsigned char * getNodeIdWithLength(size_t *length) {
203         if (!nodeIdSet) {
204                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
205         }
206
207         if (length != NULL) {
208                 *length = nodeIdLength;
209         }
210
211         return &nodeId[0];
212 }
213
214 /**
215  Set the node ID.
216
217  @param value
218  The value of the node ID to set (in string representation)
219  @param data
220  Unused
221  @param addon
222  Unused
223
224  @return
225  - true when an error is detected
226  - false otherwise
227  */
228 int setNodeId(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
229         static const char * valueName = PUD_NODE_ID_NAME;
230         size_t valueLength;
231
232         assert (value != NULL);
233
234         valueLength = strlen(value);
235         if (valueLength > PUD_NODEIDMAXLENGTH) {
236                 pudError(false, "Configured %s is too long, maximum length is"
237                         " %u, current length is %lu", valueName, PUD_NODEIDMAXLENGTH,
238                                 (unsigned long) valueLength);
239                 return true;
240         }
241
242         strcpy((char *) &nodeId[0], value);
243         nodeIdLength = valueLength;
244         nodeIdSet = true;
245
246         return false;
247 }
248
249 /*
250  * rxNonOlsrIf
251  */
252
253 /** The maximum number of RX non-OLSR interfaces */
254 #define PUD_RX_NON_OLSR_IF_MAX 32
255
256 /** Array with RX non-OLSR interface names */
257 unsigned char rxNonOlsrInterfaceNames[PUD_RX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
258
259 /** The number of RX non-OLSR interface names in the array */
260 unsigned int rxNonOlsrInterfaceCount = 0;
261
262 /**
263  Determine whether a give interface name is configured as a receive non-OLSR
264  interface.
265
266  @param ifName
267  The interface name to check
268
269  @return
270  - true when the given interface name is configured as a receive non-OLSR
271  interface
272  - false otherwise
273  */
274 bool isRxNonOlsrInterface(const char *ifName) {
275         unsigned int i;
276
277         assert (ifName != NULL);
278
279         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
280                 if (strncmp((char *) &rxNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
281                                 + 1) == 0) {
282                         return true;
283                 }
284         }
285
286         return false;
287 }
288
289 /**
290  Add a receive non-OLSR interface
291
292  @param value
293  The name of the non-OLSR interface to add
294  @param data
295  Unused
296  @param addon
297  Unused
298
299  @return
300  - true when an error is detected
301  - false otherwise
302  */
303 int addRxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
304                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
305         unsigned long valueLength;
306
307         assert (value != NULL);
308
309         valueLength = strlen(value);
310         if (valueLength > IFNAMSIZ) {
311                 pudError(false, "Configured %s (%s) is too long,"
312                         " maximum length is %u, current length is %lu",
313                                 PUD_RX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
314                 return true;
315         }
316
317         if (!isRxNonOlsrInterface(value)) {
318                 if (rxNonOlsrInterfaceCount >= PUD_RX_NON_OLSR_IF_MAX) {
319                         pudError(false, "Can't configure more than %u receive interfaces",
320                                         PUD_RX_NON_OLSR_IF_MAX);
321                         return true;
322                 }
323
324                 strcpy((char *) &rxNonOlsrInterfaceNames[rxNonOlsrInterfaceCount][0],
325                                 value);
326                 rxNonOlsrInterfaceCount++;
327         }
328
329         return false;
330 }
331
332 /*
333  * rxAllowedSourceIpAddress
334  */
335
336 /** The maximum number of RX allowed source IP addresses */
337 #define PUD_RX_ALLOWED_SOURCE_IP_MAX 32
338
339 /** Array with RX allowed source IP addresses */
340 struct sockaddr rxAllowedSourceIpAddresses[PUD_RX_ALLOWED_SOURCE_IP_MAX];
341
342 /** The number of RX allowed source IP addresses in the array */
343 unsigned int rxAllowedSourceIpAddressesCount = 0;
344
345 /**
346  Determine whether a give IP address is configured as an allowed source IP
347  address.
348
349  @param sender
350  The IP address to check
351
352  @return
353  - true when the given IP address is configured as an allowed source IP
354  address
355  - false otherwise
356  */
357 bool isRxAllowedSourceIpAddress(struct sockaddr * sender) {
358         void * addr;
359         unsigned int addrSize;
360         unsigned int i;
361
362         if (rxAllowedSourceIpAddressesCount == 0) {
363                 return true;
364         }
365
366         if (sender == NULL) {
367                 return false;
368         }
369
370         if (sender->sa_family == AF_INET) {
371                 addr = (void *) (&((struct sockaddr_in *) sender)->sin_addr);
372                 addrSize = sizeof(struct in_addr);
373         } else {
374                 addr = (void *) (&((struct sockaddr_in6 *) sender)->sin6_addr);
375                 addrSize = sizeof(struct in6_addr);
376         }
377
378         for (i = 0; i < rxAllowedSourceIpAddressesCount; i++) {
379                 if ((rxAllowedSourceIpAddresses[i].sa_family == sender->sa_family)
380                                 && (memcmp(&rxAllowedSourceIpAddresses[i].sa_data, addr,
381                                                 addrSize) == 0)) {
382                         return true;
383                 }
384         }
385
386         return false;
387 }
388
389 /**
390  Set the RX allowed source IP addresses.
391
392  @param value
393  The RX allowed source IP address (in string representation)
394  @param data
395  Unused
396  @param addon
397  Unused
398
399  @return
400  - true when an error is detected
401  - false otherwise
402  */
403 int addRxAllowedSourceIpAddress(const char *value, void *data __attribute__ ((unused)),
404                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
405         static const char * valueName = PUD_RX_ALLOWED_SOURCE_IP_NAME;
406         const char * valueInternal = value;
407         int conversion;
408         struct sockaddr addr;
409
410         assert (value != NULL);
411
412         memset(&addr, 0, sizeof(addr));
413
414         addr.sa_family = olsr_cnf->ip_version;
415         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, &addr.sa_data);
416         if (conversion != 1) {
417                 pudError((conversion == -1) ? true : false,
418                                 "Configured %s (%s) is not an IP address", valueName,
419                                 valueInternal);
420                 return true;
421         }
422
423         if ((rxAllowedSourceIpAddressesCount == 0) || !isRxAllowedSourceIpAddress(&addr)) {
424                 if (rxAllowedSourceIpAddressesCount >= PUD_RX_ALLOWED_SOURCE_IP_MAX) {
425                         pudError(false, "Can't configure more than %u allowed source IP"
426                                 " addresses", PUD_RX_ALLOWED_SOURCE_IP_MAX);
427                         return true;
428                 }
429
430                 memcpy(&rxAllowedSourceIpAddresses[rxAllowedSourceIpAddressesCount],
431                                 &addr, sizeof(addr));
432                 rxAllowedSourceIpAddressesCount++;
433         }
434
435         return false;
436 }
437
438 /*
439  * rxMcAddr
440  */
441
442 /** The rx multicast address */
443 union olsr_sockaddr rxMcAddr;
444
445 /** True when the rx multicast address is set */
446 bool rxMcAddrSet = false;
447
448 /**
449  @return
450  The receive multicast address (in network byte order). Sets both the address
451  and the port to their default values when the address was not yet set.
452  */
453 union olsr_sockaddr * getRxMcAddr(void) {
454         if (!rxMcAddrSet) {
455                 setRxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
456         }
457         return &rxMcAddr;
458 }
459
460 /**
461  Set the receive multicast address. Sets the address to its default value when
462  the value is NULL. Also sets the port to its default value when the address
463  was not yet set.
464
465  @param value
466  The receive multicast address (in string representation)
467  @param data
468  Unused
469  @param addon
470  Unused
471
472  @return
473  - true when an error is detected
474  - false otherwise
475  */
476 int setRxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
477         static const char * valueName = PUD_RX_MC_ADDR_NAME;
478         void * ipAddress;
479         in_port_t * port;
480         const char * valueInternal = value;
481         int conversion;
482
483         if (olsr_cnf->ip_version == AF_INET) {
484                 rxMcAddr.in4.sin_family = olsr_cnf->ip_version;
485                 ipAddress = (void *) &rxMcAddr.in4.sin_addr;
486                 port = (void *) &rxMcAddr.in4.sin_port;
487                 if (valueInternal == NULL) {
488                         valueInternal = PUD_RX_MC_ADDR_4_DEFAULT;
489                 }
490         } else {
491                 rxMcAddr.in6.sin6_family = olsr_cnf->ip_version;
492                 ipAddress = (void *) &rxMcAddr.in6.sin6_addr;
493                 port = (void *) &rxMcAddr.in6.sin6_port;
494                 if (valueInternal == NULL) {
495                         valueInternal = PUD_RX_MC_ADDR_6_DEFAULT;
496                 }
497         }
498
499         if (!rxMcAddrSet) {
500                 *port = htons(PUD_RX_MC_PORT_DEFAULT);
501         }
502
503         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
504         if (conversion != 1) {
505                 pudError((conversion == -1) ? true : false,
506                                 "Configured %s (%s) is not an IP address", valueName,
507                                 valueInternal);
508                 return true;
509         }
510
511         if (!isMulticast(olsr_cnf->ip_version, &rxMcAddr)) {
512                 pudError(false, "Configured %s (%s) is not a multicast address",
513                                 valueName, valueInternal);
514                 return true;
515         }
516
517         rxMcAddrSet = true;
518         return false;
519 }
520
521 /*
522  * rxMcPort
523  */
524
525 /**
526  @return
527  The receive multicast port (in network byte order)
528  */
529 unsigned short getRxMcPort(void) {
530         in_port_t * port;
531         union olsr_sockaddr * addr = getRxMcAddr();
532
533         if (olsr_cnf->ip_version == AF_INET) {
534                 port = (void *) &addr->in4.sin_port;
535         } else {
536                 port = (void *) &addr->in6.sin6_port;
537         }
538
539         return *port;
540 }
541
542 /**
543  Set the receive multicast port
544
545  @param value
546  The receive multicast port (a number in string representation)
547  @param data
548  Unused
549  @param addon
550  Unused
551
552  @return
553  - true when an error is detected
554  - false otherwise
555  */
556 int setRxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
557         static const char * valueName = PUD_RX_MC_PORT_NAME;
558         unsigned long long rxMcPortNew;
559         in_port_t * port;
560         union olsr_sockaddr * addr = getRxMcAddr();
561
562         assert (value != NULL);
563
564         if (!readULL(valueName, value, &rxMcPortNew)) {
565                 return true;
566         }
567
568         if ((rxMcPortNew < 1) || (rxMcPortNew > 65535)) {
569                 pudError(false, "Configured %s (%llu) is outside of"
570                         " valid range 1-65535", valueName, rxMcPortNew);
571                 return true;
572         }
573
574         if (olsr_cnf->ip_version == AF_INET) {
575                 port = (void *) &addr->in4.sin_port;
576         } else {
577                 port = (void *) &addr->in6.sin6_port;
578         }
579
580         *port = htons((uint16_t) rxMcPortNew);
581
582         return false;
583 }
584
585 /*
586  * txNonOlsrIf
587  */
588
589 /** The maximum number of rx non-olsr interfaces */
590 #define PUD_TX_NON_OLSR_IF_MAX 32
591
592 /** Array with tx non-olsr interface names */
593 unsigned char txNonOlsrInterfaceNames[PUD_TX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
594
595 /** The number of tx interface names in the array */
596 unsigned int txNonOlsrInterfaceCount = 0;
597
598 /**
599  Determine whether a give interface name is configured as a transmit non-OLSR
600  interface.
601
602  @param ifName
603  The interface to check
604
605  @return
606  - true when the given interface name is configured as a transmit non-OLSR
607  interface
608  - false otherwise
609  */
610 bool isTxNonOlsrInterface(const char *ifName) {
611         unsigned int i;
612
613         assert (ifName != NULL);
614
615         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
616                 if (strncmp((char *) &txNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
617                                 + 1) == 0) {
618                         return true;
619                 }
620         }
621
622         return false;
623 }
624
625 /**
626  Add a transmit non-OLSR interface
627
628  @param value
629  The name of the non-OLSR interface to add
630  @param data
631  Unused
632  @param addon
633  Unused
634
635  @return
636  - true when an error is detected
637  - false otherwise
638  */
639 int addTxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
640                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
641         unsigned long valueLength;
642
643         assert (value != NULL);
644
645         valueLength = strlen(value);
646         if (valueLength > IFNAMSIZ) {
647                 pudError(false, "Configured %s (%s) is too long,"
648                         " maximum length is %u, current length is %lu",
649                                 PUD_TX_NON_OLSR_IF_NAME, value, IFNAMSIZ, valueLength);
650                 return true;
651         }
652
653         if (!isTxNonOlsrInterface(value)) {
654                 if (txNonOlsrInterfaceCount >= PUD_TX_NON_OLSR_IF_MAX) {
655                         pudError(false, "Can not configure more than %u transmit"
656                                 " interfaces", PUD_TX_NON_OLSR_IF_MAX);
657                         return true;
658                 }
659
660                 strcpy((char *) &txNonOlsrInterfaceNames[txNonOlsrInterfaceCount][0],
661                                 value);
662                 txNonOlsrInterfaceCount++;
663         }
664
665         return false;
666 }
667
668 /*
669  * txMcAddr
670  */
671
672 /** The tx multicast address */
673 union olsr_sockaddr txMcAddr;
674
675 /** True when the tx multicast address is set */
676 bool txMcAddrSet = false;
677
678 /**
679  @return
680  The transmit multicast address (in network byte order). Sets both the address
681  and the port to their default values when the address was not yet set.
682  */
683 union olsr_sockaddr * getTxMcAddr(void) {
684         if (!txMcAddrSet) {
685                 setTxMcAddr(NULL, NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
686         }
687         return &txMcAddr;
688 }
689
690 /**
691  Set the transmit multicast address. Sets the address to its default value when
692  the value is NULL. Also sets the port to its default value when the address
693  was not yet set.
694
695  @param value
696  The transmit multicast address (in string representation)
697  @param data
698  Unused
699  @param addon
700  Unused
701
702  @return
703  - true when an error is detected
704  - false otherwise
705  */
706 int setTxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
707         static const char * valueName = PUD_TX_MC_ADDR_NAME;
708         void * ipAddress;
709         in_port_t * port;
710         const char * valueInternal = value;
711         int conversion;
712
713         if (olsr_cnf->ip_version == AF_INET) {
714                 txMcAddr.in4.sin_family = olsr_cnf->ip_version;
715                 ipAddress = (void *) &txMcAddr.in4.sin_addr;
716                 port = (void *) &txMcAddr.in4.sin_port;
717                 if (valueInternal == NULL) {
718                         valueInternal = PUD_TX_MC_ADDR_4_DEFAULT;
719                 }
720         } else {
721                 txMcAddr.in6.sin6_family = olsr_cnf->ip_version;
722                 ipAddress = (void *) &txMcAddr.in6.sin6_addr;
723                 port = (void *) &txMcAddr.in6.sin6_port;
724                 if (valueInternal == NULL) {
725                         valueInternal = PUD_TX_MC_ADDR_6_DEFAULT;
726                 }
727         }
728
729         if (!txMcAddrSet) {
730                 *port = htons(PUD_TX_MC_PORT_DEFAULT);
731         }
732
733         conversion = inet_pton(olsr_cnf->ip_version, valueInternal, ipAddress);
734         if (conversion != 1) {
735                 pudError((conversion == -1) ? true : false,
736                                 "Configured %s (%s) is not an IP address", valueName,
737                                 valueInternal);
738                 return true;
739         }
740
741         if (!isMulticast(olsr_cnf->ip_version, &txMcAddr)) {
742                 pudError(false, "Configured %s (%s) is not a multicast address",
743                                 valueName, valueInternal);
744                 return true;
745         }
746
747         txMcAddrSet = true;
748         return false;
749 }
750
751 /*
752  * txMcPort
753  */
754
755 /**
756  @return
757  The transmit multicast port (in network byte order)
758  */
759 unsigned short getTxMcPort(void) {
760         in_port_t * port;
761         union olsr_sockaddr * addr = getTxMcAddr();
762
763         if (olsr_cnf->ip_version == AF_INET) {
764                 port = (void *) &addr->in4.sin_port;
765         } else {
766                 port = (void *) &addr->in6.sin6_port;
767         }
768
769         return *port;
770 }
771
772 /**
773  Set the transmit multicast port
774
775  @param value
776  The transmit multicast port (a number in string representation)
777  @param data
778  Unused
779  @param addon
780  Unused
781
782  @return
783  - true when an error is detected
784  - false otherwise
785  */
786 int setTxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
787         static const char * valueName = PUD_TX_MC_PORT_NAME;
788         unsigned long long txMcPortNew;
789         in_port_t * port;
790         union olsr_sockaddr * addr = getTxMcAddr();
791
792         assert (value != NULL);
793
794         if (!readULL(valueName, value, &txMcPortNew)) {
795                 return true;
796         }
797
798         if ((txMcPortNew < 1) || (txMcPortNew > 65535)) {
799                 pudError(false, "Configured %s (%llu) is outside of"
800                         " valid range 1-65535", valueName, txMcPortNew);
801                 return true;
802         }
803
804         if (olsr_cnf->ip_version == AF_INET) {
805                 port = (void *) &addr->in4.sin_port;
806         } else {
807                 port = (void *) &addr->in6.sin6_port;
808         }
809
810         *port = htons((uint16_t) txMcPortNew);
811
812         return false;
813 }
814
815 /*
816  * txTtl
817  */
818
819 /** The tx TTL */
820 unsigned char txTtl = PUD_TX_TTL_DEFAULT;
821
822 /**
823  @return
824  The transmit multicast IP packet time-to-live
825  */
826 unsigned char getTxTtl(void) {
827         return txTtl;
828 }
829
830 /**
831  Set the transmit multicast IP packet time-to-live
832
833  @param value
834  The transmit multicast IP packet time-to-live (a number in string representation)
835  @param data
836  Unused
837  @param addon
838  Unused
839
840  @return
841  - true when an error is detected
842  - false otherwise
843  */
844 int setTxTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
845         static const char * valueName = PUD_TX_TTL_NAME;
846         unsigned long long txTtlNew;
847
848         assert (value != NULL);
849
850         if (!readULL(valueName, value, &txTtlNew)) {
851                 return true;
852         }
853
854         if ((txTtlNew < 1) || (txTtlNew > MAX_TTL)) {
855                 pudError(false, "Configured %s (%llu) is outside of"
856                         " valid range 1-%u", valueName, txTtlNew, MAX_TTL);
857                 return true;
858         }
859
860         txTtl = txTtlNew;
861
862         return false;
863 }
864
865 /*
866  * txNmeaMessagePrefix
867  */
868
869 /** The exact length of the tx NMEA message prefix */
870 #define PUD_TXNMEAMESSAGEPREFIXLENGTH 4
871
872 /** The tx NMEA message prefix buffer */
873 unsigned char txNmeaMessagePrefix[PUD_TXNMEAMESSAGEPREFIXLENGTH + 1];
874
875 /** True when the tx NMEA message prefix is set */
876 bool txNmeaMessagePrefixSet = false;
877
878 /**
879  @return
880  The transmit multicast NMEA message prefix
881  */
882 unsigned char * getTxNmeaMessagePrefix(void) {
883         if (!txNmeaMessagePrefixSet) {
884                 setTxNmeaMessagePrefix(PUD_TX_NMEAMESSAGEPREFIX_DEFAULT, NULL,
885                                 (set_plugin_parameter_addon) {.pc = NULL});
886         }
887         return &txNmeaMessagePrefix[0];
888 }
889
890 /**
891  Set the transmit multicast NMEA message prefix
892
893  @param value
894  The transmit multicast NMEA message prefix (in string representation)
895  @param data
896  Unused
897  @param addon
898  Unused
899
900  @return
901  - true when an error is detected
902  - false otherwise
903  */
904 int setTxNmeaMessagePrefix(const char *value, void *data __attribute__ ((unused)),
905                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
906         static const char * valueName = PUD_TX_NMEAMESSAGEPREFIX_NAME;
907         size_t valueLength;
908
909         assert (value != NULL);
910
911         valueLength = strlen(value);
912         if (valueLength != PUD_TXNMEAMESSAGEPREFIXLENGTH) {
913                 pudError(false, "Configured %s (%s) must be %u exactly characters",
914                                 valueName, value, PUD_TXNMEAMESSAGEPREFIXLENGTH);
915                 return true;
916         }
917
918         if (hasInvalidNmeaChars(value, valueName)) {
919                 return true;
920         }
921
922         if ((strchr(value, ' ') != NULL) || (strchr(value, '\t') != NULL)) {
923                 pudError(false, "Configured %s (%s) can not contain whitespace",
924                                 valueName, value);
925                 return true;
926         }
927
928         strcpy((char *) &txNmeaMessagePrefix[0], value);
929         txNmeaMessagePrefixSet = true;
930         return false;
931 }
932
933 /*
934  * olsrTtl
935  */
936
937 /** The OLSR TTL */
938 unsigned char olsrTtl = PUD_OLSR_TTL_DEFAULT;
939
940 /**
941  @return
942  The OLSR multicast IP packet time-to-live
943  */
944 unsigned char getOlsrTtl(void) {
945         return olsrTtl;
946 }
947
948 /**
949  Set the OLSR multicast IP packet time-to-live
950
951  @param value
952  The OLSR multicast IP packet time-to-live (a number in string representation)
953  @param data
954  Unused
955  @param addon
956  Unused
957
958  @return
959  - true when an error is detected
960  - false otherwise
961  */
962 int setOlsrTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
963         static const char * valueName = PUD_OLSR_TTL_NAME;
964         unsigned long long olsrTtlNew;
965
966         assert (value != NULL);
967
968         if (!readULL(valueName, value, &olsrTtlNew)) {
969                 return true;
970         }
971
972         if ((olsrTtlNew < 1) || (olsrTtlNew > MAX_TTL)) {
973                 pudError(false, "Configured %s (%llu) is outside of valid range 1-%u",
974                                 valueName, olsrTtlNew, MAX_TTL);
975                 return true;
976         }
977
978         olsrTtl = olsrTtlNew;
979
980         return false;
981 }
982
983 /*
984  * updateIntervalStationary
985  */
986
987 /** The stationary interval update plugin parameter (in seconds) */
988 unsigned long long updateIntervalStationary = PUD_UPDATE_INTERVAL_STATIONARY_DEFAULT;
989
990 /**
991  @return
992  The stationary interval update plugin parameter (in seconds)
993  */
994 unsigned long long getUpdateIntervalStationary(void) {
995         return updateIntervalStationary;
996 }
997
998 /**
999  Set stationary interval update plugin parameter
1000
1001  @param value
1002  The stationary interval update plugin parameter (in seconds)
1003  @param data
1004  Unused
1005  @param addon
1006  Unused
1007
1008  @return
1009  - true when an error is detected
1010  - false otherwise
1011  */
1012 int setUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1013                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1014         static const char * valueName = PUD_UPDATE_INTERVAL_STATIONARY_NAME;
1015         unsigned long long updateIntervalStationaryNew;
1016
1017         assert (value != NULL);
1018
1019         if (!readULL(valueName, value, &updateIntervalStationaryNew)) {
1020                 return true;
1021         }
1022
1023         if (updateIntervalStationaryNew < 1) {
1024                 pudError(false, "Configured %s must be at least 1", valueName);
1025                 return true;
1026         }
1027
1028         updateIntervalStationary = updateIntervalStationaryNew;
1029
1030         return false;
1031 }
1032
1033 /*
1034  * updateIntervalMoving
1035  */
1036
1037 /** The moving interval update plugin parameter (in seconds) */
1038 unsigned long long updateIntervalMoving = PUD_UPDATE_INTERVAL_MOVING_DEFAULT;
1039
1040 /**
1041  @return
1042  The moving interval update plugin parameter (in seconds)
1043  */
1044 unsigned long long getUpdateIntervalMoving(void) {
1045         return updateIntervalMoving;
1046 }
1047
1048 /**
1049  Set moving interval update plugin parameter
1050
1051  @param value
1052  The moving interval update plugin parameter (in seconds)
1053  @param data
1054  Unused
1055  @param addon
1056  Unused
1057
1058  @return
1059  - true when an error is detected
1060  - false otherwise
1061  */
1062 int setUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1063                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1064         static const char * valueName = PUD_UPDATE_INTERVAL_MOVING_NAME;
1065         unsigned long long updateIntervalMovingNew;
1066
1067         assert (value != NULL);
1068
1069         if (!readULL(valueName, value, &updateIntervalMovingNew)) {
1070                 return true;
1071         }
1072
1073         if (updateIntervalMovingNew < 1) {
1074                 pudError(false, "Configured %s must be at least 1", valueName);
1075                 return true;
1076         }
1077
1078         updateIntervalMoving = updateIntervalMovingNew;
1079
1080         return false;
1081 }
1082
1083 /*
1084  * movingSpeedThreshold
1085  */
1086
1087 /** The moving speed threshold plugin parameter (in kph) */
1088 unsigned long long movingSpeedThreshold = PUD_MOVING_SPEED_THRESHOLD_DEFAULT;
1089
1090 /**
1091  @return
1092  The moving speed threshold plugin parameter (in kph)
1093  */
1094 unsigned long long getMovingSpeedThreshold(void) {
1095         return movingSpeedThreshold;
1096 }
1097
1098 /**
1099  Set moving speed threshold plugin parameter
1100
1101  @param value
1102  The moving speed threshold plugin parameter (in kph)
1103  @param data
1104  Unused
1105  @param addon
1106  Unused
1107
1108  @return
1109  - true when an error is detected
1110  - false otherwise
1111  */
1112 int setMovingSpeedThreshold(const char *value, void *data __attribute__ ((unused)),
1113                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1114         static const char * valueName = PUD_MOVING_SPEED_THRESHOLD_NAME;
1115         unsigned long long movingSpeedThresholdNew;
1116
1117         assert (value != NULL);
1118
1119         if (!readULL(valueName, value, &movingSpeedThresholdNew)) {
1120                 return true;
1121         }
1122
1123         movingSpeedThreshold = movingSpeedThresholdNew;
1124
1125         return false;
1126 }
1127
1128 /*
1129  * movingDistanceThreshold
1130  */
1131
1132 /** The moving distance threshold plugin parameter (in meters) */
1133 unsigned long long movingDistanceThreshold = PUD_MOVING_DISTANCE_THRESHOLD_DEFAULT;
1134
1135 /**
1136  @return
1137  The moving distance threshold plugin parameter (in meters)
1138  */
1139 unsigned long long getMovingDistanceThreshold(void) {
1140         return movingDistanceThreshold;
1141 }
1142
1143 /**
1144  Set moving distance threshold plugin parameter
1145
1146  @param value
1147  The moving distance threshold plugin parameter (in meter)
1148  @param data
1149  Unused
1150  @param addon
1151  Unused
1152
1153  @return
1154  - true when an error is detected
1155  - false otherwise
1156  */
1157 int setMovingDistanceThreshold(const char *value, void *data __attribute__ ((unused)),
1158                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1159         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1160         unsigned long long movingDistanceThresholdNew;
1161
1162         assert (value != NULL);
1163
1164         if (!readULL(valueName, value, &movingDistanceThresholdNew)) {
1165                 return true;
1166         }
1167
1168         movingDistanceThreshold = movingDistanceThresholdNew;
1169
1170         return false;
1171 }
1172
1173 /*
1174  * dopMultiplier
1175  */
1176
1177 /* The DOP multiplier plugin parameter */
1178 double dopMultiplier = PUD_DOP_MULTIPLIER_DEFAULT;
1179
1180 /**
1181  @return
1182  The DOP multiplier plugin parameter
1183  */
1184 double getDopMultiplier(void) {
1185         return dopMultiplier;
1186 }
1187
1188 /**
1189  Set DOP multiplier plugin parameter
1190
1191  @param value
1192  The DOP multiplier plugin parameter
1193  @param data
1194  Unused
1195  @param addon
1196  Unused
1197
1198  @return
1199  - true when an error is detected
1200  - false otherwise
1201  */
1202 int setDopMultiplier(const char *value, void *data __attribute__ ((unused)),
1203                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1204         static const char * valueName = PUD_DOP_MULTIPLIER_NAME;
1205         double dopMultiplierNew;
1206
1207         assert (value != NULL);
1208
1209         if (!readDouble(valueName, value, &dopMultiplierNew)) {
1210                 return true;
1211         }
1212
1213         dopMultiplier = dopMultiplierNew;
1214
1215         return false;
1216 }
1217
1218 /*
1219  * defaultHdop
1220  */
1221
1222 /** The default HDOP plugin parameter (in meters) */
1223 unsigned long long defaultHdop = PUD_DEFAULT_HDOP_DEFAULT;
1224
1225 /**
1226  @return
1227  The default HDOP plugin parameter (in meters)
1228  */
1229 unsigned long long getDefaultHdop(void) {
1230         return defaultHdop;
1231 }
1232
1233 /**
1234  Set default HDOP plugin parameter
1235
1236  @param value
1237  The default HDOP plugin parameter (in meters)
1238  @param data
1239  Unused
1240  @param addon
1241  Unused
1242
1243  @return
1244  - true when an error is detected
1245  - false otherwise
1246  */
1247 int setDefaultHdop(const char *value, void *data __attribute__ ((unused)),
1248                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1249         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1250         unsigned long long defaultHdopNew;
1251
1252         assert (value != NULL);
1253
1254         if (!readULL(valueName, value, &defaultHdopNew)) {
1255                 return true;
1256         }
1257
1258         defaultHdop = defaultHdopNew;
1259
1260         return false;
1261 }
1262
1263 /*
1264  * defaultVdop
1265  */
1266
1267 /** The default VDOP plugin parameter (in meters) */
1268 unsigned long long defaultVdop = PUD_DEFAULT_VDOP_DEFAULT;
1269
1270 /**
1271  @return
1272  The default VDOP plugin parameter (in meters)
1273  */
1274 unsigned long long getDefaultVdop(void) {
1275         return defaultVdop;
1276 }
1277
1278 /**
1279  Set default VDOP plugin parameter
1280
1281  @param value
1282  The default VDOP plugin parameter (in meters)
1283  @param data
1284  Unused
1285  @param addon
1286  Unused
1287
1288  @return
1289  - true when an error is detected
1290  - false otherwise
1291  */
1292 int setDefaultVdop(const char *value, void *data __attribute__ ((unused)),
1293                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1294         static const char * valueName = PUD_MOVING_DISTANCE_THRESHOLD_NAME;
1295         unsigned long long defaultVdopNew;
1296
1297         assert (value != NULL);
1298
1299         if (!readULL(valueName, value, &defaultVdopNew)) {
1300                 return true;
1301         }
1302
1303         defaultVdop = defaultVdopNew;
1304
1305         return false;
1306 }
1307
1308 /*
1309  * averageDepth
1310  */
1311
1312 /** The depth of the average list */
1313 unsigned long long averageDepth = PUD_AVERAGE_DEPTH_DEFAULT;
1314
1315 /**
1316  @return
1317  The depth of the average list
1318  */
1319 unsigned long long getAverageDepth(void) {
1320         return averageDepth;
1321 }
1322
1323 /**
1324  Set average depth plugin parameter
1325
1326  @param value
1327  The average depth plugin parameter
1328  @param data
1329  Unused
1330  @param addon
1331  Unused
1332
1333  @return
1334  - true when an error is detected
1335  - false otherwise
1336  */
1337 int setAverageDepth(const char *value, void *data __attribute__ ((unused)),
1338                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1339         static const char * valueName = PUD_AVERAGE_DEPTH_NAME;
1340         unsigned long long averageDepthNew;
1341
1342         assert (value != NULL);
1343
1344         if (!readULL(valueName, value, &averageDepthNew)) {
1345                 return true;
1346         }
1347
1348         if (averageDepthNew < 1) {
1349                 pudError(false, "Configured %s must be at least 1", valueName);
1350                 return true;
1351         }
1352
1353         averageDepth = averageDepthNew;
1354
1355         return false;
1356 }
1357
1358 /*
1359  * hysteresisCountToStationary
1360  */
1361
1362 /** The hysteresis count for changing state from moving to stationary */
1363 unsigned long long hysteresisCountToStationary = PUD_HYSTERESIS_COUNT_2STAT_DEFAULT;
1364
1365 /**
1366  @return
1367  The hysteresis count for changing state from moving to stationary
1368  */
1369 unsigned long long getHysteresisCountToStationary(void) {
1370         return hysteresisCountToStationary;
1371 }
1372
1373 /**
1374  Set hysteresis count plugin parameter
1375
1376  @param value
1377  The hysteresis count plugin parameter
1378  @param data
1379  Unused
1380  @param addon
1381  Unused
1382
1383  @return
1384  - true when an error is detected
1385  - false otherwise
1386  */
1387 int setHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1388                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1389         static const char * valueName = PUD_HYSTERESIS_COUNT_2STAT_NAME;
1390         unsigned long long hysteresisCountNew;
1391
1392         assert (value != NULL);
1393
1394         if (!readULL(valueName, value, &hysteresisCountNew)) {
1395                 return true;
1396         }
1397
1398         hysteresisCountToStationary = hysteresisCountNew;
1399
1400         return false;
1401 }
1402
1403 /*
1404  * hysteresisCountToMoving
1405  */
1406
1407 /** The hysteresis count for changing state from stationary to moving */
1408 unsigned long long hysteresisCountToMoving = PUD_HYSTERESIS_COUNT_2MOV_DEFAULT;
1409
1410 /**
1411  @return
1412  The hysteresis count for changing state from stationary to moving
1413  */
1414 unsigned long long getHysteresisCountToMoving(void) {
1415         return hysteresisCountToMoving;
1416 }
1417
1418 /**
1419  Set hysteresis count plugin parameter
1420
1421  @param value
1422  The hysteresis count plugin parameter
1423  @param data
1424  Unused
1425  @param addon
1426  Unused
1427
1428  @return
1429  - true when an error is detected
1430  - false otherwise
1431  */
1432 int setHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1433                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1434         static const char * valueName = PUD_HYSTERESIS_COUNT_2MOV_NAME;
1435         unsigned long long hysteresisCountNew;
1436
1437         assert (value != NULL);
1438
1439         if (!readULL(valueName, value, &hysteresisCountNew)) {
1440                 return true;
1441         }
1442
1443         hysteresisCountToMoving = hysteresisCountNew;
1444
1445         return false;
1446 }
1447
1448 /*
1449  * useDeDup
1450  */
1451
1452 /* when true then duplicate message detection is performed */
1453 bool useDeDup = PUD_USE_DEDUP_DEFAULT;
1454
1455 /**
1456  @return
1457  The duplicate message detection setting
1458  */
1459 bool getUseDeDup(void) {
1460         return useDeDup;
1461 }
1462
1463 /**
1464  Set duplicate message detection setting plugin parameter
1465
1466  @param value
1467  The duplicate message detection setting plugin parameter
1468  @param data
1469  Unused
1470  @param addon
1471  Unused
1472
1473  @return
1474  - true when an error is detected
1475  - false otherwise
1476  */
1477 int setUseDeDup(const char *value, void *data __attribute__ ((unused)),
1478                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1479         static const char * valueName = PUD_USE_DEDUP_NAME;
1480         unsigned long long useDeDupNew;
1481
1482         assert (value != NULL);
1483
1484         if (!readULL(valueName, value, &useDeDupNew)) {
1485                 return true;
1486         }
1487
1488         if ((useDeDupNew != 0) && (useDeDupNew != 1)) {
1489                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
1490                                 valueName);
1491                 return true;
1492         }
1493
1494         useDeDup = (useDeDupNew == 1);
1495
1496         return false;
1497 }
1498
1499 /*
1500  * deDupDepth
1501  */
1502
1503 /** The hysteresis count for changing state from stationary to moving */
1504 unsigned long long deDupDepth = PUD_DEDUP_DEPTH_DEFAULT;
1505
1506 /**
1507  @return
1508  The hysteresis count for changing state from stationary to moving
1509  */
1510 unsigned long long getDeDupDepth(void) {
1511         return deDupDepth;
1512 }
1513
1514 /**
1515  Set de-duplication depth plugin parameter
1516
1517  @param value
1518  The de-duplication depth plugin parameter
1519  @param data
1520  Unused
1521  @param addon
1522  Unused
1523
1524  @return
1525  - true when an error is detected
1526  - false otherwise
1527  */
1528 int setDeDupDepth(const char *value, void *data __attribute__ ((unused)),
1529                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1530         static const char * valueName = PUD_DEDUP_DEPTH_NAME;
1531         unsigned long long deDupDepthNew;
1532
1533         assert (value != NULL);
1534
1535         if (!readULL(valueName, value, &deDupDepthNew)) {
1536                 return true;
1537         }
1538
1539         deDupDepth = deDupDepthNew;
1540
1541         return false;
1542 }
1543
1544 /*
1545  * useLoopback
1546  */
1547
1548 /* when true then loopback is performed */
1549 bool useLoopback = PUD_USE_LOOPBACK_DEFAULT;
1550
1551 /**
1552  @return
1553  The loopback usage setting
1554  */
1555 bool getUseLoopback(void) {
1556         return useLoopback;
1557 }
1558
1559 /**
1560  Set loopback usage plugin parameter
1561
1562  @param value
1563  The loopback usage plugin parameter
1564  @param data
1565  Unused
1566  @param addon
1567  Unused
1568
1569  @return
1570  - true when an error is detected
1571  - false otherwise
1572  */
1573 int setUseLoopback(const char *value, void *data __attribute__ ((unused)),
1574                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1575         static const char * valueName = PUD_USE_LOOPBACK_NAME;
1576         unsigned long long useLoopbackNew;
1577
1578         assert (value != NULL);
1579
1580         if (!readULL(valueName, value, &useLoopbackNew)) {
1581                 return true;
1582         }
1583
1584         if ((useLoopbackNew != 0) && (useLoopbackNew != 1)) {
1585                 pudError(false, "Configured %s must be 0 (false) or 1 (true)",
1586                                 valueName);
1587                 return true;
1588         }
1589
1590         useLoopback = (useLoopbackNew == 1);
1591
1592         return false;
1593 }
1594
1595 /*
1596  * Check Functions
1597  */
1598
1599 /**
1600  Check the configuration for consistency and validity.
1601
1602  @return
1603  - true when the configuration is consistent and valid
1604  - false otherwise
1605  */
1606 unsigned int checkConfig(void) {
1607         int retval = true;
1608
1609         if (rxNonOlsrInterfaceCount == 0) {
1610                 pudError(false, "No receive non-OLSR interfaces configured");
1611                 retval = false;
1612         }
1613
1614         if (txNonOlsrInterfaceCount == 0) {
1615                 pudError(false, "No transmit non-OLSR interfaces configured");
1616                 retval = false;
1617         }
1618
1619         if (!nodeIdSet) {
1620                 if (nodeIdType == PUD_NODEIDTYPE_DNS) {
1621                         char name[PUD_NODEIDMAXLENGTH + 1];
1622
1623                         errno = 0;
1624                         if (gethostname(&name[0], sizeof(name)) < 0) {
1625                                 pudError(true, "Could not get the host name");
1626                                 retval = false;
1627                         } else {
1628                                 setNodeId(&name[0], NULL,
1629                                                 (set_plugin_parameter_addon) {.pc = NULL});
1630                         }
1631                 } else if ((nodeIdType != PUD_NODEIDTYPE_MAC) && (nodeIdType
1632                                 != PUD_NODEIDTYPE_IPV4) && (nodeIdType != PUD_NODEIDTYPE_IPV6)) {
1633                         pudError(false, "No node ID set while one is required for"
1634                                 " node type %u", nodeIdType);
1635                         retval = false;
1636                 }
1637         }
1638
1639         if (!validateNodeId(nodeIdType)) {
1640                 retval = false;
1641         }
1642
1643         if (updateIntervalMoving > updateIntervalStationary) {
1644                 pudError(false,"The update interval for moving situations must not be"
1645                 " larger than that for stationary situations");
1646                 retval = false;
1647         }
1648
1649         return retval;
1650 }
1651
1652 /**
1653  Check the configuration for consistency and validity after everything has been
1654  setup.
1655
1656  @return
1657  - true when the configuration is consistent and valid
1658  - false otherwise
1659  */
1660 unsigned int checkRunSetup(void) {
1661         int retval = true;
1662         unsigned int i;
1663
1664         /* any receive interface name that is configured but is not the name of an
1665          * actual receive interface is not a valid interface name */
1666         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
1667                 unsigned char * nonOlsrInterfaceName = &rxNonOlsrInterfaceNames[i][0];
1668
1669                 TRxTxNetworkInterface * interfaceObject = getRxNetworkInterfaces();
1670                 bool found = false;
1671                 while (interfaceObject != NULL) {
1672                         if (strncmp((char *) nonOlsrInterfaceName,
1673                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
1674                                 found = true;
1675                                 break;
1676                         }
1677                         interfaceObject = interfaceObject->next;
1678                 }
1679                 if (!found) {
1680                         pudError(false, "Configured receive non-OLSR interface %s is not"
1681                                 " a known interface name", nonOlsrInterfaceName);
1682                         retval = false;
1683                 }
1684         }
1685
1686         /* any transmit interface name that is configured but is not the name of an
1687          * actual transmit interface is not a valid interface name */
1688         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
1689                 unsigned char * nonOlsrInterfaceName = &txNonOlsrInterfaceNames[i][0];
1690
1691                 TRxTxNetworkInterface * interfaceObject = getTxNetworkInterfaces();
1692                 bool found = false;
1693                 while (interfaceObject != NULL) {
1694                         if (strncmp((char *) nonOlsrInterfaceName,
1695                                         (char *) &interfaceObject->name[0], IFNAMSIZ + 1) == 0) {
1696                                 found = true;
1697                                 break;
1698                         }
1699                         interfaceObject = interfaceObject->next;
1700                 }
1701                 if (!found) {
1702                         pudError(false, "Configured transmit non-OLSR interface %s is not"
1703                                 " a known interface name", nonOlsrInterfaceName);
1704                         retval = false;
1705                 }
1706         }
1707
1708         return retval;
1709 }