00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "parser.h"
00043 #include "ipcalc.h"
00044 #include "defs.h"
00045 #include "process_package.h"
00046 #include "olsr_clock.h"
00047 #include "duplicate_set.h"
00048 #include "mid_set.h"
00049 #include "olsr.h"
00050 #include "os_net.h"
00051 #include "olsr_logging.h"
00052 #include "net_olsr.h"
00053
00054 #include <assert.h>
00055 #include <errno.h>
00056 #include <stdlib.h>
00057
00058 #ifdef WIN32
00059 #undef EWOULDBLOCK
00060 #define EWOULDBLOCK WSAEWOULDBLOCK
00061 #endif
00062
00063 static void parse_packet(uint8_t *binary, int size, struct interface *in_if, union olsr_ip_addr *from_addr);
00064
00065 static struct parse_function_entry *parse_functions = NULL;
00066 static struct preprocessor_function_entry *preprocessor_functions = NULL;
00067 static struct packetparser_function_entry *packetparser_functions = NULL;
00068
00069 static int olsr_forward_message(struct olsr_message *msg,
00070 uint8_t *binary, struct interface *in_if, union olsr_ip_addr *from_addr);
00071
00077 void
00078 olsr_init_parser(void)
00079 {
00080 OLSR_INFO(LOG_PACKET_PARSING, "Initializing parser...\n");
00081
00082
00083 olsr_init_package_process();
00084 }
00085
00086 void
00087 olsr_deinit_parser(void)
00088 {
00089 OLSR_INFO(LOG_PACKET_PARSING, "Deinitializing parser...\n");
00090 olsr_deinit_package_process();
00091 }
00092
00093 void
00094 olsr_parser_add_function(parse_function * function, uint32_t type)
00095 {
00096 struct parse_function_entry *new_entry;
00097
00098 new_entry = olsr_malloc(sizeof(*new_entry), "Register parse function");
00099
00100 new_entry->function = function;
00101 new_entry->type = type;
00102
00103
00104 new_entry->next = parse_functions;
00105 parse_functions = new_entry;
00106
00107 OLSR_INFO(LOG_PACKET_PARSING, "Register parse function: Added function for type %u\n", type);
00108 }
00109
00110 int
00111 olsr_parser_remove_function(parse_function * function)
00112 {
00113 struct parse_function_entry *entry, *prev;
00114
00115 for (entry = parse_functions, prev = NULL; entry != NULL; prev = entry, entry = entry->next) {
00116 if ((entry->function == function)) {
00117 if (entry == parse_functions) {
00118 parse_functions = entry->next;
00119 } else {
00120 prev->next = entry->next;
00121 }
00122 free(entry);
00123 return 1;
00124 }
00125 }
00126 return 0;
00127 }
00128
00129 void
00130 olsr_preprocessor_add_function(preprocessor_function * function)
00131 {
00132 struct preprocessor_function_entry *new_entry;
00133
00134 new_entry = olsr_malloc(sizeof(*new_entry), "Register preprocessor function");
00135 new_entry->function = function;
00136
00137
00138 new_entry->next = preprocessor_functions;
00139 preprocessor_functions = new_entry;
00140
00141 OLSR_INFO(LOG_PACKET_PARSING, "Registered preprocessor function\n");
00142 }
00143
00144 int
00145 olsr_preprocessor_remove_function(preprocessor_function * function)
00146 {
00147 struct preprocessor_function_entry *entry, *prev;
00148
00149 for (entry = preprocessor_functions, prev = NULL; entry != NULL; prev = entry, entry = entry->next) {
00150 if (entry->function == function) {
00151 if (entry == preprocessor_functions) {
00152 preprocessor_functions = entry->next;
00153 } else {
00154 prev->next = entry->next;
00155 }
00156 free(entry);
00157 return 1;
00158 }
00159 }
00160 return 0;
00161 }
00162
00163 void
00164 olsr_packetparser_add_function(packetparser_function * function)
00165 {
00166 struct packetparser_function_entry *new_entry;
00167
00168 new_entry = olsr_malloc(sizeof(struct packetparser_function_entry), "Register packetparser function");
00169
00170 new_entry->function = function;
00171
00172
00173 new_entry->next = packetparser_functions;
00174 packetparser_functions = new_entry;
00175
00176 OLSR_INFO(LOG_PACKET_PARSING, "Registered packetparser function\n");
00177 }
00178
00179 int
00180 olsr_packetparser_remove_function(packetparser_function * function)
00181 {
00182 struct packetparser_function_entry *entry, *prev;
00183
00184 for (entry = packetparser_functions, prev = NULL; entry != NULL; prev = entry, entry = entry->next) {
00185 if (entry->function == function) {
00186 if (entry == packetparser_functions) {
00187 packetparser_functions = entry->next;
00188 } else {
00189 prev->next = entry->next;
00190 }
00191 free(entry);
00192 return 1;
00193 }
00194 }
00195 return 0;
00196 }
00197
00198 static void
00199 olsr_parse_msg_hdr(const uint8_t **curr, struct olsr_message *msg)
00200 {
00201 assert(curr);
00202 assert(msg);
00203
00204 msg->header = *curr;
00205
00206 pkt_get_u8(curr, &msg->type);
00207 pkt_get_reltime(curr, &msg->vtime);
00208 pkt_get_u16(curr, &msg->size);
00209 pkt_get_ipaddress(curr, &msg->originator);
00210 pkt_get_u8(curr, &msg->ttl);
00211 pkt_get_u8(curr, &msg->hopcnt);
00212 pkt_get_u16(curr, &msg->seqno);
00213
00214 msg->payload = *curr;
00215 msg->end = msg->header + msg->size;
00216 }
00217
00227 static void
00228 parse_packet(uint8_t *binary, int size, struct interface *in_if, union olsr_ip_addr *from_addr)
00229 {
00230 struct olsr_packet pkt;
00231 struct olsr_message msg;
00232 struct parse_function_entry *entry;
00233 struct packetparser_function_entry *packetparser;
00234 enum duplicate_status dup_status = 0;
00235 uint8_t *curr, *end;
00236 const uint8_t *packet;
00237
00238 #if !defined(REMOVE_LOG_INFO) || !defined(REMOVE_LOG_WARN)
00239 struct ipaddr_str buf;
00240 #endif
00241
00242 curr = binary;
00243 packet = binary;
00244 end = binary + size;
00245
00246
00247 if (size < 4) {
00248 OLSR_WARN(LOG_PACKET_PARSING, "Received too small packet (%u bytes) from %s\n",
00249 size, olsr_ip_to_string(&buf, from_addr));
00250 return;
00251 }
00252
00253 pkt_get_u16(&packet, &pkt.size);
00254 pkt_get_u16(&packet, &pkt.seqno);
00255
00256 if (pkt.size != (size_t) size) {
00257 OLSR_WARN(LOG_PACKET_PARSING, "Received packet from %s (%u bytes) has bad size field: %u bytes\n",
00258 olsr_ip_to_string(&buf, from_addr), size, pkt.size);
00259 return;
00260 }
00261
00262
00263 for (packetparser = packetparser_functions; packetparser != NULL; packetparser = packetparser->next) {
00264 packetparser->function(&pkt, binary, in_if, from_addr);
00265 }
00266
00267
00268 curr += 4;
00269
00270 for (;curr <= end - MIN_MESSAGE_SIZE(); curr += msg.size) {
00271 const uint8_t *msg_payload = curr;
00272 olsr_parse_msg_hdr(&msg_payload, &msg);
00273
00274
00275 if (curr + msg.size > end) {
00276 OLSR_WARN(LOG_PACKET_PARSING, "Packet received from %s is too short (%u bytes) for message %u (%u bytes)!",
00277 olsr_ip_to_string(&buf, from_addr), size, msg.type, msg.size);
00278 break;
00279 }
00280 else if (msg.size == 0) {
00281 OLSR_WARN(LOG_PACKET_PARSING, "Received a zero lengthed message from %s (typde %d), ignoring all further content of the packet!",
00282 olsr_ip_to_string(&buf, from_addr), msg.type);
00283 return;
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 if (olsr_ipcmp(&msg.originator, &olsr_cnf->router_id) == 0
00296 || !olsr_validate_address(&msg.originator)) {
00297 OLSR_INFO(LOG_PACKET_PARSING, "Skip processing our own message coming from %s!\n",
00298 olsr_ip_to_string(&buf, from_addr));
00299 continue;
00300 }
00301
00302 if (msg.ttl == 0 || (int)msg.ttl + (int)msg.hopcnt > 255) {
00303 #if !defined(REMOVE_LOG_WARN)
00304 struct ipaddr_str buf2;
00305 #endif
00306 OLSR_WARN(LOG_PACKET_PARSING, "Malformed incoming message type %u from %s with originator %s: ttl=%u and hopcount=%u\n",
00307 msg.type, olsr_ip_to_string(&buf, from_addr), olsr_ip_to_string(&buf2, &msg.originator), msg.ttl, msg.hopcnt);
00308 continue;
00309 }
00310 if (olsr_is_duplicate_message(&msg, false, &dup_status)) {
00311 OLSR_INFO(LOG_PACKET_PARSING, "Not processing message duplicate from %s (seqnr %u)!\n",
00312 olsr_ip_to_string(&buf, &msg.originator), msg.seqno);
00313 }
00314 else {
00315 OLSR_DEBUG(LOG_PACKET_PARSING, "Processing message type %u (seqno %u) from %s\n",
00316 msg.type, msg.seqno, olsr_ip_to_string(&buf, &msg.originator));
00317 for (entry = parse_functions; entry != NULL; entry = entry->next) {
00318
00319
00320 if ((entry->type == PROMISCUOUS) || (entry->type == msg.type)) {
00321 entry->function(&msg, in_if, from_addr, dup_status);
00322 }
00323 }
00324 }
00325 olsr_forward_message(&msg, curr, in_if, from_addr);
00326 }
00327 }
00328
00337 void
00338 olsr_input(int fd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
00339 {
00340 unsigned int cpu_overload_exit = 0;
00341 #ifndef REMOVE_LOG_DEBUG
00342 char addrbuf[128];
00343 #endif
00344 #if !defined(REMOVE_LOG_INFO) || !defined(REMOVE_LOG_WARN)
00345 struct ipaddr_str buf;
00346 #endif
00347
00348 for (;;) {
00349 struct interface *olsr_in_if;
00350 union olsr_ip_addr from_addr;
00351 struct preprocessor_function_entry *entry;
00352 uint8_t *packet;
00353
00354 union olsr_sockaddr from;
00355 socklen_t fromlen;
00356 int size;
00357 uint8_t inbuf[MAXMESSAGESIZE] __attribute__ ((aligned));
00358
00359 if (32 < ++cpu_overload_exit) {
00360 OLSR_WARN(LOG_PACKET_PARSING, "CPU overload detected, ending olsr_input() loop\n");
00361 break;
00362 }
00363
00364 fromlen = sizeof(from);
00365 size = os_recvfrom(fd, inbuf, sizeof(inbuf), 0, &from, &fromlen);
00366
00367 if (size <= 0) {
00368 if (size < 0 && errno != EWOULDBLOCK) {
00369 OLSR_WARN(LOG_PACKET_PARSING, "error recvfrom: %s", strerror(errno));
00370 }
00371 break;
00372 }
00373
00374 OLSR_DEBUG(LOG_PACKET_PARSING, "Recieved a packet from %s (fd=%d)\n",
00375 sockaddr_to_string(addrbuf, sizeof(addrbuf), (struct sockaddr *)&from, fromlen),
00376 fd);
00377
00378 if (olsr_cnf->ip_version == AF_INET) {
00379
00380 if (fromlen != sizeof(struct sockaddr_in)) {
00381 OLSR_WARN(LOG_PACKET_PARSING, "Got wrong ip size from recv()\n");
00382 break;
00383 }
00384 from_addr.v4 = ((struct sockaddr_in *)&from)->sin_addr;
00385 } else {
00386
00387 if (fromlen != sizeof(struct sockaddr_in6)) {
00388 OLSR_WARN(LOG_PACKET_PARSING, "Got wrong ip size from recv()\n");
00389 break;
00390 }
00391 from_addr.v6 = ((struct sockaddr_in6 *)&from)->sin6_addr;
00392 }
00393
00394
00395 if (if_ifwithaddr(&from_addr) != NULL) {
00396 OLSR_INFO(LOG_PACKET_PARSING, "Ignore packet from ourself (%s).\n",
00397 olsr_ip_to_string(&buf, &from_addr));
00398 return;
00399 }
00400 olsr_in_if = if_ifwithsock(fd);
00401 if (olsr_in_if == NULL) {
00402 OLSR_WARN(LOG_PACKET_PARSING, "Could not find input interface for message from %s size %d\n",
00403 olsr_ip_to_string(&buf, &from_addr), size);
00404 return;
00405 }
00406
00407 packet = &inbuf[0];
00408 for (entry = preprocessor_functions; entry != NULL; entry = entry->next) {
00409 packet = entry->function(packet, olsr_in_if, &from_addr, &size);
00410
00411 if (packet == NULL) {
00412 OLSR_INFO(LOG_PACKET_PARSING, "Discard package because of preprocessor\n");
00413 return;
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422 parse_packet(packet, size, olsr_in_if, &from_addr);
00423 }
00424 }
00425
00434 static int
00435 olsr_forward_message(struct olsr_message *msg, uint8_t *binary, struct interface *in_if, union olsr_ip_addr *from_addr)
00436 {
00437 union olsr_ip_addr *src;
00438 struct nbr_entry *neighbor;
00439 struct interface *ifn, *iterator;
00440 uint8_t *tmp;
00441 #if !defined REMOVE_LOG_DEBUG
00442 struct ipaddr_str buf;
00443 #endif
00444
00445
00446 src = olsr_lookup_main_addr_by_alias(from_addr);
00447 if (!src)
00448 src = from_addr;
00449
00450 neighbor = olsr_lookup_nbr_entry(src, true);
00451 if (!neighbor) {
00452 OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d because no nbr entry found for %s\n",
00453 msg->type, olsr_ip_to_string(&buf, src));
00454 return 0;
00455 }
00456 if (!neighbor->is_sym) {
00457 OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d because received by non-symmetric neighbor %s\n",
00458 msg->type, olsr_ip_to_string(&buf, src));
00459 return 0;
00460 }
00461
00462
00463 if (neighbor->mprs_count == 0) {
00464 OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d because we are no MPR for %s\n",
00465 msg->type, olsr_ip_to_string(&buf, src));
00466
00467 return 0;
00468 }
00469
00470
00471 if (olsr_is_duplicate_message(msg, true, NULL)) {
00472 OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d from %s because we already forwarded it.\n",
00473 msg->type, olsr_ip_to_string(&buf, src));
00474 return 0;
00475 }
00476
00477
00478 msg->hopcnt++;
00479 msg->ttl--;
00480 tmp = binary;
00481 olsr_put_msg_hdr(&tmp, msg);
00482
00483 if (msg->ttl == 0) {
00484 OLSR_DEBUG(LOG_PACKET_PARSING, "Not forwarding message type %d from %s because TTL is 0.\n",
00485 msg->type, olsr_ip_to_string(&buf, src));
00486 return 0;
00487 }
00488 OLSR_DEBUG(LOG_PACKET_PARSING, "Forwarding message type %d from %s.\n",
00489 msg->type, olsr_ip_to_string(&buf, src));
00490
00491
00492 OLSR_FOR_ALL_INTERFACES(ifn, iterator) {
00493 if (net_output_pending(ifn)) {
00494
00495 if (in_if->mode == IF_MODE_ETHER && ifn == in_if)
00496 continue;
00497
00498
00499
00500
00501 if (net_outbuffer_push(ifn, binary, msg->size) != msg->size) {
00502
00503 net_output(ifn);
00504
00505 set_buffer_timer(ifn);
00506
00507 if (net_outbuffer_push(ifn, binary, msg->size) != msg->size) {
00508 OLSR_WARN(LOG_NETWORKING, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msg->size);
00509 }
00510 }
00511 } else {
00512
00513 set_buffer_timer(ifn);
00514
00515 if (net_outbuffer_push(ifn, binary, msg->size) != msg->size) {
00516 OLSR_WARN(LOG_NETWORKING, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msg->size);
00517 }
00518 }
00519 }
00520
00521 return 1;
00522 }
00523
00524
00525
00526
00527
00528
00529