ping.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #include "ping.h"
  2. #include "socket.h"
  3. #include "w5500.h"
  4. PINGMSGR PingRequest; // Variable for Ping Request
  5. PINGMSGR PingReply; // Variable for Ping Reply
  6. static uint16_t RandomID = 0x1234;
  7. static uint16_t RandomSeqNum = 0x4321;
  8. uint8_t ping_reply_received = 0;
  9. uint8_t req = 0;
  10. uint8_t rep = 0;
  11. extern void ping_wait_ms(int ms);
  12. uint8_t ping_auto(uint8_t s, uint8_t* addr) {
  13. uint8_t i;
  14. int32_t len = 0;
  15. uint8_t cnt = 0;
  16. int ret = 0;
  17. for(i = 0; i <= 3; i++) {
  18. uint8_t sr = getSn_SR(s);
  19. //logger("SR: %02X\r\n", sr);
  20. switch(sr) {
  21. case SOCK_CLOSED:
  22. close(s);
  23. IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol
  24. if((ret = socket(s, Sn_MR_IPRAW, 3000, 0)) !=
  25. s) { // open the SOCKET with IPRAW mode, if fail then Error
  26. //logger( "\r\n socket %d fail %d\r\n", s, ret);
  27. #ifdef PING_DEBUG
  28. return SOCKET_ERROR;
  29. #endif
  30. }
  31. /* Check socket register */
  32. while(getSn_SR(s) != SOCK_IPRAW)
  33. ;
  34. ping_wait_ms(1000); // wait 1000ms
  35. ping_wait_ms(1000); // wait 1000ms
  36. break;
  37. case SOCK_IPRAW:
  38. ping_request(s, addr);
  39. req++;
  40. while(1) {
  41. if((len = getSn_RX_RSR(s)) > 0) {
  42. ping_reply(s, addr, len);
  43. rep++;
  44. break;
  45. } else if(cnt > 100) {
  46. //logger("Request Time out. \r\n");
  47. cnt = 0;
  48. break;
  49. } else {
  50. cnt++;
  51. ping_wait_ms(50); // wait 50ms
  52. }
  53. // wait_time for 2 seconds, Break on fail
  54. }
  55. break;
  56. default:
  57. break;
  58. }
  59. #ifdef PING_DEBUG
  60. if(req >= 3) {
  61. //logger("Ping Request = %d, PING_Reply = %d\r\n", req, rep);
  62. if(rep == req)
  63. return PING_SUCCESS;
  64. else
  65. return REPLY_ERROR;
  66. }
  67. #endif
  68. }
  69. return FUNCTION_ERROR;
  70. }
  71. uint8_t ping_count(uint8_t s, uint16_t pCount, uint8_t* addr) {
  72. uint16_t rlen, cnt, i;
  73. cnt = 0;
  74. for(i = 0; i < pCount + 1; i++) {
  75. if(i != 0) {
  76. /* Output count number */
  77. //logger( "\r\nNo.%d\r\n", (i-1));
  78. }
  79. uint8_t sr = getSn_SR(s);
  80. //logger("SR: %d\r\n", sr);
  81. switch(sr) {
  82. case SOCK_CLOSED:
  83. close(s);
  84. // close the SOCKET
  85. /* Create Socket */
  86. IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol
  87. if(socket(s, Sn_MR_IPRAW, 3000, 0) !=
  88. s) { // open the SOCKET with IPRAW mode, if fail then Error
  89. //logger( "\r\n socket %d fail r\n", (s));
  90. #ifdef PING_DEBUG
  91. return SOCKET_ERROR;
  92. #endif
  93. }
  94. /* Check socket register */
  95. while(getSn_SR(s) != SOCK_IPRAW)
  96. ;
  97. ping_wait_ms(1000);
  98. break;
  99. case SOCK_IPRAW:
  100. ping_request(s, addr);
  101. req++;
  102. while(1) {
  103. if((rlen = getSn_RX_RSR(s)) > 0) {
  104. ping_reply(s, addr, rlen);
  105. rep++;
  106. if(ping_reply_received) break;
  107. }
  108. /* wait_time for 2 seconds, Break on fail*/
  109. if((cnt > 100)) {
  110. //logger( "\r\nRequest Time out. \r\n") ;
  111. cnt = 0;
  112. break;
  113. } else {
  114. cnt++;
  115. ping_wait_ms(20);
  116. }
  117. }
  118. break;
  119. default:
  120. break;
  121. }
  122. #ifdef PING_DEBUG
  123. if(req >= pCount) {
  124. //logger("Ping Request = %d, PING_Reply = %d\r\n", req, rep);
  125. if(rep == req)
  126. return PING_SUCCESS;
  127. else
  128. return REPLY_ERROR;
  129. }
  130. #endif
  131. }
  132. return FUNCTION_ERROR;
  133. }
  134. uint8_t ping_request(uint8_t s, uint8_t* addr) {
  135. uint16_t i;
  136. //Initailize flag for ping reply
  137. ping_reply_received = 0;
  138. /* make header of the ping-request */
  139. PingRequest.Type = PING_REQUEST; // Ping-Request
  140. PingRequest.Code = CODE_ZERO; // Always '0'
  141. PingRequest.ID = htons(RandomID++); // set ping-request's ID to random integer value
  142. PingRequest.SeqNum =
  143. htons(RandomSeqNum++); // set ping-request's sequence number to ramdom integer value
  144. //size = 32; // set Data size
  145. /* Fill in Data[] as size of BIF_LEN (Default = 32)*/
  146. for(i = 0; i < BUF_LEN; i++) {
  147. PingRequest.Data[i] = (i) % 8; //'0'~'8' number into ping-request's data
  148. }
  149. /* Do checksum of Ping Request */
  150. PingRequest.CheckSum =
  151. 0; // value of checksum before calucating checksum of ping-request packet
  152. PingRequest.CheckSum =
  153. htons(checksum((uint8_t*)&PingRequest, sizeof(PingRequest))); // Calculate checksum
  154. /* sendto ping_request to destination */
  155. if(sendto(s, (uint8_t*)&PingRequest, sizeof(PingRequest), addr, 3000) ==
  156. 0) { // Send Ping-Request to the specified peer.
  157. //logger( "\r\n Fail to send ping-reply packet r\n") ;
  158. } else {
  159. //logger( "Send Ping Request to Destination (") ;
  160. //logger( "%d.%d.%d.%d )", (addr[0]), (addr[1]), (addr[2]), (addr[3])) ;
  161. //logger( " ID:%x SeqNum:%x CheckSum:%x\r\n", htons(PingRequest.ID), htons(PingRequest.SeqNum), htons(PingRequest.CheckSum)) ;
  162. }
  163. return 0;
  164. } // ping request
  165. uint8_t ping_reply(uint8_t s, uint8_t* addr, uint16_t rlen) {
  166. uint16_t tmp_checksum;
  167. uint16_t len;
  168. uint16_t i;
  169. uint8_t data_buf[128];
  170. uint16_t port = 3000;
  171. PINGMSGR PingReply;
  172. /* receive data from a destination */
  173. len = recvfrom(s, (uint8_t*)data_buf, rlen, addr, &port);
  174. if(data_buf[0] == PING_REPLY) {
  175. PingReply.Type = data_buf[0];
  176. PingReply.Code = data_buf[1];
  177. PingReply.CheckSum = (data_buf[3] << 8) + data_buf[2];
  178. PingReply.ID = (data_buf[5] << 8) + data_buf[4];
  179. PingReply.SeqNum = (data_buf[7] << 8) + data_buf[6];
  180. for(i = 0; i < len - 8; ++i) {
  181. PingReply.Data[i] = data_buf[8 + i];
  182. }
  183. /* check Checksum of Ping Reply */
  184. tmp_checksum = ~checksum(data_buf, len);
  185. if(tmp_checksum != 0xffff) {
  186. //logger("tmp_checksum = %x\r\n",tmp_checksum);
  187. } else {
  188. /* Output the Destination IP and the size of the Ping Reply Message*/
  189. //logger("Reply from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
  190. // (addr[0]), (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), htons(PingReply.SeqNum), (rlen+6) );
  191. //logger("\r\n");
  192. /* SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/
  193. ping_reply_received = 1;
  194. }
  195. } else if(data_buf[0] == PING_REQUEST) {
  196. PingReply.Code = data_buf[1];
  197. PingReply.Type = data_buf[2];
  198. PingReply.CheckSum = (data_buf[3] << 8) + data_buf[2];
  199. PingReply.ID = (data_buf[5] << 8) + data_buf[4];
  200. PingReply.SeqNum = (data_buf[7] << 8) + data_buf[6];
  201. for(i = 0; i < len - 8; ++i) {
  202. PingReply.Data[i] = data_buf[8 + i];
  203. }
  204. /* check Checksum of Ping Reply */
  205. tmp_checksum = PingReply.CheckSum;
  206. PingReply.CheckSum = 0;
  207. PingReply.CheckSum = htons(checksum((uint8_t*)&PingReply, len));
  208. if(tmp_checksum != PingReply.CheckSum) {
  209. //logger( " \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), htons(PingReply.CheckSum));
  210. } else {
  211. //logger( "\r\n Checksum is correct \r\n") ;
  212. }
  213. /* Output the Destination IP and the size of the Ping Reply Message*/
  214. //logger("Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
  215. // (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), (PingReply.SeqNum), (rlen+6) );
  216. /* SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/
  217. ping_reply_received = 1;
  218. } else {
  219. //logger(" Unkonwn msg. \n");
  220. }
  221. return 0;
  222. } // ping_reply
  223. uint16_t checksum(uint8_t* data_buf, uint16_t len) {
  224. uint16_t sum, tsum, i, j;
  225. uint32_t lsum;
  226. j = len >> 1;
  227. lsum = 0;
  228. tsum = 0;
  229. for(i = 0; i < j; ++i) {
  230. tsum = data_buf[i * 2];
  231. tsum = tsum << 8;
  232. tsum += data_buf[i * 2 + 1];
  233. lsum += tsum;
  234. }
  235. if(len % 2) {
  236. tsum = data_buf[i * 2];
  237. lsum += (tsum << 8);
  238. }
  239. sum = (uint16_t)lsum;
  240. sum = ~(sum + (lsum >> 16));
  241. return sum;
  242. }
  243. uint16_t htons(uint16_t hostshort) {
  244. #if 1
  245. //#ifdef LITTLE_ENDIAN
  246. uint16_t netshort = 0;
  247. netshort = (hostshort & 0xFF) << 8;
  248. netshort |= ((hostshort >> 8) & 0xFF);
  249. return netshort;
  250. #else
  251. return hostshort;
  252. #endif
  253. }