📄 rerr.c
字号:
/* * Copyright (C) 2001, University of California, Santa Barbara * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Other copyrights might apply to parts of this software and are so * noted when applicable. *//* * Parts of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * * The pimd program is COPYRIGHT 1998 by University of Southern California. * */#include <arpa/inet.h>#include <netinet/in.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include "aodvConst.h"#include "aodvMsg.h"#include "aodvPktInfo.h"#include "aodvSocket.h"#include "const.h"#include "debug.h"#include "inet.h"#include "localRepair.h"#include "rerr.h"#include "routingTable.h"#include "sendDatagram.h"int localRepair = FALSE;static void fill_rerr(struct RERR *rerr, int N){ trace(TRACE_RERR,"fill_rerr"); rerr->type=AODV_RERR; rerr->N=N; rerr->reserved1=0; rerr->reserved2=0; rerr->destCount=0; rerr->unreachables=NULL;}void sendRERR(struct RERR *rerr){ struct AodvPktInfo info; int intermediateN; int i; int datalen; char *data; struct UnreachableDest *cur; trace(TRACE_RERR,"sending RERR"); printRERR(rerr); //kind of a pain because we have the linked list of unreachables. //we have to create a buffer to send, then remove it afterward. //4 = size of RERR datalen = 4 + 8 * rerr->destCount; //malloc data data = (char *)malloc(datalen); //fill in the data data[0]=rerr->type; intermediateN = rerr->N; intermediateN = intermediateN << 7; data[1]=intermediateN; data[2]=rerr->reserved2; data[3]=rerr->destCount; for(i = 0, cur = rerr->unreachables ; (i < rerr->destCount) && (cur != NULL) ; i++, cur = cur->next) { memcpy(data + 4 + i * 8, &(cur->unreachableDest), 4); memcpy(data + 8 + i * 8, &(cur->unreachableDestSeqNum), 4); } fill_pktInfo(&info,BROADCAST); if(datalen >= 12){ trace(TRACE_METRIC,"s RERR"); sendDatagram(&info,data,datalen); } //free data free(data);}void assembleRERR(char *data, struct RERR *rerr){ int intermediateN; int i; int destCount; u_int32_t unreachableDest; u_int32_t unreachableDestSeqNum; trace(TRACE_RERR,"assembleRERR"); //this should reverse the sending process rerr->type = data[0]; intermediateN = data[1]; intermediateN = intermediateN >> 7; rerr->N = intermediateN; rerr->reserved2 = data[2]; destCount = data[3]; rerr->unreachables = NULL; for (i = 0 ; i < destCount ; i++ ) { memcpy(&unreachableDest, data + 4 + i * 8, 4); memcpy(&unreachableDestSeqNum, data + 8 + i * 8, 4); //trace(TRACE_RERR,"assembleRERR:i=%i",i); //trace(TRACE_RERR,"assembleRERR:rerr->destcount=%u" //,rerr->destCount); //trace(TRACE_RERR,"assembleRERR:unreachableDest=%s" // ,inet_fmt_n(unreachableDest,s1)); //trace(TRACE_RERR,"assembleRERR:unreachableDestSeqNum=%u" // ,unreachableDestSeqNum); appendUnreachable(rerr , ntohl(unreachableDest) , ntohl(unreachableDestSeqNum)); }}void deleteRERRUnreachables(struct RERR *rerr){ struct UnreachableDest *cur; struct UnreachableDest *next; trace(TRACE_RERR,"deleteRERRUnreachables"); for(cur = rerr->unreachables ; (rerr->unreachables != NULL) && (cur != NULL) ; cur = next ) { if((rerr->unreachables != NULL) && (cur != NULL)){ next = cur->next; } //free unreachableDest free(cur); }}void appendUnreachable(struct RERR *rerr , u_int32_t dest , u_int32_t destSeqNum){ struct UnreachableDest *first = NULL; struct UnreachableDest *new_u = NULL; trace(TRACE_RERR,"appendUnreachable"); rerr->destCount++; first = rerr->unreachables; //malloc UnreachableDest new_u = (struct UnreachableDest *)malloc(sizeof(struct UnreachableDest)); if(new_u == NULL){ log(LOG_ERR,TRUE,"unable to allocate memory, UnreachableDest"); } new_u->unreachableDest=htonl(dest); new_u->unreachableDestSeqNum=htonl(destSeqNum); new_u->next=first; rerr->unreachables=new_u;}void createAndSendRERR(u_int32_t broken,int N){ struct RERR rerr; mySeqNum++; trace(TRACE_RT,"Increasing SeqNum to %d because sending RERR",mySeqNum); trace(TRACE_RERR|TRACE_DEMO ,"send RERR, broken link to %s" ,inet_fmt_h(broken,s1)); //create RERR fill_rerr(&rerr,N); //also increments DestSeqNum for anyone who has the broken as nextHop //and expires each unreachable route appendUnreachables(&rerr,broken); removeBrokenFromPrecursors(broken); sendRERR(&rerr); deleteRERRUnreachables(&rerr);}void generateRERR(u_int32_t broken){ int hopCount; trace(TRACE_RERR,"generateRERR"); hopCount=getHopCount(broken); if(hopCount == DELETE_ROUTE){ //don't genreate RERR, we already have return; } if((localRepair == TRUE) && (hopCount != -1) && (hopCount <= MAX_REPAIR_TTL)) { //attempt to repair locally repairLocally(broken); //in localRepair } else { createAndSendRERR(broken,0); }}void receiveRERR(u_int32_t src, char *raw){ struct RERR rerr; struct RERR new_rerr; updateNeighbor(src,0); //need to reassemble RREQ, unreachables aren't right. assembleRERR(raw, &rerr); trace(TRACE_RERR|TRACE_DEMO, "received RERR from %s",inet_fmt_h(src,s1)); printRERR(&rerr); trace(TRACE_RERR|TRACE_DEMO ,"received RERR first unreachable is %s" ,inet_fmt_n(rerr.unreachables->unreachableDest,s1)); if(rerr.N == 1){ //TODO FUTURE local repair rerr messages return; } else { fill_rerr(&new_rerr,0); if(processRERR(src, &rerr, &new_rerr) == TRUE){ sendRERR(&new_rerr); } deleteRERRUnreachables(&rerr); deleteRERRUnreachables(&new_rerr); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -