|
NETWORK ATTACKS FRAMEWORK
1.0.0
A NETwork Attacks framework. Making network attacks impact evaluation easier!
|
Go to the source code of this file.
Defines | |
| #define | NS_PORT |
| #define | OMNETPP |
| #define | MAX_SEQ 4294967295 |
| #define | HCNT_LIMIT 0 |
| #define | TTL_VALUE ttl |
Functions | |
| RREQ *NS_CLASS | 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. | |
| AODV_ext * | rreq_add_ext (RREQ *rreq, int type, unsigned int offset, int len, char *data) |
| void NS_CLASS | rreq_send (struct in_addr dest_addr, u_int32_t dest_seqno, int ttl, u_int8_t flags) |
| void NS_CLASS | rreq_forward (RREQ *rreq, int size, int ttl) |
| void NS_CLASS | rreq_process (RREQ *rreq, int rreqlen, struct in_addr ip_src, struct in_addr ip_dst, int ip_ttl, unsigned int ifindex) |
| void NS_CLASS | rreq_route_discovery (struct in_addr dest_addr, u_int8_t flags, struct ip_data *ipd) |
| void NS_CLASS | rreq_local_repair (rt_table_t *rt, struct in_addr src_addr, struct ip_data *ipd) |
| void NS_CLASS | rreq_proactive (void *arg) |
| NS_STATIC struct rreq_record *NS_CLASS | rreq_record_insert (struct in_addr orig_addr, u_int32_t rreq_id) |
| NS_STATIC struct rreq_record *NS_CLASS | rreq_record_find (struct in_addr orig_addr, u_int32_t rreq_id) |
| void NS_CLASS | rreq_record_timeout (void *arg) |
| struct blacklist *NS_CLASS | rreq_blacklist_insert (struct in_addr dest_addr) |
| struct blacklist *NS_CLASS | rreq_blacklist_find (struct in_addr dest_addr) |
| void NS_CLASS | rreq_blacklist_timeout (void *arg) |
| #define HCNT_LIMIT 0 |
Definition at line 70 of file NA_aodv_rreq.cc.
| #define MAX_SEQ 4294967295 |
Definition at line 64 of file NA_aodv_rreq.cc.
| #define NS_PORT |
Definition at line 34 of file NA_aodv_rreq.cc.
| #define OMNETPP |
Definition at line 35 of file NA_aodv_rreq.cc.
| #define TTL_VALUE ttl |
| AODV_ext* rreq_add_ext | ( | RREQ * | rreq, |
| int | type, | ||
| unsigned int | offset, | ||
| int | len, | ||
| char * | data | ||
| ) |
Definition at line 153 of file NA_aodv_rreq.cc.
{
AODV_ext *ext = NULL;
#ifndef OMNETPP
if (offset < RREQ_SIZE)
return NULL;
ext = (AODV_ext *) ((char *) rreq + offset);
ext->type = type;
ext->length = len;
memcpy(AODV_EXT_DATA(ext), data, len);
#else
ext = rreq->addExtension(type,len,data);
#endif
return ext;
}
| struct blacklist* NS_CLASS rreq_blacklist_find | ( | struct in_addr | dest_addr | ) | [read] |
Definition at line 1173 of file NA_aodv_rreq.cc.
{
RreqBlacklist::iterator it = rreq_blacklist.find(dest_addr.s_addr);
if (it != rreq_blacklist.end())
return it->second;
return NULL;
}
| struct blacklist* NS_CLASS 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 NS_CLASS rreq_blacklist_timeout | ( | void * | arg | ) |
Definition at line 1181 of file NA_aodv_rreq.cc.
| RREQ* NS_CLASS 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 NS_CLASS 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 NS_CLASS 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 NS_CLASS 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 NS_CLASS 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
}
}
}
| NS_STATIC struct rreq_record* NS_CLASS rreq_record_find | ( | struct in_addr | orig_addr, |
| u_int32_t | rreq_id | ||
| ) | [read] |
Definition at line 1117 of file NA_aodv_rreq.cc.
{
for (unsigned int i = 0 ; i < rreq_records.size();i++)
{
struct rreq_record *rec = rreq_records[i];
if (rec->orig_addr.s_addr == orig_addr.s_addr &&
(rec->rreq_id == rreq_id))
return rec;
}
return NULL;
}
| NS_STATIC struct rreq_record* NS_CLASS rreq_record_insert | ( | struct in_addr | orig_addr, |
| u_int32_t | rreq_id | ||
| ) | [read] |
Definition at line 1085 of file NA_aodv_rreq.cc.
{
struct rreq_record *rec;
/* First check if this rreq packet is already buffered */
rec = rreq_record_find(orig_addr, rreq_id);
/* If already buffered, should we update the timer??? */
if (rec)
return rec;
if ((rec =
(struct rreq_record *) malloc(sizeof(struct rreq_record))) == NULL)
{
fprintf(stderr, "Malloc failed!!!\n");
exit(-1);
}
rec->orig_addr = orig_addr;
rec->rreq_id = rreq_id;
timer_init(&rec->rec_timer, &NS_CLASS rreq_record_timeout, rec);
rreq_records.push_back(rec);
DEBUG(LOG_INFO, 0, "Buffering RREQ %s rreq_id=%lu time=%u",
ip_to_str(orig_addr), rreq_id, PATH_DISCOVERY_TIME);
timer_set_timeout(&rec->rec_timer, PATH_DISCOVERY_TIME);
return rec;
}
| void NS_CLASS 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 NS_CLASS 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;
}
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
}
}