The usage and implementation principle of ping command in Linux

Source: Internet
Author: User
Tags get ip socket socket error dnn


The general format of the ping command is:
ping [-dfnqrrv][-c send number][-i interval seconds][-i network interface][-l Front load][-p template style][-s packet size][-t survival value [host name or IP address]


Parameter description:
-D uses the So_debug function of the socket.
-F limit detection. Send a large and fast network packet to a machine to see its response.
-N outputs only values.
-Q Displays no information about the delivery packet and displays only the final results.
-R ignores the normal routing table and sends the packet directly to the remote host. It is usually a matter of viewing the network interface on this computer.
-R to record the routing process.
-V details the execution of the instruction.
The-c number stops after sending the specified number of packages.
-I seconds set interval a few seconds to send a network packet to a machine, the default is a second send.
The-I network interface sends out packets using the specified network interface.
-L pre-load setting packets that are sent before the request information is sent.
The-P template style sets the template style that fills the packet.
-S bytes Specifies the number of bytes sent, the default value is 56, plus the 8-byte ICMP header, which is a total of 64ICMP data bytes.
-T survival value sets the size of the Live value TTL.


: Linux ping and ping under Windows slightly different, Linux ping does not automatically terminate, you need to press CTRL + C to terminate or use parameter-C to specify the number of responses required to complete

Linux to test the connectivity of the target host computer command is Ping, which mainly explains two parameters –c and – I

Where the number of –c count, which is the number of ping

-I interval interval, time space between pings

Introduction to the Ping principle

Ping Program Implementation

@ header file Common.h definition, contains header files used in the program and public variables, macros, constants, static variable definitions

#include <sys/socket.h>
#include <sys/time.h>
#include <sys/signal.h>

#include <netdb.h>

#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/in.h>

#include <unistd.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <ctype.h>

#include <errno.h>

#define Ip_head_len 20
#define Icmp_len 8
#define BUFFER_SIZE 50 * 1024

/*
* Original socket descriptor, as required in signal processor
* is shared with the main program, so it is defined as an external variable (global)
*/
int ip_fd;

/* Process Number * *
int p_id;

/*packet_len is the sum of the IP header and the ICMP header length * *
extern int Packet_len;

/* To end address * *
struct sockaddr_in send_addr;

/* Send Application Buffer * *
Char send_buf[1024];

* * Message Serial number * *
extern int sequence;

/* Host name pointer/*
struct Hostent *host;

/* Identity has received a palindrome */
int flag;


@ Main function MAIN.C definition

#include "Common.h"

Main (int argc, char **argv)
{

/* command is Ping host (host name) |ip_address (IP address) * *
if (argc!= 2)
{
/* Command not correct * *
fprintf (stderr, "usage:ping <HOST|IP_ADDRESS>.N");
Exit (1);
}

/* Create the original socket using ICMP, which can only be generated by root
IP_FD = socket (af_inet, Sock_raw, ipproto_icmp);
if (IP_FD < 0)
{
fprintf (stderr, "raw socket ERROR.N");
Exit (1);
}

/* Change the user ID of the process, Reclaim root permissions, set the current user rights/
Setuid (Getpid ());

Ping (argv[1]);
}

The establishment of the @ping framework ping.c for initializing ping-related information and port information

#include "Common.h"

/*
*handle_alarm used to send IP packets at timed intervals
*/
void handle_alarm (int signo)
{
Send_ip ();

Alarm (1);
}

Ping (char *argv)
{
struct Sigaction Act;

Act.sa_handler = Handle_alarm;
act.sa_flags = 0;
Sigemptyset (&act.sa_mask);
Sigaction (SIGALRM, &act, NULL);
/* Gets the process ID of main, which is used to set the ICMP identifier * *
p_id = Getpid ();

/* Enlarge socket Receive buffer to 50K this is mainly to reduce the possibility of receiving buffer overflow, if accidentally ping a broadcast address or multicast address, will attract a lot of response.
SetSockOpt (IP_FD, Sol_socket, So_rcvbuf, &buffer_size, sizeof (buffer_size));

/* Only address information, do not need to specify port information, because the original socket under the Transport layer * *
send_addr.sin_family = af_inet;

/* Determine whether the host name or IP address * *
if (inet_addr (argv) = = Inaddr_none)
{
/* is the host name * *
if ((host = gethostbyname (argv)) = = NULL)
{
/* Host name Error * *
Perror ("Get host by name Error:unknow host.");
Exit (1);
}
memcpy (&send_addr.sin_addr, host->h_addr, host->h_length);
}
Else
{
/* is the IP address */
Inet_aton (argv, &send_addr.sin_addr);
}

printf ("Ping%s (%s)%d (%d) bytes of Datan", argv,
Inet_ntoa (SEND_ADDR.SIN_ADDR), sizeof (struct timeval),
sizeof (struct timeval) + Ip_head_len + Icmp_len);

Flag = 0;
/* Trigger a SIGALRM signal * *
Raise (SIGALRM);
Recv_ip ();

}

@ Send Message SEND.C, set up ICMP message and package as IP packet, send

#include "Common.h"

int sequence = 0;
int Packet_len = Ip_head_len + Icmp_len;

/*
*SEND_IP is used to send IP packets containing ICMP packets
*/
Send_ip (void)
{
if (sequence!= 0 &&!flag)
{
printf ("Destination Host Unreachablen");
}
int Len;
struct ICMPHDR *icmp_p;

Icmp_p = (struct ICMPHDR *) send_buf;

/* Fill in ICMP message type * *
Icmp_p->type = Icmp_echo;
* * Fill in the ICMP message code/
Icmp_p->code = 0;
/* Fill in the ICMP message identifier * *
(icmp_p->un). echo.id = p_id;
/* Fill in the ICMP message serial number, and increase the ICMP serial number * *
(icmp_p->un). Echo.sequence = sequence + +;

/* Record Sending time * *
Gettimeofday ((struct timeval*) (icmp_p + 1), NULL);

   /*printf ("%dn", sizeof (struct ICMPHDR));
    printf ("Type:%dncode:%dnchecksum:%dnun.echo.id:%dnun.echo.sequence:%dnun.gateway:% dnun.frag.__unused:%d        nun.frag.mtu:%dnn ", Icmp_p->type, icmp_p-> Code, Icmp_p->checksum, (Icmp_p->un). Echo.id, (icmp_p-    >un). Echo.sequence, (icmp_p-> UN). Gateway, (Icmp_p->un) frag.__unused, (Icmp_p->un). Frag.mtu);
    printf ("Type:%dncode:%dnchecksum:%dnun.echo.id:%dnun.echo.sequence:%dnun.gateway:% dnun.frag.__unused:%d    nun.frag.mtu:%dnn ", sizeof (Icmp_p->type), sizeof (Icmp_p->code), sizeof (icmp_p->checksum), sizeof ((icmp_p-        >un). echo.id), sizeof ( Icmp_p->un). echo.sequence), sizeof ((Icmp_p->un). Gateway), sizeof ((Icmp_p->un). frag.__unused),          sizeof ((icmp_p->un). Frag.mtu)); */

/* Message length is equal to IP packet length plus ICMP message length and data length * *
len = sizeof (struct timeval) + Packet_len;

/* Compute the ICMP checksum by using the IP compute method of IP header checksum * *
icmp_p->checksum = 0;
Icmp_p->checksum = Ip_checksum (U_short *) icmp_p, Len);

/* Send IP packet * *
if (SendTo (IP_FD, Send_buf, Len, 0, (struct sockaddr*) &send_addr, sizeof (SEND_ADDR)) < 0)
{
fprintf (stderr, "Send to ERROR.N");
}
}


@ Data Verification CHECK_SUM.C implementation of network data verification work

#include "Common.h"

unsigned short ip_checksum (unsigned short *pcheck, int check_len)
{
int nleft = Check_len;
int sum = 0;
unsigned short *p = Pcheck;
unsigned short result = 0;

while (Nleft > 1)
{
sum = sum + *p + +;
Nleft-= 2;
}

if (Nleft = 1)
{
* (unsigned char *) (&result) = * (unsigned char *) p;
sum + = result;
}

sum = (sum >>) + (sum & 0xFFFF);
sum + = (sum >> 16);

result = SUM;

return result;
}


@ packet receives RECEIVE.C, receives IP message and analyzes, prints related information

#include "Common.h"

/*
*RECV_IP is used to accept IP packets containing ICMP packets
*/
Recv_ip (void)
{
Char recv_buf[1024];
int Len;
int n;

struct IP *ip_p;
struct Timeval *time_now, *time_send;
struct Timeval now;

int Iphead_len;
int Icmp_len;

struct ICMPHDR *icmp_p;

float delay;

while (1)
{
n = recvfrom (ip_fd, Recv_buf, sizeof (RECV_BUF), 0, NULL, NULL);
if (n < 0)
{
if (errno = eintr)
Continue
Else
{
printf ("Recvfrom ERROR.N");
Continue
}

}

Ip_p = (struct ip*) recv_buf;

/* Get IP Header Length * *
Iphead_len = ip_p->ip_hl<<2;
/* Get the ICMP message contained in the IP packet * *
Icmp_p = (struct ICMPHDR *) (recv_buf + Iphead_len);
/* Computes the length of the ICMP message, which equals the length of the received minus the length of the IP header.
Icmp_len = N-iphead_len;

if (Icmp_len < 8)
{
fprintf (stderr, "error ICMP len =%D.N", Icmp_len);
}

//* If the ICMP type is the same, the output is displayed * *
if (Icmp_p->type = = icmp_echoreply)
{
if ((Icmp_p->un). Echo.id!= p_id)
Return
if (Icmp_len < 16)
printf ("Icmplen =%D.N", Icmp_len);

Flag = 1;//said has received a palindrome;

Gettimeofday (&now, NULL);

Time_now = &now;
Time_send = (struct timeval*) (icmp_p + 1);

if ((time_now->tv_usec-= Time_send->tv_usec) < 0)
{
Time_now->tv_sec--;
Time_now->tv_usec + 1000000;
}

Time_now->tv_sec-= time_send->tv_sec;

/* Calculation Delay * *
Delay = time_now->tv_sec * 1000.0 + time_now->tv_usec/1000.0;

/* Print received message related information * *
printf ("%d (%d) bytes from%s:icmp_seq=%d ttl=%d time=%.3fmsn",
Icmp_len, N, Inet_ntoa (SEND_ADDR.SIN_ADDR), (Icmp_p->un). Echo.sequence,
Ip_p->ip_ttl, delay);
}
}
}

@makefile file

#小型ping程序
#用c语言编写
#2008年03月30日

CC = GCC

obj = main.o ping.o send.o receive.o CHECK_SUM.O

ping:$ (obj)
$ (cc) $ (obj)-O Ping

MAIN.O:MAIN.C Common.h ping.c
$ (CC)-C MAIN.C

PING.O:PING.C common.h receive.c SEND.C
$ (CC)-C ping.c

SEND.O:SEND.C Common.h CHECK_SUM.C
$ (CC)-C SEND.C

Receive.o:receive.c Common.h
$ (CC)-C receive.c

CHECK_SUM.O:CHECK_SUM.C Common.h
$ (CC)-C CHECK_SUM.C

Clean
Rm-f $ (obj)


References: "Linux network Programming"
Edited by Lin Yu Guo Lingyun
Published by People's Post and telecommunications press


enters makefile directory
Execute make-f makefile
    make clean can

Program Run Results: (platform Ubuntu)
lwj@lwj-desktop:~/desktop/c/myping$ make-f makefile
gcc-c main.c
gcc-c ping.c
GCC -C SEND.C
gcc-c receive.c
gcc-c check_sum.c
gcc main.o ping.o send.o receive.o check_sum.o-o Ping
lwj@ lwj-desktop:~/desktop/c/myping$ make clean
rm-f main.o ping.o send.o receive.o check_sum.o
lwj@lwj-desktop:~/ desktop/c/myping$ sudo./ping localhost
Password:
ping localhost (127.0.0.1) 8 (+) bytes of data
(a) bytes F Rom 127.0.0.1:icmp_seq=0 ttl=64 time=0.061ms
(a) bytes from 127.0.0.1:icmp_seq=1 ttl=64 time=0.051ms
() b Ytes from 127.0.0.1:icmp_seq=2 ttl=64 time=0.039ms
(a) bytes from 127.0.0.1:icmp_seq=3 ttl=64 time=0.051ms
36 (a) bytes from 127.0.0.1:icmp_seq=4 ttl=64 time=0.050ms
(a) bytes from 127.0.0.1:icmp_seq=5 ttl=64 br> bytes from 127.0.0.1:icmp_seq=6 ttl=64 time=0.051ms
(a) bytes from 127.0.0.1:icmp_seq=7 ttl=64. 053MS

[2]+ Stopped sudo./ping localhost
lwj@lwj-desktop:~/desktop/c/myping$ sudo./ping 10.3.2.206
Ping 10.3.2.206 (10.3.2.206) 8 (+) bytes of data
Bytes from 10.3.2.206:icmp_seq=0 ttl=64 time=0.233ms
Bytes from 10.3.2.206:icmp_seq=1 ttl=64 time=0.063ms
Bytes from 10.3.2.206:icmp_seq=2 ttl=64 time=0.044ms
Bytes from 10.3.2.206:icmp_seq=3 ttl=64 time=0.054ms
Bytes from 10.3.2.206:icmp_seq=4 ttl=64 time=0.044ms
Bytes from 10.3.2.206:icmp_seq=5 ttl=64 time=0.052ms
Bytes from 10.3.2.206:icmp_seq=6 ttl=64 time=0.058ms
Bytes from 10.3.2.206:icmp_seq=7 ttl=64 time=0.055ms
Bytes from 10.3.2.206:icmp_seq=8 ttl=64 time=0.066ms
Bytes from 10.3.2.206:icmp_seq=9 ttl=64 time=0.053ms
Bytes from 10.3.2.206:icmp_seq=10 ttl=64 time=0.053ms
Bytes from 10.3.2.206:icmp_seq=11 ttl=64 time=0.052ms

[3]+ Stopped sudo./ping 10.3.2.206
lwj@lwj-desktop:~/desktop/c/myping$ sudo./ping 10.3.2.205
Ping 10.3.2.205 (10.3.2.205) 8 (+) bytes of data

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.