Main Page | Class List | File List | Class Members | File Members

icmp.c File Reference

#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fcntl.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/string.h>
#include <linux/netfilter_ipv4.h>
#include <net/snmp.h>
#include <net/ip.h>
#include <net/route.h>
#include <net/protocol.h>
#include <net/icmp.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/raw.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <linux/errno.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <net/checksum.h>

Go to the source code of this file.

Classes

struct  icmp_bxm
struct  icmp_control

Defines

#define icmp_socket   (&__icmp_inode[smp_processor_id()].u.socket_i)
#define icmp_socket_cpu(X)   (&__icmp_inode[(X)].u.socket_i)
#define XRLIM_BURST_FACTOR   6

Functions

int icmp_xmit_lock (void)
void icmp_xmit_unlock (void)
int xrlim_allow (struct dst_entry *dst, int timeout)
int icmpv4_xrlim_allow (struct rtable *rt, int type, int code)
void icmp_out_count (int type)
int icmp_glue_bits (const void *p, char *to, unsigned int offset, unsigned int fraglen)
void icmp_reply (struct icmp_bxm *icmp_param, struct sk_buff *skb)
void icmp_send (struct sk_buff *skb_in, int type, int code, u32 info)
void icmp_unreach (struct sk_buff *skb)
void icmp_redirect (struct sk_buff *skb)
void icmp_echo (struct sk_buff *skb)
void icmp_timestamp (struct sk_buff *skb)
void icmp_address (struct sk_buff *skb)
void icmp_address_reply (struct sk_buff *skb)
void icmp_discard (struct sk_buff *skb)
int icmp_rcv (struct sk_buff *skb)
void __init icmp_init (struct net_proto_family *ops)

Variables

icmp_mib icmp_statistics [NR_CPUS *2]
icmp_err icmp_err_convert []
int sysctl_ip_default_ttl
int sysctl_icmp_echo_ignore_all
int sysctl_icmp_echo_ignore_broadcasts
int sysctl_icmp_ignore_bogus_error_responses
int sysctl_icmp_ratelimit = 1*HZ
int sysctl_icmp_ratemask = 0x1818
icmp_control icmp_pointers [NR_ICMP_TYPES+1]
inode __icmp_inode [NR_CPUS]


Define Documentation

#define icmp_socket   (&__icmp_inode[smp_processor_id()].u.socket_i)
 

Definition at line 187 of file icmp.c.

Referenced by icmp_reply(), icmp_send(), icmp_xmit_lock(), and icmp_xmit_unlock().

#define icmp_socket_cpu  )     (&__icmp_inode[(X)].u.socket_i)
 

Definition at line 188 of file icmp.c.

Referenced by icmp_init().

#define XRLIM_BURST_FACTOR   6
 

Definition at line 229 of file icmp.c.

Referenced by xrlim_allow().


Function Documentation

void icmp_address struct sk_buff skb  )  [static]
 

Definition at line 808 of file icmp.c.

References net_ratelimit().

00809 { 00810 #if 0 00811 if (net_ratelimit()) 00812 printk(KERN_DEBUG "a guy asks for address mask. Who is it?\n"); 00813 #endif 00814 }

void icmp_address_reply struct sk_buff skb  )  [static]
 

Definition at line 821 of file icmp.c.

References sk_buff::dev, sk_buff::dst, IN_DEV_FORWARD, in_dev_get(), IN_DEV_LOG_MARTIANS, in_dev_put(), inet_ifa_match(), sk_buff::len, net_ratelimit(), and skb_copy_bits().

00822 { 00823 struct rtable *rt = (struct rtable*)skb->dst; 00824 struct net_device *dev = skb->dev; 00825 struct in_device *in_dev; 00826 struct in_ifaddr *ifa; 00827 u32 mask; 00828 00829 if (skb->len < 4 || !(rt->rt_flags&RTCF_DIRECTSRC)) 00830 return; 00831 00832 in_dev = in_dev_get(dev); 00833 if (!in_dev) 00834 return; 00835 read_lock(&in_dev->lock); 00836 if (in_dev->ifa_list && 00837 IN_DEV_LOG_MARTIANS(in_dev) && 00838 IN_DEV_FORWARD(in_dev)) { 00839 if (skb_copy_bits(skb, 0, &mask, 4)) 00840 BUG(); 00841 for (ifa=in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { 00842 if (mask == ifa->ifa_mask && inet_ifa_match(rt->rt_src, ifa)) 00843 break; 00844 } 00845 if (!ifa && net_ratelimit()) { 00846 printk(KERN_INFO "Wrong address mask %u.%u.%u.%u from %s/%u.%u.%u.%u\n", 00847 NIPQUAD(mask), dev->name, NIPQUAD(rt->rt_src)); 00848 } 00849 } 00850 read_unlock(&in_dev->lock); 00851 in_dev_put(in_dev); 00852 }

void icmp_discard struct sk_buff skb  )  [static]
 

Definition at line 854 of file icmp.c.

00855 { 00856 }

void icmp_echo struct sk_buff skb  )  [static]
 

Definition at line 719 of file icmp.c.

References icmp_bxm::data, icmp_bxm::data_len, sk_buff::h, icmp_bxm::head_len, icmp_reply(), sk_buff::len, icmp_bxm::offset, icmp_bxm::skb, and sysctl_icmp_echo_ignore_all.

00720 { 00721 if (!sysctl_icmp_echo_ignore_all) { 00722 struct icmp_bxm icmp_param; 00723 00724 icmp_param.data.icmph=*skb->h.icmph; 00725 icmp_param.data.icmph.type=ICMP_ECHOREPLY; 00726 icmp_param.skb=skb; 00727 icmp_param.offset=0; 00728 icmp_param.data_len=skb->len; 00729 icmp_param.head_len=sizeof(struct icmphdr); 00730 icmp_reply(&icmp_param, skb); 00731 } 00732 }

int icmp_glue_bits const void *  p,
char *  to,
unsigned int  offset,
unsigned int  fraglen
[static]
 

Definition at line 284 of file icmp.c.

References csum_fold(), csum_partial_copy_nocheck(), and skb_copy_and_csum_bits().

Referenced by icmp_reply(), and icmp_send().

00285 { 00286 struct icmp_bxm *icmp_param = (struct icmp_bxm *)p; 00287 struct icmphdr *icmph; 00288 unsigned int csum; 00289 00290 if (offset) { 00291 icmp_param->csum=skb_copy_and_csum_bits(icmp_param->skb, 00292 icmp_param->offset+(offset-icmp_param->head_len), 00293 to, fraglen,icmp_param->csum); 00294 return 0; 00295 } 00296 00297 /* 00298 * First fragment includes header. Note that we've done 00299 * the other fragments first, so that we get the checksum 00300 * for the whole packet here. 00301 */ 00302 csum = csum_partial_copy_nocheck((void *)&icmp_param->data, 00303 to, icmp_param->head_len, 00304 icmp_param->csum); 00305 csum=skb_copy_and_csum_bits(icmp_param->skb, 00306 icmp_param->offset, 00307 to+icmp_param->head_len, 00308 fraglen-icmp_param->head_len, 00309 csum); 00310 icmph=(struct icmphdr *)to; 00311 icmph->checksum = csum_fold(csum); 00312 return 0; 00313 }

void __init icmp_init struct net_proto_family ops  ) 
 

Definition at line 967 of file icmp.c.

References __icmp_inode, net_proto_family::create, icmp_socket_cpu, IP_PMTUDISC_DONT, IPPROTO_ICMP, MAXTTL, SK_WMEM_MAX, and SS_UNCONNECTED.

Referenced by inet_init().

00968 { 00969 int err, i; 00970 00971 for (i = 0; i < NR_CPUS; i++) { 00972 __icmp_inode[i].i_mode = S_IFSOCK; 00973 __icmp_inode[i].i_sock = 1; 00974 __icmp_inode[i].i_uid = 0; 00975 __icmp_inode[i].i_gid = 0; 00976 init_waitqueue_head(&__icmp_inode[i].i_wait); 00977 init_waitqueue_head(&__icmp_inode[i].u.socket_i.wait); 00978 00979 icmp_socket_cpu(i)->inode = &__icmp_inode[i]; 00980 icmp_socket_cpu(i)->state = SS_UNCONNECTED; 00981 icmp_socket_cpu(i)->type = SOCK_RAW; 00982 00983 if ((err=ops->create(icmp_socket_cpu(i), IPPROTO_ICMP)) < 0) 00984 panic("Failed to create the ICMP control socket.\n"); 00985 00986 icmp_socket_cpu(i)->sk->allocation=GFP_ATOMIC; 00987 icmp_socket_cpu(i)->sk->sndbuf = SK_WMEM_MAX*2; 00988 icmp_socket_cpu(i)->sk->protinfo.af_inet.ttl = MAXTTL; 00989 icmp_socket_cpu(i)->sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT; 00990 00991 /* Unhash it so that IP input processing does not even 00992 * see it, we do not wish this socket to see incoming 00993 * packets. 00994 */ 00995 icmp_socket_cpu(i)->sk->prot->unhash(icmp_socket_cpu(i)->sk); 00996 } 00997 }

void icmp_out_count int  type  )  [static]
 

Definition at line 272 of file icmp.c.

References ICMP_INC_STATS, icmp_pointers, and icmp_control::output.

Referenced by icmp_reply(), and icmp_send().

00273 { 00274 if (type>NR_ICMP_TYPES) 00275 return; 00276 (icmp_pointers[type].output)[(smp_processor_id()*2+!in_softirq())*sizeof(struct icmp_mib)/sizeof(unsigned long)]++; 00277 ICMP_INC_STATS(IcmpOutMsgs); 00278 }

int icmp_rcv struct sk_buff skb  ) 
 

Definition at line 862 of file icmp.c.

References CHECKSUM_HW, CHECKSUM_NONE, sk_buff::csum, csum_fold(), sk_buff::dst, error, sk_buff::h, icmp_control::handler, ICMP_INC_STATS_BH, icmp_pointers, icmp_control::input, sk_buff::ip_summed, kfree_skb(), sk_buff::len, net_ratelimit(), NETDEBUG, pskb_pull(), skb_checksum(), and sysctl_icmp_echo_ignore_broadcasts.

00863 { 00864 struct icmphdr *icmph; 00865 struct rtable *rt = (struct rtable*)skb->dst; 00866 00867 ICMP_INC_STATS_BH(IcmpInMsgs); 00868 00869 switch (skb->ip_summed) { 00870 case CHECKSUM_HW: 00871 if ((u16)csum_fold(skb->csum) == 0) 00872 break; 00873 NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "icmp v4 hw csum failure\n")); 00874 case CHECKSUM_NONE: 00875 if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) 00876 goto error; 00877 default:; 00878 } 00879 00880 if (!pskb_pull(skb, sizeof(struct icmphdr))) 00881 goto error; 00882 00883 icmph = skb->h.icmph; 00884 00885 /* 00886 * 18 is the highest 'known' ICMP type. Anything else is a mystery 00887 * 00888 * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently discarded. 00889 */ 00890 if (icmph->type > NR_ICMP_TYPES) 00891 goto error; 00892 00893 00894 /* 00895 * Parse the ICMP message 00896 */ 00897 00898 if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST)) { 00899 /* 00900 * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be 00901 * silently ignored (we let user decide with a sysctl). 00902 * RFC 1122: 3.2.2.8 An ICMP_TIMESTAMP MAY be silently 00903 * discarded if to broadcast/multicast. 00904 */ 00905 if (icmph->type == ICMP_ECHO && 00906 sysctl_icmp_echo_ignore_broadcasts) { 00907 goto error; 00908 } 00909 if (icmph->type != ICMP_ECHO && 00910 icmph->type != ICMP_TIMESTAMP && 00911 icmph->type != ICMP_ADDRESS && 00912 icmph->type != ICMP_ADDRESSREPLY) { 00913 goto error; 00914 } 00915 } 00916 00917 icmp_pointers[icmph->type].input[smp_processor_id()*2*sizeof(struct icmp_mib)/sizeof(unsigned long)]++; 00918 (icmp_pointers[icmph->type].handler)(skb); 00919 00920 drop: 00921 kfree_skb(skb); 00922 return 0; 00923 error: 00924 ICMP_INC_STATS_BH(IcmpInErrors); 00925 goto drop; 00926 }

void icmp_redirect struct sk_buff skb  )  [static]
 

Definition at line 674 of file icmp.c.

References sk_buff::data, sk_buff::dev, sk_buff::h, ICMP_INC_STATS_BH, ip_rt_redirect(), sk_buff::len, sk_buff::nh, and pskb_may_pull().

00675 { 00676 struct iphdr *iph; 00677 unsigned long ip; 00678 00679 if (skb->len < sizeof(struct iphdr)) { 00680 ICMP_INC_STATS_BH(IcmpInErrors); 00681 return; 00682 } 00683 00684 /* 00685 * Get the copied header of the packet that caused the redirect 00686 */ 00687 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 00688 return; 00689 00690 iph = (struct iphdr *) skb->data; 00691 ip = iph->daddr; 00692 00693 switch (skb->h.icmph->code & 7) { 00694 case ICMP_REDIR_NET: 00695 case ICMP_REDIR_NETTOS: 00696 /* 00697 * As per RFC recommendations now handle it as 00698 * a host redirect. 00699 */ 00700 00701 case ICMP_REDIR_HOST: 00702 case ICMP_REDIR_HOSTTOS: 00703 ip_rt_redirect(skb->nh.iph->saddr, ip, skb->h.icmph->un.gateway, iph->saddr, iph->tos, skb->dev); 00704 break; 00705 default: 00706 break; 00707 } 00708 }

void icmp_reply struct icmp_bxm icmp_param,
struct sk_buff skb
[static]
 

Driving logic for building and sending ICMP messages.

if the ICMP is not to be echoed, then drop Definition at line 318 of file icmp.c.

References ipcm_cookie::addr, icmp_bxm::csum, icmp_bxm::data, icmp_bxm::data_len, sk_buff::dst, ip_options::faddr, icmp_bxm::head_len, icmp_glue_bits(), icmp_out_count(), icmp_socket, icmp_xmit_lock(), icmp_xmit_unlock(), icmpv4_xrlim_allow(), ip_build_xmit(), ip_options_echo(), ip_route_output(), ip_rt_put(), sk_buff::nh, ipcm_cookie::opt, ip_options::optlen, icmp_bxm::replyopts, ip_options::srr, and sysctl_ip_default_ttl.

Referenced by icmp_echo(), and icmp_timestamp().

00319 { 00320 struct sock *sk=icmp_socket->sk; 00321 struct ipcm_cookie ipc; 00322 struct rtable *rt = (struct rtable*)skb->dst; 00323 u32 daddr; 00324 00326 if (ip_options_echo(&icmp_param->replyopts, skb)) 00327 return; 00328 00329 if (icmp_xmit_lock()) 00330 return; 00331 00332 icmp_param->data.icmph.checksum=0; 00333 icmp_param->csum=0; 00334 icmp_out_count(icmp_param->data.icmph.type); 00335 00336 sk->protinfo.af_inet.tos = skb->nh.iph->tos; 00337 sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl; 00338 daddr = ipc.addr = rt->rt_src; 00339 ipc.opt = NULL; 00340 if (icmp_param->replyopts.optlen) { 00341 ipc.opt = &icmp_param->replyopts; 00342 if (ipc.opt->srr) 00343 daddr = icmp_param->replyopts.faddr; 00344 } 00345 if (ip_route_output(&rt, daddr, rt->rt_spec_dst, RT_TOS(skb->nh.iph->tos), 0)) 00346 goto out; 00347 if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type, 00348 icmp_param->data.icmph.code)) { 00349 ip_build_xmit(sk, icmp_glue_bits, icmp_param, 00350 icmp_param->data_len+icmp_param->head_len, 00351 &ipc, rt, MSG_DONTWAIT); 00352 } 00353 ip_rt_put(rt); 00354 out: 00355 icmp_xmit_unlock(); 00356 }

void icmp_send struct sk_buff skb_in,
int  type,
int  code,
u32  info
 

Definition at line 369 of file icmp.c.

References ipcm_cookie::addr, icmp_bxm::csum, icmp_bxm::data, sk_buff::data, sk_buff::dst, icmp_control::error, ip_options::faddr, sk_buff::head, icmp_glue_bits(), icmp_out_count(), icmp_pointers, icmp_socket, icmp_xmit_lock(), icmp_xmit_unlock(), icmpv4_xrlim_allow(), ip_build_xmit(), IP_OFFSET, ip_options_echo(), ip_route_output(), ip_rt_put(), IPCB, IPPROTO_ICMP, IPSKB_TRANSLATED, IPTOS_PREC_INTERNETCONTROL, IPTOS_TOS_MASK, sk_buff::len, sk_buff::nh, icmp_bxm::offset, ipcm_cookie::opt, sk_buff::pkt_type, icmp_bxm::replyopts, icmp_bxm::skb, skb_copy_bits(), ip_options::srr, sysctl_ip_default_ttl, and sk_buff::tail.

Referenced by fw_in(), ip_error(), ip_expire(), ip_forward(), ip_local_deliver_finish(), ip_options_compile(), ip_options_rcv_srr(), ip_queue_xmit2(), ip_rt_send_redirect(), ip_vs_bypass_xmit(), ip_vs_dr_xmit(), ip_vs_in_icmp(), ip_vs_leave(), ip_vs_nat_xmit(), ip_vs_out(), ip_vs_tunnel_xmit(), ipgre_err(), ipgre_rcv(), ipgre_tunnel_xmit(), ipip_err(), ipip_rcv(), ipip_tunnel_xmit(), ipt_mirror_target(), ipv4_link_failure(), and udp_rcv().

00370 { 00371 struct iphdr *iph; 00372 int room; 00373 struct icmp_bxm icmp_param; 00374 struct rtable *rt = (struct rtable*)skb_in->dst; 00375 struct ipcm_cookie ipc; 00376 u32 saddr; 00377 u8 tos; 00378 00379 if (!rt) 00380 return; 00381 00382 /* 00383 * Find the original header. It is expected to be valid, of course. 00384 * Check this, icmp_send is called from the most obscure devices 00385 * sometimes. 00386 */ 00387 iph = skb_in->nh.iph; 00388 00389 if ((u8*)iph < skb_in->head || (u8*)(iph+1) > skb_in->tail) 00390 return; 00391 00392 /* 00393 * No replies to physical multicast/broadcast 00394 */ 00395 if (skb_in->pkt_type!=PACKET_HOST) 00396 return; 00397 00398 /* 00399 * Now check at the protocol level 00400 */ 00401 if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST)) 00402 return; 00403 00404 /* 00405 * Only reply to fragment 0. We byte re-order the constant 00406 * mask for efficiency. 00407 */ 00408 if (iph->frag_off&htons(IP_OFFSET)) 00409 return; 00410 00411 /* 00412 * If we send an ICMP error to an ICMP error a mess would result.. 00413 */ 00414 if (icmp_pointers[type].error) { 00415 /* 00416 * We are an error, check if we are replying to an ICMP error 00417 */ 00418 if (iph->protocol==IPPROTO_ICMP) { 00419 u8 inner_type; 00420 00421 if (skb_copy_bits(skb_in, 00422 skb_in->nh.raw + (iph->ihl<<2) 00423 + offsetof(struct icmphdr, type) 00424 - skb_in->data, 00425 &inner_type, 1)) 00426 return; 00427 00428 /* 00429 * Assume any unknown ICMP type is an error. This isn't 00430 * specified by the RFC, but think about it.. 00431 */ 00432 if (inner_type>NR_ICMP_TYPES || icmp_pointers[inner_type].error) 00433 return; 00434 } 00435 } 00436 00437 if (icmp_xmit_lock()) 00438 return; 00439 00440 /* 00441 * Construct source address and options. 00442 */ 00443 00444 #ifdef CONFIG_IP_ROUTE_NAT 00445 /* 00446 * Restore original addresses if packet has been translated. 00447 */ 00448 if (rt->rt_flags&RTCF_NAT && IPCB(skb_in)->flags&IPSKB_TRANSLATED) { 00449 iph->daddr = rt->key.dst; 00450 iph->saddr = rt->key.src; 00451 } 00452 #endif 00453 00454 saddr = iph->daddr; 00455 if (!(rt->rt_flags & RTCF_LOCAL)) 00456 saddr = 0; 00457 00458 tos = icmp_pointers[type].error ? 00459 ((iph->tos & IPTOS_TOS_MASK) | IPTOS_PREC_INTERNETCONTROL) : 00460 iph->tos; 00461 00462 if (ip_route_output(&rt, iph->saddr, saddr, RT_TOS(tos), 0)) 00463 goto out; 00464 00465 if (ip_options_echo(&icmp_param.replyopts, skb_in)) 00466 goto ende; 00467 00468 00469 /* 00470 * Prepare data for ICMP header. 00471 */ 00472 00473 icmp_param.data.icmph.type=type; 00474 icmp_param.data.icmph.code=code; 00475 icmp_param.data.icmph.un.gateway = info; 00476 icmp_param.data.icmph.checksum=0; 00477 icmp_param.csum=0; 00478 icmp_param.skb=skb_in; 00479 icmp_param.offset=skb_in->nh.raw - skb_in->data; 00480 icmp_out_count(icmp_param.data.icmph.type); 00481 icmp_socket->sk->protinfo.af_inet.tos = tos; 00482 icmp_socket->sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl; 00483 ipc.addr = iph->saddr; 00484 ipc.opt = &icmp_param.replyopts; 00485 if (icmp_param.replyopts.srr) { 00486 ip_rt_put(rt); 00487 if (ip_route_output(&rt, icmp_param.replyopts.faddr, saddr, RT_TOS(tos), 0)) 00488 goto out; 00489 } 00490 00491 if (!icmpv4_xrlim_allow(rt, type, code)) 00492 goto ende; 00493 00494 /* RFC says return as much as we can without exceeding 576 bytes. */ 00495 00496 room = rt->u.dst.pmtu; 00497 if (room > 576) 00498 room = 576; 00499 room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen; 00500 room -= sizeof(struct icmphdr); 00501 00502 icmp_param.data_len=skb_in->len-icmp_param.offset; 00503 if (icmp_param.data_len > room) 00504 icmp_param.data_len = room; 00505 icmp_param.head_len = sizeof(struct icmphdr); 00506 00507 ip_build_xmit(icmp_socket->sk, icmp_glue_bits, &icmp_param, 00508 icmp_param.data_len+sizeof(struct icmphdr), 00509 &ipc, rt, MSG_DONTWAIT); 00510 00511 ende: 00512 ip_rt_put(rt); 00513 out: 00514 icmp_xmit_unlock(); 00515 }

void icmp_timestamp struct sk_buff skb  )  [static]
 

Definition at line 742 of file icmp.c.

References icmp_bxm::data, icmp_bxm::data_len, sk_buff::h, icmp_bxm::head_len, ICMP_INC_STATS_BH, icmp_reply(), sk_buff::len, icmp_bxm::offset, icmp_bxm::skb, and skb_copy_bits().

00743 { 00744 struct timeval tv; 00745 struct icmp_bxm icmp_param; 00746 00747 /* 00748 * Too short. 00749 */ 00750 00751 if (skb->len < 4) { 00752 ICMP_INC_STATS_BH(IcmpInErrors); 00753 return; 00754 } 00755 00756 /* 00757 * Fill in the current time as ms since midnight UT: 00758 */ 00759 do_gettimeofday(&tv); 00760 icmp_param.data.times[1] = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000); 00761 icmp_param.data.times[2] = icmp_param.data.times[1]; 00762 if (skb_copy_bits(skb, 0, &icmp_param.data.times[0], 4)) 00763 BUG(); 00764 icmp_param.data.icmph=*skb->h.icmph; 00765 icmp_param.data.icmph.type=ICMP_TIMESTAMPREPLY; 00766 icmp_param.data.icmph.code=0; 00767 icmp_param.skb=skb; 00768 icmp_param.offset=0; 00769 icmp_param.data_len=0; 00770 icmp_param.head_len=sizeof(struct icmphdr)+12; 00771 icmp_reply(&icmp_param, skb); 00772 }

void icmp_unreach struct sk_buff skb  )  [static]
 

Definition at line 522 of file icmp.c.

References __raw_v4_lookup(), sk_buff::data, sk_buff::dev, inet_protocol::err_handler, sk_buff::h, ICMP_INC_STATS_BH, net_device::ifindex, inet_addr_type(), inet_protos, ip_rt_frag_needed(), MAX_INET_PROTOS, net_device::name, net_ratelimit(), inet_protocol::next, pskb_may_pull(), raw_err(), raw_v4_htable, raw_v4_lock, and sysctl_icmp_ignore_bogus_error_responses.

00523 { 00524 struct iphdr *iph; 00525 struct icmphdr *icmph; 00526 int hash, protocol; 00527 struct inet_protocol *ipprot; 00528 struct sock *raw_sk; 00529 u32 info = 0; 00530 00531 /* 00532 * Incomplete header ? 00533 * Only checks for the IP header, there should be an 00534 * additional check for longer headers in upper levels. 00535 */ 00536 00537 if (!pskb_may_pull(skb, sizeof(struct iphdr))) { 00538 ICMP_INC_STATS_BH(IcmpInErrors); 00539 return; 00540 } 00541 00542 icmph = skb->h.icmph; 00543 iph = (struct iphdr *) skb->data; 00544 00545 if (iph->ihl<5) { 00546 /* Mangled header, drop. */ 00547 ICMP_INC_STATS_BH(IcmpInErrors); 00548 return; 00549 } 00550 00551 if(icmph->type==ICMP_DEST_UNREACH) { 00552 switch(icmph->code & 15) { 00553 case ICMP_NET_UNREACH: 00554 break; 00555 case ICMP_HOST_UNREACH: 00556 break; 00557 case ICMP_PROT_UNREACH: 00558 break; 00559 case ICMP_PORT_UNREACH: 00560 break; 00561 case ICMP_FRAG_NEEDED: 00562 if (ipv4_config.no_pmtu_disc) { 00563 if (net_ratelimit()) 00564 printk(KERN_INFO "ICMP: %u.%u.%u.%u: fragmentation needed and DF set.\n", 00565 NIPQUAD(iph->daddr)); 00566 } else { 00567 info = ip_rt_frag_needed(iph, ntohs(icmph->un.frag.mtu)); 00568 if (!info) 00569 goto out; 00570 } 00571 break; 00572 case ICMP_SR_FAILED: 00573 if (net_ratelimit()) 00574 printk(KERN_INFO "ICMP: %u.%u.%u.%u: Source Route Failed.\n", NIPQUAD(iph->daddr)); 00575 break; 00576 default: 00577 break; 00578 } 00579 if (icmph->code>NR_ICMP_UNREACH) 00580 goto out; 00581 } else if (icmph->type == ICMP_PARAMETERPROB) { 00582 info = ntohl(icmph->un.gateway)>>24; 00583 } 00584 00585 /* 00586 * Throw it at our lower layers 00587 * 00588 * RFC 1122: 3.2.2 MUST extract the protocol ID from the passed header. 00589 * RFC 1122: 3.2.2.1 MUST pass ICMP unreach messages to the transport layer. 00590 * RFC 1122: 3.2.2.2 MUST pass ICMP time expired messages to transport layer. 00591 */ 00592 00593 /* 00594 * Check the other end isnt violating RFC 1122. Some routers send 00595 * bogus responses to broadcast frames. If you see this message 00596 * first check your netmask matches at both ends, if it does then 00597 * get the other vendor to fix their kit. 00598 */ 00599 00600 if (!sysctl_icmp_ignore_bogus_error_responses) 00601 { 00602 00603 if (inet_addr_type(iph->daddr) == RTN_BROADCAST) 00604 { 00605 if (net_ratelimit()) 00606 printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP type %u, code %u error to a broadcast: %u.%u.%u.%u on %s\n", 00607 NIPQUAD(iph->saddr), 00608 icmph->type, icmph->code, 00609 NIPQUAD(iph->daddr), 00610 skb->dev->name); 00611 goto out; 00612 } 00613 } 00614 00615 /* Checkin full IP header plus 8 bytes of protocol to 00616 * avoid additional coding at protocol handlers. 00617 */ 00618 if (!pskb_may_pull(skb, iph->ihl*4+8)) 00619 goto out; 00620 00621 iph = (struct iphdr *) skb->data; 00622 protocol = iph->protocol; 00623 00624 /* 00625 * Deliver ICMP message to raw sockets. Pretty useless feature? 00626 */ 00627 00628 /* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */ 00629 hash = protocol & (MAX_INET_PROTOS - 1); 00630 read_lock(&raw_v4_lock); 00631 if ((raw_sk = raw_v4_htable[hash]) != NULL) 00632 { 00633 while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, 00634 iph->saddr, skb->dev->ifindex)) != NULL) { 00635 raw_err(raw_sk, skb, info); 00636 raw_sk = raw_sk->next; 00637 iph = (struct iphdr *)skb->data; 00638 } 00639 } 00640 read_unlock(&raw_v4_lock); 00641 00642 /* 00643 * This can't change while we are doing it. 00644 * Callers have obtained BR_NETPROTO_LOCK so 00645 * we are OK. 00646 */ 00647 00648 ipprot = (struct inet_protocol *) inet_protos[hash]; 00649 while (ipprot) { 00650 struct inet_protocol *nextip; 00651 00652 nextip = (struct inet_protocol *) ipprot->next; 00653 00654 /* 00655 * Pass it off to everyone who wants it. 00656 */ 00657 00658 /* RFC1122: OK. Passes appropriate ICMP errors to the */ 00659 /* appropriate protocol layer (MUST), as per 3.2.2. */ 00660 00661 if (protocol == ipprot->protocol && ipprot->err_handler) 00662 ipprot->err_handler(skb, info); 00663 00664 ipprot = nextip; 00665 } 00666 out:; 00667 }

int icmp_xmit_lock void   )  [static]
 

Definition at line 190 of file icmp.c.

References icmp_socket.

Referenced by icmp_reply(), and icmp_send().

00191 { 00192 local_bh_disable(); 00193 if (unlikely(!spin_trylock(&icmp_socket->sk->lock.slock))) { 00194 /* This can happen if the output path signals a 00195 * dst_link_failure() for an outgoing ICMP packet. 00196 */ 00197 local_bh_enable(); 00198 return 1; 00199 } 00200 return 0; 00201 }

void icmp_xmit_unlock void   )  [static]
 

Definition at line 203 of file icmp.c.

References icmp_socket.

Referenced by icmp_reply(), and icmp_send().

00204 { 00205 spin_unlock_bh(&icmp_socket->sk->lock.slock); 00206 }

int icmpv4_xrlim_allow struct rtable rt,
int  type,
int  code
[inline, static]
 

Definition at line 246 of file icmp.c.

References sysctl_icmp_ratelimit, sysctl_icmp_ratemask, rtable::u, and xrlim_allow().

Referenced by icmp_reply(), and icmp_send().

00247 { 00248 struct dst_entry *dst = &rt->u.dst; 00249 00250 if (type > NR_ICMP_TYPES) 00251 return 1; 00252 00253 /* Don't limit PMTU discovery. */ 00254 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) 00255 return 1; 00256 00257 /* No rate limit on loopback */ 00258 if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) 00259 return 1; 00260 00261 /* Limit if icmp type is enabled in ratemask. */ 00262 if((1 << type) & sysctl_icmp_ratemask) 00263 return xrlim_allow(dst, sysctl_icmp_ratelimit); 00264 else 00265 return 1; 00266 }

