ping.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /**
  2. ******************************************************************************
  3. * @file ping.c
  4. * @author WIZnet Software Team
  5. * @version V1.0
  6. * @date 2015-12-12
  7. * @brief ping 演示函数
  8. ******************************************************************************
  9. **/
  10. #include "ping.h"
  11. #define PING_DEBUG
  12. PINGMSGR PingRequest;
  13. PINGMSGR PingReply;
  14. static uint16 RandomID = 0x1234;
  15. static uint16 RandomSeqNum = 0x4321;
  16. uint8 ping_reply_received = 0;
  17. uint8 req=0;
  18. uint8 rep=0;
  19. /**
  20. *@brief 自动PING外网IP函数
  21. *@param s;socket number
  22. *@param addr:外网IP地址
  23. *@return 无
  24. */
  25. void ping_auto(uint8 s, uint8 *addr)
  26. {
  27. uint8 i;
  28. int32_t len = 0;
  29. uint8 cnt=0;
  30. for(i = 0; i<=3;i++) /*循环ping3次*/
  31. {
  32. delay_ms(10);
  33. switch(getSn_SR(s)) /*获取socket状*/
  34. {
  35. case SOCK_CLOSED: /*socket关闭状态*/
  36. close(s);
  37. IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); /*设置ICMP 协议*/
  38. if(socket(s,Sn_MR_IPRAW,3000,0)!=0) /*判断ip raw模式socket是否开启*/
  39. { }
  40. while(getSn_SR(s)!=SOCK_IPRAW);
  41. delay_us(1000); /*等待 1000ms*/
  42. delay_us(1000); /*等待 1000ms*/
  43. break;
  44. case SOCK_IPRAW: /*ip raw模式*/
  45. ping_request(s, addr); /*发送Ping请求*/
  46. req++;
  47. while(1)
  48. {
  49. if ( (len = getSn_RX_RSR(s) ) > 0)
  50. {
  51. ping_reply(s, addr, len); /*获取回复信息*/
  52. delay_us(500); // wait 50ms
  53. rep++;
  54. break;
  55. }
  56. else if(cnt > 200)
  57. {
  58. printf( "Request Time out. \r\n");
  59. cnt = 0;
  60. break;
  61. }
  62. else
  63. {
  64. cnt++;
  65. delay_ms(1); // wait 50ms
  66. }
  67. // wait_time for 2 seconds, Break on fail
  68. }
  69. break;
  70. default:
  71. break;
  72. }
  73. #ifdef PING_DEBUG
  74. if(rep!=0)
  75. {
  76. printf("Ping Request = %d, PING_Reply = %d\r\n",req,rep);
  77. if(rep == req)
  78. if(rep == req)
  79. printf( "PING SUCCESS\r\n " );
  80. else
  81. printf( "REPLY_ERROR\r\n " );
  82. }
  83. else{}
  84. #endif
  85. }
  86. }
  87. /**
  88. *@brief 设定次数ping外网IP函数
  89. *@param s- socket number
  90. *@param addr- 外网IP地址
  91. *@param pCount- ping的次数
  92. *@return 无
  93. */
  94. void ping_count(uint8 s, uint16 pCount, uint8 *addr)
  95. {
  96. uint16 rlen, cnt,i;
  97. cnt = 0;
  98. for(i=0; i<pCount+1;i++) /*循环ping pCount次*/
  99. {
  100. if(i!=0)
  101. {
  102. /* Output count number */
  103. printf( "\r\nNo.%d\r\n", (i-1));
  104. }
  105. switch(getSn_SR(s)) /*获取socket状态*/
  106. {
  107. case SOCK_CLOSED: /*socket关闭状态*/
  108. close(s);
  109. /* Create Socket */
  110. IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); /*设置ICMP 协议*/
  111. /* Check socket register */
  112. while(getSn_SR(s)!=SOCK_IPRAW);
  113. delay_us(1000); /*等待 1000ms*/
  114. delay_us(1000); /*等待 1000ms*/
  115. break;
  116. case SOCK_IPRAW: /*ip raw模式*/
  117. ping_request(s, addr); /*发送Ping请求*/
  118. req++;
  119. while(1)
  120. {
  121. if ( (rlen = getSn_RX_RSR(s) ) > 0)
  122. {
  123. ping_reply(s, addr, rlen); /*获取回复信息*/
  124. rep++;
  125. if (ping_reply_received) break;
  126. }
  127. if ( (cnt > 100) )
  128. {
  129. printf( "\r\nRequest Time out. \r\n") ;
  130. cnt = 0;
  131. break;
  132. }
  133. else
  134. {
  135. cnt++;
  136. delay_us(50); // wait 50ms
  137. }
  138. }
  139. break;
  140. default:
  141. break;
  142. }
  143. if(req>=pCount)
  144. {
  145. #ifdef PING_DEBUG
  146. printf("Ping Request = %d, PING_Reply = %d\r\n",req,rep);
  147. if(rep == req)
  148. printf( "PING SUCCESS\r\n " );
  149. else
  150. printf( "REPLY_ERROR\r\n " );
  151. #endif
  152. }
  153. }
  154. }
  155. /**
  156. *@brief ping响应函数
  157. *@param s- socket number
  158. *@param addr- P地址
  159. *@return 无
  160. */
  161. uint8 ping_request(uint8 s, uint8 *addr)
  162. {
  163. uint16 i;
  164. ping_reply_received = 0; /*ping 回复初始化标志位*/
  165. PingRequest.Type = PING_REQUEST; /*Ping-Request*/
  166. PingRequest.Code = CODE_ZERO; /*总是 '0'*/
  167. PingRequest.ID = htons(RandomID++); /*设置ping响应ID为随机的整型变量*/
  168. PingRequest.SeqNum =htons(RandomSeqNum++); /*设置ping响应的序列号为随机整形变量*/
  169. for(i = 0 ; i < BUF_LEN; i++)
  170. {
  171. PingRequest.Data[i] = (i) % 8; /*ping相应的数在'0'~'8‘*/
  172. }
  173. PingRequest.CheckSum = 0;
  174. /* 计算响应次数*/
  175. PingRequest.CheckSum = htons(checksum((uint8*)&PingRequest,sizeof(PingRequest)));
  176. /*发送ping响应到目的方 */
  177. if(sendto(s,(uint8 *)&PingRequest,sizeof(PingRequest),addr,3000)==0)
  178. {
  179. printf( "\r\n Fail to send ping-reply packet r\n") ;
  180. }
  181. else
  182. {
  183. printf(" 正在 Ping: %d.%d.%d.%d \r\n",(addr[0]), (addr[1]), (addr[2]), (addr[3]));
  184. }
  185. return 0;
  186. }
  187. /**
  188. *@brief 解析Ping回复
  189. *@param s- socket number
  190. *@param addr- Ping地址
  191. *@return 无
  192. */
  193. uint8 ping_reply(uint8 s, uint8 *addr, uint16 rlen)
  194. {
  195. uint16 tmp_checksum;
  196. uint16 len;
  197. uint16 i;
  198. uint8 data_buf[128];
  199. uint16 port = 3000;
  200. PINGMSGR PingReply;
  201. len = recvfrom(s, (uint8 *)data_buf,rlen,addr,&port); /*从目的端接收数据*/
  202. if(data_buf[0] == PING_REPLY)
  203. {
  204. PingReply.Type = data_buf[0];
  205. PingReply.Code = data_buf[1];
  206. PingReply.CheckSum = (data_buf[3]<<8) + data_buf[2];
  207. PingReply.ID = (data_buf[5]<<8) + data_buf[4];
  208. PingReply.SeqNum = (data_buf[7]<<8) + data_buf[6];
  209. for(i=0; i<len-8 ; i++)
  210. {
  211. PingReply.Data[i] = data_buf[8+i];
  212. }
  213. tmp_checksum = ~checksum(data_buf,len); /*检查ping回复的次数*/
  214. if(tmp_checksum != 0xffff)
  215. printf("tmp_checksum = %x\r\n",tmp_checksum);
  216. else
  217. {
  218. printf(" 来自 %d.%d.%d.%d 的回复 :ID=%x 字节=%d \r\n",
  219. (addr[0]), (addr[1]), (addr[2]), (addr[3]),htons(PingReply.ID),(rlen+6));
  220. ping_reply_received =1; /*当退出ping回复循环时,设置ping回复标志为1*/
  221. }
  222. }
  223. else if(data_buf[0] == PING_REQUEST)
  224. {
  225. PingReply.Code = data_buf[1];
  226. PingReply.Type = data_buf[2];
  227. PingReply.CheckSum = (data_buf[3]<<8) + data_buf[2];
  228. PingReply.ID = (data_buf[5]<<8) + data_buf[4];
  229. PingReply.SeqNum = (data_buf[7]<<8) + data_buf[6];
  230. for(i=0; i<len-8 ; i++)
  231. {
  232. PingReply.Data[i] = data_buf[8+i];
  233. }
  234. tmp_checksum = PingReply.CheckSum; /*检查ping回复次数*/
  235. PingReply.CheckSum = 0;
  236. if(tmp_checksum != PingReply.CheckSum)
  237. {
  238. printf( " \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), htons(PingReply.CheckSum)) ;
  239. }
  240. else
  241. { }
  242. printf(" Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
  243. (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), (PingReply.SeqNum), (rlen+6) );
  244. ping_reply_received =1; /* 当退出ping回复循环时,设置ping回复标志为1 */
  245. }
  246. else
  247. {
  248. printf(" Unkonwn msg. \n");
  249. }
  250. return 0;
  251. }
  252. /**
  253. *@brief 执行ping函数�
  254. *@param 无
  255. *@return 无
  256. */
  257. void do_ping(void)
  258. {
  259. printf("------------PING_TEST_START-----------------------\r\n");
  260. delay_ms(1000); // wait 1000ms
  261. ping_auto(SOCK_PING,remote_ip);
  262. }