NETWORK ATTACKS FRAMEWORK
1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
|
#include "NA_defs_aodv.h"
#include "NA_seek_list.h"
#include "NA_routing_table.h"
#include <endian.h>
Go to the source code of this file.
Classes | |
struct | RREQ |
struct | rreq_record |
struct | blacklist |
Defines | |
#define | RREQ_JOIN 0x1 |
#define | RREQ_REPAIR 0x2 |
#define | RREQ_GRATUITOUS 0x4 |
#define | RREQ_DEST_ONLY 0x8 |
#define | RREQ_SIZE sizeof(RREQ) |
Functions | |
RREQ * | rreq_create (u_int8_t flags, struct in_addr dest_addr, u_int32_t dest_seqno, struct in_addr orig_addr) |
Route Request process hacked. | |
void | rreq_send (struct in_addr dest_addr, u_int32_t dest_seqno, int ttl, u_int8_t flags) |
void | rreq_forward (RREQ *rreq, int size, int ttl) |
void | rreq_process (RREQ *rreq, int rreqlen, struct in_addr ip_src, struct in_addr ip_dst, int ip_ttl, unsigned int ifindex) |
void | rreq_route_discovery (struct in_addr dest_addr, u_int8_t flags, struct ip_data *ipd) |
void | rreq_record_timeout (void *arg) |
struct blacklist * | rreq_blacklist_insert (struct in_addr dest_addr) |
void | rreq_blacklist_timeout (void *arg) |
void | rreq_local_repair (rt_table_t *rt, struct in_addr src_addr, struct ip_data *ipd) |
void | rreq_proactive (void *arg) |
#define RREQ_DEST_ONLY 0x8 |
Definition at line 46 of file NA_aodv_rreq.h.
#define RREQ_GRATUITOUS 0x4 |
Definition at line 45 of file NA_aodv_rreq.h.
#define RREQ_JOIN 0x1 |
Definition at line 43 of file NA_aodv_rreq.h.
#define RREQ_REPAIR 0x2 |
Definition at line 44 of file NA_aodv_rreq.h.
Definition at line 76 of file NA_aodv_rreq.h.
struct blacklist* rreq_blacklist_insert | ( | struct in_addr | dest_addr | ) | [read] |
Definition at line 1146 of file NA_aodv_rreq.cc.
{ struct blacklist *bl; /* First check if this rreq packet is already buffered */ bl = rreq_blacklist_find(dest_addr); /* If already buffered, should we update the timer??? */ if (bl) return bl; if ((bl = (struct blacklist *) malloc(sizeof(struct blacklist))) == NULL) { fprintf(stderr, "Malloc failed!!!\n"); exit(-1); } bl->dest_addr.s_addr = dest_addr.s_addr; timer_init(&bl->bl_timer, &NS_CLASS rreq_blacklist_timeout, bl); rreq_blacklist.insert(std::make_pair(dest_addr.s_addr,bl)); timer_set_timeout(&bl->bl_timer, BLACKLIST_TIMEOUT); return bl; }
void rreq_blacklist_timeout | ( | void * | arg | ) |
Definition at line 1181 of file NA_aodv_rreq.cc.
RREQ* rreq_create | ( | u_int8_t | flags, |
struct in_addr | dest_addr, | ||
u_int32_t | dest_seqno, | ||
struct in_addr | orig_addr | ||
) |
Route Request process hacked.
This class implement the code modifications for the specific implemented attacks. Each modification has a specific label (
Attacks implemented
Attack | Label | Implementation notes |
---|---|---|
Sinkhole | NA_SINKHOLE | Modified methods: rreq_process() |
Definition at line 112 of file NA_aodv_rreq.cc.
{ RREQ *rreq; #ifndef OMNETPP rreq = (RREQ *) aodv_socket_new_msg(); #else rreq = new RREQ(); rreq->cost=0; #endif rreq->type = AODV_RREQ; rreq->res1 = 0; rreq->res2 = 0; rreq->hcnt = 0; rreq->rreq_id = htonl(this_host.rreq_id++); rreq->dest_addr = dest_addr.s_addr; rreq->dest_seqno = htonl(dest_seqno); rreq->orig_addr = orig_addr.s_addr; /* Immediately before a node originates a RREQ flood it must increment its sequence number... */ seqno_incr(this_host.seqno); rreq->orig_seqno = htonl(this_host.seqno); if (flags & RREQ_JOIN) rreq->j = 1; if (flags & RREQ_REPAIR) rreq->r = 1; if (flags & RREQ_GRATUITOUS) rreq->g = 1; if (flags & RREQ_DEST_ONLY) rreq->d = 1; DEBUG(LOG_DEBUG, 0, "Assembled RREQ %s", ip_to_str(dest_addr)); #ifdef DEBUG_OUTPUT log_pkt_fields((AODV_msg *) rreq); #endif return rreq; }
void rreq_forward | ( | RREQ * | rreq, |
int | size, | ||
int | ttl | ||
) |
Definition at line 208 of file NA_aodv_rreq.cc.
{ struct in_addr dest, orig; int i; dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST)); orig.s_addr = rreq->orig_addr; /* FORWARD the RREQ if the TTL allows it. */ DEBUG(LOG_INFO, 0, "forwarding RREQ src=%s, rreq_id=%lu", ip_to_str(orig), ntohl(rreq->rreq_id)); /* Queue the received message in the send buffer */ #ifndef OMNETPP rreq = (RREQ *) aodv_socket_queue_msg((AODV_msg *) rreq, size); rreq->hcnt++; /* Increase hopcount to account for * intermediate route */ /* Send out on all interfaces */ for (i = 0; i < MAX_NR_INTERFACES; i++) { if (!DEV_NR(i).enabled) continue; aodv_socket_send((AODV_msg *) rreq, dest, size, ttl, &DEV_NR(i)); #else rreq->hcnt++; /* Increase hopcount to account for * intermediate route */ if (this->isStaticNode()) rreq->hopfix++; /* Send out on all interfaces */ double delay = -1; if (par("EqualDelay")) delay = par("broadcastDelay"); for (i = 0; i < MAX_NR_INTERFACES; i++) { if (!DEV_NR(i).enabled) continue; totalRreqSend++; RREQ * rreq_new = check_and_cast <RREQ*>(rreq->dup()); rreq_new->ttl=ttl; aodv_socket_send((AODV_msg *) rreq_new, dest, size, ttl, &DEV_NR(i),delay); #endif } }
void rreq_local_repair | ( | rt_table_t * | rt, |
struct in_addr | src_addr, | ||
struct ip_data * | ipd | ||
) |
Definition at line 897 of file NA_aodv_rreq.cc.
{ struct timeval now; seek_list_t *seek_entry; rt_table_t *src_entry; int ttl; u_int8_t flags = 0; if (!rt) return; if (seek_list_find(rt->dest_addr)) return; if (!(rt->flags & RT_REPAIR)) return; gettimeofday(&now, NULL); DEBUG(LOG_DEBUG, 0, "REPAIRING route to %s", ip_to_str(rt->dest_addr)); /* Caclulate the initial ttl to use for the RREQ. MIN_REPAIR_TTL mentioned in the draft is the last known hop count to the destination. */ src_entry = rt_table_find(src_addr); if (src_entry) ttl = max((int)rt->hcnt, (int)(0.5 * src_entry->hcnt)) + LOCAL_ADD_TTL; else ttl = rt->hcnt + LOCAL_ADD_TTL; DEBUG(LOG_DEBUG, 0, "%s, rreq ttl=%d, dest_hcnt=%d", ip_to_str(rt->dest_addr), ttl, rt->hcnt); /* Reset the timeout handler, was probably previously local_repair_timeout */ rt->rt_timer.handler = &NS_CLASS route_expire_timeout; #ifdef AODV_USE_STL if ((rt->rt_timer.timeout -simTime()) < (2 * NET_TRAVERSAL_TIME)) rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); #else if (timeval_diff(&rt->rt_timer.timeout, &now) < (2 * NET_TRAVERSAL_TIME)) rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); #endif rreq_send(rt->dest_addr, rt->dest_seqno, ttl, flags); /* Remember that we are seeking this destination and setup the timers */ seek_entry = seek_list_insert(rt->dest_addr, rt->dest_seqno, ttl, flags, ipd); if (expanding_ring_search) timer_set_timeout(&seek_entry->seek_timer, 2 * ttl * NODE_TRAVERSAL_TIME); else timer_set_timeout(&seek_entry->seek_timer, NET_TRAVERSAL_TIME); DEBUG(LOG_DEBUG, 0, "Seeking %s ttl=%d", ip_to_str(rt->dest_addr), ttl); return; }
void rreq_proactive | ( | void * | arg | ) |
Definition at line 964 of file NA_aodv_rreq.cc.
{ struct in_addr dest; if (!isRoot) return; if (this->isInMacLayer()) dest.s_addr= ManetAddress(MACAddress::BROADCAST_ADDRESS); else dest.s_addr= ManetAddress(IPv4Address::ALLONES_ADDRESS); rreq_send(dest,0,NET_DIAMETER, RREQ_DEST_ONLY); timer_set_timeout(&proactive_rreq_timer, proactive_rreq_timeout); }
void rreq_process | ( | RREQ * | rreq, |
int | rreqlen, | ||
struct in_addr | ip_src, | ||
struct in_addr | ip_dst, | ||
int | ip_ttl, | ||
unsigned int | ifindex | ||
) |
Definition at line 254 of file NA_aodv_rreq.cc.
{ AODV_ext *ext=NULL; RREP *rrep = NULL; int rrep_size = RREP_SIZE; rt_table_t *rev_rt=NULL, *fwd_rt = NULL; u_int32_t rreq_orig_seqno, rreq_dest_seqno; u_int32_t rreq_id, rreq_new_hcnt, life; unsigned int extlen = 0; struct in_addr rreq_dest, rreq_orig; unsigned int ifaddr; uint32_t cost; uint8_t hopfix; // BEGIN NA_SINKHOLE - sancale // Seqno sinkhole definition u_int32_t seqno_sinkhole; // END NA_SINKHOLE - sancale ManetAddress aux; if (getAp(rreq->dest_addr, aux) && !isBroadcast(rreq->dest_addr)) { rreq_dest.s_addr = aux; } else rreq_dest.s_addr = rreq->dest_addr; if (getAp(rreq->orig_addr, aux)) { rreq_orig.s_addr = aux; } else rreq_orig.s_addr = rreq->orig_addr; rreq_id = ntohl(rreq->rreq_id); rreq_dest_seqno = ntohl(rreq->dest_seqno); rreq_orig_seqno = ntohl(rreq->orig_seqno); rreq_new_hcnt = rreq->hcnt + 1; cost = rreq->cost; hopfix = rreq->hopfix; if (this->isStaticNode()) hopfix++; /* Ignore RREQ's that originated from this node. Either we do this or we buffer our own sent RREQ's as we do with others we receive. */ ifaddr = DEV_IFINDEX(ifindex).ipaddr.s_addr.getIPv4().getInt(); #ifndef OMNETPP if (rreq_orig.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr) return; #else if (isLocalAddress (rreq_orig.s_addr)) return; #endif DEBUG(LOG_DEBUG, 0, "ip_src=%s rreq_orig=%s rreq_dest=%s\n", ip_to_str(ip_src), ip_to_str(rreq_orig), ip_to_str(rreq_dest)); #ifdef OMNETPP totalRreqRec++; if (!ev.isDisabled()) ev.printf("ip_src=%s rreq_orig=%s rreq_dest=%s\n",ip_to_str(ip_src), ip_to_str(rreq_orig), ip_to_str(rreq_dest)); // BEGIN NA_SINKHOLE - sancale // If sinkhole does not know the route, update seqno to seqno_sinkhole and hop_count to 1. if (sinkholeAttackIsActive) { if ((sinkOnlyWhenRouteInTable == false) and (uniform(0, 1) < sinkholeAttackProbability)) { u_int32_t seqno_added = seqnoAdded->doubleValue(); int num_hops = numHops; seqno_sinkhole = rreq_dest_seqno + seqno_added; EV << "Sinkhole does not know the route but sends false RREP with seqnoAdded = " << seqno_added << " and numHops = " << num_hops << ".\n"; //IPv4Address node_address = IPvXAddressResolver().resolve("attacker").get4(); //EV << simTime() << "s: " << rreq->getName() << " received in " << node_address << " (" << getParentModule()->getFullName() << ") originated from " << ip_to_str(rreq_orig) << "\n"; /* The node always creates or updates a REVERSE ROUTE entry to the source of the RREQ. */ rev_rt = rt_table_find(rreq_orig); /* Calculate the extended minimal life time. */ life = PATH_DISCOVERY_TIME - 2 * rreq_new_hcnt * NODE_TRAVERSAL_TIME; if (rev_rt == NULL) { DEBUG(LOG_DEBUG, 0, "Creating REVERSE route entry, RREQ orig: %s", ip_to_str(rreq_orig)); rev_rt = rt_table_insert(rreq_orig, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, 0, ifindex,cost,hopfix); } else { if (!useHover && (rev_rt->dest_seqno == 0 || (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state == INVALID || rreq_new_hcnt < rev_rt->hcnt)))) { rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, rev_rt->flags,ifindex,cost,hopfix); } else if (useHover && (rev_rt->dest_seqno == 0 || (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state == INVALID || cost < rev_rt->cost)))) { rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, rev_rt->flags,ifindex,cost,hopfix); } } /**** END updating/creating REVERSE route ****/ /* Set the destination IP address in RREP (dest_addr) to the IP address of the destination for which a route is supplied (rreq_dest in RREQ). * Set the originator IP address in RREP (orig_addr) to the IP address of the node which originated the RREQ for which the route is supplied (rreq_orig in RREQ). */ rrep = rrep_create(0, 0, num_hops, rreq_dest, seqno_sinkhole, rreq_orig, ACTIVE_ROUTE_TIMEOUT); rrep_send(rrep, rev_rt, NULL, RREP_SIZE); return; } } // END NA_SINKHOLE - sancale #endif if (rreqlen < (int) RREQ_SIZE) { alog(LOG_WARNING, 0, __FUNCTION__, "IP data field too short (%u bytes)" "from %s to %s", rreqlen, ip_to_str(ip_src), ip_to_str(ip_dst)); return; } /* Check if the previous hop of the RREQ is in the blacklist set. If it is, then ignore the RREQ. */ if (rreq_blacklist_find(ip_src)) { DEBUG(LOG_DEBUG, 0, "prev hop of RREQ blacklisted, ignoring!"); #ifdef OMNETPP EV << "prev hop of RREQ blacklisted, ignoring!"; #endif return; } /* Ignore already processed RREQs. */ if (rreq_record_find(rreq_orig, rreq_id)) { life = PATH_DISCOVERY_TIME - 2 * rreq_new_hcnt * NODE_TRAVERSAL_TIME; #ifdef OMNETPP if (isBroadcast(rreq_dest.s_addr)) { rev_rt = rt_table_find(rreq_orig); if (rev_rt == NULL) { rev_rt = rt_table_insert(rreq_orig, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, 0, ifindex,cost,hopfix); // opp_error("reverse route NULL with RREQ in the processed table" ); } if (rev_rt->dest_seqno != 0) { if ((int32_t) rreq_orig_seqno < (int32_t) rev_rt->dest_seqno) return; if (!useHover && (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state != INVALID && rreq_new_hcnt >= rev_rt->hcnt))) return; if (useHover && (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state != INVALID && cost >= rev_rt->cost))) return; } } else #endif { rev_rt = rt_table_find(rreq_orig); if (rev_rt == NULL) { rev_rt = rt_table_insert(rreq_orig, ip_src, rreq_new_hcnt,rreq_orig_seqno, life, VALID, 0, ifindex,cost,hopfix); // opp_error("reverse route NULL with RREQ in the processed table" ); } if (useHover && (rev_rt->dest_seqno == 0 || (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state == INVALID || cost < rev_rt->cost)))) { life = PATH_DISCOVERY_TIME - 2 * rreq_new_hcnt * NODE_TRAVERSAL_TIME; rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, rev_rt->flags,ifindex,cost,hopfix); } return; } } /* Now buffer this RREQ so that we don't process a similar RREQ we get within PATH_DISCOVERY_TIME. */ rreq_record_insert(rreq_orig, rreq_id); /* Determine whether there are any RREQ extensions */ #ifndef OMNETPP ext = (AODV_ext *) ((char *) rreq + RREQ_SIZE); while ((rreqlen - extlen) > RREQ_SIZE) { #else ext = rreq->getFirstExtension(); for (int i=0; i<rreq->getNumExtension (); i++) { #endif switch (ext->type) { case RREQ_EXT: DEBUG(LOG_INFO, 0, "RREQ include EXTENSION"); /* Do something here */ break; default: alog(LOG_WARNING, 0, __FUNCTION__, "Unknown extension type %d", ext->type); break; } extlen += AODV_EXT_SIZE(ext); ext = AODV_EXT_NEXT(ext); } #ifdef DEBUG_OUTPUT log_pkt_fields((AODV_msg *) rreq); #endif /* The node always creates or updates a REVERSE ROUTE entry to the source of the RREQ. */ rev_rt = rt_table_find(rreq_orig); /* Calculate the extended minimal life time. */ life = PATH_DISCOVERY_TIME - 2 * rreq_new_hcnt * NODE_TRAVERSAL_TIME; if (rev_rt == NULL) { DEBUG(LOG_DEBUG, 0, "Creating REVERSE route entry, RREQ orig: %s", ip_to_str(rreq_orig)); rev_rt = rt_table_insert(rreq_orig, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, 0, ifindex,cost,hopfix); } else { if (!useHover && (rev_rt->dest_seqno == 0 || (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state == INVALID || rreq_new_hcnt < rev_rt->hcnt)))) { rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, rev_rt->flags,ifindex,cost,hopfix); } else if (useHover && (rev_rt->dest_seqno == 0 || (int32_t) rreq_orig_seqno > (int32_t) rev_rt->dest_seqno || (rreq_orig_seqno == rev_rt->dest_seqno && (rev_rt->state == INVALID || cost < rev_rt->cost)))) { rev_rt = rt_table_update(rev_rt, ip_src, rreq_new_hcnt, rreq_orig_seqno, life, VALID, rev_rt->flags,ifindex,cost,hopfix); } #ifdef DISABLED /* This is a out of draft modification of AODV-UU to prevent nodes from creating routing entries to themselves during the RREP phase. We simple drop the RREQ if there is a missmatch between the reverse path on the node and the one suggested by the RREQ. */ else if (rev_rt->next_hop.s_addr != ip_src.s_addr) { DEBUG(LOG_DEBUG, 0, "Dropping RREQ due to reverse route mismatch!"); return; } #endif } /**** END updating/creating REVERSE route ****/ #ifdef CONFIG_GATEWAY /* This is a gateway */ if (internet_gw_mode) { /* Subnet locality decision */ switch (locality(rreq_dest, ifindex)) { case HOST_ADHOC: break; case HOST_INET: /* We must increase the gw's sequence number before sending a RREP, * otherwise intermediate nodes will not forward the RREP. */ seqno_incr(this_host.seqno); rrep = rrep_create(0, 0, 0, DEV_IFINDEX(rev_rt->ifindex).ipaddr, this_host.seqno, rev_rt->dest_addr, ACTIVE_ROUTE_TIMEOUT); ext = rrep_add_ext(rrep, RREP_INET_DEST_EXT, rrep_size, sizeof(struct in_addr), (char *) &rreq_dest); rrep_size += AODV_EXT_SIZE(ext); DEBUG(LOG_DEBUG, 0, "Responding for INTERNET dest: %s rrep_size=%d", ip_to_str(rreq_dest), rrep_size); rrep_send(rrep, rev_rt, NULL, rrep_size); return; case HOST_UNKNOWN: default: DEBUG(LOG_DEBUG, 0, "GW: Destination unkown"); } } #endif #ifdef OMNETPP if (getIsGateway()) { /* Subnet locality decision */ // search address if (isAddressInProxyList(rreq_dest.s_addr)) { /* We must increase the gw's sequence number before sending a RREP, * otherwise intermediate nodes will not forward the RREP. */ seqno_incr(this_host.seqno); rrep = rrep_create(0, 0, 0, DEV_IFINDEX(rev_rt->ifindex).ipaddr, this_host.seqno, rev_rt->dest_addr, ACTIVE_ROUTE_TIMEOUT); ext = rrep_add_ext(rrep, RREP_INET_DEST_EXT, rrep_size, sizeof(struct in_addr), (char *) &rreq_dest); rrep_size += AODV_EXT_SIZE(ext); DEBUG(LOG_DEBUG, 0, "Responding for INTERNET dest: %s rrep_size=%d", ip_to_str(rreq_dest), rrep_size); rrep_send(rrep, rev_rt, NULL, rrep_size); return; } } #endif /* Are we the destination of the RREQ?, if so we should immediately send a RREP.. */ #ifndef OMNETPP if (rreq_dest.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr) { #else if (isLocalAddress (rreq_dest.s_addr)) { #endif /* WE are the RREQ DESTINATION. Update the node's own sequence number to the maximum of the current seqno and the one in the RREQ. */ if (rreq_dest_seqno != 0) { if ((int32_t) this_host.seqno < (int32_t) rreq_dest_seqno) this_host.seqno = rreq_dest_seqno; else if (this_host.seqno == rreq_dest_seqno) seqno_incr(this_host.seqno); } rrep = rrep_create(0, 0, 0, DEV_IFINDEX(rev_rt->ifindex).ipaddr, this_host.seqno, rev_rt->dest_addr, MY_ROUTE_TIMEOUT); #ifdef OMNETPP EV << " create a rrep" << ip_to_str(DEV_IFINDEX(rev_rt->ifindex).ipaddr) << "seq n" << this_host.seqno << " to " << ip_to_str(rev_rt->dest_addr); #endif rrep_send(rrep, rev_rt, NULL, RREP_SIZE); } else if (isBroadcast (rreq_dest.s_addr)) { if(!rreq->d) return; if (!propagateProactive) return; /* WE are the RREQ DESTINATION. Update the node's own sequence number to the maximum of the current seqno and the one in the RREQ. */ seqno_incr(this_host.seqno); rrep = rrep_create(0, 0, 0, DEV_IFINDEX(rev_rt->ifindex).ipaddr,this_host.seqno, rev_rt->dest_addr, MY_ROUTE_TIMEOUT); EV << " create a rrep" << ip_to_str(DEV_IFINDEX(rev_rt->ifindex).ipaddr) << "seq n" << this_host.seqno << " to " << ip_to_str(rev_rt->dest_addr); rrep_send(rrep, rev_rt, NULL, RREP_SIZE); if (ip_ttl > 0) { rreq_forward(rreq, rreqlen, ip_ttl); // the ttl is decremented for ip layer } else { DEBUG(LOG_DEBUG, 0, "RREQ not forwarded - ttl=0"); EV << "RREQ not forwarded - ttl=0"; } return; } else { /* We are an INTERMEDIATE node. - check if we have an active * route entry */ fwd_rt = rt_table_find(rreq_dest); // BEGIN NA_SINKHOLE - sancale // If sinkhole knows the route, update seqno to seqno_sinkhole and hop_count to 1. // If route exist and is valid. We do not care about the "only destination" flag in the RREQ. if (fwd_rt && (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL)){ /* Respond only if the sequence number is fresh enough... */ if ((fwd_rt->dest_seqno != 0 && (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno && (fwd_rt->hcnt>HCNT_LIMIT))|| fwd_rt->state==IMMORTAL) { if (sinkholeAttackIsActive) { if ((sinkOnlyWhenRouteInTable == true) and (uniform(0,1) < sinkholeAttackProbability)) { struct timeval now; u_int32_t lifetime; gettimeofday(&now, NULL); if (fwd_rt->state == IMMORTAL) lifetime = 10000; else { #ifdef AODV_USE_STL double val = SIMTIME_DBL(fwd_rt->rt_timer.timeout - simTime()); lifetime = (val * 1000.0); #else lifetime = timeval_diff(&fwd_rt->rt_timer.timeout, &now); #endif } u_int32_t seqno_added = seqnoAdded->doubleValue(); int num_hops = numHops; seqno_sinkhole = rreq_dest_seqno + seqno_added; rrep = rrep_create(0, 0, num_hops, fwd_rt->dest_addr, seqno_sinkhole, rev_rt->dest_addr, lifetime); rrep_send(rrep, rev_rt, fwd_rt, rrep_size); EV << "Sinkhole knows the route and sends false RREP with seqnoAdded = " << seqno_added << " and numHops = " << num_hops << ".\n"; return; } } } } // END NA_SINKHOLE - sancale if (fwd_rt && (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL) && !rreq->d) { struct timeval now; u_int32_t lifetime; /* GENERATE RREP, i.e we have an ACTIVE route entry that is fresh enough (our destination sequence number for that route is larger than the one in the RREQ). */ gettimeofday(&now, NULL); #ifdef CONFIG_GATEWAY_DISABLED if (fwd_rt->flags & RT_INET_DEST) { rt_table_t *gw_rt; /* This node knows that this is a rreq for an Internet * destination and it has a valid route to the gateway */ goto forward; // DISABLED gw_rt = rt_table_find(fwd_rt->next_hop); if (!gw_rt || gw_rt->state == INVALID) goto forward; lifetime = timeval_diff(&gw_rt->rt_timer.timeout, &now); rrep = rrep_create(0, 0, gw_rt->hcnt, gw_rt->dest_addr, gw_rt->dest_seqno, rev_rt->dest_addr, lifetime); ext = rrep_add_ext(rrep, RREP_INET_DEST_EXT, rrep_size, sizeof(struct in_addr), (char *) &rreq_dest); rrep_size += AODV_EXT_SIZE(ext); DEBUG(LOG_DEBUG, 0, "Intermediate node response for INTERNET dest: %s rrep_size=%d", ip_to_str(rreq_dest), rrep_size); rrep_send(rrep, rev_rt, gw_rt, rrep_size); return; } #endif /* CONFIG_GATEWAY_DISABLED */ /* Respond only if the sequence number is fresh enough... */ // if ((fwd_rt->dest_seqno != 0 && // (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno && // (fwd_rt->hcnt>HCNT_LIMIT || (fwd_rt->hcnt==HCNT_LIMIT && uniform(0, 1)>0.8 ))) || fwd_rt->state==IMMORTAL) { if ((fwd_rt->dest_seqno != 0 && (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno && (fwd_rt->hcnt>HCNT_LIMIT))|| fwd_rt->state==IMMORTAL) { // if (fwd_rt->dest_seqno != 0 && // (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno) { #ifdef AODV_USE_STL if (fwd_rt->state==IMMORTAL) lifetime = 10000; else { double val = SIMTIME_DBL(fwd_rt->rt_timer.timeout - simTime()); lifetime = (val * 1000.0); } #else if (fwd_rt->state==IMMORTAL) lifetime = 10000; else lifetime = timeval_diff(&fwd_rt->rt_timer.timeout, &now); #endif rrep = rrep_create(0, 0, fwd_rt->hcnt, fwd_rt->dest_addr, fwd_rt->dest_seqno, rev_rt->dest_addr, lifetime); rrep_send(rrep, rev_rt, fwd_rt, rrep_size); /* If the GRATUITOUS flag is set, we must also unicast a gratuitous RREP to the destination. */ if (rreq->g) { rrep = rrep_create(0, 0, rev_rt->hcnt, rev_rt->dest_addr, rev_rt->dest_seqno, fwd_rt->dest_addr, lifetime); rrep_send(rrep, fwd_rt, rev_rt, RREP_SIZE); DEBUG(LOG_INFO, 0, "Sending G-RREP to %s with rte to %s", ip_to_str(rreq_dest), ip_to_str(rreq_orig)); } return; } /* else { goto forward; } // If the GRATUITOUS flag is set, we must also unicast a // gratuitous RREP to the destination. if (rreq->g) { rrep = rrep_create(0, 0, rev_rt->hcnt, rev_rt->dest_addr, rev_rt->dest_seqno, fwd_rt->dest_addr, lifetime); rrep_send(rrep, fwd_rt, rev_rt, RREP_SIZE); DEBUG(LOG_INFO, 0, "Sending G-RREP to %s with rte to %s", ip_to_str(rreq_dest), ip_to_str(rreq_orig)); } return; */ } forward: #ifndef OMNETPP if (ip_ttl > 1) #else if (ip_ttl > 0) #endif { /* Update the sequence number in case the maintained one is larger */ if (fwd_rt && (fwd_rt->state == VALID || fwd_rt->state == IMMORTAL) && !rreq->d&& 0!=HCNT_LIMIT) { if (fwd_rt->dest_seqno != 0 && (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno && fwd_rt->hcnt==HCNT_LIMIT) ip_ttl = HCNT_LIMIT; } if (fwd_rt && !(fwd_rt->flags & RT_INET_DEST) && (int32_t) fwd_rt->dest_seqno > (int32_t) rreq_dest_seqno) rreq->dest_seqno = htonl(fwd_rt->dest_seqno); #ifndef OMNETPP rreq_forward(rreq, rreqlen, --ip_ttl); #else rreq_forward(rreq, rreqlen, ip_ttl); // the ttl is decremented for ip layer #endif } else { DEBUG(LOG_DEBUG, 0, "RREQ not forwarded - ttl=0"); #ifdef OMNETPP EV << "RREQ not forwarded - ttl=0"; #endif } } }
void rreq_record_timeout | ( | void * | arg | ) |
Definition at line 1130 of file NA_aodv_rreq.cc.
{ struct rreq_record *rec = (struct rreq_record *) arg; for (RreqRecords::iterator it = rreq_records.begin();it!=rreq_records.end();it++) { struct rreq_record *recAux = *it; if (rec == recAux) { rreq_records.erase(it); break; } } free(rec); }
void rreq_route_discovery | ( | struct in_addr | dest_addr, |
u_int8_t | flags, | ||
struct ip_data * | ipd | ||
) |
Definition at line 828 of file NA_aodv_rreq.cc.
{ struct timeval now; rt_table_t *rt; seek_list_t *seek_entry; u_int32_t dest_seqno; int ttl; #define TTL_VALUE ttl gettimeofday(&now, NULL); if (seek_list_find(dest_addr)) return; /* If we already have a route entry, we use information from it. */ rt = rt_table_find(dest_addr); ttl = NET_DIAMETER; /* This is the TTL if we don't use expanding ring search */ if (!rt) { dest_seqno = 0; if (expanding_ring_search) ttl = TTL_START; } else { dest_seqno = rt->dest_seqno; if (expanding_ring_search) { ttl = rt->hcnt + TTL_INCREMENT; } /* if (rt->flags & RT_INET_DEST) */ /* flags |= RREQ_DEST_ONLY; */ /* A routing table entry waiting for a RREP should not be expunged before 2 * NET_TRAVERSAL_TIME... */ #ifdef AODV_USE_STL if ((rt->rt_timer.timeout - simTime()) < (2 * NET_TRAVERSAL_TIME)) rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); #else if (timeval_diff(&rt->rt_timer.timeout, &now) < (2 * NET_TRAVERSAL_TIME)) rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); #endif } rreq_send(dest_addr, dest_seqno, ttl, flags); /* Remember that we are seeking this destination */ seek_entry = seek_list_insert(dest_addr, dest_seqno, ttl, flags, ipd); /* Set a timer for this RREQ */ if (expanding_ring_search) timer_set_timeout(&seek_entry->seek_timer, RING_TRAVERSAL_TIME); else timer_set_timeout(&seek_entry->seek_timer, NET_TRAVERSAL_TIME); DEBUG(LOG_DEBUG, 0, "Seeking %s ttl=%d", ip_to_str(dest_addr), ttl); return; }
void rreq_send | ( | struct in_addr | dest_addr, |
u_int32_t | dest_seqno, | ||
int | ttl, | ||
u_int8_t | flags | ||
) |
Definition at line 173 of file NA_aodv_rreq.cc.
{ RREQ *rreq; struct in_addr dest; int i; dest.s_addr = ManetAddress(IPv4Address(AODV_BROADCAST)); /* Check if we should force the gratuitous flag... (-g option). */ if (rreq_gratuitous) flags |= RREQ_GRATUITOUS; /* Broadcast on all interfaces */ #ifdef OMNETPP double delay = -1; if (par("EqualDelay")) delay = par("broadcastDelay"); #endif for (i = 0; i < MAX_NR_INTERFACES; i++) { if (!DEV_NR(i).enabled) continue; rreq = rreq_create(flags, dest_addr, dest_seqno, DEV_NR(i).ipaddr); #ifdef OMNETPP rreq->ttl = ttl; aodv_socket_send((AODV_msg *) rreq, dest, RREQ_SIZE, 1, &DEV_NR(i),delay); totalRreqSend++; #else aodv_socket_send((AODV_msg *) rreq, dest, RREQ_SIZE, 1, &DEV_NR(i)); #endif } }