赞
踩
ping命令属于Network layer的ICMP(Internet control massage protol)协议构成,ICMP报文可以分为两大类:
ICMP报文种类 | type | 功能* |
---|---|---|
错误报告报文 | 3 | 目的站不可达 |
4 | 源站抑制 | |
5 | 重定向(改变路由) | |
11 | 数据包超时 | |
12 | 数据包参数错误 | |
查询报文 | 0/8 | 会话请求或回答 |
9/10 | 路由器询问或通告 | |
13/14 | 时间戳请求或回答 | |
15/16 | 信息请求或回答 | |
17/18 | 地址掩码请求或回答 |
ping命令主要是用来测试两个IP地址之间的网络是否能够连通,确定具有一条通路。在Windows
控制台中我们可以使用Ping命令来测试我们的主机是否能与其他主机通信,格式如下:
ping xxx.xxx.xxx.xxx(dest IP_addr)
在测试TCP/IP协议栈是否移植成功时,一个简便的方法就是测试 ping
命令是否能够应答成功,效果如下:
先给出ping命令的帧格式
type
:指ICMP报文的类型,例如ICMP两大类报文:差错报告报文和查询报文,其中含有许多不同类型的功能报文,因此对其分类。code
:对于每种不同类型(type)的报文在又含有不同的编码信息,例如差错报告报文中的数据包超时报文,就可分为两种:数据包分片超时和TTL超时。Identifier
:标识符,没有指明其正式定义,可自行定义。Seq number
:序列号,没有正式指明其定义,可自行定义。void Ping_Init(void) { #if FUNC_DBG_ON printf("run in %s .\r\n",__FUNCTION__); #endif IP4_ADDR(&dest_ip,192,168,1,31); IP4_ADDR(&local_ip,192,168,1,10); /*bind local IP.*/ printf("local IP address:%4d.%4d.%4d.%4d\r\n",ip4_addr1(&local_ip),\ ip4_addr2(&local_ip),\ ip4_addr3(&local_ip),\ ip4_addr4(&local_ip)); /*bind dest IP.*/ printf("dest IP address:%4d.%4d.%4d.%4d\r\n", ip4_addr1(&dest_ip),\ ip4_addr2(&dest_ip),\ ip4_addr3(&dest_ip),\ ip4_addr4(&dest_ip)); /*allocate a new pcb*/ ping_pcb = raw_new(IP_PROTO_ICMP);//set IP protocol type to ICMP if(NULL == ping_pcb) { printf("get n new raw pcb failed.\r\n"); return; } PingCmd_start(ping_pcb); } void PingCmd_start(struct raw_pcb *pcb) { #if FUNC_DBG_ON printf("run in %s .\r\n",__FUNCTION__); #endif raw_bind(pcb,&local_ip);//bind local IP to pcb. // raw_connect(pcb,&dest_ip); raw_recv(pcb,recv_callback,NULL); // ping_cnt--; /*sys_timeout()为注册一个单次定时事件,当计时结束后,会主动发送REQUEST包,PC会给予响应 * 接收Ping命令时关闭,MCU发起ping请求时打开。 */ // sys_timeout(PING_DELAY,timeoutHandle,pcb);//set a oneshot time event for periodicly. }
在Windows终端对MCU已设置好的IP地址进行ping命令调试,PC端发出的ICMP报文中type应为0x08
,code为0x00
,identifier和seq number可随意指定,故在MCU端接收代码可设置为如下格式:
u8_t recv_callback(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr) { // p->payload point the IP header/Ethernet frame data field. struct icmp_echo_hdr *icmp_hdr = NULL; struct ip_hdr *ip_hdr = NULL; u8_t ip_hlen = 0; u8_t *data_ptr = NULL; #if FUNC_DBG_ON printf("run in %s .\r\n",__FUNCTION__); #endif (void)arg; if(ip_addr_cmp(&dest_ip,addr) &&\ p->tot_len > (IP_HLEN + sizeof(struct icmp_echo_hdr)))//process packet { ip_hdr = (struct ip_hdr *)p->payload; //point to IP header ip_hlen = IPH_HL(ip_hdr)*4; //1 len means 4 bytes. //adjust p->payload point ICMP header. if(pbuf_header(p,-ip_hlen)) printf("Adjust header failed.\r\n"); icmp_hdr = (struct icmp_echo_hdr *)p->payload; if(0x00 == icmp_hdr->code) { data_ptr = (u8_t*)p->payload + sizeof(struct icmp_echo_hdr); printf("icmp_hdr->type %d .\r\n",icmp_hdr->type); switch (icmp_hdr->type) { case PING_REPLY: //receive a reply message. printf("[Receive message]:%s.\r\n",data_ptr); printf("[ID]:%x.\r\n",icmp_hdr->id); printf("[SEQ Number]:%x.\r\n",icmp_hdr->seqno); sys_timeout(PING_DELAY,timeoutHandle,pcb);//continue to send a ping REQUEST packet. break; case PING_REQUEST: //need ack printf("Receive a REQUEST message.\r\n"); printf("[Receive message]:%s.\r\n",data_ptr); printf("[ID]:%x.\r\n",icmp_hdr->id); printf("[SEQ Number]:%x.\r\n",icmp_hdr->seqno); /*change type,reset checksum*/ ICMPH_TYPE_SET(icmp_hdr,PING_REPLY);//set type. /*checksum*/ if(icmp_hdr->chksum >= htons(0xffffU - (PING_REQUEST<<8))) icmp_hdr->chksum +=htons(PING_REQUEST<<8 + 1); else icmp_hdr->chksum +=htons(PING_REQUEST<<8); raw_sendto(pcb,p,addr); break; default: break; } } else printf("[ERROR]:It's not a ping format packet.\r\n"); } pbuf_free(p); return 1;//delete pbuf. }
该代码块流程如下:
从代码块中可以看出,在处理接收pbuf时与发送pbuf时不同。发送时申请的pbuf为IP层pbuf模型,Lwip默认将IP首部预留给底层函数添加其信息,而payload指针直接指向其数据区;接收时,下层处理函数直接将完整的pbuf数据包传递给pcb控制块,关于为何没有直接将payload指向IP数据区,有待研究。
192.168.1.31
192.168.1.10
PC终端发起ping请求:
WireShark抓包结果
ping数据区域值为This a ping test,only for REQUSET message.
,由于MCU是在上电启动后自动执行ping命令,直接给出WireShark抓包结果。
查看数据是否正确
从结果来看,PC端正确接收数据,至此关于MCU发起、接收ping命令结束,当然,MCU程序设计还有些许不足,没有对ping包进行数量限制,而是持续发送。
链接:https://pan.baidu.com/s/1ez-gm1TW0rLBo6xK2aNGFA?pwd=lfds
提取码:lfds
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。