⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aodvsocket.c

📁 ucsb大学开发的aodv路由协议代码。
💻 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 <errno.h>#include <netinet/ip.h>#include <signal.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include "aodvMsg.h"#include "aodvPktInfo.h"#include "callout.h"#include "const.h"#include "debug.h"#include "inet.h"#include "routingTable.h"#include "rreq.h"#include "rrep.h"#include "main.h"u_int32_t mySeqNum = 1;u_int32_t broadcastId = 1;char	*aodv_recv_buf;		/* input packet buffer   */char	*aodv_send_buf;		/* output packet buffer  */int     aodv_socket = -1;static void read_aodvSocket __P((int f, fd_set *rfd));static void accept_aodvSocket __P((struct AodvPktInfo *info, int recvlen));void k_set_rcvbuf(int socket, int bufsize, int minsize);void k_hdr_include(int socket, int bool);/* * create the aodvSocket */void new_aodvSocket() {  struct sockaddr_in my_addr;  const int yes = 1;  const int zero = 0;  int test=0;  int sizeoftest;  //had to use DGRAM, 0 so that multicast could be used  //YOU CAN'T USE MULTICAST WITH RAW, or any other protocol  if ((aodv_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {    log(LOG_ERR, FALSE, "failed to create AODV socket");  } else {    trace(TRACE_INIT|TRACE_AODV_SOCKET, "created AODV socket=%i",aodv_socket);  }  if (setsockopt(aodv_socket, SOL_SOCKET, SO_BROADCAST,  		 &yes, sizeof(yes)) < 0){    log(LOG_ERR, FALSE, "setsockopt SO_BROADCAST failed:%i",errno);  }  if (getsockopt(aodv_socket, SOL_SOCKET, SO_PRIORITY ,  		 &test, &sizeoftest) < 0){    log(LOG_ERR, FALSE, "getsockopt SO_PRIORITY failed:%i",errno);  }else{    trace(TRACE_CUR,"getsockopt SO_PRIORITY = %i",test);  }  if (setsockopt(aodv_socket, SOL_SOCKET, SO_PRIORITY ,  		 &zero, sizeof(zero)) < 0){    log(LOG_ERR, FALSE, "setsockopt SO_PRIORITY failed:%i",errno);  }  if (setsockopt(aodv_socket, SOL_SOCKET, SO_PRIORITY ,  		 &zero, sizeof(zero)) < 0){    log(LOG_ERR, FALSE, "setsockopt SO_PRIORITY failed:%i",errno);  }  /* Tell socket to send IP_TTL for received messages. */  if (setsockopt(aodv_socket, SOL_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0){    log(LOG_ERR, FALSE, "setsockopt IP_RECVTTL failed:%i",errno);  }  /* Tell socket to send PKTINFO for received messages. */  if (setsockopt(aodv_socket, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0){    log(LOG_ERR, FALSE, "setsockopt IP_PKTINFO failed:%i",errno);  }   aodv_recv_buf = malloc(RECV_BUF_SIZE);  aodv_send_buf = malloc(RECV_BUF_SIZE);    my_addr.sin_family = AF_INET;     /* host byte order */  my_addr.sin_port = htons(AODV_PORT); /* short, network byte order */  my_addr.sin_addr.s_addr = INADDR_ANY;  bzero(&(my_addr.sin_zero), 8);    /* zero the rest of the struct */  if (bind(aodv_socket	   , (struct sockaddr *)&my_addr	   , sizeof(struct sockaddr)) < 0){    log(LOG_ERR, FALSE, "Can't bind AODV socket");  } else {    trace(TRACE_INIT|TRACE_AODV_SOCKET, "bind successful for AODV socket");  }    if (register_input_handler(aodv_socket, read_aodvSocket) == ERROR){    log(LOG_ERR, FALSE,  \	"cannot register aodv_read() as an input handler");  }}struct a_in_pktinfo{  unsigned int   ipi_ifindex;  /* Interface index */  struct in_addr ipi_spec_dst; /* Routing destination address */  struct in_addr ipi_addr;     /* Header Destination address */};union control_union {  struct cmsghdr cm;  char control[CMSG_SPACE(sizeof(int)) + 	      CMSG_SPACE(sizeof(struct a_in_pktinfo))];};//used to print out ip addresseschar s1[19], s2[19];  /* Read an AODV message */static void read_aodvSocket(int f, fd_set *rfd) {  register int aodv_recvlen;  register int omask;  int addr_len = sizeof(struct sockaddr_in);  struct sockaddr_in their_addr;  struct cmsghdr *cmsg;  struct msghdr msgh;  int cmsgi;  struct a_in_pktinfo pktinfo;  int *ttlptr;  int received_ttl = 0;  struct AodvPktInfo info;  union control_union control_un;  trace(TRACE_AODV_SOCKET, FALSE,"read_aodvSocket");    msgh.msg_name = NULL;  msgh.msg_namelen = 0;  msgh.msg_iov = NULL;  msgh.msg_iovlen = 0;  msgh.msg_control = control_un.control;  msgh.msg_controllen = sizeof(control_un.control);  if (recvmsg (aodv_socket, &msgh, MSG_PEEK) == -1){    log(LOG_ERR, TRUE,"read_aodvSocket recmsg ERROR=%i",errno);  }  aodv_recvlen = recvfrom(aodv_socket, aodv_recv_buf, RECV_BUF_SIZE,			  0, (struct sockaddr *)&their_addr, &addr_len);    trace(TRACE_AODV_SOCKET,"aodv_read:their_addr.sin_addr.s_addr=%s"      ,inet_fmt_n(their_addr.sin_addr.s_addr,s1));    if (aodv_recvlen < 0) {    trace(TRACE_AODV_SOCKET, "aodv_read:no length read from socket");    return;  } else {    trace(TRACE_AODV_SOCKET, "aodv_read:read %i bytes",aodv_recvlen);    omask = sigblock(sigmask(SIGALRM));             /* Get the TLL, set <received_ttl>.     */        cmsg = CMSG_FIRSTHDR(&msgh);    if (msgh.msg_controllen == 40) {      for (cmsgi = 0; cmsgi < 2; cmsgi++) {	if (cmsg->cmsg_level == SOL_IP && 	    cmsg->cmsg_type == IP_TTL) {	  ttlptr = (int *) CMSG_DATA(cmsg);	  received_ttl = *ttlptr;	  cmsg = (void*)cmsg + CMSG_SPACE(sizeof(int));	} else if (cmsg->cmsg_level == SOL_IP && 		   cmsg->cmsg_type == IP_PKTINFO) {	  memcpy(&pktinfo, CMSG_DATA(cmsg),		 sizeof(struct a_in_pktinfo));	  cmsg = (void*)cmsg + 	    CMSG_SPACE(sizeof(struct a_in_pktinfo));	}      }    }else{      log(LOG_ERR,TRUE,"read_aodvSocket:HEADER NOT INCLUDED");    }        /* drop packets sent from this node.       prevents bouncing messages. */    if((pktinfo.ipi_addr.s_addr == BROADCAST)        && (their_addr.sin_addr.s_addr == getip())){      trace(TRACE_AODV_SOCKET	    ,"aodv_read:broadcast packet from self ignored");      return;    }    if((pktinfo.ipi_addr.s_addr == BROADCAST)        && (their_addr.sin_addr.s_addr == 0)){      trace(TRACE_AODV_SOCKET	    ,"aodv_read:broadcast packet from 0.0.0.0 packet ignored");      return;    }    info.src = their_addr.sin_addr.s_addr;        //if this is a broadcast packet re-address it to me    if(pktinfo.ipi_addr.s_addr == BROADCAST){      trace(TRACE_AODV_SOCKET,"read_aodvSocket:info->dest was BROADCAST");      info.dest = getip();    } else {      info.dest = pktinfo.ipi_addr.s_addr;    }    info.ttl = received_ttl;            trace(TRACE_AODV_SOCKET,"read_aodvSocket:info->src=%s"	,inet_fmt_n(info.src,s1));    trace(TRACE_AODV_SOCKET,"read_aodvSocket:info->dest=%s"	,inet_fmt_n(info.dest,s1));    trace(TRACE_AODV_SOCKET,"read_aodvSocket:info->ttl=%u"	,info.ttl);    accept_aodvSocket(&info,aodv_recvlen);    (void)sigsetmask(omask);      }}/* * called when we receive an aodv packet * determines type and calls method to take care of it */static void accept_aodvSocket(struct AodvPktInfo *info, int aodvlen) {  //register struct ip *ip;  register struct AodvMsg *aodvMsg;  //struct iphdr *ipH;  //char dbuf[25];  trace(TRACE_AODV_SOCKET,"received packet on aodvSocket");  if (aodvlen < sizeof(struct AodvMsg)) {    log(LOG_WARNING, FALSE, 	"IP data field too short (%u bytes) for AODV header, from %s", 	aodvlen, inet_fmt_n(info->src, s1));    return;  }  trace(TRACE_AODV_SOCKET, "accept_aodvSocket:src=%s"      ,inet_fmt_n(info->src, s1));  aodvMsg       = (struct AodvMsg *)(aodv_recv_buf);    trace(TRACE_AODV_SOCKET,      "Received message type:%u for AODV header, from %s, to %s",       aodvMsg->type, inet_fmt_n(info->src, s1), inet_fmt_n(info->dest, s2));    switch (aodvMsg->type) {  case AODV_RREQ:    trace(TRACE_METRIC,"r RREQ");    if(rebootTime==0){      receiveRREQ(info, (struct RREQ *)(aodvMsg));     }else{      trace(TRACE_AODV_SOCKET|TRACE_RREQ	    ,"dropping RREQ because during reboot");    }    break;  case AODV_RREP:       //moved to receiveRREP so could     //differeniate between rrep and hello    //trace(TRACE_METRIC,"r RREP");    receiveRREP(info, (struct RREP *)(aodvMsg));    break;  case AODV_RERR:       trace(TRACE_METRIC,"r RERR");    if(rebootTime==0){      receiveRERR(ntohl(info->src), (char *)(aodvMsg));    }else{      trace(TRACE_AODV_SOCKET|TRACE_RERR	    ,"dropping RERR because during reboot");    }    break;      default:    trace(TRACE_AODV_SOCKET,	"ignore unknown AODV message type %u from %s",	aodvMsg->type, inet_fmt_n(info->src, s1));    /*    trace(TRACE_AODV_SOCKET,	  "checking message for iphdr");        ipH = (struct iphdr *)(aodv_recv_buf);    trace(TRACE_AODV_SOCKET,	  "ipH->saddr=%s",inet_fmt_n(ipH->saddr,s1));    trace(TRACE_AODV_SOCKET,	  "ipH->daddr=%s",inet_fmt_n(ipH->daddr,s1));        //check that dest isn't broadcast    sprintf(dbuf,"%s",inet_fmt_n(ipH->daddr,s1));    if(strstr(dbuf,"255")==NULL){      //if have active route update lifetime      if(routeUsed(ipH->daddr)==FALSE){	//if don't have an active route	//create RERR	trace(TRACE_DEMO,"received message to (%s) NO ROUTE"	      ,inet_fmt_n(ipH->daddr,s1));		generateRERR(ipH->daddr);      }    }*/    break;  }}/* * Set/reset the IP_HDRINCL option */void k_hdr_include(int socket, int bool) {#ifdef IP_HDRINCL  if (setsockopt(socket, IPPROTO_IP, IP_HDRINCL,		 (char *)&bool, sizeof(bool)) < 0){    log(LOG_ERR, FALSE, "setsockopt IP_HDRINCL %u", bool);  }#endif}/* * Set the socket receiving buffer. `bufsize` is the preferred size, * `minsize` is the smallest acceptable size. */void k_set_rcvbuf(int socket, int bufsize, int minsize) {  int delta = bufsize / 2;  int iter = 0;    /*   * Set the socket buffer.  If we can't set it as large as we   * want, search around to try to find the highest acceptable   * value.  The highest acceptable value being smaller than   * minsize is a fatal error.   */  if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF,                   (char *)&bufsize, sizeof(bufsize)) < 0) {    bufsize -= delta;    while (1) {      iter++;      if (delta > 1){	delta /= 2;      }      if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF,		     (char *)&bufsize, sizeof(bufsize)) < 0) {                bufsize -= delta;      } else {	if (delta < 1024)	  break;	bufsize += delta;      }    }    if (bufsize < minsize) {      log(LOG_ERR, FALSE, "OS-allowed buffer size %u < app min %u",	  bufsize, minsize);      /*NOTREACHED*/    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -