/* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. * * The IP forwarding functionality. * * Version: $Id: ip_forward.c,v 1.48 2000/12/13 18:31:48 davem Exp $ * * Authors: see ip.c * * Fixes: * Many : Split from ip.c , see ip_input.c for * history. * Dave Gregorich : NULL ip_rt_put fix for multicast * routing. * Jos Vos : Add call_out_firewall before sending, * use output device for accounting. * Jos Vos : Call forward firewall after routing * (always use output device). * Mike McLagan : Routing by source */ // ECE435 CHANGES BEGIN /* ECE435: net/ipv4/ip_forward.c * Kernel modification to drop packets * Work at KERNEL level * * Before you recompile the kernel: * (1) Replace the original file under net/ipv4/ip_forward.c by this file * (2) Change the drop pattern in dropqueue * (3) Change the source and destination IP address network representation using the posted testip function */ // ECE435 CHANGES END #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAXNODE 20 //ECE435 CHANGES BEGIN //ECE435 Lab2 Drop Pattern, -1 means dropping a packet, 0 means forwarding the packet //ECE435 You can change drop pattern here static int dropqueue[MAXNODE] = {0,0,0,0,-1,0,0,0,0,-1,0,0,0,0,-1,0,0,0,0,-1}; static int queueptr = 0; //ECE435 drop queue pointer static int sysctl_srcip = 151038144; //ECE435 src ip = 192.168.0.9 //Change here using testip static int sysctl_dstip = 167815360; //ECE435 dst ip = 192.168.0.10 //Change here using testip //ECE435 CHANGES END static inline int ip_forward_finish(struct sk_buff *skb) { struct ip_options * opt = &(IPCB(skb)->opt); IP_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS); if (unlikely(opt->optlen)) ip_forward_options(skb); return dst_output(skb); } int ip_forward(struct sk_buff *skb) { struct iphdr *iph; /* Our header */ struct rtable *rt; /* Route we use */ struct ip_options * opt = &(IPCB(skb)->opt); // ECE435 CHANGES BEGIN /*******************************************************************************************/ // ECE435 for processing dropped packets u8 *hzxip = (u8 *) skb->data; struct iphdr *myiph = (struct iphdr *) hzxip; // ECE435 ip header // if (queueptr >= MAXNODE) queueptr = 0; printk("\n*********\n src_ip= %u, dest_ip = %u (%u,%u)\n\n", myiph->saddr, myiph->daddr, sysctl_srcip, sysctl_dstip); if (myiph->saddr == sysctl_srcip && myiph->daddr == sysctl_dstip) { queueptr ++; if (queueptr >= MAXNODE) queueptr = 0; if (dropqueue[queueptr] == -1) // ECE435 drop a packet { printk("\n\n H301 Drop a packet!!"); goto drop; } } /*******************************************************************************************/ // ECE435 CHANGES END if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb)) goto drop; if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb)) return NET_RX_SUCCESS; if (skb->pkt_type != PACKET_HOST) goto drop; skb_forward_csum(skb); /* * According to the RFC, we must first decrease the TTL field. If * that reaches zero, we must reply an ICMP control message telling * that the packet's lifetime expired. */ if (ip_hdr(skb)->ttl <= 1) goto too_many_hops; if (!xfrm4_route_forward(skb)) goto drop; rt = (struct rtable*)skb->dst; if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway) goto sr_failed; if (unlikely(skb->len > dst_mtu(&rt->u.dst) && (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) { IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dst_mtu(&rt->u.dst))); goto drop; } /* We are about to mangle packet. Copy it! */ if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+rt->u.dst.header_len)) goto drop; iph = ip_hdr(skb); /* Decrease ttl after skb cow done */ ip_decrease_ttl(iph); /* * We now generate an ICMP HOST REDIRECT giving the route * we calculated. */ if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr) ip_rt_send_redirect(skb); skb->priority = rt_tos2priority(iph->tos); return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, rt->u.dst.dev, ip_forward_finish); sr_failed: /* * Strict routing permits no gatewaying */ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0); goto drop; too_many_hops: /* Tell the sender its packet died... */ IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); drop: kfree_skb(skb); return NET_RX_DROP; }