ping.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <ip.h>
  4. typedef struct Icmp Icmp;
  5. struct Icmp
  6. {
  7. uchar vihl; /* Version and header length */
  8. uchar tos; /* Type of service */
  9. uchar length[2]; /* packet length */
  10. uchar id[2]; /* Identification */
  11. uchar frag[2]; /* Fragment information */
  12. uchar ttl; /* Time to live */
  13. uchar proto; /* Protocol */
  14. uchar ipcksum[2]; /* Header checksum */
  15. uchar src[4]; /* Ip source */
  16. uchar dst[4]; /* Ip destination */
  17. uchar type;
  18. uchar code;
  19. uchar cksum[2];
  20. uchar icmpid[2];
  21. uchar seq[2];
  22. uchar data[1];
  23. };
  24. enum
  25. { /* Packet Types */
  26. EchoReply = 0,
  27. Unreachable = 3,
  28. SrcQuench = 4,
  29. EchoRequest = 8,
  30. TimeExceed = 11,
  31. Timestamp = 13,
  32. TimestampReply = 14,
  33. InfoRequest = 15,
  34. InfoReply = 16,
  35. ICMP_IPSIZE = 20,
  36. ICMP_HDRSIZE = 8,
  37. };
  38. static void
  39. catch(void *a, char *msg)
  40. {
  41. USED(a);
  42. if(strstr(msg, "alarm"))
  43. noted(NCONT);
  44. else
  45. noted(NDFLT);
  46. }
  47. #define MSG "dhcp probe"
  48. /*
  49. * make sure noone is using the address
  50. */
  51. int
  52. icmpecho(uchar *a)
  53. {
  54. int fd;
  55. char buf[512];
  56. Icmp *ip;
  57. int i, n, len;
  58. ushort sseq, x;
  59. int rv;
  60. rv = 0;
  61. sprint(buf, "%I", a);
  62. fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0);
  63. if(fd < 0){
  64. return 0;
  65. }
  66. sseq = getpid()*time(0);
  67. ip = (Icmp*)buf;
  68. notify(catch);
  69. for(i = 0; i < 3; i++){
  70. ip->type = EchoRequest;
  71. ip->code = 0;
  72. strcpy((char*)ip->data, MSG);
  73. ip->seq[0] = sseq;
  74. ip->seq[1] = sseq>>8;
  75. len = ICMP_IPSIZE+ICMP_HDRSIZE+sizeof(MSG);
  76. /* send a request */
  77. if(write(fd, buf, len) < len)
  78. break;
  79. /* wait 1/10th second for a reply and try again */
  80. alarm(100);
  81. n = read(fd, buf, sizeof(buf));
  82. alarm(0);
  83. if(n <= 0)
  84. continue;
  85. /* an answer to our echo request? */
  86. x = (ip->seq[1]<<8)|ip->seq[0];
  87. if(n >= len)
  88. if(ip->type == EchoReply)
  89. if(x == sseq)
  90. if(strcmp((char*)ip->data, MSG) == 0){
  91. rv = 1;
  92. break;
  93. }
  94. }
  95. close(fd);
  96. return rv;
  97. }