📄 packet_input.c
字号:
/***************************************************************************** * * Copyright (C) 2001 Uppsala University & Ericsson AB. * Copyright (C) 2003 Simon Fraser University and NewMIC * * 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鰉, <erik.nordstrom@it.uu.se> * : Peter Lee <peter.lee@shaw.ca> * *****************************************************************************/#ifdef NS_PORT#include "aodv-uu.h"#else#include <linux/if_ether.h>#include <linux/netfilter.h>#include <netinet/ip.h>#include <netinet/udp.h>#include <netinet/ip_icmp.h>//PL: for IPv6#include <netinet/icmp6.h>#include "defs.h"#include "debug.h"#include "routing_table.h"#include "aodv_rreq.h"#include "aodv_rerr.h"#include "libipq.h"#include "params.h"#include "timer_queue.h"#include "aodv_timeout.h"#include "aodv_socket.h"#include "seek_list.h" /* for struct ip_data */#include "packet_queue.h"#include "packet_input.h"#include "aodv_rrep.h"#include "address_areq.h"#include "address_arep.h"#include "address_conf.h"//PL:#ifdef _IPV6#include "ipv6_utils.h"#endif /* _IPV6 */#define BUFSIZE 2048extern int internet_gw_mode, wait_on_reboot;extern struct timer worb_timer;int gw_find_flag=GW_FIND_NO_NEED;struct ipq_handle *h;static void packet_input(int fd);#endif /* NS_PORT *//* Set this if you want lots of debug printouts: */#define DEBUG_PACKET /*ZJH*/#ifndef NS_PORTstatic void die(struct ipq_handle *h){ packet_queue_destroy(); ipq_destroy_handle(h); exit(1);}#endifvoid NS_CLASS packet_input_cleanup(){ packet_queue_destroy();#ifndef NS_PORT ipq_destroy_handle(h);#endif}void NS_CLASS packet_input_init(){#ifndef NS_PORT int status; //PL:#ifdef _IPV6 h = ipq_create_handle(0, PF_INET6);#else h = ipq_create_handle(0);#endif /* _IPV6 */ if (h == NULL) { fprintf(stderr, "Initialization failed!\n"); exit(1); } /* Copy 100 bytes of payload: ip header 60 bytes + max 20 bytes Transport Layer header (TCP) + 20 extra bytes just to be sure.... */ status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE); if (status < 0) { die(h); } if (attach_callback_func(h->fd, packet_input) < 0) { log(LOG_ERR, 0, "packet_input_init:"); } printf("rreq size:%d rrep size:%d areq size:%d arep size:%d\n",sizeof(RREQ),sizeof(RREP),sizeof(AREQ),sizeof(AREP));#endif /* NS_PORT */}#ifdef NS_PORTvoid NS_CLASS processPacket(Packet * p)#elsestatic void packet_input(int fd)#endif{ rt_table_t *fwd_rt, *rev_rt, *repair_rt, *next_hop_rt; //PL:#ifdef _IPV6 struct in6_addr dest_addr, src_addr;#else u_int32_t dest_addr, src_addr;#endif /* _IPV6 */ u_int8_t rreq_flags = 0; unsigned int ifindex; struct ip_data *ipd = NULL; seek_list_t *seek_entry;#ifdef NS_PORT ifindex = NS_IFINDEX; // Always use ns interface fwd_rt = NULL; // In case of broadcast we provide no next hop ipd = NULL; // No ICMP messaging struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); src_addr = ih->saddr(); dest_addr = ih->daddr(); /* Any packets with our IP address as destination arriving here are packets that weren't caught by any agent attached to the node. Throw away those. */ if (dest_addr == DEV_IFINDEX(ifindex).ipaddr) { DEBUG(LOG_WARNING, 0, "processPacket: Received orphan packet. Throwing it away."); Packet::free(p); return; } /* If this is a TCP packet and we don't have a route, we should set the gratuituos flag in the RREQ. */ if (ch->ptype() == PT_TCP) { rreq_flags |= RREQ_GRATUITOUS; }#else int status; char buf[BUFSIZE], *dev_name; ipq_packet_msg_t *pkt; //PL:#ifdef _IPV6 struct ip6_hdr *ip; struct icmp6_hdr *icmp = NULL;#else struct iphdr *ip; struct icmphdr *icmp = NULL;#endif /* _IPV6 */ struct udphdr *udp; 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.o module is loaded.\n"); die(h); } pkt = ipq_get_packet(buf); printf("ZJH:packet_input called!!!\n");#ifdef DEBUG_PACKET DEBUG(LOG_DEBUG, 0, "Protocol %u indev=%s outdev=%s\n", pkt->hw_protocol, pkt->indev_name, pkt->outdev_name);#endif printf("ZJH:Protocol %u indev=%s outdev=%s\n", pkt->hw_protocol, pkt->indev_name, pkt->outdev_name); if (pkt->hook == 0) dev_name = pkt->indev_name; else if (pkt->hook == 3) dev_name = pkt->outdev_name; else dev_name = NULL; //PL:#ifdef _IPV6 /* We know from kaodv.c that this is an IP packet */ ip = (struct ip6_hdr *) pkt->payload; copy_in6_addr(&dest_addr, &ip->ip6_dst); copy_in6_addr(&src_addr, &ip->ip6_src); printf("ZJH:dest_addr:%s src_addr:%s hop:%d\n",ip6_to_str(dest_addr),ip6_to_str(src_addr),ip->ip6_hlim); //PL: Instead of ip->protocol, it is now ip->ip6_nxt switch (ip->ip6_nxt) { /* Don't process AODV control packets (UDP on port 654). They are accounted for on the aodv socket */ case IPPROTO_UDP: //PL: I believe IPv6 header is 40 bytes printf("ZJH:ipproto_udp!!!\n"); udp = (struct udphdr *) ((char *) ip + 40); if (ntohs(udp->dest) == AODV_PORT || ntohs(udp->source) == AODV_PORT) 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: printf("ZJH:************* ipproto_tcp ******************!!!\n"); rreq_flags |= RREQ_GRATUITOUS; break; /* We set the gratuitous flag also on ICMP ECHO requests, since the destination will also need a route back for the reply... */ case IPPROTO_ICMPV6: printf("ZJH:ipproto_icmpv6!!!\n"); //PL: debug //printf("receive an icmp6 packet\n"); //icmp = (struct icmp6_hdr *) ((char *) ip + (ip->ihl << 2)); icmp = (struct icmp6_hdr *) ((char *) ip + 40); if (icmp->icmp6_type == ND_NEIGHBOR_SOLICIT) { printf("ZJH:icmp NEIGHBOR_SOLICIT message\n"); goto accept; } if (icmp->icmp6_type == ND_NEIGHBOR_ADVERT) { printf("ZJH:icmp NEIGHBOR_ADVERT\n"); goto accept; } if (icmp->icmp6_type == ICMP6_ECHO_REQUEST) { printf("ZJH:Setting RREQ_GRATUITOUS flag.\n"); rreq_flags |= RREQ_GRATUITOUS; } //PL: debug if (icmp->icmp6_type == ICMP6_ECHO_REPLY) { printf("ZJH:ICMP6_ECHO_REPLY - dst: %s, src: %s \n", ip6_to_str(dest_addr), ip6_to_str(src_addr)); }#ifdef DEBUG_PACKET DEBUG(LOG_INFO, 0, "packet_input: setting G flag for RREQ to %s", ip6_to_str(dest_addr));#endif /* DEBUG_PACKET */ break; default:printf("ZJH:wrong protocol in ip packet!!!\n");/*ZJH*/ } /* End of switch */#else /* We know from kaodv.c that this is an IP packet */ ip = (struct iphdr *) pkt->payload; dest_addr = ntohl(ip->daddr); src_addr = ntohl(ip->saddr); 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 || ntohs(udp->source) == AODV_PORT) 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 |= RREQ_GRATUITOUS; break; /* We set the gratuitous flag also on ICMP ECHO requests, since the destination will also need a route back for the reply... */ case IPPROTO_ICMP: icmp = (struct icmphdr *) ((char *) ip + (ip->ihl << 2)); if (icmp->type == ICMP_ECHO) rreq_flags |= RREQ_GRATUITOUS;#ifdef DEBUG_PACKET DEBUG(LOG_INFO, 0, "packet_input: setting G flag for RREQ to %s", ip_to_str(dest_addr));#endif /* DEBUG_PACKET */ break; default: } /* End of switch */#endif /* _IPV6 */#ifdef DEBUG_PACKET//PL:#ifdef _IPV6
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -