/*---------------------------------------------------------------------------*/ static int rreq_packet_received(struct netflood_conn *nf, const rimeaddr_t *from, const rimeaddr_t *originator, uint8_t seqno, uint8_t hops) { struct route_msg *msg = packetbuf_dataptr(); struct route_discovery_conn *c = (struct route_discovery_conn *) ((char *)nf - offsetof(struct route_discovery_conn, rreqconn)); PRINTF("%d.%d: rreq_packet_received from %d.%d hops %d rreq_id %d last %d.%d/%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], from->u8[0], from->u8[1], hops, msg->rreq_id, c->last_rreq_originator.u8[0], c->last_rreq_originator.u8[1], c->last_rreq_id); if(!(rimeaddr_cmp(&c->last_rreq_originator, originator) && c->last_rreq_id == msg->rreq_id)) { PRINTF("%d.%d: rreq_packet_received: request for %d.%d originator %d.%d / %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], msg->dest.u8[0], msg->dest.u8[1], originator->u8[0], originator->u8[1], msg->rreq_id); rimeaddr_copy(&c->last_rreq_originator, originator); c->last_rreq_id = msg->rreq_id; if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) { PRINTF("%d.%d: route_packet_received: route request for our address\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); PRINTF("from %d.%d hops %d rssi %d lqi %d\n", from->u8[0], from->u8[1], hops, packetbuf_attr(PACKETBUF_ATTR_RSSI), packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY)); insert_route(originator, from, hops); /* Send route reply back to source. */ send_rrep(c, originator); return 0; /* Don't continue to flood the rreq packet. */ } else { /* PRINTF("route request for %d\n", msg->dest_id);*/ PRINTF("from %d.%d hops %d rssi %d lqi %d\n", from->u8[0], from->u8[1], hops, packetbuf_attr(PACKETBUF_ATTR_RSSI), packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY)); insert_route(originator, from, hops); } return 1; } return 0; /* Don't forward packet. */ }
/*---------------------------------------------------------------------------*/ static void handle_incoming_rrep(void) { struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata; struct uaodv_rt_entry *rt; /* Useless HELLO message? */ if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) { #ifdef AODV_RESPOND_TO_HELLOS uint32_t net_seqno; #ifdef CC2420_RADIO int ret = cc2420_check_remote(uip_udp_sender()->u16[1]); if(ret == REMOTE_YES) { print_debug("HELLO drop is remote\n"); return; } else if (ret == REMOTE_NO) { /* Is neigbour, accept it. */ } else if(cc2420_last_rssi < RSSI_THRESHOLD) { print_debug("HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation); return; } #endif /* Sometimes it helps to send a non-requested RREP in response! */ net_seqno = uip_htonl(my_hseqno); send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0); #endif return; } print_debug("RREP %d.%d.%d.%d -> %d.%d.%d.%d" " dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&BUF->srcipaddr), uip_ipaddr_to_quad(&BUF->destipaddr), uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno), rm->hop_count, uip_ipaddr_to_quad(&rm->orig_addr)); rt = uaodv_rt_lookup(&rm->dest_addr); /* New forward route? */ if(rt == NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) { print_debug("Inserting3\n"); rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(), rm->hop_count, &rm->dest_seqno); #ifdef CC2420_RADIO /* This link is ok since he is unicasting back to us! */ cc2420_recv_ok(uip_udp_sender()); print_debug("RREP recv ok %d %d\n", cc2420_last_rssi, cc2420_last_correlation); #endif } else { print_debug("Not inserting\n"); } /* Forward RREP towards originator? */ if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) { print_debug("ROUTE FOUND\n"); if(rm->flags & UAODV_RREP_ACK) { struct uaodv_msg_rrep_ack *ack = (void *)uip_appdata; ack->type = UAODV_RREP_ACK_TYPE; ack->reserved = 0; sendto(uip_udp_sender(), ack, sizeof(*ack)); } } else { rt = uaodv_rt_lookup(&rm->orig_addr); if(rt == NULL) { print_debug("RREP received, but no route back to originator... :-( \n"); return; } if(rm->flags & UAODV_RREP_ACK) { print_debug("RREP with ACK request (ignored)!\n"); /* Don't want any RREP-ACKs in return! */ rm->flags &= ~UAODV_RREP_ACK; } rm->hop_count++; print_debug("Fwd RREP to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&rt->nexthop)); sendto(&rt->nexthop, rm, sizeof(struct uaodv_msg_rrep)); } }
/*---------------------------------------------------------------------------*/ static void handle_incoming_rreq(void) { struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata; uip_ipaddr_t dest_addr, orig_addr; struct uaodv_rt_entry *rt, *fw = NULL; print_debug("RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u" " orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n", uip_ipaddr_to_quad(&BUF->srcipaddr), uip_ipaddr_to_quad(&BUF->destipaddr), BUF->ttl, uip_ipaddr_to_quad(&rm->orig_addr), uip_ntohl(rm->orig_seqno), rm->hop_count, uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno)); if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) { return; /* RREQ looped back! */ } #ifdef CC2420_RADIO { int ret = cc2420_check_remote(uip_udp_sender()->u16[1]); if(ret == REMOTE_YES) { print_debug("RREQ drop is remote\n"); return; } else if (ret == REMOTE_NO) { /* Is neigbour, accept it. */ } else if(cc2420_last_rssi < RSSI_THRESHOLD) { print_debug("RREQ drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation); return; } } #endif #ifdef AODV_BAD_HOP_EXTENSION if(uip_len > (sizeof(*rm) + 2)) { struct uaodv_bad_hop_ext *ext = (void *)(uip_appdata + sizeof(*rm)); uint8_t *end = uip_appdata + uip_len; for(; (uint8_t *)ext < end; ext = (void *)((uint8_t *)ext + ext->length + 2)) { uint8_t *eend = (uint8_t *)ext + ext->length; if(eend > end) eend = end; if(ext->type == RREQ_BAD_HOP_EXT) { uip_ipaddr_t *a; for(a = ext->addrs; (uint8_t *)a < eend; a++) { if(uip_ipaddr_cmp(a, &uip_hostaddr)) { print_debug("BAD_HOP drop\n"); return; } } } } } #endif /* AODV_BAD_HOP_EXTENSION */ /* New reverse route? */ rt = uaodv_rt_lookup(&rm->orig_addr); if(rt == NULL || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0) /* New route. */ || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0 && rm->hop_count < rt->hop_count)) { /* Better route. */ print_debug("Inserting1\n"); rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(), rm->hop_count, &rm->orig_seqno); } /* Check if it is for our address or a fresh route. */ if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr) || rm->flags & UAODV_RREQ_DESTONLY) { fw = NULL; } else { fw = uaodv_rt_lookup(&rm->dest_addr); if(!(rm->flags & UAODV_RREQ_UNKSEQNO) && fw != NULL && SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) { fw = NULL; } } if (fw != NULL) { uint32_t net_seqno; print_debug("RREQ for known route\n"); uip_ipaddr_copy(&dest_addr, &rm->dest_addr); uip_ipaddr_copy(&orig_addr, &rm->orig_addr); net_seqno = uip_htonl(fw->hseqno); send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, fw->hop_count + 1); } else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) { uint32_t net_seqno; print_debug("RREQ for our address\n"); uip_ipaddr_copy(&dest_addr, &rm->dest_addr); uip_ipaddr_copy(&orig_addr, &rm->orig_addr); my_hseqno++; if(!(rm->flags & UAODV_RREQ_UNKSEQNO) && SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) { print_debug("New my_hseqno %lu\n", my_hseqno); /* We have rebooted. */ my_hseqno = uip_ntohl(rm->dest_seqno) + 1; } net_seqno = uip_htonl(my_hseqno); send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0); } else if(BUF->ttl > 1) { int len; /* Have we seen this RREQ before? */ if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) { print_debug("RREQ cached, not fwd\n"); return; } fwc_add(&rm->orig_addr, &rm->rreq_id); print_debug("RREQ fwd\n"); rm->hop_count++; bcastconn->ttl = BUF->ttl - 1; len = sizeof(struct uaodv_msg_rreq); len += add_rreq_extensions(rm + 1); uip_udp_packet_send(bcastconn, rm, len); } }