日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux用ICMP协议实现简单Ping网络监测功能

發布時間:2023/12/9 linux 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux用ICMP协议实现简单Ping网络监测功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

From:?http://www.linuxidc.com/Linux/2012-05/61073.htm

ICMP是(Internet Control Message Protocol)Internet控制報文協議。它是TCP/IP協議族的一個子協議,用于在IP主機、路由器之間傳遞控制消息。控制消息是指網絡通不通、主機是否可達、路由是否可用等網絡本身的消息。這些控制消息雖然并不傳輸用戶數據,但是對于用戶數據的傳遞起著重要的作用。

ICMP協議是一種面向無連接的協議,用于傳輸出錯報告控制信息。它是一個非常重要的協議,它對于網絡安全具有極其重要的意義。

折騰半天,原來ICMP也是TCP/IP其中一種協議.那么監測網絡是否ping的通,就跟TCP協議差不多了。

步驟簡單歸納為:1.綁定套接字,2.發送數據包 3.接收數據包 4.解析數據包
  • #include?<stdio.h>???
  • #include?<sys/socket.h>???
  • #include?<netinet/in.h>???
  • #include?<netinet/ip.h>???
  • #include?<netinet/ip_icmp.h>???
  • #include?<netdb.h>??
  • ?
  • #define?PACKET_SIZE?????4096???
  • #define?ERROR???????????0???
  • #define?SUCCESS?????????1???
  • ??
  • //效驗算法(百度下有注釋,但是還是看不太明白)???
  • unsigned?short?cal_chksum(unsigned?short?*addr,?int?len)??
  • {??
  • ????int?nleft=len;??
  • ????int?sum=0;??
  • ????unsigned?short?*w=addr;??
  • ????unsigned?short?answer=0;??
  • ??????
  • ????while(nleft?>?1)??
  • ????{??
  • ????????sum?+=?*w++;??
  • ????????nleft?-=?2;??
  • ????}??
  • ??????
  • ????if(?nleft?==?1)??
  • ????{?????????
  • ????????*(unsigned?char?*)(&answer)?=?*(unsigned?char?*)w;??
  • ????????sum?+=?answer;??
  • ????}??
  • ??????
  • ????sum?=?(sum?>>?16)?+?(sum?&?0xffff);??
  • ????sum?+=?(sum?>>?16);??
  • ????answer?=?~sum;??
  • ??????
  • ????return?answer;??
  • }??
  • //?Ping函數???
  • int?ping(?char?*ips,?int?timeout)????
  • {????????
  • ????struct?timeval?*tval;??????????
  • ????int?maxfds?=?0;????
  • ????fd_set?readfds;????
  • ??????
  • ????struct?sockaddr_in?addr;????
  • ????struct?sockaddr_in?from;????
  • ????//?設定Ip信息?????
  • ????bzero(&addr,sizeof(addr));????
  • ????addr.sin_family?=?AF_INET;????
  • ????addr.sin_addr.s_addr?=?inet_addr(ips);????
  • ??????
  • ????int?sockfd;????
  • ????//?取得socket?????
  • ????sockfd?=?socket(AF_INET,?SOCK_RAW,?IPPROTO_ICMP);????
  • ????if?(sockfd?<?0)????
  • ????{????
  • ????????printf("ip:%s,socket?error\n",ips);????
  • ????????return?ERROR;????
  • ????}????
  • ??????
  • ????struct?timeval?timeo;????
  • ????//?設定TimeOut時間?????
  • ????timeo.tv_sec?=?timeout?/?1000;????
  • ????timeo.tv_usec?=?timeout?%?1000;????
  • ??????
  • ????if?(setsockopt(sockfd,?SOL_SOCKET,?SO_SNDTIMEO,?&timeo,?sizeof(timeo))?==?-1)????
  • ????{????
  • ????????printf("ip:%s,setsockopt?error\n",ips);????
  • ????????return?ERROR;????
  • ????}????
  • ??????
  • ????char?sendpacket[PACKET_SIZE];????
  • ????char?recvpacket[PACKET_SIZE];????
  • ????//?設定Ping包?????
  • ????memset(sendpacket,?0,?sizeof(sendpacket));????
  • ??????
  • ????pid_t?pid;????
  • ????//?取得PID,作為Ping的Sequence?ID?????
  • ????pid=getpid();????
  • ??????
  • ????struct?ip?*iph;????
  • ????struct?icmp?*icmp;????
  • ??????
  • ????
  • ????icmp=(struct?icmp*)sendpacket;????
  • ????icmp->icmp_type=ICMP_ECHO;??//回顯請求???
  • ????icmp->icmp_code=0;????
  • ????icmp->icmp_cksum=0;????
  • ????icmp->icmp_seq=0;????
  • ????icmp->icmp_id=pid;???
  • ????tval=?(struct?timeval?*)icmp->icmp_data;????
  • ????gettimeofday(tval,NULL);????
  • ????icmp->icmp_cksum=cal_chksum((unsigned?short?*)icmp,sizeof(struct?icmp));??//校驗???
  • ??????
  • ????int?n;????
  • ????//?發包?????
  • ????n?=?sendto(sockfd,?(char?*)&sendpacket,?sizeof(struct?icmp),?0,?(struct?sockaddr?*)&addr,?sizeof(addr));????
  • ????if?(n?<?1)????
  • ????{????
  • ????????printf("ip:%s,sendto?error\n",ips);????
  • ????????return?ERROR;????
  • ????}????
  • ??????
  • ????//?接受?????
  • ????//?由于可能接受到其他Ping的應答消息,所以這里要用循環?????
  • ????while(1)????
  • ????{????
  • ????????//?設定TimeOut時間,這次才是真正起作用的?????
  • ????????FD_ZERO(&readfds);????
  • ????????FD_SET(sockfd,?&readfds);????
  • ????????maxfds?=?sockfd?+?1;????
  • ????????n?=?select(maxfds,?&readfds,?NULL,?NULL,?&timeo);????
  • ????????if?(n?<=?0)????
  • ????????{????
  • ????????????printf("ip:%s,Time?out?error\n",ips);????
  • ????????????close(sockfd);????
  • ????????????return?ERROR;????
  • ????????}????
  • ??????????
  • ????????//?接受?????
  • ????????memset(recvpacket,?0,?sizeof(recvpacket));????
  • ????????int?fromlen?=?sizeof(from);????
  • ????????n?=?recvfrom(sockfd,?recvpacket,?sizeof(recvpacket),?0,?(struct?sockaddr?*)&from,?(socklen_t?*)&fromlen);????
  • ????????if?(n?<?1)?{????
  • ????????????break;????
  • ????????}????
  • ??????????
  • ???????
  • ????????char?*from_ip?=?(char?*)inet_ntoa(from.sin_addr);????
  • ????????????//?判斷是否是自己Ping的回復?????
  • ????????if?(strcmp(from_ip,ips)?!=?0)????
  • ????????{????
  • ????????????printf("NowPingip:%s?Fromip:%s\nNowPingip?is?not?same?to?Fromip,so?ping?wrong!\n",ips,from_ip);????
  • ????????????return?ERROR;??
  • ????????}????
  • ??????????
  • ????????iph?=?(struct?ip?*)recvpacket;????
  • ??????????
  • ????????icmp=(struct?icmp?*)(recvpacket?+?(iph->ip_hl<<2));????
  • ??????????
  • ????????printf("ip:%s\n,icmp->icmp_type:%d\n,icmp->icmp_id:%d\n",ips,icmp->icmp_type,icmp->icmp_id);????
  • ????????//?判斷Ping回復包的狀態?????
  • ????????if?(icmp->icmp_type?==?ICMP_ECHOREPLY?&&?icmp->icmp_id?==?pid)???//ICMP_ECHOREPLY回顯應答???
  • ????????{????
  • ????????????//?正常就退出循環?????
  • ????????????break;????
  • ????????}????
  • ????????else????
  • ????????{????
  • ????????????//?否則繼續等?????
  • ????????????continue;????
  • ????????}????
  • ????}????
  • ??????
  • ????int?main()??
  • {??
  • ????char?cPing[16];??
  • ????printf("Please?input?ping?IP:");??
  • ????scanf("%s",cPing);??
  • ??????
  • ????if(ping(cPing,10000))??
  • ????{??
  • ????????printf("Ping?succeed!\n");??
  • ????}??
  • ????else??
  • ????{??
  • ????????printf("Ping?wrong!\n");??
  • ????}??
  • ??????
  • }??
  • 測試結果: root@an-virtual-machine:~/wyz/test# ./testping
    Please input ping IP:192.168.1.155
    Nowip:192.168.1.155 Fromip:192.168.1.133
    Nowip is not same to Fromip,so ping wrong!
    Ping wrong!
    root@an-virtual-machine:~/wyz/test# ./testping
    Please input ping IP:192.168.1.188
    ip:192.168.1.188
    ,icmp->icmp_type:0
    ,icmp->icmp_id:27865
    Ping succeed!

    總結

    以上是生活随笔為你收集整理的Linux用ICMP协议实现简单Ping网络监测功能的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。