0% found this document useful (0 votes)
53 views

Implementation Coding of Jamming Attack in MANET

This document contains code for implementing a jamming attack in a mobile ad hoc network (MANET) using the AODV routing protocol. It includes code for starting and stopping hello message transmissions, generating random jitter for hello timers, sending hello messages, processing received hello messages, and creating route reply (RREP) and acknowledgement (ACK) messages. The code handles neighbor detection, bidirectional link determination, and updating routing table entries based on hello messages.

Uploaded by

Nancy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
53 views

Implementation Coding of Jamming Attack in MANET

This document contains code for implementing a jamming attack in a mobile ad hoc network (MANET) using the AODV routing protocol. It includes code for starting and stopping hello message transmissions, generating random jitter for hello timers, sending hello messages, processing received hello messages, and creating route reply (RREP) and acknowledgement (ACK) messages. The code handles neighbor detection, bidirectional link determination, and updating routing table entries based on hello messages.

Uploaded by

Nancy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

Appendix A

Implementation Coding of Jamming Attack in MANET


#include "aodv_hello.h"
#include "aodv_timeout.h"
#include "aodv_rrep.h"
#include "aodv_rreq.h"
#include "routing_table.h"
#include "timer_queue.h"
#include "params.h"
#include "aodv_socket.h"
#include "defs.h"
#include "debug.h"

extern int unidir_hack, receive_n_hellos, hello_jittering, optimized_hellos;


static struct timer hello_timer;

#endif
long NS_CLASS hello_jitter()
{
if (hello_jittering) {
#ifdef NS_PORT
return (long) (((float) Random::integer(RAND_MAX + 1) / RAND_MAX - 0.5)
* JITTER_INTERVAL);
#else
return (long) (((float) random() / RAND_MAX - 0.5) * JITTER_INTERVAL);
#endif
} else
return 0;
}

void NS_CLASS hello_start()


{
if (hello_timer.used)
return;

gettimeofday(&this_host.fwd_time, NULL);

DEBUG(LOG_DEBUG, 0, "Starting to send HELLOs!");


timer_init(&hello_timer, &NS_CLASS hello_send, NULL);

hello_send(NULL);
}

void NS_CLASS hello_stop()


{
DEBUG(LOG_DEBUG, 0,
"No active forwarding routes - stopped sending HELLOs!");
timer_remove(&hello_timer);
}

void NS_CLASS hello_send(void *arg)


{
RREP *rrep;

Https://WWW.ThesisScientist.com
AODV_ext *ext = NULL;
u_int8_t flags = 0;
struct in_addr dest;
long time_diff, jitter;
struct timeval now;
int msg_size = RREP_SIZE;
int i;

gettimeofday(&now, NULL);

if (optimized_hellos &&
timeval_diff(&now, &this_host.fwd_time) > ACTIVE_ROUTE_TIMEOUT) {
hello_stop();
return;
}

time_diff = timeval_diff(&now, &this_host.bcast_time);


jitter = hello_jitter();

if (time_diff >= HELLO_INTERVAL) {

for (i = 0; i < MAX_NR_INTERFACES; i++) {


if (!DEV_NR(i).enabled)
continue;
#ifdef DEBUG_HELLO
DEBUG(LOG_DEBUG, 0, "sending Hello to 255.255.255.255");
#endif
rrep = rrep_create(flags, 0, 0, DEV_NR(i).ipaddr,
this_host.seqno,
DEV_NR(i).ipaddr,
ALLOWED_HELLO_LOSS * HELLO_INTERVAL);

/* Assemble a RREP extension which contain our neighbor set... */


if (unidir_hack) {
int i;

if (ext)
ext = AODV_EXT_NEXT(ext);
else
ext = (AODV_ext *) ((char *) rrep + RREP_SIZE);

ext->type = RREP_HELLO_NEIGHBOR_SET_EXT;
ext->length = 0;

for (i = 0; i < RT_TABLESIZE; i++) {


list_t *pos;
list_foreach(pos, &rt_tbl.tbl[i]) {
rt_table_t *rt = (rt_table_t *) pos;

if (rt->hello_timer.used) {
#ifdef DEBUG_HELLO
DEBUG(LOG_INFO, 0,
"Adding %s to hello neighbor set ext",
ip_to_str(rt->dest_addr));
#endif

Https://WWW.ThesisScientist.com
memcpy(AODV_EXT_DATA(ext), &rt->dest_addr,
sizeof(struct in_addr));
ext->length += sizeof(struct in_addr);
}
}
}
if (ext->length)
msg_size = RREP_SIZE + AODV_EXT_SIZE(ext);
}
dest.s_addr = AODV_BROADCAST;
aodv_socket_send((AODV_msg *) rrep, dest, msg_size, 1, &DEV_NR(i));
}

timer_set_timeout(&hello_timer, HELLO_INTERVAL + jitter);


} else {
if (HELLO_INTERVAL - time_diff + jitter < 0)
timer_set_timeout(&hello_timer,
HELLO_INTERVAL - time_diff - jitter);
else
timer_set_timeout(&hello_timer,
HELLO_INTERVAL - time_diff + jitter);
}
}

/* Process a hello message */


