使用数据流和字节数组改进以太网驱动,以后禁止直接使用指针转换,那样带来极大隐患。

未完成,编译通过
This commit is contained in:
nnhy 2015-06-22 03:31:04 +00:00
parent cf38650a73
commit 9f262dc519
6 changed files with 30 additions and 52 deletions

View File

@ -111,8 +111,8 @@ bool ArpSocket::Process(Stream* ms)
bool RequestCallback(TinyIP* tip, void* param, Stream& ms) bool RequestCallback(TinyIP* tip, void* param, Stream& ms)
{ {
ETH_HEADER* eth = (ETH_HEADER*)tip->Buffer; ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
ARP_HEADER* arp = (ARP_HEADER*)eth->Next(); ARP_HEADER* arp = ms.Retrieve<ARP_HEADER>();
// 处理ARP // 处理ARP
if(eth->Type == ETH_ARP) if(eth->Type == ETH_ARP)

View File

@ -53,8 +53,8 @@ bool IcmpSocket::Process(Stream* ms)
bool PingCallback(TinyIP* tip, void* param, Stream& ms) bool PingCallback(TinyIP* tip, void* param, Stream& ms)
{ {
ETH_HEADER* eth = (ETH_HEADER*)tip->Buffer; ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
IP_HEADER* _ip = (IP_HEADER*)eth->Next(); IP_HEADER* _ip = ms.Retrieve<IP_HEADER>();
if(eth->Type == ETH_IP && _ip->Protocol == IP_ICMP) if(eth->Type == ETH_IP && _ip->Protocol == IP_ICMP)
{ {

View File

@ -329,7 +329,7 @@ void TcpSocket::SetMss(TCP_HEADER* tcp)
TCP_HEADER* TcpSocket::Create() TCP_HEADER* TcpSocket::Create()
{ {
return (TCP_HEADER*)(Tip->Buffer + sizeof(ETH_HEADER) + sizeof(IP_HEADER)); return (TCP_HEADER*)(Tip->Buffer.GetBuffer() + sizeof(ETH_HEADER) + sizeof(IP_HEADER));
} }
void TcpSocket::SendAck(uint len) void TcpSocket::SendAck(uint len)
@ -369,11 +369,11 @@ void TcpSocket::Send(const byte* buf, uint len)
TCP_HEADER* tcp = Create(); TCP_HEADER* tcp = Create();
tcp->Init(true); tcp->Init(true);
byte* end = Tip->Buffer + Tip->BufferSize; byte* end = Tip->Buffer.GetBuffer() + Tip->Buffer.Length();
if(buf < tcp->Next() || buf >= end) if(buf < tcp->Next() || buf >= end)
{ {
// 复制数据,确保数据不会溢出 // 复制数据,确保数据不会溢出
uint len2 = Tip->BufferSize - tcp->Offset() - tcp->Size(); uint len2 = Tip->Buffer.Length() - tcp->Offset() - tcp->Size();
assert_param(len <= len2); assert_param(len <= len2);
memcpy(tcp->Next(), buf, len); memcpy(tcp->Next(), buf, len);

View File

@ -3,9 +3,9 @@
#define NET_DEBUG DEBUG #define NET_DEBUG DEBUG
TinyIP::TinyIP() { Init(); } TinyIP::TinyIP() : Buffer(1500) { Init(); }
TinyIP::TinyIP(ITransport* port) TinyIP::TinyIP(ITransport* port) : Buffer(1500)
{ {
Init(); Init();
Init(port); Init(port);
@ -16,9 +16,6 @@ TinyIP::~TinyIP()
delete _port; delete _port;
_port = NULL; _port = NULL;
delete Buffer;
Buffer = NULL;
delete Arp; delete Arp;
Arp = NULL; Arp = NULL;
} }
@ -31,14 +28,9 @@ void TinyIP::Init()
Mask = 0x00FFFFFF; Mask = 0x00FFFFFF;
DHCPServer = Gateway = DNSServer = IP = 0; DHCPServer = Gateway = DNSServer = IP = 0;
Buffer = NULL;
BufferSize = 1500;
EnableBroadcast = true; EnableBroadcast = true;
//EnableArp = true;
Sockets.SetCapacity(0x10); Sockets.SetCapacity(0x10);
// 必须有Arp否则无法响应别人的IP询问
//Arp = new ArpSocket(this);
Arp = NULL; Arp = NULL;
} }
@ -67,18 +59,20 @@ void TinyIP::Init(ITransport* port)
} }
// 循环调度的任务 // 循环调度的任务
uint TinyIP::Fetch(byte* buf, uint len) uint TinyIP::Fetch(Stream& ms)
{ {
if(!buf) buf = Buffer;
if(!len) len = BufferSize;
// 获取缓冲区的包 // 获取缓冲区的包
len = _port->Read(buf, len); int len = _port->Read(ms.GetBuffer(), ms.Length);
// 如果缓冲器里面没有数据则转入下一次循环 // 如果缓冲器里面没有数据则转入下一次循环
if(len < sizeof(ETH_HEADER)/* || !_net->Unpack(len)*/) return 0; if(len < sizeof(ETH_HEADER)) return 0;
ETH_HEADER* eth = (ETH_HEADER*)buf; // 设置数据流实际长度
ms.Length = len;
// 获取第一个结构体,不要移动指针
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>(false);
ulong v = eth->DestMac.Value(); ulong v = eth->DestMac.Value();
// 广播地址有效,直接返回
if(!v || v == 0xFFFFFFFFFFFFFFFFull) return len; if(!v || v == 0xFFFFFFFFFFFFFFFFull) return len;
// 只处理发给本机MAC的数据包。此时进行目标Mac地址过滤可能是广播包 // 只处理发给本机MAC的数据包。此时进行目标Mac地址过滤可能是广播包
@ -103,7 +97,6 @@ void TinyIP::Process(Stream* ms)
// 处理ARP // 处理ARP
if(eth->Type == ETH_ARP) if(eth->Type == ETH_ARP)
{ {
//if(EnableArp && Arp) Arp->Process(ms);
if(Arp && Arp->Enable) Arp->Process(ms); if(Arp && Arp->Enable) Arp->Process(ms);
return; return;
@ -134,7 +127,6 @@ void TinyIP::Process(Stream* ms)
RemoteIP = ip->SrcIP; RemoteIP = ip->SrcIP;
// 移交给ARP处理为了让它更新ARP表 // 移交给ARP处理为了让它更新ARP表
//if(Arp && Arp->Enable) Arp->Process(NULL);
if(Arp) Arp->Process(NULL); if(Arp) Arp->Process(NULL);
FixPayloadLength(ip, ms); FixPayloadLength(ip, ms);
@ -185,12 +177,11 @@ void TinyIP::Work(void* param)
TinyIP* tip = (TinyIP*)param; TinyIP* tip = (TinyIP*)param;
if(tip) if(tip)
{ {
uint len = tip->Fetch(); // 注意此时指针位于0而内容长度为缓冲区长度
Stream ms(tip->Buffer);
uint len = tip->Fetch(ms);
if(len) if(len)
{ {
// 注意此时指针位于0而内容长度为缓冲区长度
Stream ms(tip->Buffer, tip->BufferSize);
ms.Length = len;
tip->Process(&ms); tip->Process(&ms);
} }
} }
@ -198,14 +189,16 @@ void TinyIP::Work(void* param)
bool TinyIP::LoopWait(LoopFilter filter, void* param, uint msTimeout) bool TinyIP::LoopWait(LoopFilter filter, void* param, uint msTimeout)
{ {
Stream ms(Buffer, BufferSize); // 分配一个同样大小的缓冲区
ByteArray bs(Buffer.Length());
Stream ms(bs);
// 总等待时间 // 总等待时间
TimeWheel tw(0, msTimeout, 0); TimeWheel tw(0, msTimeout, 0);
while(!tw.Expired()) while(!tw.Expired())
{ {
// 阻塞其它任务频繁调度OnWork等待目标数据 // 阻塞其它任务频繁调度OnWork等待目标数据
uint len = Fetch(); uint len = Fetch(ms);
if(!len) if(!len)
{ {
Sys.Sleep(2); // 等待一段时间释放CPU Sys.Sleep(2); // 等待一段时间释放CPU
@ -215,12 +208,10 @@ bool TinyIP::LoopWait(LoopFilter filter, void* param, uint msTimeout)
// 业务 // 业务
ms.SetPosition(0); ms.SetPosition(0);
ms.Length = len;
if(filter(this, param, ms)) return true; if(filter(this, param, ms)) return true;
// 用不到数据包交由系统处理 // 用不到数据包交由系统处理
ms.SetPosition(0); ms.SetPosition(0);
ms.Length = len;
Process(&ms); Process(&ms);
} }
@ -237,20 +228,10 @@ bool TinyIP::Open()
return false; return false;
} }
// 分配缓冲区。比较大,小心堆空间不够
if(!Buffer)
{
Buffer = new byte[BufferSize];
assert_param(Buffer);
assert_param(Sys.CheckMemory());
}
// 必须有Arp否则无法响应别人的IP询问 // 必须有Arp否则无法响应别人的IP询问
if(!Arp) Arp = new ArpSocket(this); if(!Arp) Arp = new ArpSocket(this);
Arp->Enable = true; Arp->Enable = true;
//if(!Open()) return false;
ShowInfo(); ShowInfo();
// 添加到系统任务,马上开始,尽可能多被调度 // 添加到系统任务,马上开始,尽可能多被调度
@ -268,8 +249,6 @@ bool TinyIP::Open()
void TinyIP::ShowInfo() void TinyIP::ShowInfo()
{ {
#if NET_DEBUG #if NET_DEBUG
String str;
debug_printf(" IP:\t"); debug_printf(" IP:\t");
IP.Show(); IP.Show();
debug_printf("\r\n Mask:\t"); debug_printf("\r\n Mask:\t");

View File

@ -44,12 +44,12 @@ private:
ulong _StartTime; ulong _StartTime;
// 循环调度的任务,捕获数据包,返回长度 // 循环调度的任务,捕获数据包,返回长度
uint Fetch(byte* buf = NULL, uint len = 0); uint Fetch(Stream& ms);
void Init(); void Init();
public: public:
byte* Buffer; // 缓冲区 ByteArray Buffer; // 缓冲区
// 任务函数 // 任务函数
static void Work(void* param); static void Work(void* param);
@ -74,7 +74,6 @@ public:
IPAddress RemoteIP; // 远程IP地址 IPAddress RemoteIP; // 远程IP地址
//ushort RemotePort; // 远程端口 //ushort RemotePort; // 远程端口
ushort BufferSize; // 缓冲区大小
IPAddress DHCPServer; IPAddress DHCPServer;
IPAddress DNSServer; IPAddress DNSServer;
IPAddress Gateway; IPAddress Gateway;

View File

@ -147,7 +147,7 @@ void UdpSocket::Send(UDP_HEADER* udp, uint len, bool checksum)
UDP_HEADER* UdpSocket::Create() UDP_HEADER* UdpSocket::Create()
{ {
return (UDP_HEADER*)(Tip->Buffer + sizeof(ETH_HEADER) + sizeof(IP_HEADER)); return (UDP_HEADER*)(Tip->Buffer.GetBuffer() + sizeof(ETH_HEADER) + sizeof(IP_HEADER));
} }
// 发送UDP数据到目标地址 // 发送UDP数据到目标地址
@ -161,11 +161,11 @@ void UdpSocket::Send(const byte* buf, uint len, IPAddress ip, ushort port)
UDP_HEADER* udp = Create(); UDP_HEADER* udp = Create();
udp->Init(true); udp->Init(true);
byte* end = Tip->Buffer + Tip->BufferSize; byte* end = Tip->Buffer.GetBuffer() + Tip->Buffer.Length();
if(buf < udp->Next() || buf >= end) if(buf < udp->Next() || buf >= end)
{ {
// 复制数据,确保数据不会溢出 // 复制数据,确保数据不会溢出
uint len2 = Tip->BufferSize - udp->Offset() - udp->Size(); uint len2 = Tip->Buffer.Length() - udp->Offset() - udp->Size();
assert_param(len <= len2); assert_param(len <= len2);
memcpy(udp->Next(), buf, len); memcpy(udp->Next(), buf, len);