/*
Reference Code http://bbs.csdn.net/topics/230001156
Original version of Win32
This has been modified to UNIX version
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <netdb.h>//gethostbyname
typedef int SOCKET;
typedef struct ICMP_HDR
{
unsigned char icmp_type; Message type
unsigned char icmp_code; Code
unsigned short icmp_checksum; Checksum
Here is the Echo header
unsigned short icmp_id; ID number used to uniquely identify this request
unsigned short icmp_sequence; Serial number
unsigned long icmp_timestamp; Time stamp
} ICMP_HDR, *picmp_hdr;
typedef struct _IPHEADER//20-byte IP header
{
uint8_t Iphverlen; Version number and head length (4 bits each)
uint8_t Iptos; Service type
uint16_t iplength; Total packet length, which is the length of the entire IP report
uint16_t IpID; Packet identity, the unique identity of each number of messages sent
uint16_t Ipflags; Sign
uint8_t Ipttl; Time To Live is TTL
uint8_t Ipprotocol; protocol, which may be TCP, UDP, ICMP, etc.
uint16_t ipchecksum; Checksum
uint32_t Ipsource; Source IP Address
uint32_t ipdestination; Destination IP Address
} Ipheader, *pipheader;
uint16_t Checksum (uint16_t* buff, int size);
BOOL SetTimeout (SOCKET s, int ntime, bool brecv = TRUE);
int main (int args, const char * * argv)
{
Destination IP address, which is the IP address to ping
const char * Szdestip = (args > 1)? argv[1]: "127.0.0.1";
uint16_t PID = (uint16_t):: Time (0);
To create the original nested section Word
Socket Sraw =:: Socket (af_inet, Sock_raw, ipproto_icmp);
if (Sraw = =-1)
{
Auto Eno = errno;
if (Eno = = 1)
{
You must use sudo to create a raw socket
printf ("Operation not permitted!\n");
}
Else
{
printf ("Cannot create socket! Error%d ", Eno);
}
return-1;
}
Set the Receive timeout
if (! SetTimeout (Sraw, +, TRUE))
{
printf ("Cannot set timeout!\n");
}
Set Destination Address
Sockaddr_in dest;
dest.sin_family = af_inet;
Dest.sin_port = htons (0);
DEST.SIN_ADDR.S_ADDR = inet_addr (Szdestip);
Create an ICMP packet
Char buff[sizeof (ICMP_HDR) + 32];
icmp_hdr* picmp = (icmp_hdr*) buff;
Filling in ICMP packet data
Picmp->icmp_type = 8; Request an ICMP echo
Picmp->icmp_code = 0;
picmp->icmp_id = (uint16_t) PID;
picmp->icmp_checksum = 0;
picmp->icmp_sequence = 0;
The Fill Data section, which can be used for any
memset (&buff[sizeof (ICMP_HDR)], ' E ', 32);
Start sending and receiving ICMP packets
uint16_t nseq = 0;
Char recvbuf[1024];
Sockaddr_in from;
socklen_t Nlen = sizeof (from);
while (TRUE)
{
static int ncount = 0;
Long nret;
if (ncount++ = = 4)
Break
picmp->icmp_checksum = 0;
Picmp->icmp_timestamp =:: Clock ();
Picmp->icmp_sequence = nseq++;
Picmp->icmp_checksum = Checksum ((uint16_t*) buff, sizeof (ICMP_HDR) + 32);
Nret = (long):: SendTo (Sraw, Buff, sizeof (ICMP_HDR) + 32,
0, (SOCKADDR *) &dest, sizeof (dest));
if (nret = =-1)
{
printf ("SendTo () failed:%d \ n", errno);
return-1;
}
Nret = (long):: Recvfrom (Sraw, Recvbuf, 1024x768, 0, (sockaddr*) &from, &nlen);
if (nret = =-1)
{
printf ("Recvfrom () failed:%d\n", errno);
return-1;
}
The following begins parsing the received ICMP packets
Auto Ntick =:: Clock ();
if (Nret < sizeof (Ipheader) + sizeof (ICMP_HDR))
{
printf ("Too few bytes from%s \ n",:: Inet_ntoa (FROM.SIN_ADDR));
}
The received data contains an IP header with an IP header size of 20 bytes, so add 20 to get the ICMP header
icmp_hdr* precvicmp = (icmp_hdr*) (Recvbuf + 20); (icmp_hdr*) (recvbuf + sizeof (ipheader));
if (Precvicmp->icmp_type! = 0)//Echo
{
printf ("Nonecho type%d RECVD \ n", Precvicmp->icmp_type);
return-1;
}
if (precvicmp->icmp_id! = PID)
{
printf ("Someone else ' s packet! \ n ");
return-1;
}
printf ("%d bytes from%s:", (int) nret, Inet_ntoa (FROM.SIN_ADDR));
printf ("icmp_seq =%d.", precvicmp->icmp_sequence);
printf ("Time:%d MS", (int) Ntick-(int) precvicmp->icmp_timestamp);
printf ("\ n");
}
return 0;
}
uint16_t Checksum (uint16_t* buff, int size)
{
unsigned long cksum = 0;
while (size>1)
{
Cksum + = *buff++;
Size-= sizeof (uint16_t);
}
is odd
if (size)
{
Cksum + = * (uint8_t*) buff;
}
Add the 32-bit chsum high 16-bit and low 16-bit, then take the inverse
while (Cksum >> 16)
Cksum = (cksum >> +) + (Cksum & 0xFFFF);
Return (uint16_t) (~cksum);
}
BOOL SetTimeout (SOCKET s, int ntime, BOOL brecv)
{
int ret =:: setsockopt (S, Sol_socket,
Brecv? So_rcvtimeo:so_sndtimeo, (char*) &ntime, sizeof (ntime));
return ret! =-1;
}
ping function with socket (logging)