📄 pingipv6.c
字号:
/*This is a test program used for IPV6*/#ifndef linyichar right[]="@#Copyright(c) 2005 the regents of the Teaching University of Linyi.\n\ All rights reserved.\n";#endif /* PINGIPV6.C */#include<fcntl.h>#include<sys/ioctl.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<netinet/in.h>#include<sys/socket.h>#include <unistd.h>#include <time.h>#include <errno.h>#include <string.h>#include <netdb.h>#include<pthread.h>#include<linux/icmpv6.h>#include <netinet/ip6.h>#define MAXTHREADS 50void handle_tv(struct timeval*out,struct timeval*in){ if((out->tv_usec-=in->tv_usec)<0) { out->tv_sec--; out->tv_usec+=1000000; } out->tv_sec-=in->tv_sec;}/*receive the echo icmp6 packet and handle it*/void recv_icmp6(int icmp6_socket,int pid,char*ip){ char *msg_buf[256]; int msg_len; int n; int hlen,icmplen; int count=0; double rtt; int i=0; int bread; int timeout=1000; /* int val; val=fcntl(icmp6_socket,F_GETFL,0); if(val<0) { fprintf(stderr,"get socket attributer error!\n"); exit(1); } fcntl(socket,F_SETFL,val|O_NONBLOCK);*/ int on=1; ioctl(icmp6_socket,FIONBIO,&on); /* bread=setsockopt(icmp6_socket,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)); if(bread==SOCKET_ERROR) { printf("failed to set recv timeout:%d\n"); return(0); }*/ while(1) { if(n=recv(icmp6_socket,msg_buf,sizeof(msg_buf),0)>0) { struct ip6_hdr*iph; struct icmp6hdr*icmph1; iph=(struct ip6_hdr*)msg_buf; icmph1=(struct icmp6hdr*)(msg_buf); struct timeval*tvsend; struct timeval tvrecv; if(icmph1->icmp6_type==ICMPV6_ECHO_REPLY) { if(icmph1->icmp6_identifier!=pid) { /* printf("the icmp->id !=pid\n"); printf("the pid %d\n",icmph1->icmp6_identifier);*/ } else { printf("-------------------------------recv sucessfully----------------------------------\n"); printf("the ip adress is %s,the seq is %d received successly\n",ip,icmph1->icmp6_sequence); count++; } } /* gettimeofday(&tvrecv,NULL); tvsend=(struct timeval*)(icmph1+1); rtt=tvrecv.tv_sec*1000.0+tvrecv.tv_usec/1000.0; printf("%d bytes from %s:seq=%u,ttl=%d,rtt=%.3fms\n", icmplen,hostname,inet_ntop(dest.sin6_addr), icmp1*/ /* printf("%s\n","good good");*/ } else if(n<0) { printf("n has already <0\n"); if(errno==EINTR) continue; else { fprintf(stderr,"recvform error"); continue; } } else { if(count==0) { printf("-------------------------------unreachable----------------------------------\n"); printf("the ip adress is %s received unreachable\n",ip); } printf("********IP: %s\n",ip); printf("%s:\n","statistics"); printf("the ip adress is %s,the sent is 4, the receive is %d,sucessfully received %d%\n",ip,count,(count/4)*100); return; } } }/*pack every icmp6 packet*/void packet(int icmp6_socket,int id, struct sockaddr_in6 dest ,char*ip){ printf("the start pid is %d\n",id); int len; int seq=0; int send_no=0; u_char sendbuf[1280]; struct icmp6hdr*icmph; icmph=(struct icmp6hdr*)sendbuf; icmph->icmp6_type=ICMPV6_ECHO_REQUEST; icmph->icmp6_code=0; icmph->icmp6_cksum=0x76dc; icmph->icmp6_sequence=seq; icmph->icmp6_identifier=id; id=icmph->icmp6_identifier; printf("the tianchong iden is %d\n", icmph->icmp6_identifier); gettimeofday((struct timeval*)(icmph+1),(struct timezone*)NULL); len=8+sizeof(struct timeval); while(send_no<4){ len=sendto(icmp6_socket,(char*)sendbuf,len,0,(struct sockaddr_in6*)&dest, sizeof(struct sockaddr_in6)); printf("send to IP:%s finished,the pid is %d\n",ip,id); if(len<0) { printf("%s\n","sendto error"); fprintf(stderr,"sendto error"); printf("%d\n",len); exit(1); } /* recv_icmp6(icmp6_socket,pid,seq);*/ send_no++; icmph->icmp6_sequence++; sleep(1); } recv_icmp6(icmp6_socket,id,ip);}/*handle every thread*/void *handle_thread(char*ip){ char*target; int icmp6_socket; char hostname[256]; int pid; struct hostent *host; struct sockaddr_in6 dest; struct in6_addr addr; pid=pthread_self(); target=ip; char temp[256]; memset(&dest,0,sizeof(struct sockaddr_in6)); dest.sin6_family=AF_INET6; dest.sin6_port=htons(IPPROTO_ICMPV6); if(inet_pton(AF_INET6,target,(char*)&dest.sin6_addr)==1) { strcpy(hostname,target); inet_ntop(AF_INET6,&dest.sin6_addr,temp,sizeof(temp)); } else { host=gethostbyname2(target,AF_INET6); if(host!=NULL) { memcpy(&dest.sin6_addr,host->h_addr_list[0],16); strcpy(hostname,host->h_name); exit(1); } else { fprintf(stderr,"host name error:%s\n",target); exit(1); } } printf("PING %s(%s)\n",hostname,temp); /*create icmpv6 socket*/ icmp6_socket=socket(AF_INET6,SOCK_RAW,IPPROTO_ICMPV6); if(icmp6_socket<0) { fprintf(stderr,"socket error\n"); printf("%s\n","socket error"); exit(1); } /* int val; val=fcntl(icmp6_socket,F_GETFL,0); if(val<0) { fprintf(stderr,"get socket attributer error!\n"); exit(1); } fcntl(socket,F_SETFL,val|O_NONBLOCK);*/ packet(icmp6_socket,pid,dest,target);}int main(int argc,char**argv[]){ int i; int loop_num; loop_num=argc-1; pthread_t pid[ MAXTHREADS]; /* if(agrc<2) { Usage(); exit(0); }*/ if(loop_num< MAXTHREADS){ for(i=0;i<loop_num;i++){ pthread_create(&pid[i],NULL,handle_thread,argv[i+1]); } for(i=0;i<loop_num;i++){ pthread_join(pid[i],NULL); } } else printf("%s\n","the number of threads is over 50!"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -