📄 aodv.cc
字号:
/************************************************************************ ---AODV-UIUC--- This software can be used under GNU General Public License.Author: Binita Gupta <binita@uiuc.edu> University of Illinois, Urbana-Champaign************************************************************************/#include "common.h"#include "externDec.h"void process_aodv_handler(void);void recv_asl_data_handler(void);void resendRREQ_handler(void * data);void LR_timer_handler(void *data);void global_handler(int type);void sigint_timer_handler(int type);void sendHello_handler(void * data);void rrepAck_handler(void * data);void rebootHandler_stub(void *data);void periodicHandler_stub(void *data);/* AODV initialization function */void aodv::aodv_init(char * interface){ struct sockaddr_in my_addr; struct in_addr def; if(check_root() == -1) { cout<< "You must be root to run this program" << endl; exit(1); } /* create AODV socket and register handler function */ aodvSock.createSock(interface, &my_addr); register_handler_func(aodvSock.getSock(), process_aodv_handler); if (get_interface_ip(aodvSock.getSock(), interface, &my_addr) == -1) { cout << "Error getting Interface IP" << endl; exit(1); } /* ASL: open a new socket connection to asl thread */ asl_sock = open_route_request(); if(asl_sock < 0) cout << "Failed to open route request " << endl; register_handler_func(asl_sock, recv_asl_data_handler); /* ASL: add a deferred route */ inet_aton("0.0.0.0",&def); if (route_add(def.s_addr, def.s_addr, interface) < 0) cout << "Error in adding deferred route" << endl; /* open socket for communication with kernel routing table */ ksock = init_krtsocket(); if(ksock == -1) { cout << "Error Initializing kernel socket" << endl; exit(1); } return;}void aodv::register_handler_func(int fd, hfunc_t fun){ handlers[handler_cnt].fd = fd; handlers[handler_cnt].func = fun; handler_cnt++; return;}/* handler function for aodv socket */void process_aodv_handler(void){ aodvOb.process_aodv();}/* this function is called when data is received on aodv socket */void aodv::process_aodv(void){ /* receive aodv message and call appropriate handlers */ struct aodvData data; int length; memset(&data,0,sizeof(struct aodvData)); length = aodvSock.readFromSock(&data); processRecvMsg(&data, length); return;}void aodv::genSndData(sendData *snd,u_int32_t dst, int ttl){ snd->setDestIP(dst); snd->setTTL(ttl);}/* This function processes received AODV messages */void aodv::processRecvMsg(struct aodvData *data, int len){ AODV_Msg *aodv_msg; aodv_msg = (AODV_Msg *)recvBuffer;#ifdef DEBUG cout << "processRecvMsg:: entered" << endl; cout << " processRecvmsg: src address is " << getDotIP(data->src_ip) << endl; cout << " processRecvMsg: local node address is " << getDotIP(g_my_ip) << endl;#endif if(data->src_ip == g_my_ip) { cout << "processRecvMsg: ignore messages from the local node" << endl; return; }#ifdef DEBUG cout << "processRecvMsg: received ttl is " << data->ttl << endl;#endif /* decrement ttl value */ data->ttl--; /* check for various received message types and do * processing accordingly */ switch(aodv_msg->type){ case AODV_RREQ: processRREQ(data); break; case AODV_RREP: processRREP(data); break; case AODV_RERR: processRERR(data); break; case AODV_RREP_ACK: processRREP_ACK(data); break; default: cout << "processRecvMsg: default case" << endl; break; }}void aodv::processRREQ(aodvData *data){ int result=0; AODV_Msg *aodv_msg; sendData snd; u_int32_t next_hop; u_int64_t currtime; aodv_msg = (AODV_Msg *)recvBuffer;#ifdef DEBUG cout << "aodv: processRREQ: entered" << endl;#endif if(duringReboot) {#ifdef DEBUG cout << "aodv: processRREQ: in the reboot process" << endl;#endif /* create route entries for the prev hop and the source * of the rreq */ RREQ rreqOb((RREQ *)aodv_msg); rtable_entry rtEntry, rtNeighborEntry; u_int32_t seqNum=0; currtime = getcurrtime(); if(rreqOb.getSrcIP() == data->src_ip) seqNum = rreqOb.getSrcSeqNum(); /* update route to the neighbor */ rtable.rebootNeighborUpdate(data->src_ip,seqNum,(currtime+ALLOWED_HELLO_LOSS*HELLO_INTERVAL)); /* update reverse route */ if(rreqOb.getSrcIP() != data->src_ip) rtable.rebootReverseRouteUpdate(data->src_ip, &rreqOb); /* update the local nodes seq number from the received packet */ if(rreqOb.getDestIP() == g_my_ip) { if(rreqOb.getDestSeqNum() > localSeqNum) localSeqNum = rreqOb.getDestSeqNum(); } return; } else {#ifdef DEBUG cout << "aodv: processRREQ: not inside reboot " << endl;#endif RREQ rreqOb((RREQ *)aodv_msg);#ifdef DEBUG cout << "aodv: processRREQ: dest ip is " << getDotIP(rreqOb.getDestIP())<< endl; cout << "aodv: processRREQ: hop cnt is " << (int)(rreqOb.getHopCnt())<< endl; cout << "aodv: processRREQ: dest seq num is" << (rreqOb.getDestSeqNum())<< endl; cout << "aodv: processRREQ: src ip is" << getDotIP(rreqOb.getSrcIP())<< endl; cout << "aodv: processRREQ: src seq num is" << (rreqOb.getSrcSeqNum())<< endl; cout << "aodv: processRREQ: rreq id is" << (rreqOb.getRreqId())<< endl;#endif /* process received RREQ */ result = rreqOb.recvRREQ(data->src_ip); if(result == 0) { /* do nothing */ return; } else if( result == FWD_RREQ) {#ifdef DEBUG cout << "aodv: processRREQ: forward the RREQ " << endl; cout << "aodv: processRREQ: ttl value is " << data->ttl << endl;#endif if(data->ttl > 0) { genSndData(&snd, BROADCAST_ADDR, data->ttl); copyToSendBuf((void *)&rreqOb, sizeof(RREQ)); sendPacket(&snd,(void *)sendBuffer,sizeof(RREQ)); } } else if(result == GEN_RREP) {#ifdef DEBUG cout << "aodv: processRREQ: generate RREP " << endl;#endif /* generate a RREP packet */ RREP rrepOb; rrepOb.createRREP(data->src_ip,(RREQ *)aodv_msg); if((next_hop = get_next_hop(rreqOb.getSrcIP())) != 0) { /* unicast RREP */ /* also set up a rrep_ack timer if needed*/ if(rrepOb.getA() == 1) {#ifdef DEBUG cout << "aodv::processRREQ: set rrep_ack timer " << endl;#endif struct timerData tData; tData.type = RREP_ACK_TIMER; tData.data = next_hop; timer_Q.set_timer(RREP_ACK_TIMEOUT, rrepAck_handler, (void *) &tData); } genSndData(&snd, next_hop, -1); copyToSendBuf((void *)&rrepOb, sizeof(RREP)); /* send out the generated packet */ sendPacket(&snd,(void *)sendBuffer,sizeof(RREP)); } /* check if need to generate gratuitour RREP */ if(rreqOb.getG() == 1 && (rreqOb.getDestIP() != g_my_ip)) { /* Generate Gratuitous RREP at the intermediate node*/#ifdef DEBUG cout << "aodv: processRREQ: generate gratuitous RREP " << endl;#endif RREP grrepOb; grrepOb.createGRREP(rreqOb.getSrcIP(), rreqOb.getDestIP(), rreqOb.getSrcSeqNum()); if((next_hop = get_next_hop(rreqOb.getDestIP())) != 0) { genSndData(&snd, next_hop, -1); copyToSendBuf((void *)&grrepOb, sizeof(RREP)); sendPacket(&snd,(void *)sendBuffer,sizeof(RREP)); } } } } return;}/* handler function called when timer to receive RREP-ACK expires */void rrepAck_handler(void *data){ aodvOb.rrep_ack_handler(data);}void aodv::rrep_ack_handler(void *val){ /* add the next hop to the blacklist of nodes */ struct timerData *tData;#ifdef DEBUG cout << "aodv::rrep_ack_handler: entered" << endl;#endif tData = (struct timerData*)val; u_int32_t dst=tData->data; /* add the node to the black list */ black_list.addToList(dst, BLACKLIST_TIMEOUT);}/* this function processes incoming RREP */void aodv::processRREP(aodvData *data){ int result=0; AODV_Msg *aodv_msg; sendData snd; u_int32_t next_hop; u_int64_t currtime; aodv_msg = (AODV_Msg *)recvBuffer;#ifdef DEBUG cout << "aodv: processRREP: entered" << endl;#endif if(duringReboot) {#ifdef DEBUG cout << "aodv: processRREP: during reboot time - ignore received RREP" << endl;#endif /* create route entries for the prev hop and the source * of the rrep */ RREP rrepOb((RREP *)aodv_msg); rtable_entry rtEntry; u_int32_t seqNum=0; currtime = getcurrtime(); if(rrepOb.getDestIP() == data->src_ip) seqNum = rrepOb.getDestSeqNum(); /* update route to the neighbor */ rtable.rebootNeighborUpdate(data->src_ip,seqNum,(currtime+ALLOWED_HELLO_LOSS*HELLO_INTERVAL)); /* update forward route */ if(rrepOb.getDestIP() != data->src_ip) rtable.rebootForwardRouteUpdate(data->src_ip, &rrepOb); return; } else {#ifdef DEBUG cout << "adov: processRREP: not during reboot time" << endl;#endif /* generate a RREP object from the received buffer */ RREP rrepOb((RREP *)aodv_msg); /* check if an ACK needs to be sent for the received RREP */ if( rrepOb.getA() == 1) { /* send a rrep_ack message */ RREP_ACK rrepAckOb;#ifdef DEBUG cout << "adov: processRREP: rrep ack flag set, send ack" << endl;#endif genSndData(&snd, data->src_ip, 1 ); copyToSendBuf((void *)&rrepAckOb, sizeof(RREP_ACK)); sendPacket(&snd,(void *)sendBuffer,sizeof(RREP_ACK)); } /* process the received RREP */ result = rrepOb.recvRREP(data->src_ip); if(result == SEND_RREP) {#ifdef DEBUG cout << "aodv: processRREP: send RREP ahead" << endl;#endif if((next_hop = get_next_hop(rrepOb.getSrcIP())) != 0) { /* also set up a rrep_ack timer if needed*/ if(rrepOb.getA() == 1) { struct timerData tData; tData.type = RREP_ACK_TIMER; tData.data = next_hop; timer_Q.set_timer(RREP_ACK_TIMEOUT, rrepAck_handler, (void *) &tData); } genSndData(&snd, next_hop, -1 ); copyToSendBuf((void *)&rrepOb, sizeof(RREP)); sendPacket(&snd,(void *)sendBuffer,sizeof(RREP)); } } } return;}/* this function processes the incoming RERR messages */void aodv::processRERR(aodvData *data){ char *buf; u_int32_t *precAddr; sendData snd; bool result = false; u_int64_t currtime = getcurrtime();#ifdef DEBUG cout << "adov: processRERR: entered" << endl;#endif precAddr = (u_int32_t *)malloc(sizeof(u_int32_t)); /* recvBuffer is in htonl() format */ buf = (char *)recvBuffer; if(duringReboot) {#ifdef DEBUG cout << "adov: processRERR: during reboot" << endl;#endif /* create route entries for the neighbor from which the rerr is received*/ RERR rerrOb; rerrOb.createRERR(buf); rtable.rebootNeighborUpdate(data->src_ip,0,(currtime + ALLOWED_HELLO_LOSS*HELLO_INTERVAL)); /* update both valid and invalid entries in the routing table based * on the information received in the RERR message */ rerrOb.updateInvalidEntries(); rerrOb.updateValidEntries(data->src_ip); return; } else {#ifdef DEBUG cout << "adov: processRERR: not during reboot" << endl;#endif RERR rerrOb, rerrNewOb; /* create a RERR message from the received message */ rerrOb.createRERR(buf); /* incorporate received information into the existing routing table */ // neighborUpdate(); rtable.neighborUpdate(data->src_ip,data->src_ip,0,(currtime+ALLOWED_HELLO_LOSS*HELLO_INTERVAL)); /* only update invalid (infinity metric) route table entries, valid route * table entries get updated in createNewRerr() */ rerrOb.updateInvalidEntries(); /* handle rerr with N bit set */ int n_val = rerrOb.getN();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -