以太网输入输出处理的实现
生活随笔
收集整理的這篇文章主要介紹了
以太网输入输出处理的实现
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- 1 以太網(wǎng)輸入輸出處理的實(shí)現(xiàn)
- 1.1 實(shí)現(xiàn)原理
- 1.2 代碼實(shí)現(xiàn)
1 以太網(wǎng)輸入輸出處理的實(shí)現(xiàn)
1.1 實(shí)現(xiàn)原理
先看下數(shù)據(jù)包的傳遞過程:
以太網(wǎng)數(shù)據(jù)包格式(RFC894):
上面有誤,正確的包格式如下:
字節(jié)對(duì)齊的特殊處理:
大小端轉(zhuǎn)換:
1.2 代碼實(shí)現(xiàn)
代碼結(jié)構(gòu)如下:
xnet_tiny.h中添加以太網(wǎng)包頭相關(guān)的定義:
xnet_tiny.h添加以太網(wǎng)輸入輸出處理的代碼:
static uint8_t netif_mac[XNET_MAC_ADDR_SIZE]; // mac地址#define swap_order16(v) ((((v) & 0xFF) << 8) | (((v) >> 8) & 0xFF))/*** 以太網(wǎng)初始化* @return 初始化結(jié)果*/ static xnet_err_t ethernet_init (void) {xnet_err_t err = xnet_driver_open(netif_mac);if (err < 0) return err;return XNET_ERR_OK; }/*** 發(fā)送一個(gè)以太網(wǎng)數(shù)據(jù)幀* @param protocol 上層數(shù)據(jù)協(xié)議,IP或ARP* @param mac_addr 目標(biāo)網(wǎng)卡的mac地址* @param packet 待發(fā)送的數(shù)據(jù)包* @return 發(fā)送結(jié)果*/ static xnet_err_t ethernet_out_to(xnet_protocol_t protocol, const uint8_t *mac_addr, xnet_packet_t * packet) {xether_hdr_t* ether_hdr;// 添加頭部add_header(packet, sizeof(xether_hdr_t));ether_hdr = (xether_hdr_t*)packet->data;memcpy(ether_hdr->dest, mac_addr, XNET_MAC_ADDR_SIZE);memcpy(ether_hdr->src, netif_mac, XNET_MAC_ADDR_SIZE);ether_hdr->protocol = swap_order16(protocol);// 數(shù)據(jù)發(fā)送return xnet_driver_send(packet); }/*** 以太網(wǎng)數(shù)據(jù)幀輸入輸出* @param packet 待處理的包*/ static void ethernet_in (xnet_packet_t * packet) {// 至少要比頭部數(shù)據(jù)大if (packet->size <= sizeof(xether_hdr_t)) {return;}// 往上分解到各個(gè)協(xié)議處理xether_hdr_t* hdr = (xether_hdr_t*)packet->data;switch (swap_order16(hdr->protocol)) {case XNET_PROTOCOL_ARP:break;case XNET_PROTOCOL_IP: {break;}} }/*** 查詢網(wǎng)絡(luò)接口,看看是否有數(shù)據(jù)包,有則進(jìn)行處理*/ static void ethernet_poll (void) {xnet_packet_t * packet;if (xnet_driver_read(&packet) == XNET_ERR_OK) {// 正常情況下,在此打個(gè)斷點(diǎn),全速運(yùn)行// 然后在對(duì)方端ping 192.168.254.2,會(huì)停在這里ethernet_in(packet);} }/*** 協(xié)議棧的初始化*/ void xnet_init (void) {ethernet_init(); }/*** 輪詢處理數(shù)據(jù)包,并在協(xié)議棧中處理*/ void xnet_poll(void) {ethernet_poll(); }總結(jié)
以上是生活随笔為你收集整理的以太网输入输出处理的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。