理论部分
本课程中ICMP主要负责2项任务:检查连通性,差错报告,交换路由器之间的信息通信码




代码实现部分
在xnet_tinny.h中添加ICMP协议
cpp
typedef enum _xnet_protocol_t
{
XNET_PROTOCOL_ARP = 0x0806,
XNET_PROTOCOL_IP = 0x0800,
XNET_PROTOCOL_ICMP = 1,
}xnet_protocol_t;
xnet_tinny.c中IP协议处理中向上层协议交付可添加ICMP协议的处理部分
cpp
#define xipaddr_from_buf(dest,buf) ((dest)->addr = *(uint32_t*)(buf))
switch (iphdr->protocol)
{
case XNET_PROTOCOL_ICMP:
remove_header(packet, header_size);
ximcp_in(&src_ip, packet);
default:
break;
}
接下来实现xicmp_in函数
铺垫工作:
cpp
void xicmp_init(void);
void xicmp_in(xipaddr_t* src_ip, xnet_packet_t* packet);
cpp
void xnet_init(void)
{
ethernet_init();
xarp_init();
xip_init();
xicmp_init();
}
ICMP数据包格式

cpp
typedef struct _xicmp_hdr_t
{
uint8_t type;
uint8_t code;
uint16_t checksum;
uint16_t id;
uint16_t seq;
}xicmp_hdr_t;
cpp
#define XICMP_CODE_ECHO_REQUEST 8 //ICMP回显请求
#define XICMP_CODE_ECHO_REPLY 0 //ICMP回显响应
xicmp_in函数实现:
cpp
void xicmp_in(xipaddr_t* src_ip, xnet_packet_t* packet)
{
xicmp_hdr_t* icmphdr = (xicmp_hdr_t*)packet->data;
if ((packet->size >= sizeof(xicmp_hdr_t)) && (icmphdr->type == XICMP_CODE_ECHO_REQUEST))
reply_icmp_request(icmphdr, src_ip, packet);
}
reply_icmp_request函数实现:
cpp
static xnet_err_t reply_icmp_request(xicmp_hdr_t* icmp_hdr, xipaddr_t* src_ip, xnet_packet_t* packet)
{
xicmp_hdr_t* reply_hdr;
xnet_packet_t* tx = xnet_alloc_for_send(packet->size);
reply_hdr = (xicmp_hdr_t*)tx->data;
reply_hdr->type = XICMP_CODE_ECHO_REPLY;
reply_hdr->code = 0;
reply_hdr->id = icmp_hdr->id;
reply_hdr->seq = icmp_hdr->seq;
reply_hdr->checksum = 0;
memcpy(((uint8_t*)reply_hdr) + sizeof(xicmp_hdr_t), ((uint8_t*)icmp_hdr) + sizeof(xicmp_hdr_t),
packet->size - sizeof(xicmp_hdr_t));
reply_hdr->checksum = checksum16((uint16_t*)reply_hdr, tx->size, 0, 1);
return xip_out(XNET_PROTOCOL_ICMP, src_ip, tx);
}
测试部分



