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