简易ping程序的问题,弄了两天,没有弄出来。

软件和网站开发以及相关技术探讨
回复
lkcgood
帖子: 2
注册时间: 2006-05-07 19:29

简易ping程序的问题,弄了两天,没有弄出来。

#1

帖子 lkcgood » 2006-07-23 10:11

发送是发送了,但就是没有接收,我估计是icmp报头的问题,
大虾帮帮忙呀,小弟在此静候佳音,不胜感激。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>
#include <pthread.h>

#define BUFSIZE 1024
#define PACKET_LEN 72
#define oops(s) {perror(s); exit(EXIT_FAILURE);}
#define oohs(s) {herror(s); exit(EXIT_FAILURE);}
#define USAGE "USAGE:%s <hostname>.\n"

int sockfd;
struct sockaddr_in send_addr;

u_short check_sum(u_short *, int );
void make_icmp_packet(char *, int, int);
float calc_time(struct timeval *, struct timeval *);
void *receiver();
void *sender();

int main(int argc, char **argv)
{
struct hostent *hp;
pthread_t recv_thread;
pthread_t send_thread;

if(argc != 2)
{
printf(USAGE, argv[0]);
exit(EXIT_FAILURE);
}
if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
oops("RAW SOCKET");

bzero((void *)&send_addr, sizeof(send_addr));
if((hp = gethostbyname(argv[1])) == NULL)
oohs("Gethostbyname");

send_addr.sin_family = AF_INET;
bcopy((void *)hp->h_addr, (void *)&send_addr.sin_addr, hp->h_length);
printf("PING %s(%s).\n",inet_ntoa(send_addr.sin_addr), hp->h_name);
pthread_create(&send_thread, NULL, sender, NULL);
pthread_create(&recv_thread, NULL, receiver, NULL);

pthread_join(send_thread, NULL);
pthread_join(recv_thread, NULL);

return EXIT_SUCCESS;
}

void *sender()
{
char send_buff[PACKET_LEN];
struct timeval timeout;
int send_len;
fd_set fds;
static int i = 0;
timeout.tv_sec = 0;
timeout.tv_usec = 100 * 1000;
while(1)
{
make_icmp_packet(send_buff, PACKET_LEN, (i == 256) ? 0 : (i ++));
if(select(0, NULL, NULL, NULL, &timeout) <= 0)
{
if((send_len = sendto(sockfd, send_buff, PACKET_LEN, 0, (struct sockaddr *)&send_addr,
sizeof(struct sockaddr))) < 0)
oops("SENDTO");
timeout.tv_sec = 0;
timeout.tv_usec = 100 * 1000;
}
}
}

void *receiver()
{
char recv_buff[BUFSIZE];
int recv_len;
while(1)
{
if((recv_len = recvfrom(sockfd, recv_buff, BUFSIZE, 0, NULL, NULL)) < 0)
oops("RECVFROM");

printf("%d bytes received!\n", recv_len);
}
}

void make_icmp_packet(char *buff, int len, int seq)
{
struct icmp *icmp = (struct icmp *)buff;
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_code = 0;
icmp->icmp_cksum = 0;
icmp->icmp_id = 0;
icmp->icmp_seq = seq;
gettimeofday((struct timeval *)icmp->icmp_data, (struct timezone *)0);
icmp->icmp_cksum = check_sum((u_short *)buff, len);
}

u_short check_sum(u_short *data, int len)
{
register u_short *p = data;
register int nleft = len;
register u_short sum = 0;

for(; nleft > 1; nleft -= 2)
sum += *p++;

if(nleft == 1)
{
u_short i = 0;
*(u_char *)&i = *(u_char *)p;
sum += i;
}

sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}

float calc_time(struct timeval *out, struct timeval *in)
{
return (float)((out->tv_sec * 1000.0 + out->tv_usec / 1000.0)
-
(in->tv_sec * 1000.0 + in->tv_usec / 1000.0));
}
回复