int xrlim_allow struct dst_entry dst,
int  timeout
 

Definition at line 230 of file icmp.c.

References dst_entry::rate_last, dst_entry::rate_tokens, and XRLIM_BURST_FACTOR.

Referenced by icmpv4_xrlim_allow(), and send_unreach().

00231 { 00232 unsigned long now; 00233 00234 now = jiffies; 00235 dst->rate_tokens += now - dst->rate_last; 00236 dst->rate_last = now; 00237 if (dst->rate_tokens > XRLIM_BURST_FACTOR*timeout) 00238 dst->rate_tokens = XRLIM_BURST_FACTOR*timeout; 00239 if (dst->rate_tokens >= timeout) { 00240 dst->rate_tokens -= timeout; 00241 return 1; 00242 } 00243 return 0; 00244 }


Variable Documentation

struct inode __icmp_inode[NR_CPUS] [static]
 

Definition at line 186 of file icmp.c.

Referenced by icmp_init().

struct icmp_err icmp_err_convert[]
 

Initial value:

{ { ENETUNREACH, 0 }, { EHOSTUNREACH, 0 }, { ENOPROTOOPT, 1 }, { ECONNREFUSED, 1 }, { EMSGSIZE, 0 }, { EOPNOTSUPP, 0 }, { ENETUNREACH, 1 }, { EHOSTDOWN, 1 }, { ENONET, 1 }, { ENETUNREACH, 1 }, { EHOSTUNREACH, 1 }, { ENETUNREACH, 0 }, { EHOSTUNREACH, 0 }, { EHOSTUNREACH, 1 }, { EHOSTUNREACH, 1 }, { EHOSTUNREACH, 1 } }
Definition at line 123 of file icmp.c.

Referenced by raw_err(), tcp_v4_err(), and udp_err().

struct icmp_control icmp_pointers [static]
 

Definition at line 932 of file icmp.c.

Referenced by icmp_out_count(), icmp_rcv(), and icmp_send().

struct icmp_mib icmp_statistics[NR_CPUS *2]
 

Definition at line 118 of file icmp.c.

Referenced by snmp_get_info().

int sysctl_icmp_echo_ignore_all
 

Definition at line 145 of file icmp.c.

Referenced by icmp_echo().

int sysctl_icmp_echo_ignore_broadcasts
 

Definition at line 146 of file icmp.c.

Referenced by icmp_rcv().

int sysctl_icmp_ignore_bogus_error_responses
 

Definition at line 149 of file icmp.c.

Referenced by icmp_unreach().

int sysctl_icmp_ratelimit = 1*HZ
 

Definition at line 163 of file icmp.c.

Referenced by icmpv4_xrlim_allow().

int sysctl_icmp_ratemask = 0x1818
 

Definition at line 164 of file icmp.c.

Referenced by icmpv4_xrlim_allow().

int sysctl_ip_default_ttl
 

Definition at line 86 of file ip_output.c.


Generated on Wed Dec 1 21:25:34 2004 for Linux 2.4.23 Networking by doxygen 1.3.8