⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 my_ping.c

📁 ping 程序
💻 C
字号:
#include "my_ping.h"        extern int errno;struct proto proto_v4 = {proc_v4, send_v4, NULL, NULL,NULL, 0, IPPROTO_ICMP};int n_send;int n_recv;  void sig_intr(int signum) {	printf("---------------------------------\n");	printf("success send %d packets,recvie %d packtes,lost %d packets\n", n_send, n_recv, n_send-n_recv);	exit(0);}        int main(int argc, char** argv) {         datalen = 56;        int c;          struct addrinfo *ai;        opterr = 0;        while((c = getopt(argc, argv, "v")) != -1) {                switch(c) {                        case 'v':verbose++;break;                        case '?':printf("error option: %c\n", c);return -1;                }        }        if(optind != argc-1) {                printf("use ping [-v] <hostname>\n");                return -1;        }        host = argv[optind];        pid = getpid();         struct sigaction sa;        sa.sa_handler = sig_alarm;        sigaction(SIGALRM, &sa, NULL);        	struct sigaction sa2;	sa2.sa_handler = sig_intr;	sigaction(SIGINT, &sa2, NULL);                printf("host:%s\n", host);        int n = getaddrinfo(host, 0, 0, &ai);        if(n != 0) {                printf("error getaddrinfo()\n");                perror("info");        }         printf("------------------------------------\n");        printf("ai_family : %d\n", ai->ai_family);        printf("ai_socktype:%d\n", ai->ai_socktype);        printf("ai_protocol:%d\n", ai->ai_protocol);        printf("ai_addrlen:%d\n", ai->ai_addrlen);        printf("ai_canonname: %s\n", ai->ai_canonname);        printf("------------------------------------\n");        char buf[1024];        const char* p;        if(ai->ai_family == AF_INET) {                p = inet_ntop(ai->ai_family, &(((struct sockaddr_in*)ai->ai_addr)->sin_addr), buf, 1024);                pr = &proto_v4;        }        if(p == NULL)printf("error inet_ntop()\n");        pr->sasend = ai->ai_addr;        pr->sarecv = (struct sockaddr*)malloc(ai->ai_addrlen);        pr->salen = ai->ai_addrlen;         readloop();         return 0;} void readloop(void) {        char recvbuf[BUFSIZE];        char controlbuf[BUFSIZE];        struct msghdr msg;        struct iovec iov;        struct timeval tval;         sockfd = socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);        if(sockfd == -1)perror("sockfd error");        setuid(getuid());        int size = 60*1024;        setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, 4);        sig_alarm(SIGALRM);         iov.iov_base = recvbuf;        iov.iov_len = sizeof(recvbuf);        msg.msg_name = pr->sarecv;        msg.msg_iov = &iov;        msg.msg_iovlen = 1;        msg.msg_control = controlbuf;        for(;;) {                msg.msg_namelen = pr->salen;                msg.msg_controllen = sizeof(controlbuf);                int n = recvmsg(sockfd, &msg, 0);                if(n < 0) {                        if(errno == EINTR)continue;                        else  {                                perror("recvmsg");                                return;                        }                }		n_recv++;                gettimeofday(&tval, NULL);                (*pr->fproc)(recvbuf, n, &msg, &tval);         } }void tv_sub(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;}void proc_v4(char* ptr, ssize_t len, struct msghdr* msg, struct timeval* tvrecv) {        int hlen1, icmplen;        double rtt;        struct ip *ip;        struct icmp *icmp;        struct timeval *tvsend;         ip = (struct ip*)ptr;        hlen1 = ip->ip_hl << 2;        if(ip->ip_p != IPPROTO_ICMP)return;        icmp = (struct icmp*)(ptr + hlen1);		icmplen = len-hlen1;	        if(icmp->icmp_type == ICMP_ECHOREPLY) {                if(icmp->icmp_id != pid) {			printf("icmp_id doesn't equal process id\n");			return;		}                if(icmplen < 0) {			printf("icmplen less than 0\n");			return;		}                tvsend = (struct timeval*)icmp->icmp_data;                tv_sub(tvrecv, tvsend);                rtt = tvrecv->tv_sec*1000.0 + tvrecv->tv_usec/1000.0;		char buf[1024];		inet_ntop(AF_INET, &(((struct sockaddr_in*)(pr->sarecv))->sin_addr), buf, 1024);		                printf("%d bytes from:%s id:%d rtt:%.3fms\n", icmplen, buf, icmp->icmp_seq, rtt);        } }void send_v4(void) {        int len;        struct icmp *icmp;        icmp = (struct icmp*)sendbuf;        icmp->icmp_type = ICMP_ECHO;        icmp->icmp_code = 0;        icmp->icmp_id = pid;        icmp->icmp_seq = nsent++;        memset(icmp->icmp_data, 0xa5, datalen);        gettimeofday((struct timeval*)icmp->icmp_data, NULL);        len = 8+datalen;        icmp->icmp_cksum = 0;        icmp->icmp_cksum = in_cksum((u_short*)icmp, len);        int n = sendto(sockfd, sendbuf, len, 0, pr->sasend, pr->salen);	printf("success send %d bytes\n", n); 	n_send++;}void sig_alarm(int signum) {        (*pr->fsend)();        alarm(1);        return;} u_short in_cksum(u_short* data, int len) {         int result = 0;        for(int i=0; i<len/2; i++) {                result += *data;                data++;        }	while(result >> 16)result = (result&0xffff) + (result >> 16);        return ~result; }/*u_short in_cksum(u_short *addr, int len){    register int nleft = len;    register u_short *w = addr;    register int sum = 0;    u_short answer =0;    while (nleft > 1)       	{       	sum += *w++;       	nleft -= 2;      	}    if (nleft == 1)     	{             	*(u_char *)(&answer) = *(u_char *)w;        sum += answer;     	}    sum = (sum >> 16) + (sum & 0xffff);    sum += (sum >> 16);    answer = ~sum;    return(answer);}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -