Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6384337
  • 博文数量: 579
  • 博客积分: 1548
  • 博客等级: 上尉
  • 技术积分: 16634
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-12 15:29
个人简介

http://www.csdn.net/ http://www.arm.com/zh/ https://www.kernel.org/ http://www.linuxpk.com/ http://www.51develop.net/ http://linux.chinaitlab.com/ http://www.embeddedlinux.org.cn http://bbs.pediy.com/

文章分类

全部博文(579)

文章存档

2018年(18)

2015年(91)

2014年(159)

2013年(231)

2012年(80)

分类: 嵌入式

2015-01-26 16:04:06


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <netinet/in.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <arpa/inet.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <netinet/ip_icmp.h>
  10. #include <time.h>
  11. #include <string.h>
  12. #include <errno.h>

  13. #define MAX_PINGCOUNT 3

  14. #define u8 u_int8_t
  15. #define u16 u_int16_t
  16. #define u32 u_int32_t

  17. #define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b))))
  18. #define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b));

  19. //#define DEBUG 1
  20. #ifdef DEBUG
  21. #define DEBUGP(format,args...) fprintf(stdout, format, ##args)
  22. #else
  23. #define DEBUGP(format,args...)
  24. #endif

  25. static u32 seed[32];
  26. static u32 in[12];
  27. static u32 out[8];

  28. static int difftimeval(struct timeval *end, struct timeval *start)
  29. {
  30.     unsigned int timeuse;

  31.     return 1000000 * ( end->tv_sec - start->tv_sec ) + end->tv_usec - start->tv_usec;
  32. }

  33. static int retry_send(void)
  34. {
  35.     struct timespec waiter;
  36.     if (errno == EAGAIN) {
  37.         waiter.tv_sec = 0;
  38.         waiter.tv_nsec = 10000;
  39.         nanosleep(&waiter, NULL);
  40.         return 1;
  41.     }

  42.     if (errno == EINTR)
  43.         return 1;

  44.     return 0;
  45. }

  46. static void surf(void)
  47. {
  48.     u32 t[12];
  49.     u32 x;
  50.     u32 sum = 0;
  51.     int r;
  52.     int i;
  53.     int loop;

  54.     for (i = 0; i < 12; ++i) t[i] = in[i] ^ seed[12 + i];
  55.     for (i = 0; i < 8; ++i) out[i] = seed[24 + i];
  56.     x = t[11];
  57.     for (loop = 0; loop < 2; ++loop) {
  58.         for (r = 0; r < 16; ++r) {
  59.             sum += 0x9e3779b9;
  60.             MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13)
  61.             MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13)
  62.             MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13)
  63.         }
  64.         for (i = 0; i < 8; ++i) out[i] ^= t[i + 4];
  65.     }
  66. }

  67. unsigned short rand16(void)
  68. {
  69.     static int outleft = 0;

  70.     if (!outleft) {
  71.         if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
  72.         surf();
  73.         outleft = 8;
  74.     }

  75.     return (unsigned short) out[--outleft];
  76. }

  77. static int fix_fd(int fd)
  78. {
  79.     int flags;

  80.     if ((flags = fcntl(fd, F_GETFL)) == -1 ||
  81.      fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
  82.         return 0;

  83.     return 1;
  84. }

  85. static int open_socket(void)
  86. {
  87.     int fd;
  88.     int zeroopt = 0;

  89.     if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1) {
  90.         if (!fix_fd(fd) ||
  91.          setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1) {
  92.             close(fd);
  93.             fd = -1;
  94.         }
  95.     }

  96.     return fd;
  97. }

  98. static int icmp_ping(int fd, struct in_addr addr, int timeout)
  99. {
  100.     /* Try and get an ICMP echo from a machine. */

  101.     /* Note that whilst in the three second wait, we check for
  102.      (and service) events on the DNS and TFTP sockets, (so doing that
  103.      better not use any resources our caller has in use...)
  104.      but we remain deaf to signals or further DHCP packets. */

  105.     struct sockaddr_in saddr;
  106.     struct {
  107.         struct ip ip;
  108.         struct icmp icmp;
  109.     } packet;
  110.     unsigned short id = rand16();
  111.     unsigned int i, j;
  112.     int gotreply = 0;
  113.     struct timeval start, now;

  114.     saddr.sin_family = AF_INET;
  115.     saddr.sin_port = 0;
  116.     saddr.sin_addr = addr;
  117. #ifdef HAVE_SOCKADDR_SA_LEN
  118.     saddr.sin_len = sizeof(struct sockaddr_in);
  119. #endif

  120.     memset(&packet.icmp, 0, sizeof(packet.icmp));
  121.     packet.icmp.icmp_type = ICMP_ECHO;
  122.     packet.icmp.icmp_id = id;
  123.     for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
  124.         j += ((u16 *)&packet.icmp)[i];
  125.     while (j>>16)
  126.         j = (j & 0xffff) + (j >> 16);
  127.     packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;

  128.     while (sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
  129.      (struct sockaddr *)&saddr, sizeof(saddr)) == -1 &&
  130.      retry_send());

  131.     gettimeofday(&start, NULL);
  132.     now = start;
  133.     do {
  134.         struct timeval tv;
  135.         fd_set rset, wset;
  136.         struct sockaddr_in faddr;
  137.         int maxfd = fd;
  138.         socklen_t len = sizeof(faddr);

  139.         tv.tv_usec = 200000;
  140.         tv.tv_sec = 0;

  141.         FD_ZERO(&rset);
  142.         FD_ZERO(&wset);
  143.         FD_SET(fd, &rset);
  144.         //set_dns_listeners(now, &rset, &maxfd);
  145.         //set_log_writer(&wset, &maxfd);

  146.         if (select(maxfd+1, &rset, &wset, NULL, &tv) < 0) {
  147.             FD_ZERO(&rset);
  148.             FD_ZERO(&wset);
  149.         }

  150.         gettimeofday(&now, NULL);

  151.         //check_log_writer(&wset);
  152.         //check_dns_listeners(&rset, now);

  153.         if (FD_ISSET(fd, &rset) &&
  154.          recvfrom(fd, &packet, sizeof(packet), 0,
  155.          (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
  156.          saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
  157.          packet.icmp.icmp_type == ICMP_ECHOREPLY &&
  158.          packet.icmp.icmp_seq == 0 &&
  159.          packet.icmp.icmp_id == id) {
  160.             gotreply = 1;
  161.             break;
  162.         }
  163.     }while(difftimeval(&now, &start) < timeout);
  164.     DEBUGP("gotreply = %d\n", gotreply);
  165.     return gotreply;
  166. }

  167. int ping(const char *daddr, int pingcount)
  168. {
  169.     struct in_addr addr;
  170.     unsigned int timeout = 2 * 1000;
  171.     int gotreply = 0;
  172.     int fd, i;

  173.     if ((fd = open_socket()) == -1)
  174.         return -1;
  175.     
  176.     addr.s_addr = inet_addr(daddr);
  177.     if(addr.s_addr == INADDR_NONE){
  178.         close(fd);
  179.         return -3;
  180.     }
  181.     
  182.     for(i = 0; i < pingcount; i++){
  183.         gotreply = icmp_ping(fd, addr, timeout * 1000);
  184.         if(gotreply) break;
  185.     }

  186.     close(fd);
  187.     if(gotreply <= 0) return -4;
  188.     
  189.     return 0;
  190. }

  191. main(int argc, char **argv)
  192. {
  193.     if (argc < 2){
  194.         fprintf(stdout, "Please Enter IP\n");
  195.         return 1;
  196.     }
  197.     int reply;
  198.     reply = ping(argv[1], MAX_PINGCOUNT);
  199.     if (reply == 0){
  200.         fprintf(stdout, "Connect\n");
  201.         return 0;
  202.     }else{
  203.         fprintf(stdout, "Disconect\n");
  204.         return 2;
  205.     }
  206. }

阅读(1951) | 评论(0) | 转发(0) |
0

上一篇:daemon函数实现原理

下一篇:Arping代码

给主人留下些什么吧!~~