3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
45 #include "process_package.h"
47 #include "hysteresis.h"
48 #include "duplicate_set.h"
51 #include "rebuild_packet.h"
54 #include "print_packet.h"
56 #include "duplicate_handler.h"
60 #define EWOULDBLOCK WSAEWOULDBLOCK
62 #define errno WSAGetLastError()
63 char *StrError(unsigned int ErrNo);
65 #define strerror(x) StrError(x)
68 /* Sven-Ola: On very slow devices used in huge networks
69 * the amount of lq_tc messages is so high, that the
70 * recv() loop never ends. This is a small hack to end
71 * the loop in this cases
74 unsigned int cpu_overload_exit = 0;
76 struct parse_function_entry *parse_functions;
77 struct preprocessor_function_entry *preprocessor_functions;
78 struct packetparser_function_entry *packetparser_functions;
80 static uint32_t inbuf_aligned[MAXMESSAGESIZE/sizeof(uint32_t) + 1];
81 static char *inbuf = (char *)inbuf_aligned;
83 static bool disp_pack_in = false;
86 parser_set_disp_pack_in(bool val)
92 *Initialize the parser.
97 olsr_init_parser(void)
99 OLSR_PRINTF(3, "Initializing parser...\n");
101 /* Initialize the packet functions */
102 olsr_init_package_process();
107 olsr_destroy_parser(void) {
108 struct parse_function_entry *pe, *pe_next;
109 struct preprocessor_function_entry *ppe, *ppe_next;
110 struct packetparser_function_entry *pae, *pae_next;
112 for (pe = parse_functions; pe; pe = pe_next) {
116 for (ppe = preprocessor_functions; ppe; ppe = ppe_next) {
117 ppe_next = ppe->next;
120 for (pae = packetparser_functions; pae; pae = pae_next) {
121 pae_next = pae->next;
127 olsr_parser_add_function(parse_function * function, uint32_t type)
129 struct parse_function_entry *new_entry;
131 OLSR_PRINTF(3, "Parser: registering event for type %d\n", type);
133 new_entry = olsr_malloc(sizeof(struct parse_function_entry), "Register parse function");
135 new_entry->function = function;
136 new_entry->type = type;
139 new_entry->next = parse_functions;
140 parse_functions = new_entry;
142 OLSR_PRINTF(3, "Register parse function: Added function for type %d\n", type);
147 olsr_parser_remove_function(parse_function * function, uint32_t type)
149 struct parse_function_entry *entry, *prev;
151 entry = parse_functions;
155 if ((entry->function == function) && (entry->type == type)) {
156 if (entry == parse_functions) {
157 parse_functions = entry->next;
159 prev->next = entry->next;
173 olsr_preprocessor_add_function(preprocessor_function * function)
175 struct preprocessor_function_entry *new_entry;
177 OLSR_PRINTF(3, "Parser: registering preprocessor\n");
179 new_entry = olsr_malloc(sizeof(struct preprocessor_function_entry), "Register preprocessor function");
181 new_entry->function = function;
184 new_entry->next = preprocessor_functions;
185 preprocessor_functions = new_entry;
187 OLSR_PRINTF(3, "Registered preprocessor function\n");
192 olsr_preprocessor_remove_function(preprocessor_function * function)
194 struct preprocessor_function_entry *entry, *prev;
196 entry = preprocessor_functions;
200 if (entry->function == function) {
201 if (entry == preprocessor_functions) {
202 preprocessor_functions = entry->next;
204 prev->next = entry->next;
218 olsr_packetparser_add_function(packetparser_function * function)
220 struct packetparser_function_entry *new_entry;
222 OLSR_PRINTF(3, "Parser: registering packetparser\n");
224 new_entry = olsr_malloc(sizeof(struct packetparser_function_entry), "Register packetparser function");
226 new_entry->function = function;
229 new_entry->next = packetparser_functions;
230 packetparser_functions = new_entry;
232 OLSR_PRINTF(3, "Registered packetparser function\n");
237 olsr_packetparser_remove_function(packetparser_function * function)
239 struct packetparser_function_entry *entry, *prev;
241 entry = packetparser_functions;
245 if (entry->function == function) {
246 if (entry == packetparser_functions) {
247 packetparser_functions = entry->next;
249 prev->next = entry->next;
263 *Process a newly received OLSR packet. Checks the type
264 *and to the neccessary convertions and call the
265 *corresponding functions to handle the information.
266 *@param from the sockaddr struct describing the sender
267 *@param olsr the olsr struct containing the message
268 *@param size the size of the message
273 parse_packet(struct olsr *olsr, int size, struct interface *in_if, union olsr_ip_addr *from_addr)
275 union olsr_message *m = (union olsr_message *)olsr->olsr_msg;
279 struct parse_function_entry *entry;
280 struct packetparser_function_entry *packetparser;
282 count = size - ((char *)m - (char *)olsr);
284 /* minimum packet size is 4 */
288 if (ntohs(olsr->olsr_packlen) !=(uint16_t) size) {
289 struct ipaddr_str buf;
290 OLSR_PRINTF(1, "Size error detected in received packet.\nRecieved %d, in packet %d\n", size, ntohs(olsr->olsr_packlen));
292 olsr_syslog(OLSR_LOG_ERR, " packet length error in packet received from %s!", olsr_ip_to_string(&buf, from_addr));
295 // translate sequence number to host order
296 olsr->olsr_seqno = ntohs(olsr->olsr_seqno);
299 packetparser = packetparser_functions;
300 while (packetparser) {
301 packetparser->function(olsr, in_if, from_addr);
302 packetparser = packetparser->next;
305 //printf("Message from %s\n\n", olsr_ip_to_string(&buf, from_addr));
309 print_olsr_serialized_packet(stdout, (union olsr_packet *)olsr, size, from_addr);
312 * Hysteresis update - for every OLSR package
314 if (olsr_cnf->use_hysteresis) {
315 if (olsr_cnf->ip_version == AF_INET) {
317 update_hysteresis_incoming(from_addr, in_if, ntohs(olsr->olsr_seqno));
320 update_hysteresis_incoming(from_addr, in_if, ntohs(olsr->olsr_seqno));
324 for (; count > 0; m = (union olsr_message *)((char *)m + (msgsize))) {
328 /* minimum message size is 8 + ipsize */
329 if (count < 8 + olsr_cnf->ipsize)
332 if (olsr_cnf->ip_version == AF_INET) {
333 msgsize = ntohs(m->v4.olsr_msgsize);
334 seqno = ntohs(m->v4.seqno);
337 msgsize = ntohs(m->v6.olsr_msgsize);
338 seqno = ntohs(m->v6.seqno);
341 /* sanity check for msgsize */
342 if (msgsize < 8 + olsr_cnf->ipsize) {
343 struct ipaddr_str buf;
344 union olsr_ip_addr *msgorig = (union olsr_ip_addr *) &m->v4.originator;
345 OLSR_PRINTF(1, "Error, OLSR message from %s (type %d) is to small (%d bytes)"
346 ", ignoring all further content of the packet\n",
347 olsr_ip_to_string(&buf, msgorig), m->v4.olsr_msgtype, msgsize);
348 olsr_syslog(OLSR_LOG_ERR, "Error, OLSR message from %s (type %d) is too small (%d bytes)"
349 ", ignoring all further content of the packet\n",
350 olsr_ip_to_string(&buf, msgorig), m->v4.olsr_msgtype, msgsize);
354 if ((msgsize % 4) != 0) {
355 struct ipaddr_str buf;
356 union olsr_ip_addr *msgorig = (union olsr_ip_addr *) &m->v4.originator;
357 OLSR_PRINTF(1, "Error, OLSR message from %s (type %d) must be"
358 " longword aligned, but has a length of %d bytes\n",
359 olsr_ip_to_string(&buf, msgorig), m->v4.olsr_msgtype, msgsize);
360 olsr_syslog(OLSR_LOG_ERR, "Error, OLSR message from %s (type %d) must be"
361 " longword aligned, but has a length of %d bytes",
362 olsr_ip_to_string(&buf, msgorig), m->v4.olsr_msgtype, msgsize);
366 if (msgsize > count) {
367 struct ipaddr_str buf;
368 union olsr_ip_addr *msgorig = (union olsr_ip_addr *) &m->v4.originator;
369 OLSR_PRINTF(1, "Error, OLSR message from %s (type %d) says"
370 " length=%d, but only %d bytes left\n",
371 olsr_ip_to_string(&buf, msgorig), m->v4.olsr_msgtype, msgsize, count);
372 olsr_syslog(OLSR_LOG_ERR, "Error, OLSR message from %s (type %d) says"
373 " length=%d, but only %d bytes left",
374 olsr_ip_to_string(&buf, msgorig), m->v4.olsr_msgtype, msgsize, count);
380 /*RFC 3626 section 3.4:
381 * 2 If the time to live of the message is less than or equal to
382 * '0' (zero), or if the message was sent by the receiving node
383 * (i.e., the Originator Address of the message is the main
384 * address of the receiving node): the message MUST silently be
388 /* Should be the same for IPv4 and IPv6 */
389 validated = olsr_validate_address((union olsr_ip_addr *)&m->v4.originator);
390 if (ipequal((union olsr_ip_addr *)&m->v4.originator, &olsr_cnf->main_addr) || !validated) {
392 struct ipaddr_str buf;
393 OLSR_PRINTF(3, "Not processing message originating from %s!\n",
394 olsr_ip_to_string(&buf, (union olsr_ip_addr *)&m->v4.originator));
396 #ifndef NO_DUPLICATE_DETECTION_HANDLER
398 olsr_test_originator_collision(m->v4.olsr_msgtype, seqno);
404 entry = parse_functions;
406 /* Should be the same for IPv4 and IPv6 */
408 /* Promiscuous or exact match */
409 if ((entry->type == PROMISCUOUS) || (entry->type == m->v4.olsr_msgtype)) {
410 if (!entry->function(m, in_if, from_addr))
417 olsr_forward_message(m, in_if, from_addr);
423 *Processing OLSR data from socket. Reading data, setting
424 *wich interface recieved the message, Sends IPC(if used)
425 *and passes the packet on to parse_packet().
427 *@param fd the filedescriptor that data should be read from.
431 olsr_input(int fd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
433 struct interface *olsr_in_if;
434 union olsr_ip_addr from_addr;
435 struct preprocessor_function_entry *entry;
438 cpu_overload_exit = 0;
441 struct ipaddr_str buf;
442 /* sockaddr_in6 is bigger than sockaddr !!!! */
443 struct sockaddr_storage from;
447 if (32 < ++cpu_overload_exit) {
448 OLSR_PRINTF(1, "CPU overload detected, ending olsr_input() loop\n");
452 fromlen = sizeof(struct sockaddr_storage);
453 cc = olsr_recvfrom(fd, inbuf, sizeof(inbuf_aligned), 0, (struct sockaddr *)&from, &fromlen);
456 if (cc < 0 && errno != EWOULDBLOCK) {
457 OLSR_PRINTF(1, "error recvfrom: %s", strerror(errno));
459 olsr_syslog(OLSR_LOG_ERR, "error recvfrom: %m");
464 if (olsr_cnf->ip_version == AF_INET) {
465 /* IPv4 sender address */
466 memcpy(&from_addr.v4, &((struct sockaddr_in *)&from)->sin_addr, sizeof(from_addr.v4));
468 /* IPv6 sender address */
469 memcpy(&from_addr.v6, &((struct sockaddr_in6 *)&from)->sin6_addr, sizeof(from_addr.v6));
473 OLSR_PRINTF(5, "Recieved a packet from %s\n",
474 olsr_ip_to_string(&buf, &from_addr));
477 if ((olsr_cnf->ip_version == AF_INET) && (fromlen != sizeof(struct sockaddr_in)))
479 else if ((olsr_cnf->ip_version == AF_INET6) && (fromlen != sizeof(struct sockaddr_in6)))
482 /* are we talking to ourselves? */
483 if (if_ifwithaddr(&from_addr) != NULL)
486 if ((olsr_in_if = if_ifwithsock(fd)) == NULL) {
487 OLSR_PRINTF(1, "Could not find input interface for message from %s size %d\n", olsr_ip_to_string(&buf, &from_addr), cc);
488 olsr_syslog(OLSR_LOG_ERR, "Could not find input interface for message from %s size %d\n", olsr_ip_to_string(&buf, &from_addr),
492 // call preprocessors
493 entry = preprocessor_functions;
497 packet = entry->function(packet, olsr_in_if, &from_addr, &cc);
499 if (packet == NULL) {
510 parse_packet((struct olsr *)packet, cc, olsr_in_if, &from_addr);
516 *Processing OLSR data from socket. Reading data, setting
517 *wich interface recieved the message, Sends IPC(if used)
518 *and passes the packet on to parse_packet().
520 *@param fd the filedescriptor that data should be read from.
524 olsr_input_hostemu(int fd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
526 /* sockaddr_in6 is bigger than sockaddr !!!! */
527 struct sockaddr_storage from;
529 struct interface *olsr_in_if;
530 union olsr_ip_addr from_addr;
532 struct preprocessor_function_entry *entry;
535 /* Host emulator receives IP address first to emulate
538 int cc = recv(fd, (void*)from_addr.v6.s6_addr, olsr_cnf->ipsize, 0);
539 if (cc != (int)olsr_cnf->ipsize) {
540 fprintf(stderr, "Error receiving host-client IP hook(%d) %s!\n", cc, strerror(errno));
541 memcpy(&from_addr, &((struct olsr *)inbuf)->olsr_msg->originator, olsr_cnf->ipsize);
544 /* are we talking to ourselves? */
545 if (if_ifwithaddr(&from_addr) != NULL)
549 if ((cc = recv(fd, (void *)&pcklen, 2, MSG_PEEK)) != 2) { /* Win needs a cast */
551 fprintf(stderr, "Lost olsr_switch connection - exit!\n");
552 olsr_exit(__func__, EXIT_FAILURE);
554 fprintf(stderr, "[hust-emu] error extracting size(%d) %s!\n", cc, strerror(errno));
557 pcklen = ntohs(pcklen);
560 fromlen = sizeof(struct sockaddr_storage);
562 cc = olsr_recvfrom(fd, inbuf, pcklen, 0, (struct sockaddr *)&from, &fromlen);
565 if (cc < 0 && errno != EWOULDBLOCK) {
566 const char *const err_msg = strerror(errno);
567 OLSR_PRINTF(1, "error recvfrom: %s", err_msg);
568 olsr_syslog(OLSR_LOG_ERR, "error recvfrom: %s", err_msg);
574 printf("Could not read whole packet(size %d, read %d)\n", pcklen, cc);
578 if ((olsr_in_if = if_ifwithsock(fd)) == NULL) {
579 struct ipaddr_str buf;
580 OLSR_PRINTF(1, "Could not find input interface for message from %s size %d\n", olsr_ip_to_string(&buf, &from_addr), cc);
581 olsr_syslog(OLSR_LOG_ERR, "Could not find input interface for message from %s size %d\n", olsr_ip_to_string(&buf, &from_addr),
585 // call preprocessors
586 entry = preprocessor_functions;
590 packet = entry->function(packet, olsr_in_if, &from_addr, &cc);
592 if (packet == NULL) {
603 parse_packet((struct olsr *)inbuf, cc, olsr_in_if, &from_addr);
610 * indent-tabs-mode: nil