if (!(rt->rt_flags & RTCF_LOCAL)) saddr = 0; 
if (!(rt->rt_flags & RTCF_LOCAL)) { if (sysctl_icmp_errors_use_inbound_ifaddr) saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK); else saddr = 0; } 
void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info){	struct iphdr *iph;	int room;	struct icmp_bxm icmp_param;	struct rtable *rt = (struct rtable *)skb_in->dst;	struct ipcm_cookie ipc;	u32 saddr;	u8  tos;	if (!rt)		goto out;	/*	 *	Find the original header. It is expected to be valid, of course.	 *	Check this, icmp_send is called from the most obscure devices	 *	sometimes.	 */	iph = skb_in->nh.iph;	if ((u8 *)iph < skb_in->head || (u8 *)(iph + 1) > skb_in->tail)		goto out;	/*	 *	No replies to physical multicast/broadcast	 */	if (skb_in->pkt_type != PACKET_HOST)		goto out;	/*	 *	Now check at the protocol level	 */	if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))		goto out;	/*	 *	Only reply to fragment 0. We byte re-order the constant	 *	mask for efficiency.	 */	if (iph->frag_off & htons(IP_OFFSET))		goto out;	/*	 *	If we send an ICMP error to an ICMP error a mess would result..	 */	if (icmp_pointers[type].error) {		/*		 *	We are an error, check if we are replying to an		 *	ICMP error		 */		if (iph->protocol == IPPROTO_ICMP) {			u8 _inner_type, *itp;			itp = skb_header_pointer(skb_in,						 skb_in->nh.raw +						 (iph->ihl << 2) +						 offsetof(struct icmphdr,							  type) -						 skb_in->data,						 sizeof(_inner_type),						 &_inner_type);			if (itp == NULL)				goto out;			/*			 *	Assume any unknown ICMP type is an error. This			 *	isn't specified by the RFC, but think about it..			 */			if (*itp > NR_ICMP_TYPES ||			    icmp_pointers[*itp].error)				goto out;		}	}	if (icmp_xmit_lock())		return;	/*	 *	Construct source address and options.	 */	saddr = iph->daddr;	if (!(rt->rt_flags & RTCF_LOCAL))		saddr = 0;	tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) |					   IPTOS_PREC_INTERNETCONTROL) :					  iph->tos;	if (ip_options_echo(&icmp_param.replyopts, skb_in))		goto ende;	/*	 *	Prepare data for ICMP header.	 */	icmp_param.data.icmph.type	 = type;	icmp_param.data.icmph.code	 = code;	icmp_param.data.icmph.un.gateway = info;	icmp_param.data.icmph.checksum	 = 0;	icmp_param.skb	  = skb_in;	icmp_param.offset = skb_in->nh.raw - skb_in->data;	icmp_out_count(icmp_param.data.icmph.type);	inet_sk(icmp_socket->sk)->tos = tos;	ipc.addr = iph->saddr;	ipc.opt = &icmp_param.replyopts;	{		struct flowi fl = {			.nl_u = {				.ip4_u = {					.daddr = icmp_param.replyopts.srr ?						icmp_param.replyopts.faddr :						iph->saddr,					.saddr = saddr,					.tos = RT_TOS(tos)				}			},			.proto = IPPROTO_ICMP,			.uli_u = {				.icmpt = {					.type = type,					.code = code				}			}		};		if (ip_route_output_key(&rt, &fl))			goto out_unlock;	}	if (!icmpv4_xrlim_allow(rt, type, code))		goto ende;	/* RFC says return as much as we can without exceeding 576 bytes. */	room = dst_mtu(&rt->u.dst);	if (room > 576)		room = 576;	room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen;	room -= sizeof(struct icmphdr);	icmp_param.data_len = skb_in->len - icmp_param.offset;	if (icmp_param.data_len > room)		icmp_param.data_len = room;	icmp_param.head_len = sizeof(struct icmphdr);	icmp_push_reply(&icmp_param, &ipc, rt);ende:	ip_rt_put(rt);out_unlock:	icmp_xmit_unlock();out:;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/1c2fb7f93cb20621772bf304f3dba0849942e5db/icmp.c/clean/net/ipv4/icmp.c