network arplab finished
This commit is contained in:
13
network/start/xnet_tiny/src/app.c
Normal file
13
network/start/xnet_tiny/src/app.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include "xnet_tiny.h"
|
||||
|
||||
int main (void) {
|
||||
xnet_init();
|
||||
|
||||
printf("xnet running\n");
|
||||
while (1) {
|
||||
xnet_poll();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
2
network/start/xnet_tiny/src/xnet_app/CMakeLists.txt
Normal file
2
network/start/xnet_tiny/src/xnet_app/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
aux_source_directory(. DIR_HELLO_SRCS)
|
||||
add_library(xnet_app ${DIR_HELLO_SRCS} )
|
||||
52
network/start/xnet_tiny/src/xnet_app/port_pcap.c
Normal file
52
network/start/xnet_tiny/src/xnet_app/port_pcap.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "pcap_device.h"
|
||||
#include "xnet_tiny.h"
|
||||
|
||||
static pcap_t * pcap;
|
||||
|
||||
// pcap所用的网卡
|
||||
const char * ip_str = "10.20.6.8"; // 根据实际电脑上存在的网卡地址进行修改
|
||||
const char my_mac_addr[] = {0x00, 0x50, 0x56, 0xc0, 0x00, 0x08};
|
||||
/**
|
||||
* 初始化网络驱动
|
||||
* @return 0成功,其它失败
|
||||
*/
|
||||
xnet_err_t xnet_driver_open (uint8_t * mac_addr) {
|
||||
memcpy(mac_addr, my_mac_addr, sizeof(my_mac_addr));
|
||||
pcap = pcap_device_open(ip_str, mac_addr, 1);
|
||||
if (pcap == (pcap_t *)0) {
|
||||
exit(-1);
|
||||
}
|
||||
return XNET_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送数据
|
||||
* @param frame 数据起始地址
|
||||
* @param size 数据长度
|
||||
* @return 0 - 成功,其它失败
|
||||
*/
|
||||
xnet_err_t xnet_driver_send (xnet_packet_t * packet) {
|
||||
return pcap_device_send(pcap, packet->data, packet->size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取数据
|
||||
* @param frame 数据存储位置
|
||||
* @param size 数据长度
|
||||
* @return 0 - 成功,其它失败
|
||||
*/
|
||||
xnet_err_t xnet_driver_read (xnet_packet_t ** packet) {
|
||||
uint16_t size;
|
||||
xnet_packet_t * r_packet = xnet_alloc_for_read(XNET_CFG_PACKET_MAX_SIZE);
|
||||
|
||||
size = pcap_device_read(pcap, r_packet->data, XNET_CFG_PACKET_MAX_SIZE);
|
||||
if (size) {
|
||||
r_packet->size = size;
|
||||
*packet = r_packet;
|
||||
return XNET_ERR_OK;
|
||||
}
|
||||
|
||||
return XNET_ERR_IO;
|
||||
}
|
||||
1
network/start/xnet_tiny/src/xnet_app/xserver_datetime.c
Normal file
1
network/start/xnet_tiny/src/xnet_app/xserver_datetime.c
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
network/start/xnet_tiny/src/xnet_app/xserver_datetime.h
Normal file
1
network/start/xnet_tiny/src/xnet_app/xserver_datetime.h
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
network/start/xnet_tiny/src/xnet_app/xserver_http.c
Normal file
1
network/start/xnet_tiny/src/xnet_app/xserver_http.c
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
network/start/xnet_tiny/src/xnet_app/xserver_http.h
Normal file
1
network/start/xnet_tiny/src/xnet_app/xserver_http.h
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
2
network/start/xnet_tiny/src/xnet_tiny/CMakeLists.txt
Normal file
2
network/start/xnet_tiny/src/xnet_tiny/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
aux_source_directory(. DIR_HELLO_SRCS)
|
||||
add_library(xnet_tiny ${DIR_HELLO_SRCS} )
|
||||
138
network/start/xnet_tiny/src/xnet_tiny/xarp.c
Normal file
138
network/start/xnet_tiny/src/xnet_tiny/xarp.c
Normal file
@@ -0,0 +1,138 @@
|
||||
#include <string.h>
|
||||
#include "xarp.h"
|
||||
#include "xnet_tiny.h"
|
||||
|
||||
#define XARP_CACHE_SIZE 16
|
||||
|
||||
#define to_addr_buf(addr) ((uint8_t *)((addr)->data))
|
||||
|
||||
static const uint8_t net_broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
typedef enum _xarp_state_t {
|
||||
XARP_ENTRY_STATE_FREE,
|
||||
XARP_ENTRY_STATE_RESOLVED,
|
||||
} xarp_state_t;
|
||||
|
||||
typedef struct _xarp_entry_t {
|
||||
uint8_t ip_addr[4];
|
||||
uint8_t mac_addr[XNET_MAC_ADDR_SIZE];
|
||||
xarp_state_t state;
|
||||
int tmo;
|
||||
int retry;
|
||||
} xarp_entry_t;
|
||||
|
||||
static xarp_entry_t arp_table[XARP_CACHE_SIZE];
|
||||
|
||||
#define swap_order16(v) ((((v) & 0xFF) << 8) | (((v) >> 8) & 0xFF))
|
||||
|
||||
void xarp_init(void) {
|
||||
for (int i = 0; i < XARP_CACHE_SIZE; i++) {
|
||||
arp_table[i].state = XARP_ENTRY_STATE_FREE;
|
||||
}
|
||||
}
|
||||
|
||||
static xarp_entry_t *find_entry(const uint8_t *ip_addr, int force) {
|
||||
xarp_entry_t *entry = (xarp_entry_t *)0;
|
||||
|
||||
for (int i = 0; i < XARP_CACHE_SIZE; i++) {
|
||||
if (arp_table[i].state == XARP_ENTRY_STATE_FREE) {
|
||||
if (force) {
|
||||
entry = arp_table + i;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (memcmp(arp_table[i].ip_addr, ip_addr, 4) == 0) {
|
||||
entry = arp_table + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static void update_entry(const uint8_t *ip_addr, const uint8_t *mac_addr, int force) {
|
||||
xarp_entry_t *entry = find_entry(ip_addr, force);
|
||||
if (entry) {
|
||||
memcpy(entry->ip_addr, ip_addr, 4);
|
||||
memcpy(entry->mac_addr, mac_addr, XNET_MAC_ADDR_SIZE);
|
||||
entry->state = XARP_ENTRY_STATE_RESOLVED;
|
||||
}
|
||||
}
|
||||
|
||||
void xarp_in(xnet_packet_t *packet) {
|
||||
if (packet->size < sizeof(xether_hdr_t)) {
|
||||
return;
|
||||
}
|
||||
xether_hdr_t *ether_hdr = (xether_hdr_t *)packet->data;
|
||||
|
||||
remove_header(packet, sizeof(xether_hdr_t));
|
||||
|
||||
if (packet->size < sizeof(xarp_packet_t)) {
|
||||
return;
|
||||
}
|
||||
xarp_packet_t *arp_packet = (xarp_packet_t *)packet->data;
|
||||
if ((swap_order16(arp_packet->hw_type) != XARP_HW_ETHER) ||
|
||||
(swap_order16(arp_packet->pro_type) != XARP_PROTOCOL_IP) ||
|
||||
(arp_packet->hw_len != XNET_MAC_ADDR_SIZE) ||
|
||||
(arp_packet->pro_len != 4)) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_entry(arp_packet->send_ip, arp_packet->send_mac, 1);
|
||||
|
||||
if (memcmp(arp_packet->target_ip, my_ip_addr, 4) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (swap_order16(arp_packet->oper) == XARP_OPER_REQUEST) {
|
||||
xnet_packet_t *tx_packet = xnet_alloc_for_send(sizeof(xarp_packet_t));
|
||||
if (tx_packet) {
|
||||
xarp_packet_t *reply_packet = (xarp_packet_t *)tx_packet->data;
|
||||
reply_packet->hw_type = swap_order16(XARP_HW_ETHER);
|
||||
reply_packet->pro_type = swap_order16(XARP_PROTOCOL_IP);
|
||||
reply_packet->hw_len = XNET_MAC_ADDR_SIZE;
|
||||
reply_packet->pro_len = 4;
|
||||
reply_packet->oper = swap_order16(XARP_OPER_REPLY);
|
||||
|
||||
memcpy(reply_packet->send_mac, get_netif_mac(), XNET_MAC_ADDR_SIZE);
|
||||
memcpy(reply_packet->send_ip, my_ip_addr, 4);
|
||||
memcpy(reply_packet->target_mac, arp_packet->send_mac, XNET_MAC_ADDR_SIZE);
|
||||
memcpy(reply_packet->target_ip, arp_packet->send_ip, 4);
|
||||
|
||||
ethernet_out_to(XNET_PROTOCOL_ARP, ether_hdr->src, tx_packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void send_arp_request(const uint8_t *ip_addr) {
|
||||
xnet_packet_t *tx_packet = xnet_alloc_for_send(sizeof(xarp_packet_t));
|
||||
if (tx_packet) {
|
||||
xarp_packet_t *arp_request = (xarp_packet_t *)tx_packet->data;
|
||||
arp_request->hw_type = swap_order16(XARP_HW_ETHER);
|
||||
arp_request->pro_type = swap_order16(XARP_PROTOCOL_IP);
|
||||
arp_request->hw_len = XNET_MAC_ADDR_SIZE;
|
||||
arp_request->pro_len = 4;
|
||||
arp_request->oper = swap_order16(XARP_OPER_REQUEST);
|
||||
|
||||
memcpy(arp_request->send_mac, get_netif_mac(), XNET_MAC_ADDR_SIZE);
|
||||
memcpy(arp_request->send_ip, my_ip_addr, 4);
|
||||
memset(arp_request->target_mac, 0, XNET_MAC_ADDR_SIZE);
|
||||
memcpy(arp_request->target_ip, ip_addr, 4);
|
||||
|
||||
ethernet_out_to(XNET_PROTOCOL_ARP, net_broadcast_addr, tx_packet);
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t *xarp_resolve(const uint8_t *ip_addr) {
|
||||
xarp_entry_t *entry = find_entry(ip_addr, 0);
|
||||
if (entry) {
|
||||
if (entry->state == XARP_ENTRY_STATE_RESOLVED) {
|
||||
return entry->mac_addr;
|
||||
}
|
||||
} else {
|
||||
send_arp_request(ip_addr);
|
||||
}
|
||||
|
||||
return (const uint8_t *)0;
|
||||
}
|
||||
35
network/start/xnet_tiny/src/xnet_tiny/xarp.h
Normal file
35
network/start/xnet_tiny/src/xnet_tiny/xarp.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef XARP_H
|
||||
#define XARP_H
|
||||
|
||||
#include "xnet_tiny.h"
|
||||
|
||||
#define XARP_HW_ETHER 1 // 硬件类型:以太网
|
||||
#define XARP_PROTOCOL_IP 0x0800 // 协议类型:IP
|
||||
|
||||
#define XARP_OPER_REQUEST 1 // ARP请求
|
||||
#define XARP_OPER_REPLY 2 // ARP响应
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/**
|
||||
* ARP协议包
|
||||
*/
|
||||
typedef struct _xarp_packet_t {
|
||||
uint16_t hw_type; // 硬件类型
|
||||
uint16_t pro_type; // 协议类型
|
||||
uint8_t hw_len; // 硬件地址长度
|
||||
uint8_t pro_len; // 协议地址长度
|
||||
uint16_t oper; // 操作码
|
||||
uint8_t send_mac[XNET_MAC_ADDR_SIZE]; // 发送方MAC
|
||||
uint8_t send_ip[4]; // 发送方IP
|
||||
uint8_t target_mac[XNET_MAC_ADDR_SIZE]; // 接收方MAC
|
||||
uint8_t target_ip[4]; // 接收方IP
|
||||
} xarp_packet_t;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
void xarp_init(void);
|
||||
void xarp_in(xnet_packet_t *packet);
|
||||
const uint8_t *xarp_resolve(const uint8_t *ip_addr);
|
||||
|
||||
#endif // XARP_H
|
||||
74
network/start/xnet_tiny/src/xnet_tiny/xicmp.c
Normal file
74
network/start/xnet_tiny/src/xnet_tiny/xicmp.c
Normal file
@@ -0,0 +1,74 @@
|
||||
#include <string.h>
|
||||
#include "xicmp.h"
|
||||
#include "xnet_tiny.h"
|
||||
#include "xip.h"
|
||||
|
||||
#define ICMP_TYPE_ECHO_REPLY 0
|
||||
#define ICMP_TYPE_ECHO_REQUEST 8
|
||||
|
||||
#define swap_order16(v) ((((v) & 0xFF) << 8) | (((v) >> 8) & 0xFF))
|
||||
|
||||
static uint16_t checksum(void *buf, uint16_t len) {
|
||||
uint32_t sum = 0;
|
||||
uint16_t *curr = (uint16_t *)buf;
|
||||
|
||||
while (len > 1) {
|
||||
sum += *curr++;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
sum += *(uint8_t *)curr;
|
||||
}
|
||||
|
||||
uint16_t high;
|
||||
while ((high = sum >> 16) != 0) {
|
||||
sum = high + (sum & 0xFFFF);
|
||||
}
|
||||
|
||||
return ~((uint16_t)sum);
|
||||
}
|
||||
|
||||
void xicmp_in(xnet_packet_t *packet) {
|
||||
remove_header(packet, sizeof(xether_hdr_t));
|
||||
|
||||
xip_hdr_t *ip_hdr = (xip_hdr_t *)packet->data;
|
||||
if ((ip_hdr->hlen_ver & 0xF0) != 0x40) {
|
||||
return;
|
||||
}
|
||||
uint8_t hlen = (ip_hdr->hlen_ver & 0x0F) * 4;
|
||||
if (hlen < sizeof(xip_hdr_t)) {
|
||||
return;
|
||||
}
|
||||
if (checksum(ip_hdr, hlen) != 0) {
|
||||
return;
|
||||
}
|
||||
if (memcmp(ip_hdr->dest_ip, my_ip_addr, 4) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove_header(packet, hlen);
|
||||
|
||||
xicmp_packet_t *icmp_packet = (xicmp_packet_t *)packet->data;
|
||||
if (icmp_packet->type == ICMP_TYPE_ECHO_REQUEST) {
|
||||
xnet_packet_t *tx_packet = xnet_alloc_for_send(packet->size);
|
||||
if (tx_packet) {
|
||||
memcpy(tx_packet->data, packet->data, packet->size);
|
||||
|
||||
xicmp_packet_t *reply_icmp = (xicmp_packet_t *)tx_packet->data;
|
||||
reply_icmp->type = ICMP_TYPE_ECHO_REPLY;
|
||||
reply_icmp->checksum = 0;
|
||||
reply_icmp->checksum = checksum(reply_icmp, tx_packet->size);
|
||||
|
||||
xip_hdr_t *reply_ip_hdr = (xip_hdr_t *)(tx_packet->data - sizeof(xip_hdr_t));
|
||||
memcpy(reply_ip_hdr, ip_hdr, sizeof(xip_hdr_t));
|
||||
reply_ip_hdr->total_len = swap_order16(tx_packet->size + sizeof(xip_hdr_t));
|
||||
memcpy(reply_ip_hdr->dest_ip, ip_hdr->src_ip, 4);
|
||||
memcpy(reply_ip_hdr->src_ip, my_ip_addr, 4);
|
||||
reply_ip_hdr->hdr_checksum = 0;
|
||||
reply_ip_hdr->hdr_checksum = checksum(reply_ip_hdr, sizeof(xip_hdr_t));
|
||||
|
||||
xip_out(tx_packet, ip_hdr->src_ip, XNET_PROTOCOL_IP);
|
||||
}
|
||||
}
|
||||
}
|
||||
33
network/start/xnet_tiny/src/xnet_tiny/xicmp.h
Normal file
33
network/start/xnet_tiny/src/xnet_tiny/xicmp.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef XICMP_H
|
||||
#define XICMP_H
|
||||
|
||||
#include "xnet_tiny.h"
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct _xip_hdr_t {
|
||||
uint8_t hlen_ver;
|
||||
uint8_t tos;
|
||||
uint16_t total_len;
|
||||
uint16_t id;
|
||||
uint16_t flags_fragment;
|
||||
uint8_t ttl;
|
||||
uint8_t protocol;
|
||||
uint16_t hdr_checksum;
|
||||
uint8_t src_ip[4];
|
||||
uint8_t dest_ip[4];
|
||||
} xip_hdr_t;
|
||||
|
||||
typedef struct _xicmp_packet_t {
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t checksum;
|
||||
uint16_t id;
|
||||
uint16_t seq;
|
||||
} xicmp_packet_t;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
void xicmp_in(xnet_packet_t *packet);
|
||||
|
||||
#endif // XICMP_H
|
||||
10
network/start/xnet_tiny/src/xnet_tiny/xip.c
Normal file
10
network/start/xnet_tiny/src/xnet_tiny/xip.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "xip.h"
|
||||
#include "xarp.h"
|
||||
#include "xnet_tiny.h"
|
||||
|
||||
void xip_out(xnet_packet_t *packet, const uint8_t *dest_ip, uint8_t protocol) {
|
||||
const uint8_t *mac_addr = xarp_resolve(dest_ip);
|
||||
if (mac_addr) {
|
||||
ethernet_out_to(XNET_PROTOCOL_IP, mac_addr, packet);
|
||||
}
|
||||
}
|
||||
8
network/start/xnet_tiny/src/xnet_tiny/xip.h
Normal file
8
network/start/xnet_tiny/src/xnet_tiny/xip.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef XIP_H
|
||||
#define XIP_H
|
||||
|
||||
#include "xnet_tiny.h"
|
||||
|
||||
void xip_out(xnet_packet_t *packet, const uint8_t *dest_ip, uint8_t protocol);
|
||||
|
||||
#endif // XIP_H
|
||||
153
network/start/xnet_tiny/src/xnet_tiny/xnet_tiny.c
Normal file
153
network/start/xnet_tiny/src/xnet_tiny/xnet_tiny.c
Normal file
@@ -0,0 +1,153 @@
|
||||
#include <string.h>
|
||||
#include "xnet_tiny.h"
|
||||
#include "xarp.h"
|
||||
#include "xicmp.h"
|
||||
|
||||
const uint8_t my_ip_addr[] = {192, 168, 254, 2};
|
||||
|
||||
#define min(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
static uint8_t netif_mac[XNET_MAC_ADDR_SIZE]; // mac地址
|
||||
static xnet_packet_t tx_packet, rx_packet; // 接收与发送缓冲区
|
||||
|
||||
#define swap_order16(v) ((((v) & 0xFF) << 8) | (((v) >> 8) & 0xFF))
|
||||
|
||||
const uint8_t * get_netif_mac(void) {
|
||||
return netif_mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配一个网络数据包用于发送数据
|
||||
* @param data_size 数据空间大小
|
||||
* @return 分配得到的包结构
|
||||
*/
|
||||
xnet_packet_t * xnet_alloc_for_send(uint16_t data_size) {
|
||||
// 从tx_packet的后端往前分配,因为前边要预留作为各种协议的头部数据存储空间
|
||||
tx_packet.data = tx_packet.payload + XNET_CFG_PACKET_MAX_SIZE - data_size;
|
||||
tx_packet.size = data_size;
|
||||
return &tx_packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配一个网络数据包用于读取
|
||||
* @param data_size 数据空间大小
|
||||
* @return 分配得到的数据包
|
||||
*/
|
||||
xnet_packet_t * xnet_alloc_for_read(uint16_t data_size) {
|
||||
// 从最开始进行分配,用于最底层的网络数据帧读取
|
||||
rx_packet.data = rx_packet.payload;
|
||||
rx_packet.size = data_size;
|
||||
return &rx_packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为发包添加一个头部
|
||||
* @param packet 待处理的数据包
|
||||
* @param header_size 增加的头部大小
|
||||
*/
|
||||
static void add_header(xnet_packet_t *packet, uint16_t header_size) {
|
||||
packet->data -= header_size;
|
||||
packet->size += header_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为接收向上处理移去头部
|
||||
* @param packet 待处理的数据包
|
||||
* @param header_size 移去的头部大小
|
||||
*/
|
||||
void remove_header(xnet_packet_t *packet, uint16_t header_size) {
|
||||
packet->data += header_size;
|
||||
packet->size -= header_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将包的长度截断为size大小
|
||||
* @param packet 待处理的数据包
|
||||
* @param size 最终大小
|
||||
*/
|
||||
static void truncate_packet(xnet_packet_t *packet, uint16_t size) {
|
||||
packet->size = min(packet->size, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以太网初始化
|
||||
* @return 初始化结果
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送一个以太网数据帧
|
||||
* @param protocol 上层数据协议,IP或ARP
|
||||
* @param mac_addr 目标网卡的mac地址
|
||||
* @param packet 待发送的数据包
|
||||
* @return 发送结果
|
||||
*/
|
||||
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);
|
||||
|
||||
// 数据发送
|
||||
return xnet_driver_send(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以太网数据帧输入输出
|
||||
* @param packet 待处理的包
|
||||
*/
|
||||
static void ethernet_in (xnet_packet_t * packet) {
|
||||
// 至少要比头部数据大
|
||||
if (packet->size <= sizeof(xether_hdr_t)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 往上分解到各个协议处理
|
||||
xether_hdr_t* hdr = (xether_hdr_t*)packet->data;
|
||||
switch (swap_order16(hdr->protocol)) {
|
||||
case XNET_PROTOCOL_ARP:
|
||||
xarp_in(packet);
|
||||
break;
|
||||
case XNET_PROTOCOL_IP: {
|
||||
xicmp_in(packet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询网络接口,看看是否有数据包,有则进行处理
|
||||
*/
|
||||
static void ethernet_poll (void) {
|
||||
xnet_packet_t * packet;
|
||||
|
||||
if (xnet_driver_read(&packet) == XNET_ERR_OK) {
|
||||
// 正常情况下,在此打个断点,全速运行
|
||||
// 然后在对方端ping 192.168.254.2,会停在这里
|
||||
ethernet_in(packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 协议栈的初始化
|
||||
*/
|
||||
void xnet_init (void) {
|
||||
ethernet_init();
|
||||
xarp_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 轮询处理数据包,并在协议栈中处理
|
||||
*/
|
||||
void xnet_poll(void) {
|
||||
ethernet_poll();
|
||||
}
|
||||
59
network/start/xnet_tiny/src/xnet_tiny/xnet_tiny.h
Normal file
59
network/start/xnet_tiny/src/xnet_tiny/xnet_tiny.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef XNET_TINY_H
|
||||
#define XNET_TINY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define XNET_CFG_PACKET_MAX_SIZE 1516 // 收发数据包的最大大小
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define XNET_MAC_ADDR_SIZE 6 // MAC地址长度
|
||||
|
||||
/**
|
||||
* 以太网数据帧格式:RFC894
|
||||
*/
|
||||
typedef struct _xether_hdr_t {
|
||||
uint8_t dest[XNET_MAC_ADDR_SIZE]; // 目标mac地址
|
||||
uint8_t src[XNET_MAC_ADDR_SIZE]; // 源mac地址
|
||||
uint16_t protocol; // 协议/长度
|
||||
}xether_hdr_t;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
typedef enum _xnet_err_t {
|
||||
XNET_ERR_OK = 0,
|
||||
XNET_ERR_IO = -1,
|
||||
}xnet_err_t;
|
||||
|
||||
/**
|
||||
* 网络数据结构
|
||||
*/
|
||||
typedef struct _xnet_packet_t{
|
||||
uint16_t size; // 包中有效数据大小
|
||||
uint8_t * data; // 包的数据起始地址
|
||||
uint8_t payload[XNET_CFG_PACKET_MAX_SIZE]; // 最大负载数据量
|
||||
}xnet_packet_t;
|
||||
|
||||
typedef enum _xnet_protocol_t {
|
||||
XNET_PROTOCOL_ARP = 0x0806, // ARP协议
|
||||
XNET_PROTOCOL_IP = 0x0800, // IP协议
|
||||
}xnet_protocol_t;
|
||||
|
||||
xnet_packet_t * xnet_alloc_for_send(uint16_t data_size);
|
||||
xnet_packet_t * xnet_alloc_for_read(uint16_t data_size);
|
||||
|
||||
xnet_err_t xnet_driver_open (uint8_t * mac_addr);
|
||||
xnet_err_t xnet_driver_send (xnet_packet_t * packet);
|
||||
xnet_err_t xnet_driver_read (xnet_packet_t ** packet);
|
||||
|
||||
void xnet_init (void);
|
||||
void xnet_poll(void);
|
||||
|
||||
void remove_header(xnet_packet_t *packet, uint16_t header_size);
|
||||
xnet_err_t ethernet_out_to(xnet_protocol_t protocol, const uint8_t *mac_addr, xnet_packet_t * packet);
|
||||
const uint8_t * get_netif_mac(void);
|
||||
|
||||
extern const uint8_t my_ip_addr[];
|
||||
|
||||
#endif // XNET_TINY_H
|
||||
|
||||
Reference in New Issue
Block a user