ARP输入处理
文章目錄
- 1 ARP輸入原理
- 1.1 原理介紹
- 1.2 代碼實(shí)現(xiàn)
1 ARP輸入原理
1.1 原理介紹
收到ARP包時該如何處理?
處理流程:
實(shí)現(xiàn)原理:
1.2 代碼實(shí)現(xiàn)
代碼結(jié)構(gòu):
xnet_tiny.h添加如下代碼:
#define XARP_ENTRY_FREE 0 // ARP表項(xiàng)空閑 #define XARP_ENTRY_OK 1 // ARP表項(xiàng)解析成功xnet_err_t xarp_make_request(const xipaddr_t * ipaddr);xnet_tiny.c添加如下代碼:
#define xipaddr_is_equal_buf(addr, buf) (memcmp((addr)->array, (buf), XNET_IPV4_ADDR_SIZE) == 0)/*** 生成一個ARP響應(yīng)* @param arp_packet 接收到的ARP請求包* @return 生成結(jié)果*/xnet_err_t xarp_make_response(xarp_packet_t * arp_packet) {xarp_packet_t* response_packet;xnet_packet_t * packet = xnet_alloc_for_send(sizeof(xarp_packet_t));response_packet = (xarp_packet_t *)packet->data;response_packet->hw_type = swap_order16(XARP_HW_ETHER);response_packet->pro_type = swap_order16(XNET_PROTOCOL_IP);response_packet->hw_len = XNET_MAC_ADDR_SIZE;response_packet->pro_len = XNET_IPV4_ADDR_SIZE;response_packet->opcode= swap_order16(XARP_REPLY);memcpy(response_packet->target_mac, arp_packet->sender_mac, XNET_MAC_ADDR_SIZE);memcpy(response_packet->target_ip, arp_packet->sender_ip, XNET_IPV4_ADDR_SIZE);memcpy(response_packet->sender_mac, netif_mac, XNET_MAC_ADDR_SIZE);memcpy(response_packet->sender_ip, netif_ipaddr.array, XNET_IPV4_ADDR_SIZE);return ethernet_out_to(XNET_PROTOCOL_ARP, ether_broadcast, packet); }/*** 更新ARP表項(xiàng)* @param src_ip 源IP地址* @param mac_addr 對應(yīng)的mac地址*/ static void update_arp_entry(uint8_t * src_ip, uint8_t * mac_addr) {memcpy(arp_entry.ipaddr.array, src_ip, XNET_IPV4_ADDR_SIZE);memcpy(arp_entry.macaddr, mac_addr, 6);arp_entry.state = XARP_ENTRY_OK; }/*** ARP輸入處理* @param packet 輸入的ARP包*/ void xarp_in(xnet_packet_t * packet) {if (packet->size >= sizeof(xarp_packet_t)) {xarp_packet_t * arp_packet = (xarp_packet_t *) packet->data;uint16_t opcode = swap_order16(arp_packet->opcode);// 包的合法性檢查if ((swap_order16(arp_packet->hw_type) != XARP_HW_ETHER) ||(arp_packet->hw_len != XNET_MAC_ADDR_SIZE) ||(swap_order16(arp_packet->pro_type) != XNET_PROTOCOL_IP) ||(arp_packet->pro_len != XNET_IPV4_ADDR_SIZE)|| ((opcode != XARP_REQUEST) && (opcode != XARP_REPLY))) {return;}// 只處理發(fā)給自己的請求或響應(yīng)包if (!xipaddr_is_equal_buf(&netif_ipaddr, arp_packet->target_ip)) {return;}// 根據(jù)操作碼進(jìn)行不同的處理switch (swap_order16(arp_packet->opcode)) {case XARP_REQUEST: // 請求,回送響應(yīng)// 在對方機(jī)器Ping 自己,然后看wireshark,能看到ARP請求和響應(yīng)// 接下來,很可能對方要與自己通信,所以更新一下xarp_make_response(arp_packet);update_arp_entry(arp_packet->sender_ip, arp_packet->sender_mac);break;case XARP_REPLY: // 響應(yīng),更新自己的表update_arp_entry(arp_packet->sender_ip, arp_packet->sender_mac);break;}} }/*** 以太網(wǎng)數(shù)據(jù)幀輸入輸出* @param packet 待處理的包*/ static void ethernet_in (xnet_packet_t * packet) {// 至少要比頭部數(shù)據(jù)大if (packet->size <= sizeof(xether_hdr_t)) {return;}// 往上分解到各個協(xié)議處理xether_hdr_t* hdr = (xether_hdr_t*)packet->data;switch (swap_order16(hdr->protocol)) {case XNET_PROTOCOL_ARP:remove_header(packet, sizeof(xether_hdr_t));xarp_in(packet);break;case XNET_PROTOCOL_IP: {break;}} }總結(jié)
- 上一篇: CircleList
- 下一篇: LED驱动框架