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

未完成,编译通过
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)
{
ETH_HEADER* eth = (ETH_HEADER*)tip->Buffer;
ARP_HEADER* arp = (ARP_HEADER*)eth->Next();
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
ARP_HEADER* arp = ms.Retrieve<ARP_HEADER>();
// 处理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)
{
ETH_HEADER* eth = (ETH_HEADER*)tip->Buffer;
IP_HEADER* _ip = (IP_HEADER*)eth->Next();
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
IP_HEADER* _ip = ms.Retrieve<IP_HEADER>();
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()
{
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)
@ -369,11 +369,11 @@ void TcpSocket::Send(const byte* buf, uint len)
TCP_HEADER* tcp = Create();
tcp->Init(true);
byte* end = Tip->Buffer + Tip->BufferSize;
byte* end = Tip->Buffer.GetBuffer() + Tip->Buffer.Length();
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);
memcpy(tcp->Next(), buf, len);

View File

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

View File

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

View File

@ -147,7 +147,7 @@ void UdpSocket::Send(UDP_HEADER* udp, uint len, bool checksum)
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数据到目标地址
@ -161,11 +161,11 @@ void UdpSocket::Send(const byte* buf, uint len, IPAddress ip, ushort port)
UDP_HEADER* udp = Create();
udp->Init(true);
byte* end = Tip->Buffer + Tip->BufferSize;
byte* end = Tip->Buffer.GetBuffer() + Tip->Buffer.Length();
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);
memcpy(udp->Next(), buf, len);