Linux kernel Analysis

Source: Internet
Author: User
Tags echo message

Kernel version: 2.6.34

ICMP module is relatively simple, you should pay attention to the ICMP rate limiting policy, to the IP layer transfer data Ip_append_data () and Ip_push_pending_frames ().

In Net/ipv4/af_inet.c, the Inet_init () registers the ICMP protocol, and it can be seen from here that the ICMP module is bound to the IP module. Inet_add_protocol () adds Icmp_protocol to the global volume Inet_protos.

if (Inet_add_protocol (&icmp_protocol, ipproto_icmp) < 0)     
 PRINTK (kern_crit "Inet_init:cannot add ICMP Protocol\n ");     
The ICMP_PROTOCOL definition is as follows:     
static const struct Net_protocol Icmp_protocol = {     
 . Handler = ICMP_RCV,     
 . No_policy = 1,< C6/>.NETNS_OK = 1,     
};

In addition to registering the ICMP protocol, initialize the ICMP module, which is completed by Icmp_init ().

if (Icmp_init () < 0)     
 panic ("Failed to create the ICMP control socket.\n");

The Icmp_init () function is simple, register_pernet_subsys (&icmp_sk_ops), while registering the ICMP network subsystem calls Icmp_sk_ops.init (that is, icmp_sk_ init function) To complete its initialization, see the Icmp_sk_init () function in the following detail.

First, the net is to match the number of CPUs (Nr_cpu_ids) a struct sock structure space, where the net is the global network name, is generally init_inet.
Net->ipv4.icmp_sk = Kzalloc (nr_cpu_ids * sizeof (struct sock *), Gfp_kernel);

Each CPU I, its sock structure is located in net icmp_sk[i]. On each CPU I, initialize the icmp_sk[i that has just been allocated:

-The first step, Inet_ctl_sock_create () creates SK and assigns it to icmp_sk[i in net->ipv4.icmp_sk[i] = sk.

-Step two: ICMP send buffer size sk_sndbuf set to 128K

FOR_EACH_POSSIBLE_CPU (i) { 

    
 struct sock *sk;     
 Err = Inet_ctl_sock_create (&sk, pf_inet,     
    sock_raw, ipproto_icmp, net);     
 if (Err < 0)     
  Goto fail;     
         
 Net->ipv4.icmp_sk[i] = SK;     
 Sk->sk_sndbuf =     
  (2 * (1024) + sizeof (struct sk_buff)));     
 Sock_set_flag (SK, sock_use_write_queue);     
 Inet_sk (SK)->pmtudisc = Ip_pmtudisc_dont;     
}

Ignoring the ICMP echo message sent to the broadcast address, ignoring the wrong response message sent to the broadcast address;

net-

>ipv4.sysctl_icmp_echo_ignore_all = 0;     
net->ipv4.sysctl_icmp_echo_ignore_broadcasts = 1;     
net->ipv4.sysctl_icmp_ignore_bogus_error_responses = 1;

Set the ICMP processing rate, where the ratelimit and Ratemask parameters are used specifically for subsequent speed limit processing.

Net->ipv4.sysctl_icmp_ratelimit = 1 * HZ;     
Net->ipv4.sysctl_icmp_ratemask = 0x1818;     
net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0;

After the initialization is completed, or from the receiving of ICMP, ICMP_RCV completes the processing of ICMP packets.
Gets the ICMP header, at which point Skb->transport_header is set in the IP module Processing ip_local_deliver_finish () to point to the ICMP header location.

icmph = ICMP_HDR (SKB);

The type of ICMP is assigned to a different handler function.

Icmp_pointers[icmph->type].handler (SKB);

Icmp_pointers is the global amount defined in Icmp.c, in part as follows:

static const struct Icmp_control icmp_pointers[nr_icmp_types + 1] = {     
 [icmp_echoreply] = {     
  . Handler = Icmp_discard ,     
 },     
 [1] = {     
  . Handler = Icmp_discard,     
  . Error = 1,     
 }, ...     
}

For example, for the received ICMP message type 0 or 1 (response or Destination unreachable), the protocol stack to do is discard it –icmp_discard (). Examples of ICMP echo and ICMP timestamp are described below.

Received ICMP echo message execution Icmp_echo ()

Icmp_param is a reply-time message that directly copies the Echo's ICMP header Icmp_hdr (SKB), only changing the header's type = Icmp_echo_reply, and then calling icmp_reply () processing the send.

struct ICMP_BXM icmp_param;     
icmp_param.data.icmph    = *ICMP_HDR (SKB);     
Icmp_param.data.icmph.type = icmp_echoreply;     
ICMP_PARAM.SKB     = SKB;     
Icmp_param.offset    = 0;     
Icmp_param.data_len    = skb->len;     
Icmp_param.head_len    = sizeof (struct ICMPHDR);     
Icmp_reply (&icmp_param, SKB);

Execute icmp_timestamp after receiving ICMP timestamp message ()

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.