97 lines
2.2 KiB
C
97 lines
2.2 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/select.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <errno.h>
|
|
|
|
#include "ping.h"
|
|
#include "socket4.h"
|
|
#include "socket6.h"
|
|
|
|
int in_cksum( unsigned short *p, int n );
|
|
int random_data_flag = 1;
|
|
|
|
/* sized so as to be like traditional ping */
|
|
#define DEFAULT_PING_DATA_SIZE 56
|
|
|
|
int ping(char *ip_dest)
|
|
{
|
|
int sockfd;
|
|
struct sockaddr_in des_addr, recv_addr;
|
|
unsigned char recv_buf[1024];
|
|
int len;
|
|
fd_set fds;
|
|
struct timeval tv;
|
|
int ret = -1;;
|
|
|
|
int socktype4 = -1;
|
|
sockfd = open_ping_socket_ipv4(&socktype4);
|
|
if(sockfd < 0) {
|
|
//printf("create socket failed\n");
|
|
ret = -1;
|
|
goto error;
|
|
}else{
|
|
//printf("sockfd = %d\n", sockfd);
|
|
}
|
|
|
|
#if 1
|
|
struct sockaddr_in local_addr;
|
|
|
|
bzero(&local_addr, sizeof(struct sockaddr_in));
|
|
local_addr.sin_family = AF_INET;
|
|
local_addr.sin_addr.s_addr = htonl(INADDR_ANY); //使用本机器上的任何一个可用IP
|
|
local_addr.sin_port = htons(0);
|
|
bind(sockfd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in));
|
|
#endif
|
|
|
|
/* send ping package */
|
|
des_addr.sin_family = AF_INET;
|
|
des_addr.sin_addr.s_addr = inet_addr(ip_dest);
|
|
des_addr.sin_port = htons(0);
|
|
init_ping_buffer_ipv4(DEFAULT_PING_DATA_SIZE);
|
|
ret = socket_sendto_ping_ipv4(sockfd, (struct sockaddr *)&des_addr, sizeof(des_addr), 0, 61696);
|
|
if(ret < 0){
|
|
char buf[128] = "";
|
|
|
|
strerror_r(errno, buf, sizeof(buf));
|
|
//printf("socket_sendto_ping_ipv4 ret = %d, message: %s\n", ret, buf);
|
|
ret = -6;
|
|
goto error;
|
|
}
|
|
uninit_ping_buffer_ipv4();
|
|
|
|
tv.tv_sec = 0;
|
|
tv.tv_usec = 500*1000;
|
|
FD_ZERO(&fds);
|
|
FD_SET(sockfd, &fds);
|
|
ret = select(FD_SETSIZE, &fds, NULL, NULL, &tv);
|
|
if(ret < 0){
|
|
//printf("ping seclect error\n");
|
|
ret = -3;
|
|
goto error;
|
|
}else if(ret > 0){
|
|
len = sizeof(recv_addr);
|
|
ret = recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&recv_addr, (socklen_t *)&len);
|
|
if(ret < 0) {
|
|
//printf("recvfrom failed!!\n");
|
|
ret = -4;
|
|
goto error;
|
|
}
|
|
//printf("ping success receive data from: %s\n", inet_ntoa(recv_addr.sin_addr));
|
|
ret = 0;
|
|
return ret;
|
|
}else{
|
|
//printf("ping time out\n");
|
|
ret = -5;
|
|
goto error;
|
|
}
|
|
error:
|
|
close(sockfd);
|
|
return ret;
|
|
}
|