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 #include <stdio.h>
00042 #include <stdarg.h>
00043
00044 #include "contiki.h"
00045 #include "net/uaodv-def.h"
00046 #include "net/uaodv-rt.h"
00047
00048 #define NDEBUG
00049 #include "lib/assert.h"
00050
00051 #ifdef CC2420_RADIO
00052 #include "dev/cc2420.h"
00053 #define RSSI_THRESHOLD -39
00054 #endif
00055
00056
00057 #define MY_ROUTE_TIMEOUT 0x7fffffff
00058 #define MY_NET_DIAMETER 20
00059
00060 PROCESS(uaodv_process, "uAODV");
00061
00062 static struct uip_udp_conn *bcastconn, *unicastconn;
00063
00064
00065 #define SCMP32(a, b) ((s32_t)((a) - (b)))
00066
00067 static CC_INLINE u32_t
00068 last_known_seqno(uip_ipaddr_t *host)
00069 {
00070 struct uaodv_rt_entry *route = uaodv_rt_lookup_any(host);
00071
00072 if(route != NULL)
00073 return uip_htonl(route->hseqno);
00074
00075 return 0;
00076 }
00077
00078
00079 static u32_t rreq_id, my_hseqno;
00080
00081 #define NFWCACHE 16
00082
00083 static struct {
00084 uip_ipaddr_t orig;
00085 u32_t id;
00086 } fwcache[NFWCACHE];
00087
00088 static CC_INLINE int
00089 fwc_lookup(const uip_ipaddr_t *orig, const u32_t *id)
00090 {
00091 unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
00092 return fwcache[n].id == *id && uip_ipaddr_cmp(&fwcache[n].orig, orig);
00093 }
00094
00095 static CC_INLINE void
00096 fwc_add(const uip_ipaddr_t *orig, const u32_t *id)
00097 {
00098 unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
00099 fwcache[n].id = *id;
00100 uip_ipaddr_copy(&fwcache[n].orig, orig);
00101 }
00102
00103 #ifdef NDEBUG
00104 #define PRINTF(...) do {} while (0)
00105 #define print_debug(...) do{}while(0)
00106 #else
00107 #define PRINTF(...) printf(__VA_ARGS__)
00108 #ifdef __GNUC__
00109 static void
00110 print_debug(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
00111 #endif
00112 static void
00113 print_debug(const char *fmt, ...)
00114 {
00115 va_list ap;
00116
00117 va_start(ap, fmt);
00118 printf("%d.%d.%d.%d: ", uip_ipaddr_to_quad(&uip_hostaddr));
00119 vprintf(fmt, ap);
00120 va_end(ap);
00121 return;
00122 }
00123 #endif
00124
00125 #define BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
00126 #define uip_udp_sender() (&BUF->srcipaddr)
00127
00128
00129 static void
00130 sendto(const uip_ipaddr_t *dest, const void *buf, int len)
00131 {
00132
00133
00134
00135
00136
00137
00138
00139 uip_ipaddr_copy(&unicastconn->ripaddr, dest);
00140 uip_udp_conn = unicastconn;
00141 uip_udp_packet_send(unicastconn, buf, len);
00142 }
00143
00144 #ifdef AODV_BAD_HOP_EXTENSION
00145 static unsigned
00146 add_rreq_extensions(void *_p)
00147 {
00148 struct uaodv_bad_hop_ext *p = _p;
00149 uip_ipaddr_t *a = p->addrs;
00150 unsigned i, n;
00151
00152 #define SCALE_RETRANS_THRESHOLD (3*4)
00153
00154 cc2420_check_remote(0xffff);
00155 n = 0;
00156 for (i = 0; i < NNEIGBOURS; i++) {
00157 if (neigbours[i].nretrans >= SCALE_RETRANS_THRESHOLD
00158 && neigbours[i].mac != 0xffff) {
00159 a->u16[0] = uip_hostaddr.u16[0];
00160 a->u16[1] = neigbours[i].mac;
00161 n++;
00162 if(n == 15)
00163 break;
00164 print_debug("BAD HOP %d.%d.%d.%d\t%d\n",
00165 uip_ipaddr_to_quad(a), neigbours[i].nretrans);
00166 }
00167 }
00168
00169 if(n == 0)
00170 return 0;
00171
00172 p->type = RREQ_BAD_HOP_EXT;
00173 p->length = 2 + 4*n;
00174 return 2 + p->length;
00175 }
00176 #else
00177 #define add_rreq_extensions(p) 0
00178 #endif
00179
00180 static void
00181 send_rreq(uip_ipaddr_t *addr)
00182 {
00183 struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
00184 int len;
00185
00186 print_debug("send RREQ for %d.%d.%d.%d\n", uip_ipaddr_to_quad(addr));
00187
00188 rm->type = UAODV_RREQ_TYPE;
00189 rm->dest_seqno = last_known_seqno(addr);
00190 if(rm->dest_seqno == 0)
00191 rm->flags = UAODV_RREQ_UNKSEQNO;
00192 else
00193 rm->flags = 0;
00194 rm->reserved = 0;
00195 rm->hop_count = 0;
00196 rm->rreq_id = uip_htonl(rreq_id++);
00197 uip_ipaddr_copy(&rm->dest_addr, addr);
00198 uip_gethostaddr(&rm->orig_addr);
00199 my_hseqno++;
00200 rm->orig_seqno = uip_htonl(my_hseqno);
00201 bcastconn->ttl = MY_NET_DIAMETER;
00202 len = sizeof(struct uaodv_msg_rreq);
00203 len += add_rreq_extensions(rm + 1);
00204 uip_udp_packet_send(bcastconn, rm, len);
00205 }
00206
00207 static void
00208 send_rrep(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop, uip_ipaddr_t *orig,
00209 u32_t *seqno, unsigned hop_count)
00210 {
00211 struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
00212
00213 print_debug("send RREP orig=%d.%d.%d.%d hops=%d\n",
00214 uip_ipaddr_to_quad(orig), hop_count);
00215
00216 rm->type = UAODV_RREP_TYPE;
00217 rm->flags = 0;
00218 rm->prefix_sz = 0;
00219 rm->hop_count = hop_count;
00220 uip_ipaddr_copy(&rm->orig_addr, orig);
00221 rm->dest_seqno = *seqno;
00222 uip_ipaddr_copy(&rm->dest_addr, dest);
00223 rm->lifetime = UIP_HTONL(MY_ROUTE_TIMEOUT);
00224 sendto(nexthop, rm, sizeof(struct uaodv_msg_rrep));
00225 }
00226
00227 static void
00228 send_rerr(uip_ipaddr_t *addr, u32_t *seqno)
00229 {
00230 struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata;
00231
00232 print_debug("send RERR for %d.%d.%d.%d\n", uip_ipaddr_to_quad(addr));
00233
00234 rm->type = UAODV_RERR_TYPE;
00235 rm->reserved = 0;
00236 rm->dest_count = 1;
00237 uip_ipaddr_copy(&rm->unreach[0].addr, addr);
00238 rm->unreach[0].seqno = *seqno;
00239 if(*seqno == 0)
00240 rm->flags = UAODV_RERR_UNKNOWN;
00241 else
00242 rm->flags = 0;
00243
00244 uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr));
00245 }
00246
00247 static void
00248 handle_incoming_rreq(void)
00249 {
00250 struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
00251 uip_ipaddr_t dest_addr, orig_addr;
00252 struct uaodv_rt_entry *rt, *fw = NULL;
00253
00254 print_debug("RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u"
00255 " orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n",
00256 uip_ipaddr_to_quad(&BUF->srcipaddr),
00257 uip_ipaddr_to_quad(&BUF->destipaddr),
00258 BUF->ttl,
00259 uip_ipaddr_to_quad(&rm->orig_addr), uip_ntohl(rm->orig_seqno),
00260 rm->hop_count,
00261 uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno));
00262
00263 if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
00264 return;
00265 }
00266
00267 #ifdef CC2420_RADIO
00268 {
00269 int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
00270
00271 if(ret == REMOTE_YES) {
00272 print_debug("RREQ drop is remote\n");
00273 return;
00274 } else if (ret == REMOTE_NO) {
00275
00276 } else if(cc2420_last_rssi < RSSI_THRESHOLD) {
00277 print_debug("RREQ drop %d %d\n", cc2420_last_rssi,
00278 cc2420_last_correlation);
00279 return;
00280 }
00281 }
00282 #endif
00283
00284 #ifdef AODV_BAD_HOP_EXTENSION
00285 if(uip_len > (sizeof(*rm) + 2)) {
00286 struct uaodv_bad_hop_ext *ext = (void *)(uip_appdata + sizeof(*rm));
00287 u8_t *end = uip_appdata + uip_len;
00288 for(;
00289 (u8_t *)ext < end;
00290 ext = (void *)((u8_t *)ext + ext->length + 2)) {
00291 u8_t *eend = (u8_t *)ext + ext->length;
00292 if(eend > end)
00293 eend = end;
00294
00295 if(ext->type == RREQ_BAD_HOP_EXT) {
00296 uip_ipaddr_t *a;
00297 for(a = ext->addrs; (u8_t *)a < eend; a++) {
00298 if(uip_ipaddr_cmp(a, &uip_hostaddr)) {
00299 print_debug("BAD_HOP drop\n");
00300 return;
00301 }
00302 }
00303 }
00304 }
00305 }
00306 #endif
00307
00308
00309 rt = uaodv_rt_lookup(&rm->orig_addr);
00310 if(rt == NULL
00311 || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0)
00312 || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0
00313 && rm->hop_count < rt->hop_count)) {
00314 print_debug("Inserting1\n");
00315 rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(),
00316 rm->hop_count, &rm->orig_seqno);
00317 }
00318
00319
00320 if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)
00321 || rm->flags & UAODV_RREQ_DESTONLY) {
00322 fw = NULL;
00323 } else {
00324 fw = uaodv_rt_lookup(&rm->dest_addr);
00325 if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
00326 && fw != NULL
00327 && SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) {
00328 fw = NULL;
00329 }
00330 }
00331
00332 if (fw != NULL) {
00333 u32_t net_seqno;
00334
00335 print_debug("RREQ for known route\n");
00336 uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
00337 uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
00338 net_seqno = uip_htonl(fw->hseqno);
00339 send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno,
00340 fw->hop_count + 1);
00341 } else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) {
00342 u32_t net_seqno;
00343
00344 print_debug("RREQ for our address\n");
00345 uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
00346 uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
00347
00348 my_hseqno++;
00349 if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
00350 && SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) {
00351 print_debug("New my_hseqno %lu\n", my_hseqno);
00352 my_hseqno = uip_ntohl(rm->dest_seqno) + 1;
00353 }
00354 net_seqno = uip_htonl(my_hseqno);
00355 send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0);
00356 } else if(BUF->ttl > 1) {
00357 int len;
00358
00359
00360 if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) {
00361 print_debug("RREQ cached, not fwd\n");
00362 return;
00363 }
00364 fwc_add(&rm->orig_addr, &rm->rreq_id);
00365
00366 print_debug("RREQ fwd\n");
00367 rm->hop_count++;
00368 bcastconn->ttl = BUF->ttl - 1;
00369 len = sizeof(struct uaodv_msg_rreq);
00370 len += add_rreq_extensions(rm + 1);
00371 uip_udp_packet_send(bcastconn, rm, len);
00372 }
00373 }
00374
00375 static void
00376 handle_incoming_rrep(void)
00377 {
00378 struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
00379 struct uaodv_rt_entry *rt;
00380
00381
00382 if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
00383 #ifdef AODV_RESPOND_TO_HELLOS
00384 u32_t net_seqno;
00385 #ifdef CC2420_RADIO
00386 int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
00387
00388 if(ret == REMOTE_YES) {
00389 print_debug("HELLO drop is remote\n");
00390 return;
00391 } else if (ret == REMOTE_NO) {
00392
00393 } else if(cc2420_last_rssi < RSSI_THRESHOLD) {
00394 print_debug("HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation);
00395 return;
00396 }
00397 #endif
00398
00399 net_seqno = uip_htonl(my_hseqno);
00400 send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0);
00401 #endif
00402 return;
00403 }
00404
00405 print_debug("RREP %d.%d.%d.%d -> %d.%d.%d.%d"
00406 " dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n",
00407 uip_ipaddr_to_quad(&BUF->srcipaddr),
00408 uip_ipaddr_to_quad(&BUF->destipaddr),
00409 uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno),
00410 rm->hop_count,
00411 uip_ipaddr_to_quad(&rm->orig_addr));
00412
00413 rt = uaodv_rt_lookup(&rm->dest_addr);
00414
00415
00416 if(rt == NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) {
00417 print_debug("Inserting3\n");
00418 rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(),
00419 rm->hop_count, &rm->dest_seqno);
00420 #ifdef CC2420_RADIO
00421
00422 cc2420_recv_ok(uip_udp_sender());
00423 print_debug("RREP recv ok %d %d\n",
00424 cc2420_last_rssi, cc2420_last_correlation);
00425 #endif
00426 } else {
00427 print_debug("Not inserting\n");
00428 }
00429
00430
00431 if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
00432 print_debug("ROUTE FOUND\n");
00433 if(rm->flags & UAODV_RREP_ACK) {
00434 struct uaodv_msg_rrep_ack *ack = (void *)uip_appdata;
00435 ack->type = UAODV_RREP_ACK_TYPE;
00436 ack->reserved = 0;
00437 sendto(uip_udp_sender(), ack, sizeof(*ack));
00438 }
00439 } else {
00440 rt = uaodv_rt_lookup(&rm->orig_addr);
00441
00442 if(rt == NULL) {
00443 print_debug("RREP received, but no route back to originator... :-( \n");
00444 return;
00445 }
00446
00447 if(rm->flags & UAODV_RREP_ACK) {
00448 print_debug("RREP with ACK request (ignored)!\n");
00449
00450 rm->flags &= ~UAODV_RREP_ACK;
00451 }
00452
00453 rm->hop_count++;
00454
00455 print_debug("Fwd RREP to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&rt->nexthop));
00456
00457 sendto(&rt->nexthop, rm, sizeof(struct uaodv_msg_rrep));
00458 }
00459 }
00460
00461 static void
00462 handle_incoming_rerr(void)
00463 {
00464 struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata;
00465 struct uaodv_rt_entry *rt;
00466
00467 print_debug("RERR %d.%d.%d.%d -> %d.%d.%d.%d"
00468 " unreach=%d.%d.%d.%d seq=%lu\n",
00469 uip_ipaddr_to_quad(&BUF->srcipaddr),
00470 uip_ipaddr_to_quad(&BUF->destipaddr),
00471 uip_ipaddr_to_quad((uip_ipaddr_t *)&rm->unreach[0]),
00472 uip_ntohl(rm->unreach[0].seqno));
00473
00474 if(uip_ipaddr_cmp(&rm->unreach[0].addr, &uip_hostaddr))
00475 return;
00476
00477 rt = uaodv_rt_lookup_any(&rm->unreach[0].addr);
00478 if(rt != NULL && uip_ipaddr_cmp(&rt->nexthop, uip_udp_sender())) {
00479 if((rm->flags & UAODV_RERR_UNKNOWN) || rm->unreach[0].seqno == 0
00480 || SCMP32(rt->hseqno, uip_ntohl(rm->unreach[0].seqno)) <= 0) {
00481 rt->is_bad = 1;
00482 if(rm->flags & UAODV_RERR_UNKNOWN) {
00483 rm->flags &= ~UAODV_RERR_UNKNOWN;
00484 rm->unreach[0].seqno = uip_htonl(rt->hseqno);
00485 }
00486 print_debug("RERR rebroadcast\n");
00487 uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr));
00488 }
00489 }
00490 }
00491
00492 static void
00493 handle_incoming_packet(void)
00494 {
00495 struct uaodv_msg *m = (struct uaodv_msg *)uip_appdata;
00496
00497
00498 switch(m->type) {
00499 case UAODV_RREQ_TYPE:
00500 handle_incoming_rreq();
00501 break;
00502
00503 case UAODV_RREP_TYPE:
00504 handle_incoming_rrep();
00505 break;
00506
00507 case UAODV_RERR_TYPE:
00508 handle_incoming_rerr();
00509 break;
00510 }
00511
00512 }
00513
00514 static enum {
00515 COMMAND_NONE,
00516 COMMAND_SEND_RREQ,
00517 COMMAND_SEND_RERR,
00518 } command;
00519
00520 static uip_ipaddr_t bad_dest;
00521 static u32_t bad_seqno;
00522
00523 void
00524 uaodv_bad_dest(uip_ipaddr_t *dest)
00525 {
00526 struct uaodv_rt_entry *rt = uaodv_rt_lookup_any(dest);
00527
00528 if(rt == NULL)
00529 bad_seqno = 0;
00530 else {
00531 rt->is_bad = 1;
00532 bad_seqno = uip_htonl(rt->hseqno);
00533 }
00534
00535 uip_ipaddr_copy(&bad_dest, dest);
00536 command = COMMAND_SEND_RERR;
00537 process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
00538 }
00539
00540 static uip_ipaddr_t rreq_addr;
00541 static struct timer next_time;
00542
00543 struct uaodv_rt_entry *
00544 uaodv_request_route_to(uip_ipaddr_t *host)
00545 {
00546 struct uaodv_rt_entry *route = uaodv_rt_lookup(host);
00547
00548 if(route != NULL) {
00549 uaodv_rt_lru(route);
00550 return route;
00551 }
00552
00553
00554
00555
00556 if(!timer_expired(&next_time)) {
00557 return NULL;
00558 }
00559
00560 if(command != COMMAND_NONE) {
00561 return NULL;
00562 }
00563
00564 uip_ipaddr_copy(&rreq_addr, host);
00565 command = COMMAND_SEND_RREQ;
00566 process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
00567 timer_set(&next_time, CLOCK_SECOND/8);
00568 return NULL;
00569 }
00570
00571 PROCESS_THREAD(uaodv_process, ev, data)
00572 {
00573 PROCESS_EXITHANDLER(goto exit);
00574
00575 PROCESS_BEGIN();
00576
00577 printf("uaodv_process starting %lu\n", (unsigned long) my_hseqno);
00578
00579 bcastconn = udp_broadcast_new(UIP_HTONS(UAODV_UDPPORT), NULL);
00580 unicastconn = udp_broadcast_new(UIP_HTONS(UAODV_UDPPORT), NULL);
00581
00582 while(1) {
00583 PROCESS_WAIT_EVENT();
00584
00585 if(ev == tcpip_event) {
00586 if(uip_newdata()) {
00587 handle_incoming_packet();
00588 continue;
00589 }
00590 if(uip_poll()) {
00591 if(command == COMMAND_SEND_RREQ) {
00592 if(uaodv_rt_lookup(&rreq_addr) == NULL)
00593 send_rreq(&rreq_addr);
00594 } else if (command == COMMAND_SEND_RERR) {
00595 send_rerr(&bad_dest, &bad_seqno);
00596 }
00597 command = COMMAND_NONE;
00598 continue;
00599 }
00600 }
00601
00602 if(ev == PROCESS_EVENT_MSG) {
00603 tcpip_poll_udp(bcastconn);
00604 }
00605 }
00606
00607 exit:
00608 command = COMMAND_NONE;
00609 uaodv_rt_flush_all();
00610 uip_udp_remove(bcastconn);
00611 bcastconn = NULL;
00612 uip_udp_remove(unicastconn);
00613 unicastconn = NULL;
00614 printf("uaodv_process exiting\n");
00615 PROCESS_END();
00616 }
00617