SlideShare a Scribd company logo
1 of 31
Download to read offline
More Info Https://ThesisScientist.com
Appendix A
Implementation Coding of AODV
#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;
More Info Https://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
More Info Https://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) {
More Info Https://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);
More Info Https://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)
More Info Https://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));
More Info Https://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);
}
}
More Info Https://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));
More Info Https://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");
More Info Https://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();
More Info Https://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();
}
More Info Https://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);
More Info Https://ThesisScientist.com
/* Create a UDP socket */
if (this_host.nif == 0) {
fprintf(stderr, "No interfaces configuredn");
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);
}
More Info Https://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) {
More Info Https://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);
More Info Https://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);
More Info Https://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;
More Info Https://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:
More Info Https://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) {
More Info Https://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)
More Info Https://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 */
More Info Https://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;
More Info Https://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
More Info Https://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;
More Info Https://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 &&
More Info Https://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;
More Info Https://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. */
More Info Https://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;
More Info Https://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) {
More Info Https://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;
More Info Https://ThesisScientist.com
list_detach(pos);
rt->nprec--;
free(pr);
}
}

More Related Content

What's hot

Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereSergey Platonov
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays
 
Network security Lab manual
Network security Lab manual Network security Lab manual
Network security Lab manual Vivek Kumar Sinha
 
Preparation for mit ose lab4
Preparation for mit ose lab4Preparation for mit ose lab4
Preparation for mit ose lab4Benux Wei
 
Operating system and embedded systems
Operating system and embedded systemsOperating system and embedded systems
Operating system and embedded systemsgayatrigayu1
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent SevenMike Fogus
 
Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Thomas Fuchs
 
Extreme JavaScript Performance
Extreme JavaScript PerformanceExtreme JavaScript Performance
Extreme JavaScript PerformanceThomas Fuchs
 
Ugly code
Ugly codeUgly code
Ugly codeOdd-e
 
Cisco IOS shellcode: All-in-one
Cisco IOS shellcode: All-in-oneCisco IOS shellcode: All-in-one
Cisco IOS shellcode: All-in-oneDefconRussia
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)jeffz
 
The Ring programming language version 1.5.3 book - Part 87 of 184
The Ring programming language version 1.5.3 book - Part 87 of 184The Ring programming language version 1.5.3 book - Part 87 of 184
The Ring programming language version 1.5.3 book - Part 87 of 184Mahmoud Samir Fayed
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itSergey Platonov
 
Zn task - defcon russia 20
Zn task  - defcon russia 20Zn task  - defcon russia 20
Zn task - defcon russia 20DefconRussia
 
Taipei.py 2018 - Control device via ioctl from Python
Taipei.py 2018 - Control device via ioctl from Python Taipei.py 2018 - Control device via ioctl from Python
Taipei.py 2018 - Control device via ioctl from Python Hua Chu
 

What's hot (20)

Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhere
 
System Calls
System CallsSystem Calls
System Calls
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
 
Network security Lab manual
Network security Lab manual Network security Lab manual
Network security Lab manual
 
Preparation for mit ose lab4
Preparation for mit ose lab4Preparation for mit ose lab4
Preparation for mit ose lab4
 
Operating system and embedded systems
Operating system and embedded systemsOperating system and embedded systems
Operating system and embedded systems
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent Seven
 
Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)
 
Breaking the wall
Breaking the wallBreaking the wall
Breaking the wall
 
Extreme JavaScript Performance
Extreme JavaScript PerformanceExtreme JavaScript Performance
Extreme JavaScript Performance
 
Ugly code
Ugly codeUgly code
Ugly code
 
Cisco IOS shellcode: All-in-one
Cisco IOS shellcode: All-in-oneCisco IOS shellcode: All-in-one
Cisco IOS shellcode: All-in-one
 
iCloud keychain
iCloud keychainiCloud keychain
iCloud keychain
 
Qt Rest Server
Qt Rest ServerQt Rest Server
Qt Rest Server
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)
 
The Ring programming language version 1.5.3 book - Part 87 of 184
The Ring programming language version 1.5.3 book - Part 87 of 184The Ring programming language version 1.5.3 book - Part 87 of 184
The Ring programming language version 1.5.3 book - Part 87 of 184
 
Ieee 1149.1-2013-tutorial-ijtag
Ieee 1149.1-2013-tutorial-ijtagIeee 1149.1-2013-tutorial-ijtag
Ieee 1149.1-2013-tutorial-ijtag
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
Zn task - defcon russia 20
Zn task  - defcon russia 20Zn task  - defcon russia 20
Zn task - defcon russia 20
 
Taipei.py 2018 - Control device via ioctl from Python
Taipei.py 2018 - Control device via ioctl from Python Taipei.py 2018 - Control device via ioctl from Python
Taipei.py 2018 - Control device via ioctl from Python
 

Similar to Aodv routing protocol code in ns2

Linux Serial Driver
Linux Serial DriverLinux Serial Driver
Linux Serial Driver艾鍗科技
 
cmdfile.txtsleep 5ls -latrsleep 3pwdsleep 1wc .docx
cmdfile.txtsleep 5ls -latrsleep 3pwdsleep 1wc .docxcmdfile.txtsleep 5ls -latrsleep 3pwdsleep 1wc .docx
cmdfile.txtsleep 5ls -latrsleep 3pwdsleep 1wc .docxgordienaysmythe
 
R57shell
R57shellR57shell
R57shellady36
 
Php7 hashtable
Php7 hashtablePhp7 hashtable
Php7 hashtable桐 王
 
C++ Lambda and concurrency
C++ Lambda and concurrencyC++ Lambda and concurrency
C++ Lambda and concurrency명신 김
 
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docxodiliagilby
 
I have written the code but cannot complete the assignment please help.pdf
I have written the code but cannot complete the assignment please help.pdfI have written the code but cannot complete the assignment please help.pdf
I have written the code but cannot complete the assignment please help.pdfshreeaadithyaacellso
 
