ping.c 9.1 KB

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