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

📄 packet_input.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. *//***************************************************************************** * * Copyright (C) 2001 Uppsala University. * * 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 * * Authors: Erik Nordstr鰉, <erno3431@student.uu.se> *          Henrik Lundgren, <henrikl@docs.uu.se> * *****************************************************************************/#include <linux/if_ether.h>#include <linux/netfilter.h>#include <netinet/ip.h>#include <netinet/in.h>#include <netinet/udp.h>#include "libipq.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "aodvConst.h"#include "debug.h"#include "const.h"#include "inet.h"#include "main.h"#include "routingTable.h"#include "rerr.h"#define BUFSIZE 2048/* #define DEBUG_PACKET */static struct ipq_handle *h;static void packet_input __P((int fd, fd_set *rfd));void packet_buff_add(unsigned long id, u_int32_t dest);void packet_buff_destroy();int packet_buff_drop(u_int32_t dest);static void die(struct ipq_handle *h) {  ipq_destroy_handle(h);  packet_buff_destroy();  exit(1);}void packet_input_cleanup() {  die(h);}void packet_input_init() {  int status;  h = ipq_create_handle(0);  if(h == NULL) {    fprintf(stderr, "Initialization failed!\n");    exit(1);  }  status = ipq_set_mode(h, IPQ_COPY_PACKET, 0);  if (status < 0) {    die(h);  }    //if (attach_callback_func(h->fd, packet_input) < 0) {  if (register_input_handler(h->fd, packet_input) < 0) {    log(LOG_ERR, 0, "packet_input_init:");   }}static void packet_input(int fd, fd_set *rfd) {  int status;  char buf[BUFSIZE];  ipq_packet_msg_t *pkt;  struct iphdr *ip;  struct udphdr *udp;  struct RoutingTableEntry *fwd_rt;    //struct RoutingTableEntry *rev_rt;    u_int32_t dest, src;  u_int8_t rreq_flags = 0;  char dbuf[25];  ipq_read(h, buf, BUFSIZE, 0);    status = ipq_message_type(buf);    if(status == NLMSG_ERROR) {    fprintf(stderr, "ERROR packet_input: Check that the ip_queue_aodv.o module is loaded.\n");    die(h);  }    pkt = ipq_get_packet(buf);      trace(TRACE_PACKET_INPUT,"Protocol %u indev=%s outdev=%s",	   pkt->hw_protocol, pkt->indev_name, pkt->outdev_name);    if(ntohs(pkt->hw_protocol) != ETH_P_IP) {    ipq_set_verdict(h, pkt->packet_id, NF_ACCEPT, 0, NULL);    return;  }  ip = (struct iphdr *)pkt->payload;  dest = ip->daddr;  src = ip->saddr;   //IDC   trace(TRACE_PACKET_INPUT,"packet_input: src=%s dest=%s", inet_fmt_n(src,s1), inet_fmt_n(dest,s2));    switch(ip->protocol) {    /* Don't process AODV control packets (UDP on port 654). They       are accounted for on the aodv socket */  case IPPROTO_UDP:    udp = (struct udphdr *)((char *)ip + (ip->ihl << 2));    if(ntohs(udp->dest) == AODV_PORT){      if(rebootTime != 0 && src == getip()){	status = ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);	if (status < 0)	  die(h);	return;      }      trace(TRACE_PACKET_INPUT,"aodv packet received");      goto accept;    }    break;    /* If this is a TCP packet and we don't have a route, we should       set the gratuituos flag in the RREQ. */  case IPPROTO_TCP:    rreq_flags = 1;    break;  default:  }  /* If the packet is not interesting we just let it go through... */   if(dest == BROADCAST){     goto accept;   }  /* If the packet is not interesting we just let it go through... */   if(dest == getip()){     trace(TRACE_METRIC,"r DATA");     goto accept;   }   //ignore if this is local area broadcast      sprintf(dbuf,"%s",inet_fmt_n(dest,s1));   if((strstr(dbuf,"255")!=NULL)){     trace(TRACE_PACKET_INPUT,"local broadcast passed");     goto accept;   }   if(rebootTime != 0 && src != getip()){     rebootTime=getTime()+DELETE_PERIOD;     createAndSendRERR(dest,0);     status = ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);     if (status < 0)       die(h);     return;   }   //IDC   if(rebootTime == 0){     if(routeUsed(ntohl(src)) == TRUE && src != getip()){       updateNeighbor(ntohl(src),0);     }     if(routeUsed(ntohl(dest)) == FALSE && src != getip()){       //issue route error       createAndSendRERR(ntohl(dest),0);       //and drop packet       status = ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);       if (status < 0)	 die(h);       return;     }else{       if(src == getip()){	 trace(TRACE_METRIC,"s DATA");       }else{	 trace(TRACE_METRIC,"s f DATA");       }     }   }   fwd_rt = getRoute(ntohl(dest));  /*   /\* If a packet is received on the NF_IP_PRE_ROUTING hook, *//*      i.e. inbound on the interface and we don't have a route to the *//*      destination, we should send an RERR to the source and then drop *//*      the package... *\/ *//*   /\* NF_IP_PRE_ROUTING = 0 *\/ *//*   if(dest != this_host->ipaddr &&  *//*      (fwd_rt == NULL && pkt->hook == 0)) { *//*     rt_table_t *rt_entry; *//*     RERR *rerr; *//*     rerr = (RERR *)aodv_socket_new_msg(); *//*     rerr->type = AODV_RERR; *//*     rerr->reserved = 0; *//*     rerr->dest_count = 1; *//*     rerr->dest_addr = htonl(dest); *//*     /\* There is an expired entry in the routing table we wan't to send *//*        along the seqno in the RERR... *\/ *//*     if((rt_entry = rt_table_find(dest)) != NULL) *//*       rerr->dest_seqno = rt_entry->dest_seqno; *//*     else *//*       rerr->dest_seqno = 0; */    /* #ifdef DEBUG *//*     log(LOG_DEBUG, 0, "packet_input: Sending RERR for unknown dest %s",  *//* 	ip_to_str(dest)); *//* #endif *//*     aodv_socket_send((AODV_msg *)rerr, src,  *//* 		     RERR_CALC_SIZE(rerr->dest_count), 1);  *//*     status = ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL); *//*     if (status < 0) *//*       die(h); *//*     return; *//*   } */    //IDC/*   /\* If a packet is received on the NF_IP_PRE_ROUTING hook, *//*      i.e. inbound on the interface and we don't have a route to the *//*      destination, we should send an RERR to the source and then drop *//*      the package... *\/ *//*   /\* NF_IP_PRE_ROUTING = 0 *\/ */  if(dest != getip() &&     (fwd_rt == NULL && pkt->hook == 0)) {    createAndSendRERR(ntohl(dest),0);    status = ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);    if (status < 0)      die(h);    return;  }/*   if(rev_rt != NULL) { */    /*     /\* If the packet is from a node in our neighbor set, update the *//*        hello timeout. (AODV draft v.9 section 8.9.) *\/ *//*     /\*  if(rev_rt->hcnt == 1)  *\/ *//* /\*        hello_update_timeout(rev_rt, ALLOWED_HELLO_LOSS*HELLO_INTERVAL); *\/ */    /*     /\* Always update the route timeout of both forward and reverse *//*      routes when packet is forwarded... (AODV draft v.9, section *//*      8.2) *\/ *//*     rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT); *//*   } *//*   if(fwd_rt != NULL && dest != this_host->ipaddr) *//*     rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT); */  /* #ifdef DEBUG_PACKET *//*   log(LOG_INFO, 0, "packet_input: d=%s s=%s id=%lu",  *//*       ip_to_str(dest), ip_to_str(ntohl(ip->saddr)), pkt->packet_id);  *//* #endif *//*   if(fwd_rt == NULL || (fwd_rt->hcnt == 1 && (fwd_rt->flags & UNIDIR))) { *//*     /\* Buffer packets... Packets are queued by the ip_queue_aodv.o module *//*      already. We only need to save the handle id, and return the proper *//*      verdict when we know what to do... *\/ *//*     packet_buff_add(pkt->packet_id, dest); *//*     rreq_route_discovery(dest, rreq_flags); *//*     return; *//*   }  */    if((src == getip())      && ((fwd_rt == NULL)     || ((fwd_rt != NULL) && (fwd_rt->hopCount==DELETE_ROUTE))))  {     //buffer packest     packet_buff_add(pkt->packet_id,ntohl(dest));     generateRREQ(ntohl(dest),rreq_flags);     return;   }      accept:  status = ipq_set_verdict(h, pkt->packet_id, NF_ACCEPT, 0, NULL);  if (status < 0)    die(h);    return;}/* Packet buffering: */struct pkt_buff {  struct pkt_buff *next;  unsigned long id;  u_int32_t dest;};struct pkt_buff *pkt_buff_head = NULL;struct pkt_buff *pkt_buff_tail = NULL;/* Buffer a packet in a FIFO queue. Implemented as a linked list,   where we add elements at the end and remove at the beginning.... */void packet_buff_add(unsigned long id, u_int32_t dest) {  struct pkt_buff *new;  if((new = (struct pkt_buff *)malloc(sizeof(struct pkt_buff))) == NULL) {    fprintf(stderr, "packet_buff_add: Malloc failed!\n");    exit(-1);  }#ifdef DEBUG  log(LOG_INFO, 0, "packet_buff_add: %s buffering pkt (id=%lu)",       ip_to_str(dest), id);#endif  if(pkt_buff_head == NULL)    pkt_buff_head = new;    new->id = id;  new->dest = dest;  new->next = NULL;  if(pkt_buff_tail != NULL)    pkt_buff_tail->next = new;    pkt_buff_tail = new;}void packet_buff_destroy() {  struct pkt_buff *curr, *tmp;  int count = 0;    curr = pkt_buff_head;  while(curr != NULL) {    tmp = curr;    curr = curr->next;    ipq_set_verdict(h, tmp->id, NF_DROP, 0, NULL);    free(tmp);    count++;  }#ifdef DEBUG  log(LOG_INFO, 0, "packet_buff_destroy: Destroyed %d buffered packets!",       count);#endif}int packet_buff_drop(u_int32_t dest) {  struct pkt_buff *curr, *tmp, *prev;  int count = 0;      curr = pkt_buff_head;  prev = NULL;  while(curr != NULL) {            if(curr->dest == dest) {      ipq_set_verdict(h, curr->id, NF_DROP, 0, NULL);      if(prev == NULL) 	pkt_buff_head = curr->next;      else	prev->next = curr->next;            /* If we remove the last element in the queue we must update the         tail pointer */      if(curr->next == NULL)	pkt_buff_tail = prev;      tmp = curr;      curr = curr->next;      free(tmp);      count++;      continue;    }    curr = curr->next;  }#ifdef DEBUG  log(LOG_INFO, 0, "pkt_buff_drop: %s - DROPPED %d packets!",       ip_to_str(dest), count);#endif  return count;}int packet_buff_send(u_int32_t dest) {  struct pkt_buff *curr, *tmp, *prev;  int count = 0;     curr = pkt_buff_head;  prev = NULL;  while(curr != NULL) {    if(curr->dest == dest) {      //log(LOG_INFO, 0, "pkt_buff_send: %s - SENDING pkt id=%lu!",       //   ip_to_str(dest), curr->id);      ipq_set_verdict(h, curr->id, NF_ACCEPT, 0, NULL);            if(prev == NULL) 	pkt_buff_head = curr->next;      else	prev->next = curr->next;            /* If we remove the last element in the queue we must update the	 tail pointer */      if(curr->next == NULL)	pkt_buff_tail = prev;            tmp = curr;      curr = curr->next;      free(tmp);      count++;      continue;    }    curr = curr->next;  }#ifdef DEBUG log(LOG_INFO, 0, "pkt_buff_send: %s - SENT %d packets!",      ip_to_str(dest), count);#endif trace(TRACE_PACKET_INPUT       , "pkt_buff_send: %s - SENT %d packets!"       , inet_fmt_h(dest,s1)       , count); return count;}

⌨️ 快捷键说明

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