GIVEN CODE template -typename T- class DList { private- struct Node {.docx
GIVEN CODE template -typename T- class DList { private- struct Node {.docxGIVEN CODE template -typename T- class DList { private- struct Node {.docx
GIVEN CODE template -typename T- class DList { private- struct Node {.docxLeonardN9WWelchw
 
Im having difficulty with the directives i figured out a duplicatio.pdf
Im having difficulty with the directives i figured out a duplicatio.pdfIm having difficulty with the directives i figured out a duplicatio.pdf
Im having difficulty with the directives i figured out a duplicatio.pdfmaheshkumar12354
 
Senior design project code for PPG
Senior design project code for PPGSenior design project code for PPG
Senior design project code for PPGFrankDin1
 
A scrupulous code review - 15 bugs in C++ code
A scrupulous code review - 15 bugs in C++ codeA scrupulous code review - 15 bugs in C++ code
A scrupulous code review - 15 bugs in C++ codePVS-Studio LLC
 

Similar to Aodv routing protocol code in ns2 (20)

Linux Serial Driver
Linux Serial DriverLinux Serial Driver
Linux Serial Driver
 
cmdfile.txtsleep 5ls -latrsleep 3pwdsleep 1wc .docx
cmdfile.txtsleep 5ls -latrsleep 3pwdsleep 1wc .docxcmdfile.txtsleep 5ls -latrsleep 3pwdsleep 1wc .docx
cmdfile.txtsleep 5ls -latrsleep 3pwdsleep 1wc .docx
 
R57shell
R57shellR57shell
R57shell
 
Php7 hashtable
Php7 hashtablePhp7 hashtable
Php7 hashtable
 
C++ Lambda and concurrency
C++ Lambda and concurrencyC++ Lambda and concurrency
C++ Lambda and concurrency
 
Snake.c
Snake.cSnake.c
Snake.c
 
Server
ServerServer
Server
 
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
 
Marat-Slides
Marat-SlidesMarat-Slides
Marat-Slides
 
3
33
3
 
I have written the code but cannot complete the assignment please help.pdf
I have written the code but cannot complete the assignment please help.pdfI have written the code but cannot complete the assignment please help.pdf
I have written the code but cannot complete the assignment please help.pdf
 
GIVEN CODE template -typename T- class DList { private- struct Node {.docx
GIVEN CODE template -typename T- class DList { private- struct Node {.docxGIVEN CODE template -typename T- class DList { private- struct Node {.docx
GIVEN CODE template -typename T- class DList { private- struct Node {.docx
 
Ssaw08 0624
Ssaw08 0624Ssaw08 0624
Ssaw08 0624
 
Im having difficulty with the directives i figured out a duplicatio.pdf
Im having difficulty with the directives i figured out a duplicatio.pdfIm having difficulty with the directives i figured out a duplicatio.pdf
Im having difficulty with the directives i figured out a duplicatio.pdf
 
Senior design project code for PPG
Senior design project code for PPGSenior design project code for PPG
Senior design project code for PPG
 
Usp
UspUsp
Usp
 
Sysprog 11
Sysprog 11Sysprog 11
Sysprog 11
 
A scrupulous code review - 15 bugs in C++ code
A scrupulous code review - 15 bugs in C++ codeA scrupulous code review - 15 bugs in C++ code
A scrupulous code review - 15 bugs in C++ code
 
OpenBot-Code
OpenBot-CodeOpenBot-Code
OpenBot-Code
 
Open bot
Open bot Open bot
Open bot
 

More from Prof Ansari

Sci Hub New Domain
Sci Hub New DomainSci Hub New Domain
Sci Hub New DomainProf Ansari
 
Sci Hub cc Not Working
Sci Hub cc Not WorkingSci Hub cc Not Working
Sci Hub cc Not WorkingProf Ansari
 
basics of computer network
basics of computer networkbasics of computer network
basics of computer networkProf Ansari
 
JAVA INTRODUCTION
JAVA INTRODUCTIONJAVA INTRODUCTION
JAVA INTRODUCTIONProf Ansari
 
Project Evaluation and Estimation in Software Development
Project Evaluation and Estimation in Software DevelopmentProject Evaluation and Estimation in Software Development
Project Evaluation and Estimation in Software DevelopmentProf Ansari
 
Stepwise Project planning in software development
Stepwise Project planning in software developmentStepwise Project planning in software development
Stepwise Project planning in software developmentProf Ansari
 
Database and Math Relations
Database and Math RelationsDatabase and Math Relations
Database and Math RelationsProf Ansari
 
Normalisation in Database management System (DBMS)
Normalisation in Database management System (DBMS)Normalisation in Database management System (DBMS)
Normalisation in Database management System (DBMS)Prof Ansari
 
Entity-Relationship Data Model in DBMS
Entity-Relationship Data Model in DBMSEntity-Relationship Data Model in DBMS
Entity-Relationship Data Model in DBMSProf Ansari
 
A Detail Database Architecture
A Detail Database ArchitectureA Detail Database Architecture
A Detail Database ArchitectureProf Ansari
 
INTRODUCTION TO Database Management System (DBMS)
INTRODUCTION TO Database Management System (DBMS)INTRODUCTION TO Database Management System (DBMS)
INTRODUCTION TO Database Management System (DBMS)Prof Ansari
 
Master thesis on Vehicular Ad hoc Networks (VANET)
Master thesis on Vehicular Ad hoc Networks (VANET)Master thesis on Vehicular Ad hoc Networks (VANET)
Master thesis on Vehicular Ad hoc Networks (VANET)Prof Ansari
 
Master Thesis on Vehicular Ad-hoc Network (VANET)
Master Thesis on Vehicular Ad-hoc Network (VANET)Master Thesis on Vehicular Ad-hoc Network (VANET)
Master Thesis on Vehicular Ad-hoc Network (VANET)Prof Ansari
 
INTERFACING WITH INTEL 8251A (USART)
INTERFACING WITH INTEL 8251A (USART)INTERFACING WITH INTEL 8251A (USART)
INTERFACING WITH INTEL 8251A (USART)Prof Ansari
 
HOST AND NETWORK SECURITY by ThesisScientist.com
HOST AND NETWORK SECURITY by ThesisScientist.comHOST AND NETWORK SECURITY by ThesisScientist.com
HOST AND NETWORK SECURITY by ThesisScientist.comProf Ansari
 
SYSTEM NETWORK ADMINISTRATIONS GOALS and TIPS
SYSTEM NETWORK ADMINISTRATIONS GOALS and TIPSSYSTEM NETWORK ADMINISTRATIONS GOALS and TIPS
SYSTEM NETWORK ADMINISTRATIONS GOALS and TIPSProf Ansari
 
INTRODUCTION TO VISUAL BASICS
INTRODUCTION TO VISUAL BASICS INTRODUCTION TO VISUAL BASICS
INTRODUCTION TO VISUAL BASICS Prof Ansari
 
introduction to Blogging ppt
introduction to Blogging pptintroduction to Blogging ppt
introduction to Blogging pptProf Ansari
 
INTRODUCTION TO SOFTWARE ENGINEERING
INTRODUCTION TO SOFTWARE ENGINEERINGINTRODUCTION TO SOFTWARE ENGINEERING
INTRODUCTION TO SOFTWARE ENGINEERINGProf Ansari
 
Introduction to E-commerce
Introduction to E-commerceIntroduction to E-commerce
Introduction to E-commerceProf Ansari
 

More from Prof Ansari (20)

Sci Hub New Domain
Sci Hub New DomainSci Hub New Domain
Sci Hub New Domain
 
Sci Hub cc Not Working
Sci Hub cc Not WorkingSci Hub cc Not Working
Sci Hub cc Not Working
 
basics of computer network
basics of computer networkbasics of computer network
basics of computer network
 
JAVA INTRODUCTION
JAVA INTRODUCTIONJAVA INTRODUCTION
JAVA INTRODUCTION
 
Project Evaluation and Estimation in Software Development
Project Evaluation and Estimation in Software DevelopmentProject Evaluation and Estimation in Software Development
Project Evaluation and Estimation in Software Development
 
Stepwise Project planning in software development
Stepwise Project planning in software developmentStepwise Project planning in software development
Stepwise Project planning in software development
 
Database and Math Relations
Database and Math RelationsDatabase and Math Relations
Database and Math Relations
 
Normalisation in Database management System (DBMS)
Normalisation in Database management System (DBMS)Normalisation in Database management System (DBMS)
Normalisation in Database management System (DBMS)
 
Entity-Relationship Data Model in DBMS
Entity-Relationship Data Model in DBMSEntity-Relationship Data Model in DBMS
Entity-Relationship Data Model in DBMS
 
A Detail Database Architecture
A Detail Database ArchitectureA Detail Database Architecture
A Detail Database Architecture
 
INTRODUCTION TO Database Management System (DBMS)
INTRODUCTION TO Database Management System (DBMS)INTRODUCTION TO Database Management System (DBMS)
INTRODUCTION TO Database Management System (DBMS)
 
Master thesis on Vehicular Ad hoc Networks (VANET)
Master thesis on Vehicular Ad hoc Networks (VANET)Master thesis on Vehicular Ad hoc Networks (VANET)
Master thesis on Vehicular Ad hoc Networks (VANET)
 
Master Thesis on Vehicular Ad-hoc Network (VANET)
Master Thesis on Vehicular Ad-hoc Network (VANET)Master Thesis on Vehicular Ad-hoc Network (VANET)
Master Thesis on Vehicular Ad-hoc Network (VANET)
 
INTERFACING WITH INTEL 8251A (USART)
INTERFACING WITH INTEL 8251A (USART)INTERFACING WITH INTEL 8251A (USART)
INTERFACING WITH INTEL 8251A (USART)
 
HOST AND NETWORK SECURITY by ThesisScientist.com
HOST AND NETWORK SECURITY by ThesisScientist.comHOST AND NETWORK SECURITY by ThesisScientist.com
HOST AND NETWORK SECURITY by ThesisScientist.com
 
SYSTEM NETWORK ADMINISTRATIONS GOALS and TIPS
SYSTEM NETWORK ADMINISTRATIONS GOALS and TIPSSYSTEM NETWORK ADMINISTRATIONS GOALS and TIPS
SYSTEM NETWORK ADMINISTRATIONS GOALS and TIPS
 
INTRODUCTION TO VISUAL BASICS
INTRODUCTION TO VISUAL BASICS INTRODUCTION TO VISUAL BASICS
INTRODUCTION TO VISUAL BASICS
 
introduction to Blogging ppt
introduction to Blogging pptintroduction to Blogging ppt
introduction to Blogging ppt
 
INTRODUCTION TO SOFTWARE ENGINEERING
INTRODUCTION TO SOFTWARE ENGINEERINGINTRODUCTION TO SOFTWARE ENGINEERING
INTRODUCTION TO SOFTWARE ENGINEERING
 
Introduction to E-commerce
Introduction to E-commerceIntroduction to E-commerce
Introduction to E-commerce
 

Recently uploaded

Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxupamatechverse
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...Soham Mondal
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxJoão Esperancinha
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSISrknatarajan
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...Call girls in Ahmedabad High profile
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...ranjana rawat
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130Suhani Kapoor
 
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSAPPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSKurinjimalarL3
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSSIVASHANKAR N
 
HARDNESS, FRACTURE TOUGHNESS AND STRENGTH OF CERAMICS
HARDNESS, FRACTURE TOUGHNESS AND STRENGTH OF CERAMICSHARDNESS, FRACTURE TOUGHNESS AND STRENGTH OF CERAMICS
HARDNESS, FRACTURE TOUGHNESS AND STRENGTH OF CERAMICSRajkumarAkumalla
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxpurnimasatapathy1234
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130Suhani Kapoor
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxAsutosh Ranjan
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escortsranjana rawat
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...Call Girls in Nagpur High Profile
 

Recently uploaded (20)

Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptx
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSIS
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
 
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
 
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSAPPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
 
HARDNESS, FRACTURE TOUGHNESS AND STRENGTH OF CERAMICS
HARDNESS, FRACTURE TOUGHNESS AND STRENGTH OF CERAMICSHARDNESS, FRACTURE TOUGHNESS AND STRENGTH OF CERAMICS
HARDNESS, FRACTURE TOUGHNESS AND STRENGTH OF CERAMICS
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptx
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 

Aodv routing protocol code in ns2

  • 1. More Info Https://ThesisScientist.com Appendix A Implementation Coding of AODV #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;
  • 2. More Info Https://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
  • 3. More Info Https://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) {
  • 4. More Info Https://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);
  • 5. More Info Https://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)
  • 6. More Info Https://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));
  • 7. More Info Https://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); } }
  • 8. More Info Https://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));
  • 9. More Info Https://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");
  • 10. More Info Https://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();
  • 11. More Info Https://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(); }
  • 12. More Info Https://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);
  • 13. More Info Https://ThesisScientist.com /* Create a UDP socket */ if (this_host.nif == 0) { fprintf(stderr, "No interfaces configuredn"); 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); }
  • 14. More Info Https://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) {
  • 15. More Info Https://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);
  • 16. More Info Https://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);
  • 17. More Info Https://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;
  • 18. More Info Https://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:
  • 19. More Info Https://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) {
  • 20. More Info Https://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)
  • 21. More Info Https://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 */
  • 22. More Info Https://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;
  • 23. More Info Https://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
  • 24. More Info Https://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;
  • 25. More Info Https://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 &&
  • 26. More Info Https://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;
  • 27. More Info Https://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. */
  • 28. More Info Https://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;
  • 29. More Info Https://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) {
  • 30. More Info Https://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;