void NS_CLASS hello_process(RREP * hello, int rreplen, unsigned int ifindex)
{
u_int32_t hello_seqno, timeout, hello_interval = HELLO_INTERVAL;
u_int8_t state, flags = 0;
struct in_addr ext_neighbor, hello_dest;
rt_table_t *rt;
AODV_ext *ext = NULL;
int i;
struct timeval now;

gettimeofday(&now, NULL);

hello_dest.s_addr = hello->dest_addr;
hello_seqno = ntohl(hello->dest_seqno);

rt = rt_table_find(hello_dest);

if (rt)
flags = rt->flags;

if (unidir_hack)
flags |= RT_UNIDIR;

/* Check for hello interval extension: */


ext = (AODV_ext *) ((char *) hello + RREP_SIZE);

while (rreplen > (int) RREP_SIZE) {


switch (ext->type) {
case RREP_HELLO_INTERVAL_EXT:
if (ext->length == 4) {

Https://WWW.ThesisScientist.com
memcpy(&hello_interval, AODV_EXT_DATA(ext), 4);
hello_interval = ntohl(hello_interval);
#ifdef DEBUG_HELLO
DEBUG(LOG_INFO, 0, "Hello extension interval=%lu!",
hello_interval);
#endif

} else
alog(LOG_WARNING, 0,
__FUNCTION__, "Bad hello interval extension!");
break;
case RREP_HELLO_NEIGHBOR_SET_EXT:

#ifdef DEBUG_HELLO
DEBUG(LOG_INFO, 0, "RREP_HELLO_NEIGHBOR_SET_EXT");
#endif
for (i = 0; i < ext->length; i = i + 4) {
ext_neighbor.s_addr =
*(in_addr_t *) ((char *) AODV_EXT_DATA(ext) + i);

if (ext_neighbor.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr)
flags &= ~RT_UNIDIR;
}
break;
default:
alog(LOG_WARNING, 0, __FUNCTION__,
"Bad extension!! type=%d, length=%d", ext->type, ext->length);
ext = NULL;
break;
}
if (ext == NULL)
break;

rreplen -= AODV_EXT_SIZE(ext);
ext = AODV_EXT_NEXT(ext);
}

#ifdef DEBUG_HELLO
DEBUG(LOG_DEBUG, 0, "rcvd HELLO from %s, seqno %lu",
ip_to_str(hello_dest), hello_seqno);
#endif
/* This neighbor should only be valid after receiving 3
consecutive hello messages... */
if (receive_n_hellos)
state = INVALID;
else
state = VALID;

timeout = ALLOWED_HELLO_LOSS * hello_interval + ROUTE_TIMEOUT_SLACK;

if (!rt) {

rt = rt_table_insert(hello_dest, hello_dest, 1,
hello_seqno, timeout, state, flags, ifindex);

Https://WWW.ThesisScientist.com
if (flags & RT_UNIDIR) {
DEBUG(LOG_INFO, 0, "%s new NEIGHBOR, link UNI-DIR",
ip_to_str(rt->dest_addr));
} else {
DEBUG(LOG_INFO, 0, "%s new NEIGHBOR!", ip_to_str(rt->dest_addr));
}
rt->hello_cnt = 1;

} else {

if ((flags & RT_UNIDIR) && rt->state == VALID && rt->hcnt > 1) {


goto hello_update;
}

if (receive_n_hellos && rt->hello_cnt < (receive_n_hellos - 1)) {


if (timeval_diff(&now, &rt->last_hello_time) <
(long) (hello_interval + hello_interval / 2))
rt->hello_cnt++;
else
rt->hello_cnt = 1;

memcpy(&rt->last_hello_time, &now, sizeof(struct timeval));


return;
}
rt_table_update(rt, hello_dest, 1, hello_seqno, timeout, VALID, flags);
}

hello_update:

hello_update_timeout(rt, &now, ALLOWED_HELLO_LOSS * hello_interval);


return;
}

#define HELLO_DELAY 50 /* The extra time we should allow an hello


message to take (due to processing) before
assuming lost . */

NS_INLINE void NS_CLASS hello_update_timeout(rt_table_t * rt,


struct timeval *now, long time)
{
timer_set_timeout(&rt->hello_timer, time + HELLO_DELAY);
memcpy(&rt->last_hello_time, now, sizeof(struct timeval));
}

extern int unidir_hack, optimized_hellos, llfeedback;

#endif

RREP *NS_CLASS rrep_create(u_int8_t flags,


u_int8_t prefix,
u_int8_t hcnt,
struct in_addr dest_addr,
u_int32_t dest_seqno,
struct in_addr orig_addr, u_int32_t life)

Https://WWW.ThesisScientist.com
{
RREP *rrep;

rrep = (RREP *) aodv_socket_new_msg();


rrep->type = AODV_RREP;
rrep->res1 = 0;
rrep->res2 = 0;
rrep->prefix = prefix;
rrep->hcnt = hcnt;
rrep->dest_addr = dest_addr.s_addr;
rrep->dest_seqno = htonl(dest_seqno);
rrep->orig_addr = orig_addr.s_addr;
rrep->lifetime = htonl(life);

if (flags & RREP_REPAIR)


rrep->r = 1;
if (flags & RREP_ACK)
rrep->a = 1;

/* Don't print information about hello messages... */


#ifdef DEBUG_OUTPUT
if (rrep->dest_addr != rrep->orig_addr) {
DEBUG(LOG_DEBUG, 0, "Assembled RREP:");
log_pkt_fields((AODV_msg *) rrep);
}
#endif

return rrep;
}

RREP_ack *NS_CLASS rrep_ack_create()


{
RREP_ack *rrep_ack;

rrep_ack = (RREP_ack *) aodv_socket_new_msg();


rrep_ack->type = AODV_RREP_ACK;

DEBUG(LOG_DEBUG, 0, "Assembled RREP_ack");

return rrep_ack;
}

void NS_CLASS rrep_ack_process(RREP_ack * rrep_ack, int rrep_acklen,


struct in_addr ip_src, struct in_addr ip_dst)
{
rt_table_t *rt;

rt = rt_table_find(ip_src);

if (rt == NULL) {
DEBUG(LOG_WARNING, 0, "No RREP_ACK expected for %s", ip_to_str(ip_src));

return;
}
DEBUG(LOG_DEBUG, 0, "Received RREP_ACK from %s", ip_to_str(ip_src));

Https://WWW.ThesisScientist.com
/* Remove unexpired timer for this RREP_ACK */
timer_remove(&rt->ack_timer);
}

AODV_ext *NS_CLASS rrep_add_ext(RREP * rrep, int type, unsigned int offset,


int len, char *data)
{
AODV_ext *ext = NULL;

if (offset < RREP_SIZE)


return NULL;

ext = (AODV_ext *) ((char *) rrep + offset);

ext->type = type;
ext->length = len;

memcpy(AODV_EXT_DATA(ext), data, len);

return ext;
}

void NS_CLASS rrep_send(RREP * rrep, rt_table_t * rev_rt,


rt_table_t * fwd_rt, int size)
{
u_int8_t rrep_flags = 0;
struct in_addr dest;

if (!rev_rt) {
DEBUG(LOG_WARNING, 0, "Can't send RREP, rev_rt = NULL!");
return;
}

dest.s_addr = rrep->dest_addr;

/* Check if we should request a RREP-ACK */


if ((rev_rt->state == VALID && rev_rt->flags & RT_UNIDIR) ||
(rev_rt->hcnt == 1 && unidir_hack)) {
rt_table_t *neighbor = rt_table_find(rev_rt->next_hop);

if (neighbor && neighbor->state == VALID && !neighbor->ack_timer.used) {

rrep_flags |= RREP_ACK;
neighbor->flags |= RT_UNIDIR;

timer_remove(&neighbor->hello_timer);
neighbor_link_break(neighbor);

DEBUG(LOG_DEBUG, 0, "Link to %s is unidirectional!",


ip_to_str(neighbor->dest_addr));

timer_set_timeout(&neighbor->ack_timer, NEXT_HOP_WAIT);
}
}

Https://WWW.ThesisScientist.com
DEBUG(LOG_DEBUG, 0, "Sending RREP to next hop %s about %s->%s",
ip_to_str(rev_rt->next_hop), ip_to_str(rev_rt->dest_addr),
ip_to_str(dest));

aodv_socket_send((AODV_msg *) rrep, rev_rt->next_hop, size, MAXTTL,


&DEV_IFINDEX(rev_rt->ifindex));

/* Update precursor lists */


if (fwd_rt) {
precursor_add(fwd_rt, rev_rt->next_hop);
precursor_add(rev_rt, fwd_rt->next_hop);
}

if (!llfeedback && optimized_hellos)


hello_start();
}

void NS_CLASS rrep_forward(RREP * rrep, int size, rt_table_t * rev_rt,


rt_table_t * fwd_rt, int ttl)
{
/* Sanity checks... */
if (!fwd_rt || !rev_rt) {
DEBUG(LOG_WARNING, 0, "Could not forward RREP because of NULL route!");
return;
}

if (!rrep) {
DEBUG(LOG_WARNING, 0, "No RREP to forward!");
return;
}

DEBUG(LOG_DEBUG, 0, "Forwarding RREP to %s", ip_to_str(rev_rt->next_hop));

rt_table_t *neighbor;

if (rev_rt->dest_addr.s_addr != rev_rt->next_hop.s_addr)
neighbor = rt_table_find(rev_rt->next_hop);
else
neighbor = rev_rt;

if (neighbor && !neighbor->ack_timer.used) {

rrep->a = 1;
neighbor->flags |= RT_UNIDIR;

timer_set_timeout(&neighbor->ack_timer, NEXT_HOP_WAIT);
}
}

rrep = (RREP *) aodv_socket_queue_msg((AODV_msg *) rrep, size);


rrep->hcnt = fwd_rt->hcnt; /* Update the hopcount */

aodv_socket_send((AODV_msg *) rrep, rev_rt->next_hop, size, ttl,


&DEV_IFINDEX(rev_rt->ifindex));

Https://WWW.ThesisScientist.com
precursor_add(fwd_rt, rev_rt->next_hop);
precursor_add(rev_rt, fwd_rt->next_hop);

rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);
}

void NS_CLASS rrep_process(RREP * rrep, int rreplen, struct in_addr ip_src,


struct in_addr ip_dst, int ip_ttl,
unsigned int ifindex)
{
u_int32_t rrep_lifetime, rrep_seqno, rrep_new_hcnt;
u_int8_t pre_repair_hcnt = 0, pre_repair_flags = 0;
rt_table_t *fwd_rt, *rev_rt;
AODV_ext *ext;
unsigned int extlen = 0;
int rt_flags = 0;
struct in_addr rrep_dest, rrep_orig;
#ifdef CONFIG_GATEWAY
struct in_addr inet_dest_addr;
int inet_rrep = 0;
#endif

/* Convert to correct byte order on affeected fields: */


rrep_dest.s_addr = rrep->dest_addr;
rrep_orig.s_addr = rrep->orig_addr;
rrep_seqno = ntohl(rrep->dest_seqno);
rrep_lifetime = ntohl(rrep->lifetime);
/* Increment RREP hop count to account for intermediate node... */
rrep_new_hcnt = rrep->hcnt + 1;

if (rreplen < (int) RREP_SIZE) {


alog(LOG_WARNING, 0, __FUNCTION__,
"IP data field too short (%u bytes)"
" from %s to %s", rreplen, ip_to_str(ip_src), ip_to_str(ip_dst));
return;
}

/* Ignore messages which aim to a create a route to one self */


if (rrep_dest.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr)
return;

DEBUG(LOG_DEBUG, 0, "from %s about %s->%s",


ip_to_str(ip_src), ip_to_str(rrep_orig), ip_to_str(rrep_dest));
#ifdef DEBUG_OUTPUT
log_pkt_fields((AODV_msg *) rrep);
#endif

/* Determine whether there are any extensions */


ext = (AODV_ext *) ((char *) rrep + RREP_SIZE);

while ((rreplen - extlen) > RREP_SIZE) {


switch (ext->type) {
case RREP_EXT:
DEBUG(LOG_INFO, 0, "RREP include EXTENSION");

Https://WWW.ThesisScientist.com
/* Do something here */
break;
#ifdef CONFIG_GATEWAY
case RREP_INET_DEST_EXT:
if (ext->length == sizeof(u_int32_t)) {

memcpy(&inet_dest_addr, AODV_EXT_DATA(ext), ext->length);

DEBUG(LOG_DEBUG, 0, "RREP_INET_DEST_EXT: <%s>",


ip_to_str(inet_dest_addr));
/* This was a RREP from a gateway */
rt_flags |= RT_GATEWAY;
inet_rrep = 1;
break;
}
#endif
default:
alog(LOG_WARNING, 0, __FUNCTION__, "Unknown or bad extension %d",
ext->type);
break;
}
extlen += AODV_EXT_SIZE(ext);
ext = AODV_EXT_NEXT(ext);
}

fwd_rt = rt_table_find(rrep_dest);
rev_rt = rt_table_find(rrep_orig);

if (!fwd_rt) {
/* We didn't have an existing entry, so we insert a new one. */
fwd_rt = rt_table_insert(rrep_dest, ip_src, rrep_new_hcnt, rrep_seqno,
rrep_lifetime, VALID, rt_flags, ifindex);
} else if (fwd_rt->dest_seqno == 0 ||
(int32_t) rrep_seqno > (int32_t) fwd_rt->dest_seqno ||
(rrep_seqno == fwd_rt->dest_seqno &&
(fwd_rt->state == INVALID || fwd_rt->flags & RT_UNIDIR ||
rrep_new_hcnt < fwd_rt->hcnt))) {
pre_repair_hcnt = fwd_rt->hcnt;
pre_repair_flags = fwd_rt->flags;

fwd_rt = rt_table_update(fwd_rt, ip_src, rrep_new_hcnt, rrep_seqno,


rrep_lifetime, VALID,
rt_flags | fwd_rt->flags);
} else {
if (fwd_rt->hcnt > 1) {
DEBUG(LOG_DEBUG, 0,
"Dropping RREP, fwd_rt->hcnt=%d fwd_rt->seqno=%ld",
fwd_rt->hcnt, fwd_rt->dest_seqno);
}
return;
}

RREP_ack *rrep_ack;

rrep_ack = rrep_ack_create();

Https://WWW.ThesisScientist.com
aodv_socket_send((AODV_msg *) rrep_ack, fwd_rt->next_hop,
NEXT_HOP_WAIT, MAXTTL, &DEV_IFINDEX(fwd_rt->ifindex));
/* Remove RREP_ACK flag... */
rrep->a = 0;
}

if (rrep_orig.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr) {
#ifdef CONFIG_GATEWAY
if (inet_rrep) {
rt_table_t *inet_rt;
inet_rt = rt_table_find(inet_dest_addr);

if (!inet_rt)
rt_table_insert(inet_dest_addr, rrep_dest, rrep_new_hcnt, 0,
rrep_lifetime, VALID, RT_INET_DEST, ifindex);
else if (inet_rt->state == INVALID || rrep_new_hcnt < inet_rt->hcnt) {
rt_table_update(inet_rt, rrep_dest, rrep_new_hcnt, 0,
rrep_lifetime, VALID, RT_INET_DEST |
inet_rt->flags);
} else {
DEBUG(LOG_DEBUG, 0, "INET Response, but no update %s",
ip_to_str(inet_dest_addr));
}
}
#endif
if (pre_repair_flags & RT_REPAIR) {
if (fwd_rt->hcnt > pre_repair_hcnt) {
RERR *rerr;
u_int8_t rerr_flags = 0;
struct in_addr dest;

dest.s_addr = AODV_BROADCAST;

rerr_flags |= RERR_NODELETE;
rerr = rerr_create(rerr_flags, fwd_rt->dest_addr,
fwd_rt->dest_seqno);

if (fwd_rt->nprec)
aodv_socket_send((AODV_msg *) rerr, dest,
RERR_CALC_SIZE(rerr), 1,
&DEV_IFINDEX(fwd_rt->ifindex));
}
}
} else {
if (rev_rt && rev_rt->state == VALID) {
rrep_forward(rrep, rreplen, rev_rt, fwd_rt, --ip_ttl);
} else {
DEBUG(LOG_DEBUG, 0, "Could not forward RREP - NO ROUTE!!!");
}
}

if (!llfeedback && optimized_hellos)


hello_start();
}

Https://WWW.ThesisScientist.com
int rrep_add_hello_ext(RREP * rrep, int offset, u_int32_t interval)
{
AODV_ext *ext;

ext = (AODV_ext *) ((char *) rrep + RREP_SIZE + offset);


ext->type = RREP_HELLO_INTERVAL_EXT;
ext->length = sizeof(interval);
memcpy(AODV_EXT_DATA(ext), &interval, sizeof(interval));

return (offset + AODV_EXT_SIZE(ext));


}

endif /* NS_PORT */

#ifndef NS_PORT
#define SO_RECVBUF_SIZE 256*1024

static char recv_buf[RECV_BUF_SIZE];


static char send_buf[SEND_BUF_SIZE];

extern int wait_on_reboot, hello_qual_threshold, ratelimit;

static void aodv_socket_read(int fd);

static struct cmsghdr *__cmsg_nxthdr_fix(void *__ctl, size_t __size,


struct cmsghdr *__cmsg)
{
struct cmsghdr *__ptr;

__ptr = (struct cmsghdr *) (((unsigned char *) __cmsg) +


CMSG_ALIGN(__cmsg->cmsg_len));
if ((unsigned long) ((char *) (__ptr + 1) - (char *) __ctl) > __size)
return NULL;

return __ptr;
}

struct cmsghdr *cmsg_nxthdr_fix(struct msghdr *__msg, struct cmsghdr *__cmsg)


{
return __cmsg_nxthdr_fix(__msg->msg_control, __msg->msg_controllen, __cmsg);
}

#endif /* NS_PORT */

void NS_CLASS aodv_socket_init()


{
#ifndef NS_PORT
struct sockaddr_in aodv_addr;
struct ifreq ifr;
int i, retval = 0;
int on = 1;
int tos = IPTOS_LOWDELAY;
int bufsize = SO_RECVBUF_SIZE;
socklen_t optlen = sizeof(bufsize);

Https://WWW.ThesisScientist.com
/* Create a UDP socket */

if (this_host.nif == 0) {
fprintf(stderr, "No interfaces configured\n");
exit(-1);
}

/* Open a socket for every AODV enabled interface */


for (i = 0; i < MAX_NR_INTERFACES; i++) {
if (!DEV_NR(i).enabled)
continue;

/* AODV socket */
DEV_NR(i).sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (DEV_NR(i).sock < 0) {
perror("");
exit(-1);
}
#ifdef CONFIG_GATEWAY
/* Data packet send socket */
DEV_NR(i).psock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);

if (DEV_NR(i).psock < 0) {
perror("");
exit(-1);
}
#endif
/* Bind the socket to the AODV port number */
memset(&aodv_addr, 0, sizeof(aodv_addr));
aodv_addr.sin_family = AF_INET;
aodv_addr.sin_port = htons(AODV_PORT);
aodv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

retval = bind(DEV_NR(i).sock, (struct sockaddr *) &aodv_addr,


sizeof(struct sockaddr));

if (retval < 0) {
perror("Bind failed ");
exit(-1);
}
if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_BROADCAST,
&on, sizeof(int)) < 0) {
perror("SO_BROADCAST failed ");
exit(-1);
}

memset(&ifr, 0, sizeof(struct ifreq));


strcpy(ifr.ifr_name, DEV_NR(i).ifname);

if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_BINDTODEVICE,


&ifr, sizeof(ifr)) < 0) {
fprintf(stderr, "SO_BINDTODEVICE failed for %s", DEV_NR(i).ifname);
perror(" ");
exit(-1);
}

Https://WWW.ThesisScientist.com
if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_PRIORITY,
&tos, sizeof(int)) < 0) {
perror("Setsockopt SO_PRIORITY failed ");
exit(-1);
}

if (setsockopt(DEV_NR(i).sock, SOL_IP, IP_RECVTTL,


&on, sizeof(int)) < 0) {
perror("Setsockopt IP_RECVTTL failed ");
exit(-1);
}

if (setsockopt(DEV_NR(i).sock, SOL_IP, IP_PKTINFO,


&on, sizeof(int)) < 0) {
perror("Setsockopt IP_PKTINFO failed ");
exit(-1);
}
#ifdef CONFIG_GATEWAY
if (setsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_BINDTODEVICE,
&ifr, sizeof(ifr)) < 0) {
fprintf(stderr, "SO_BINDTODEVICE failed for %s", DEV_NR(i).ifname);
perror(" ");
exit(-1);
}

bufsize = 4 * 65535;

if (setsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_SNDBUF,


(char *) &bufsize, optlen) < 0) {
DEBUG(LOG_NOTICE, 0, "Could not set send socket buffer size");
}
if (getsockopt(DEV_NR(i).psock, SOL_SOCKET, SO_SNDBUF,
(char *) &bufsize, &optlen) == 0) {
alog(LOG_NOTICE, 0, __FUNCTION__,
"RAW send socket buffer size set to %d", bufsize);
}
#endif
/* Set max allowable receive buffer size... */
for (;; bufsize -= 1024) {
if (setsockopt(DEV_NR(i).sock, SOL_SOCKET, SO_RCVBUF,
(char *) &bufsize, optlen) == 0) {
alog(LOG_NOTICE, 0, __FUNCTION__,
"Receive buffer size set to %d", bufsize);
break;
}
if (bufsize < RECV_BUF_SIZE) {
alog(LOG_ERR, 0, __FUNCTION__,
"Could not set receive buffer size");
exit(-1);
}
}

retval = attach_callback_func(DEV_NR(i).sock, aodv_socket_read);

if (retval < 0) {

Https://WWW.ThesisScientist.com
perror("register input handler failed ");
exit(-1);
}
}
#endif /* NS_PORT */

num_rreq = 0;
num_rerr = 0;
}

void NS_CLASS aodv_socket_process_packet(AODV_msg * aodv_msg, int len,


struct in_addr src,
struct in_addr dst,
int ttl, unsigned int ifindex)
{

/* If this was a HELLO message... Process as HELLO. */


if ((aodv_msg->type == AODV_RREP && ttl == 1 &&
dst.s_addr == AODV_BROADCAST)) {
hello_process((RREP *) aodv_msg, len, ifindex);
return;
}

/* Make sure we add/update neighbors */


neighbor_add(aodv_msg, src, ifindex);

switch (aodv_msg->type) {

case AODV_RREQ:
rreq_process((RREQ *) aodv_msg, len, src, dst, ttl, ifindex);
break;
case AODV_RREP:
DEBUG(LOG_DEBUG, 0, "Received RREP");
rrep_process((RREP *) aodv_msg, len, src, dst, ttl, ifindex);
break;
case AODV_RERR:
DEBUG(LOG_DEBUG, 0, "Received RERR");
rerr_process((RERR *) aodv_msg, len, src, dst);
break;
case AODV_RREP_ACK:
DEBUG(LOG_DEBUG, 0, "Received RREP_ACK");
rrep_ack_process((RREP_ack *) aodv_msg, len, src, dst);
break;
default:
alog(LOG_WARNING, 0, __FUNCTION__,
"Unknown msg type %u rcvd from %s to %s", aodv_msg->type,
ip_to_str(src), ip_to_str(dst));
}
}

#ifdef NS_PORT
void NS_CLASS recvAODVUUPacket(Packet * p)
{
int len, i, ttl = 0;
struct in_addr src, dst;
struct hdr_cmn *ch = HDR_CMN(p);

Https://WWW.ThesisScientist.com
struct hdr_ip *ih = HDR_IP(p);
hdr_aodvuu *ah = HDR_AODVUU(p);

src.s_addr = ih->saddr();
dst.s_addr = ih->daddr();
len = ch->size() - IP_HDR_LEN;
ttl = ih->ttl();

AODV_msg *aodv_msg = (AODV_msg *) recv_buf;

/* Only handle AODVUU packets */


assert(ch->ptype() == PT_AODVUU);

/* Only process incoming packets */


assert(ch->direction() == hdr_cmn::UP);

/* Copy message to receive buffer */


memcpy(recv_buf, ah, RECV_BUF_SIZE);

/* Deallocate packet, we have the information we need... */


Packet::free(p);

/* Ignore messages generated locally */


for (i = 0; i < MAX_NR_INTERFACES; i++)
if (this_host.devs[i].enabled &&
memcmp(&src, &this_host.devs[i].ipaddr,
sizeof(struct in_addr)) == 0)
return;

aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, NS_IFINDEX);


}
#else
static void aodv_socket_read(int fd)
{
struct in_addr src, dst;
int i, len, ttl = -1;
AODV_msg *aodv_msg;
struct dev_info *dev;
struct msghdr msgh;
struct cmsghdr *cmsg;
struct iovec iov;
char ctrlbuf[CMSG_SPACE(sizeof(int)) +
CMSG_SPACE(sizeof(struct in_pktinfo))];
struct sockaddr_in src_addr;

dst.s_addr = -1;

iov.iov_base = recv_buf;
iov.iov_len = RECV_BUF_SIZE;
msgh.msg_name = &src_addr;
msgh.msg_namelen = sizeof(src_addr);
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
msgh.msg_control = ctrlbuf;
msgh.msg_controllen = sizeof(ctrlbuf);

Https://WWW.ThesisScientist.com
len = recvmsg(fd, &msgh, 0);

if (len < 0) {
alog(LOG_WARNING, 0, __FUNCTION__, "receive ERROR len=%d!", len);
return;
}

src.s_addr = src_addr.sin_addr.s_addr;

/* Get the ttl and destination address from the control message */
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
cmsg = CMSG_NXTHDR_FIX(&msgh, cmsg)) {
if (cmsg->cmsg_level == SOL_IP) {
switch (cmsg->cmsg_type) {
case IP_TTL:
ttl = *(CMSG_DATA(cmsg));
break;
case IP_PKTINFO:
{
struct in_pktinfo *pi = (struct in_pktinfo *)CMSG_DATA(cmsg);
dst.s_addr = pi->ipi_addr.s_addr;
}
}
}
}

if (ttl < 0) {
DEBUG(LOG_DEBUG, 0, "No TTL, packet ignored!");
return;
}

/* Ignore messages generated locally */


for (i = 0; i < MAX_NR_INTERFACES; i++)
if (this_host.devs[i].enabled &&
memcmp(&src, &this_host.devs[i].ipaddr,
sizeof(struct in_addr)) == 0)
return;

aodv_msg = (AODV_msg *) recv_buf;

dev = devfromsock(fd);

if (!dev) {
DEBUG(LOG_ERR, 0, "Could not get device info!\n");
return;
}

aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, dev->ifindex);


}
#endif /* NS_PORT */

void NS_CLASS aodv_socket_send(AODV_msg * aodv_msg, struct in_addr dst,


int len, u_int8_t ttl, struct dev_info *dev)
{
int retval = 0;
struct timeval now;

Https://WWW.ThesisScientist.com
/* Rate limit stuff: */

#ifndef NS_PORT

struct sockaddr_in dst_addr;

if (wait_on_reboot && aodv_msg->type == AODV_RREP)


return;

memset(&dst_addr, 0, sizeof(dst_addr));
dst_addr.sin_family = AF_INET;
dst_addr.sin_addr = dst;
dst_addr.sin_port = htons(AODV_PORT);

/* Set ttl */
if (setsockopt(dev->sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) {
alog(LOG_WARNING, 0, __FUNCTION__, "ERROR setting ttl!");
return;
}
#else

Packet *p = allocpkt();
struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);
hdr_aodvuu *ah = HDR_AODVUU(p);

// Clear AODVUU part of packet


memset(ah, '\0', ah->size());

// Copy message contents into packet


memcpy(ah, aodv_msg, len);

// Set common header fields


ch->ptype() = PT_AODVUU;
ch->direction() = hdr_cmn::DOWN;
ch->size() += len + IP_HDR_LEN;
ch->iface() = -2;
ch->error() = 0;
ch->prev_hop_ = (nsaddr_t) dev->ipaddr.s_addr;

// Set IP header fields


ih->saddr() = (nsaddr_t) dev->ipaddr.s_addr;
ih->daddr() = (nsaddr_t) dst.s_addr;
ih->ttl() = ttl;

// Note: Port number for routing agents, not AODV port number!
ih->sport() = RT_PORT;
ih->dport() = RT_PORT;

// Fake success
retval = len;
#endif
gettimeofday(&now, NULL);

switch (aodv_msg->type) {
case AODV_RREQ:

Https://WWW.ThesisScientist.com
if (num_rreq == (RREQ_RATELIMIT - 1)) {
if (timeval_diff(&now, &rreq_ratel[0]) < 1000) {
DEBUG(LOG_DEBUG, 0, "RATELIMIT: Dropping RREQ %ld ms",
timeval_diff(&now, &rreq_ratel[0]));
#ifdef NS_PORT
Packet::free(p);
#endif
return;
} else {
memmove(rreq_ratel, &rreq_ratel[1],
sizeof(struct timeval) * (num_rreq - 1));
memcpy(&rreq_ratel[num_rreq - 1], &now,
sizeof(struct timeval));
}
} else {
memcpy(&rreq_ratel[num_rreq], &now, sizeof(struct timeval));
num_rreq++;
}
break;
case AODV_RERR:
if (num_rerr == (RERR_RATELIMIT - 1)) {
if (timeval_diff(&now, &rerr_ratel[0]) < 1000) {
DEBUG(LOG_DEBUG, 0, "RATELIMIT: Dropping RERR %ld ms",
timeval_diff(&now, &rerr_ratel[0]));
#ifdef NS_PORT
Packet::free(p);
#endif
return;
} else {
memmove(rerr_ratel, &rerr_ratel[1],
sizeof(struct timeval) * (num_rerr - 1));
memcpy(&rerr_ratel[num_rerr - 1], &now,
sizeof(struct timeval));
}
} else {
memcpy(&rerr_ratel[num_rerr], &now, sizeof(struct timeval));
num_rerr++;
}
break;
}
}

if (dst.s_addr == AODV_BROADCAST) {

gettimeofday(&this_host.bcast_time, NULL);

#ifdef NS_PORT
ch->addr_type() = NS_AF_NONE;

sendPacket(p, dst, 0.0);


#else

retval = sendto(dev->sock, send_buf, len, 0,


(struct sockaddr *) &dst_addr, sizeof(dst_addr));

if (retval < 0) {

Https://WWW.ThesisScientist.com
alog(LOG_WARNING, errno, __FUNCTION__, "Failed send to bc %s",
ip_to_str(dst));
return;
}
#endif

} else {

#ifdef NS_PORT
ch->addr_type() = NS_AF_INET;
/* We trust the decision of next hop for all AODV messages... */

if (dst.s_addr == AODV_BROADCAST)
sendPacket(p, dst, 0.001 * Random::uniform());
else
sendPacket(p, dst, 0.0);
#else
retval = sendto(dev->sock, send_buf, len, 0,
(struct sockaddr *) &dst_addr, sizeof(dst_addr));

if (retval < 0) {
alog(LOG_WARNING, errno, __FUNCTION__, "Failed send to %s",
ip_to_str(dst));
return;
}
#endif
}

/* Do not print hello msgs... */


if (!(aodv_msg->type == AODV_RREP && (dst.s_addr == AODV_BROADCAST)))
DEBUG(LOG_INFO, 0, "AODV msg to %s ttl=%d size=%u",
ip_to_str(dst), ttl, retval, len);

return;
}

AODV_msg *NS_CLASS aodv_socket_new_msg(void)


{
memset(send_buf, '\0', SEND_BUF_SIZE);
return (AODV_msg *) (send_buf);
}

AODV_msg *NS_CLASS aodv_socket_queue_msg(AODV_msg * aodv_msg, int size)


{
memcpy((char *) send_buf, aodv_msg, size);
return (AODV_msg *) send_buf;
}

void aodv_socket_cleanup(void)
{
#ifndef NS_PORT
int i;

for (i = 0; i < MAX_NR_INTERFACES; i++) {


if (!DEV_NR(i).enabled)

Https://WWW.ThesisScientist.com
continue;
close(DEV_NR(i).sock);
}
#endif /* NS_PORT */
}

oid NS_CLASS rt_table_init()


{
int i;

rt_tbl.num_entries = 0;
rt_tbl.num_active = 0;

/* We do a for loop here... NS does not like us to use memset() */


for (i = 0; i < RT_TABLESIZE; i++) {
INIT_LIST_HEAD(&rt_tbl.tbl[i]);
}
}

void NS_CLASS rt_table_destroy()


{
int i;
list_t *tmp = NULL, *pos = NULL;

for (i = 0; i < RT_TABLESIZE; i++) {


list_foreach_safe(pos, tmp, &rt_tbl.tbl[i]) {
rt_table_t *rt = (rt_table_t *) pos;

rt_table_delete(rt);
}
}
}

/* Calculate a hash value and table index given a key... */


unsigned int hashing(struct in_addr *addr, hash_value * hash)
{
/* *hash = (*addr & 0x7fffffff); */
*hash = (hash_value) addr->s_addr;

return (*hash & RT_TABLEMASK);


}

rt_table_t *NS_CLASS rt_table_insert(struct in_addr dest_addr,


struct in_addr next,
u_int8_t hops, u_int32_t seqno,
u_int32_t life, u_int8_t state,
u_int16_t flags, unsigned int ifindex)
{
hash_value hash;
unsigned int index;
list_t *pos;
rt_table_t *rt;
struct in_addr nm;
nm.s_addr = 0;

/* Calculate hash key */

Https://WWW.ThesisScientist.com
index = hashing(&dest_addr, &hash);

/* Check if we already have an entry for dest_addr */


list_foreach(pos, &rt_tbl.tbl[index]) {
rt = (rt_table_t *) pos;
if (memcmp(&rt->dest_addr, &dest_addr, sizeof(struct in_addr))
== 0) {
DEBUG(LOG_INFO, 0, "%s already exist in routing table!",
ip_to_str(dest_addr));

return NULL;
}
}

if ((rt = (rt_table_t *) malloc(sizeof(rt_table_t))) == NULL) {


fprintf(stderr, "Malloc failed!\n");
exit(-1);
}

memset(rt, 0, sizeof(rt_table_t));

rt->dest_addr = dest_addr;
rt->next_hop = next;
rt->dest_seqno = seqno;
rt->flags = flags;
rt->hcnt = hops;
rt->ifindex = ifindex;
rt->hash = hash;
rt->state = state;

timer_init(&rt->rt_timer, &NS_CLASS route_expire_timeout, rt);

timer_init(&rt->ack_timer, &NS_CLASS rrep_ack_timeout, rt);

timer_init(&rt->hello_timer, &NS_CLASS hello_timeout, rt);

rt->last_hello_time.tv_sec = 0;
rt->last_hello_time.tv_usec = 0;
rt->hello_cnt = 0;

rt->nprec = 0;
INIT_LIST_HEAD(&rt->precursors);

/* Insert first in bucket... */

rt_tbl.num_entries++;

DEBUG(LOG_INFO, 0, "Inserting %s (bucket %d) next hop %s",


ip_to_str(dest_addr), index, ip_to_str(next));

list_add(&rt_tbl.tbl[index], &rt->l);

if (state == INVALID) {

if (flags & RT_REPAIR) {


rt->rt_timer.handler = &NS_CLASS local_repair_timeout;

Https://WWW.ThesisScientist.com
life = ACTIVE_ROUTE_TIMEOUT;
} else {
rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
life = DELETE_PERIOD;
}

} else {
rt_tbl.num_active++;
#ifndef NS_PORT
nl_send_add_route_msg(dest_addr, next, hops, life, flags,
ifindex);
#endif
}

#ifdef CONFIG_GATEWAY_DISABLE
if (rt->flags & RT_GATEWAY)
rt_table_update_inet_rt(rt, life);
#endif

//#ifdef NS_PORT
DEBUG(LOG_INFO, 0, "New timer for %s, life=%d",
ip_to_str(rt->dest_addr), life);

if (life != 0)
timer_set_timeout(&rt->rt_timer, life);
//#endif
/* In case there are buffered packets for this destination, we
* send them on the new route. */
if (rt->state == VALID && seek_list_remove(seek_list_find(dest_addr))) {
#ifdef NS_PORT
if (rt->flags & RT_INET_DEST)
packet_queue_set_verdict(dest_addr, PQ_ENC_SEND);
else
packet_queue_set_verdict(dest_addr, PQ_SEND);
#endif
}
return rt;
}

rt_table_t *NS_CLASS rt_table_update(rt_table_t * rt, struct in_addr next,


u_int8_t hops, u_int32_t seqno,
u_int32_t lifetime, u_int8_t state,
u_int16_t flags)
{
struct in_addr nm;
nm.s_addr = 0;

if (rt->state == INVALID && state == VALID) {

rt_tbl.num_active++;

if (rt->flags & RT_REPAIR)


flags &= ~RT_REPAIR;

#ifndef NS_PORT

Https://WWW.ThesisScientist.com
nl_send_add_route_msg(rt->dest_addr, next, hops, lifetime,
flags, rt->ifindex);
#endif

} else if (rt->next_hop.s_addr != 0 &&


rt->next_hop.s_addr != next.s_addr) {

DEBUG(LOG_INFO, 0, "rt->next_hop=%s, new_next_hop=%s",


ip_to_str(rt->next_hop), ip_to_str(next));

#ifndef NS_PORT
nl_send_add_route_msg(rt->dest_addr, next, hops, lifetime,
flags, rt->ifindex);
#endif
}

if (hops > 1 && rt->hcnt == 1) {


rt->last_hello_time.tv_sec = 0;
rt->last_hello_time.tv_usec = 0;
rt->hello_cnt = 0;
timer_remove(&rt->hello_timer);

neighbor_link_break(rt);
}

rt->flags = flags;
rt->dest_seqno = seqno;
rt->next_hop = next;
rt->hcnt = hops;

#ifdef CONFIG_GATEWAY
if (rt->flags & RT_GATEWAY)
rt_table_update_inet_rt(rt, lifetime);
#endif

//#ifdef NS_PORT
rt->rt_timer.handler = &NS_CLASS route_expire_timeout;

if (!(rt->flags & RT_INET_DEST))


rt_table_update_timeout(rt, lifetime);
//#endif

/* Finally, mark as VALID */


rt->state = state;

if (rt->state == VALID
&& seek_list_remove(seek_list_find(rt->dest_addr))) {
#ifdef NS_PORT
if (rt->flags & RT_INET_DEST)
packet_queue_set_verdict(rt->dest_addr, PQ_ENC_SEND);
else
packet_queue_set_verdict(rt->dest_addr, PQ_SEND);
#endif
}
return rt;

Https://WWW.ThesisScientist.com
}

NS_INLINE rt_table_t *NS_CLASS rt_table_update_timeout(rt_table_t * rt,


u_int32_t lifetime)
{
struct timeval new_timeout;

if (!rt)
return NULL;

if (rt->state == VALID) {

gettimeofday(&new_timeout, NULL);
timeval_add_msec(&new_timeout, lifetime);

if (timeval_diff(&rt->rt_timer.timeout, &new_timeout) < 0)


timer_set_timeout(&rt->rt_timer, lifetime);
} else
timer_set_timeout(&rt->rt_timer, lifetime);

return rt;
}

/* Update route timeouts in response to an incoming or outgoing data packet. */


void NS_CLASS rt_table_update_route_timeouts(rt_table_t * fwd_rt,
rt_table_t * rev_rt)
{
rt_table_t *next_hop_rt = NULL;

if (fwd_rt && fwd_rt->state == VALID) {

if (llfeedback || fwd_rt->flags & RT_INET_DEST ||


fwd_rt->hcnt != 1 || fwd_rt->hello_timer.used)
rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);

next_hop_rt = rt_table_find(fwd_rt->next_hop);

if (next_hop_rt && next_hop_rt->state == VALID &&


next_hop_rt->dest_addr.s_addr != fwd_rt->dest_addr.s_addr &&
(llfeedback || fwd_rt->hello_timer.used))
rt_table_update_timeout(next_hop_rt,
ACTIVE_ROUTE_TIMEOUT);

if (rev_rt && rev_rt->state == VALID) {

if (llfeedback || rev_rt->hcnt != 1 || rev_rt->hello_timer.used)


rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);

next_hop_rt = rt_table_find(rev_rt->next_hop);

if (next_hop_rt && next_hop_rt->state == VALID && rev_rt &&


next_hop_rt->dest_addr.s_addr != rev_rt->dest_addr.s_addr &&

Https://WWW.ThesisScientist.com
(llfeedback || rev_rt->hello_timer.used))
rt_table_update_timeout(next_hop_rt,
ACTIVE_ROUTE_TIMEOUT);

rt_table_t *NS_CLASS rt_table_find(struct in_addr dest_addr)


{
hash_value hash;
unsigned int index;
list_t *pos;

if (rt_tbl.num_entries == 0)
return NULL;

/* Calculate index */
index = hashing(&dest_addr, &hash);

/* Handle collisions: */
list_foreach(pos, &rt_tbl.tbl[index]) {
rt_table_t *rt = (rt_table_t *) pos;

if (rt->hash != hash)
continue;

if (memcmp(&dest_addr, &rt->dest_addr, sizeof(struct in_addr))


== 0)
return rt;

}
return NULL;
}

rt_table_t *NS_CLASS rt_table_find_gateway()


{
rt_table_t *gw = NULL;
int i;

for (i = 0; i < RT_TABLESIZE; i++) {


list_t *pos;
list_foreach(pos, &rt_tbl.tbl[i]) {
rt_table_t *rt = (rt_table_t *) pos;

if (rt->flags & RT_GATEWAY && rt->state == VALID) {


if (!gw || rt->hcnt < gw->hcnt)
gw = rt;
}
}
}
return gw;
}

#ifdef CONFIG_GATEWAY
int NS_CLASS rt_table_update_inet_rt(rt_table_t * gw, u_int32_t life)
{
int n = 0;

Https://WWW.ThesisScientist.com
int i;

if (!gw)
return -1;

for (i = 0; i < RT_TABLESIZE; i++) {


list_t *pos;
list_foreach(pos, &rt_tbl.tbl[i]) {
rt_table_t *rt = (rt_table_t *) pos;

if (rt->flags & RT_INET_DEST && rt->state == VALID) {


rt_table_update(rt, gw->dest_addr, gw->hcnt, 0,
life, VALID, rt->flags);
n++;
}
}
}
return n;
}
#endif /* CONFIG_GATEWAY_DISABLED */

/* Route expiry and Deletion. */


int NS_CLASS rt_table_invalidate(rt_table_t * rt)
{
struct timeval now;

gettimeofday(&now, NULL);

if (rt == NULL)
return -1;

/* If the route is already invalidated, do nothing... */


if (rt->state == INVALID) {
DEBUG(LOG_DEBUG, 0, "Route %s already invalidated!!!",
ip_to_str(rt->dest_addr));
return -1;
}

if (rt->hello_timer.used) {
DEBUG(LOG_DEBUG, 0, "last HELLO: %ld",
timeval_diff(&now, &rt->last_hello_time));
}

/* Remove any pending, but now obsolete timers. */


timer_remove(&rt->rt_timer);
timer_remove(&rt->hello_timer);
timer_remove(&rt->ack_timer);

/* Mark the route as invalid */


rt->state = INVALID;
rt_tbl.num_active--;

rt->hello_cnt = 0;

/* When the lifetime of a route entry expires, increase the sequence


number for that entry. */

Https://WWW.ThesisScientist.com
seqno_incr(rt->dest_seqno);

rt->last_hello_time.tv_sec = 0;
rt->last_hello_time.tv_usec = 0;

#ifndef NS_PORT
nl_send_del_route_msg(rt->dest_addr, rt->next_hop, rt->hcnt);
#endif

#ifdef CONFIG_GATEWAY

if (rt->flags & RT_GATEWAY) {


int i;

rt_table_t *gw = rt_table_find_gateway();

for (i = 0; i < RT_TABLESIZE; i++) {


list_t *pos;
list_foreach(pos, &rt_tbl.tbl[i]) {
rt_table_t *rt2 = (rt_table_t *) pos;

if (rt2->state == VALID
&& (rt2->flags & RT_INET_DEST)
&& (rt2->next_hop.s_addr ==
rt->dest_addr.s_addr)) {
if (0) {
DEBUG(LOG_DEBUG, 0,
"Invalidated GW %s but found new GW %s for
%s",
ip_to_str(rt->dest_addr),
ip_to_str(gw->dest_addr),
ip_to_str(rt2->
dest_addr));
rt_table_update(rt2,
gw->dest_addr,
gw->hcnt, 0,
timeval_diff
(&rt->rt_timer.
timeout, &now),
VALID,
rt2->flags);
} else {
rt_table_invalidate(rt2);
precursor_list_destroy(rt2);
}
}
}
}
}
#endif

if (rt->flags & RT_REPAIR) {


/* Set a timeout for the repair */

rt->rt_timer.handler = &NS_CLASS local_repair_timeout;

Https://WWW.ThesisScientist.com
timer_set_timeout(&rt->rt_timer, ACTIVE_ROUTE_TIMEOUT);

DEBUG(LOG_DEBUG, 0, "%s kept for repairs during %u msecs",


ip_to_str(rt->dest_addr), ACTIVE_ROUTE_TIMEOUT);
} else {

/* Schedule a deletion timer */


rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
timer_set_timeout(&rt->rt_timer, DELETE_PERIOD);

DEBUG(LOG_DEBUG, 0, "%s removed in %u msecs",


ip_to_str(rt->dest_addr), DELETE_PERIOD);
}

return 0;
}

void NS_CLASS rt_table_delete(rt_table_t * rt)


{
if (!rt) {
DEBUG(LOG_ERR, 0, "No route entry to delete");
return;
}

list_detach(&rt->l);

precursor_list_destroy(rt);

if (rt->state == VALID) {

#ifndef NS_PORT
nl_send_del_route_msg(rt->dest_addr, rt->next_hop, rt->hcnt);
#endif
rt_tbl.num_active--;
}
/* Make sure timers are removed... */
timer_remove(&rt->rt_timer);
timer_remove(&rt->hello_timer);
timer_remove(&rt->ack_timer);

rt_tbl.num_entries--;

free(rt);
return;
}

void NS_CLASS precursor_add(rt_table_t * rt, struct in_addr addr)


{
precursor_t *pr;
list_t *pos;

/* Sanity check */
if (!rt)
return;

list_foreach(pos, &rt->precursors) {

Https://WWW.ThesisScientist.com
pr = (precursor_t *) pos;

if (pr->neighbor.s_addr == addr.s_addr)
return;
}

if ((pr = (precursor_t *) malloc(sizeof(precursor_t))) == NULL) {


perror("Could not allocate memory for precursor node!!\n");
exit(-1);
}

DEBUG(LOG_INFO, 0, "Adding precursor %s to rte %s",


ip_to_str(addr), ip_to_str(rt->dest_addr));

pr->neighbor.s_addr = addr.s_addr;

/* Insert in precursors list */

list_add(&rt->precursors, &pr->l);
rt->nprec++;

return;
}

void NS_CLASS precursor_remove(rt_table_t * rt, struct in_addr addr)


{
list_t *pos;

/* Sanity check */
if (!rt)
return;

list_foreach(pos, &rt->precursors) {
precursor_t *pr = (precursor_t *) pos;
if (pr->neighbor.s_addr == addr.s_addr) {
DEBUG(LOG_INFO, 0, "Removing precursor %s from rte %s",
ip_to_str(addr), ip_to_str(rt->dest_addr));

list_detach(pos);
rt->nprec--;
free(pr);
return;
}
}
}

void precursor_list_destroy(rt_table_t * rt)


{
list_t *pos, *tmp;

/* Sanity check */
if (!rt)
return;

list_foreach_safe(pos, tmp, &rt->precursors) {


precursor_t *pr = (precursor_t *) pos;

Https://WWW.ThesisScientist.com
list_detach(pos);
rt->nprec--;
free(pr);
}
}

Https://WWW.ThesisScientist.com

You might also like