Пример #1
0
static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, int len)
{
	struct iphdr *iph;
	unsigned long ip;

	if (len < sizeof(struct iphdr)) {
		icmp_statistics.IcmpInErrors++;
		return; 
	}
		
	/*
	 *	Get the copied header of the packet that caused the redirect
	 */
	 
	iph = (struct iphdr *) (icmph + 1);
	ip = iph->daddr;

	switch(icmph->code & 7) {
		case ICMP_REDIR_NET:
		case ICMP_REDIR_NETTOS:
			/*
			 *	As per RFC recommendations now handle it as
			 *	a host redirect.
			 */
			 
		case ICMP_REDIR_HOST:
		case ICMP_REDIR_HOSTTOS:
			ip_rt_redirect(skb->nh.iph->saddr, ip, icmph->un.gateway, iph->saddr, iph->tos, skb->dev);
			break;
		default:
			break;
  	}
}
Пример #2
0
static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 source, __u32 daddr, int len)
{
	struct iphdr *iph;
	unsigned long ip;

	/*
	 *	Get the copied header of the packet that caused the redirect
	 */
	
	if(len<=sizeof(struct iphdr))
		goto flush_it;
	 
	iph = (struct iphdr *) (icmph + 1);
	ip = iph->daddr;

	/*
	 *	If we are a router and we run a routing protocol, we MUST NOT follow redirects.
	 *	When using no routing protocol, we MAY follow redirects. (RFC 1812, 5.2.7.2)
	 */

#if !defined(CONFIG_IP_DUMB_ROUTER)
	if (sysctl_ip_forward) {
	NETDEBUG(printk(KERN_INFO "icmp: ICMP redirect ignored. dest = %lX, "
	       "orig gw = %lX, \"new\" gw = %lX, device = %s.\n", ntohl(ip),
		ntohl(source), ntohl(icmph->un.gateway), dev->name));
		goto flush_it;
	}
#endif
	switch(icmph->code & 7) 
	{
		case ICMP_REDIR_NET:
			/*
			 *	This causes a problem with subnetted networks. What we should do
			 *	is use ICMP_ADDRESS to get the subnet mask of the problem route
			 *	and set both. But we don't.. [RFC1812 says routers MUST NOT
			 *	generate Network Redirects]
			 */
#ifdef not_a_good_idea
			ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY),
				ip, 0, icmph->un.gateway, dev,0, 0, 0);
#endif
			/*
			 *	As per RFC recommendations now handle it as
			 *	a host redirect.
			 */
			 
		case ICMP_REDIR_HOST:
			/*
			 *	Add better route to host.
			 *	But first check that the redirect
			 *	comes from the old gateway..
			 *	And make sure it's an ok host address
			 *	(not some confused thing sending our
			 *	address)
			 */
			NETDEBUG(printk(KERN_INFO "ICMP redirect from %s\n", in_ntoa(source)));
			ip_rt_redirect(source, ip, icmph->un.gateway, dev);
			break;
		case ICMP_REDIR_NETTOS:
		case ICMP_REDIR_HOSTTOS:
			NETDEBUG(printk(KERN_INFO "ICMP: cannot handle TOS redirects yet!\n"));
			break;
		default:
			break;
  	}

  	/*
  	 *	Discard the original packet
  	 */
flush_it:
  	kfree_skb(skb, FREE_READ);
}