parent
6364194c84
commit
cccf7bfe6f
|
@ -203,8 +203,8 @@ typedef struct _UDP_HEADER
|
|||
{
|
||||
ushort SrcPort; // 远端口号
|
||||
ushort DestPort; // 目的端口号
|
||||
ushort Length; // udp头部长度
|
||||
ushort Checksum; // 16位udp检验和
|
||||
ushort Length; // 头部加上负载的总长度
|
||||
ushort Checksum; // 检验和
|
||||
|
||||
void Init(bool recursion = false)
|
||||
{
|
||||
|
|
|
@ -122,7 +122,7 @@ bool IcmpSocket::Ping(IPAddress ip, uint payloadLength)
|
|||
icmp->Sequence = seq;
|
||||
|
||||
icmp->Checksum = 0;
|
||||
icmp->Checksum = __REV16((ushort)TinyIP::CheckSum((byte*)icmp, sizeof(ICMP_HEADER) + payloadLength, 0));
|
||||
icmp->Checksum = __REV16(Tip->CheckSum((byte*)icmp, sizeof(ICMP_HEADER) + payloadLength, 0));
|
||||
|
||||
#if NET_DEBUG
|
||||
debug_printf("Ping ");
|
||||
|
|
|
@ -127,16 +127,17 @@ bool TcpSocket::Process(MemoryStream* ms)
|
|||
|
||||
void TcpSocket::Send(TCP_HEADER* tcp, uint len, byte flags)
|
||||
{
|
||||
Tip->RemoteIP = RemoteIP;
|
||||
|
||||
tcp->SrcPort = __REV16(Port);
|
||||
tcp->DestPort = __REV16(RemotePort);
|
||||
tcp->Flags = flags;
|
||||
if(tcp->Length < sizeof(TCP_HEADER) / 4) tcp->Length = sizeof(TCP_HEADER) / 4;
|
||||
|
||||
// 必须在校验码之前设置,因为计算校验码需要地址
|
||||
Tip->RemoteIP = RemoteIP;
|
||||
|
||||
// 网络序是大端
|
||||
tcp->Checksum = 0;
|
||||
tcp->Checksum = __REV16((ushort)TinyIP::CheckSum((byte*)tcp - 8, 8 + sizeof(TCP_HEADER) + len, 2));
|
||||
tcp->Checksum = __REV16(Tip->CheckSum((byte*)tcp, tcp->Size() + len, 2));
|
||||
|
||||
debug_printf("SendTcp: Flags=0x%02x, len=%d(0x%x) %d => %d \r\n", flags, tcp->Length, tcp->Length, __REV16(tcp->SrcPort), __REV16(tcp->DestPort));
|
||||
|
||||
|
|
|
@ -306,9 +306,13 @@ void TinyIP::SendIP(IP_TYPE type, byte* buf, uint len)
|
|||
//ip->TTL = 64;
|
||||
ip->Protocol = type;
|
||||
|
||||
// 报文唯一标识。用于识别重组等
|
||||
static ushort g_Identifier = 1;
|
||||
ip->Identifier = __REV16(g_Identifier++);
|
||||
|
||||
// 网络序是大端
|
||||
ip->Checksum = 0;
|
||||
ip->Checksum = __REV16((ushort)TinyIP::CheckSum((byte*)ip, sizeof(IP_HEADER), 0));
|
||||
ip->Checksum = __REV16(CheckSum((byte*)ip, sizeof(IP_HEADER), 0));
|
||||
|
||||
assert_ptr(Arp);
|
||||
ArpSocket* arp = (ArpSocket*)Arp;
|
||||
|
@ -359,47 +363,52 @@ void TinyIP::ShowMac(const MacAddress& mac)
|
|||
debug_printf("-%02X", *m++);
|
||||
}
|
||||
|
||||
uint TinyIP::CheckSum(byte* buf, uint len, byte type)
|
||||
ushort TinyIP::CheckSum(byte* buf, uint len, byte type)
|
||||
{
|
||||
// type 0=ip
|
||||
// 1=udp
|
||||
// 2=tcp
|
||||
unsigned long sum = 0;
|
||||
uint sum = 0;
|
||||
|
||||
if(type == 1)
|
||||
{
|
||||
sum += IP_UDP; // protocol udp
|
||||
// the length here is the length of udp (data+header len)
|
||||
// =length given to this function - (IP.scr+IP.dst length)
|
||||
sum += len - 8; // = real tcp len
|
||||
}
|
||||
if(type == 2)
|
||||
{
|
||||
sum += IP_TCP;
|
||||
// the length here is the length of tcp (data+header len)
|
||||
// =length given to this function - (IP.scr+IP.dst length)
|
||||
sum += len - 8; // = real tcp len
|
||||
}
|
||||
// build the sum of 16bit words
|
||||
// !!谨记网络是大端
|
||||
if(type == 1 || type == 2)
|
||||
{
|
||||
// UDP/TCP的校验和需要计算UDP首部加数据荷载部分,但也需要加上UDP伪首部。
|
||||
// 这个伪首部指,源地址、目的地址、UDP数据长度、协议类型(0x11),协议类型就一个字节,但需要补一个字节的0x0,构成12个字节。
|
||||
// 源地址。其实可以按照4字节累加,反正后面会把高位移位到低位累加,但是得考虑溢出的问题。
|
||||
sum += __REV16(IP & 0xFFFF);
|
||||
sum += __REV16(IP >> 16);
|
||||
sum += __REV16(RemoteIP & 0xFFFF);
|
||||
sum += __REV16(RemoteIP >> 16);
|
||||
|
||||
// 数据长度
|
||||
sum += len;
|
||||
|
||||
// 加上协议类型
|
||||
if(type == 1)
|
||||
sum += IP_UDP;
|
||||
else if(type == 2)
|
||||
sum += IP_TCP;
|
||||
}
|
||||
// 按16位字计算和
|
||||
while(len > 1)
|
||||
{
|
||||
sum += 0xFFFF & (*buf << 8 | *(buf + 1));
|
||||
buf += 2;
|
||||
len -= 2;
|
||||
}
|
||||
// if there is a byte left then add it (padded with zero)
|
||||
// 如果字节个数不是偶数个,这里会剩余1,后面补0
|
||||
if (len)
|
||||
{
|
||||
sum += (0xFF & *buf) << 8;
|
||||
}
|
||||
// now calculate the sum over the bytes in the sum
|
||||
// until the result is only 16bit long
|
||||
while (sum>>16)
|
||||
// 现在计算sum字节的和,直到只有16位长
|
||||
while (sum >> 16)
|
||||
{
|
||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||
}
|
||||
// build 1's complement:
|
||||
return( (uint) sum ^ 0xFFFF);
|
||||
// 取补码
|
||||
return (ushort)(sum ^ 0xFFFF);
|
||||
}
|
||||
|
||||
bool TinyIP::IsMyIP(IPAddress ip)
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
void ShowInfo();
|
||||
static void ShowIP(IPAddress ip);
|
||||
static void ShowMac(const MacAddress& mac);
|
||||
static uint CheckSum(byte* buf, uint len, byte type);
|
||||
ushort CheckSum(byte* buf, uint len, byte type);
|
||||
|
||||
void SendEthernet(ETH_TYPE type, byte* buf, uint len);
|
||||
void SendIP(IP_TYPE type, byte* buf, uint len);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "Udp.h"
|
||||
|
||||
#define NET_DEBUG DEBUG
|
||||
|
||||
UdpSocket::UdpSocket(TinyIP* tip) : Socket(tip)
|
||||
{
|
||||
Type = IP_UDP;
|
||||
|
@ -74,6 +76,13 @@ void UdpSocket::OnProcess(UDP_HEADER* udp, MemoryStream& ms)
|
|||
uint len = __REV16(udp->Length) - sizeof(UDP_HEADER);
|
||||
assert_param(len <= ms.Remain());
|
||||
|
||||
#if NET_DEBUG
|
||||
ushort oldsum = __REV16(udp->Checksum);
|
||||
udp->Checksum = 0;
|
||||
udp->Checksum = __REV16(Tip->CheckSum((byte*)udp, sizeof(UDP_HEADER) + len, 1));
|
||||
debug_printf("UDP::Checksum ori=0x%02x new=0x%02x\r\n", oldsum, __REV16(udp->Checksum));
|
||||
#endif
|
||||
|
||||
// 触发ITransport接口事件
|
||||
uint len2 = OnReceive(data, len);
|
||||
// 如果有返回,说明有数据要回复出去
|
||||
|
@ -111,11 +120,12 @@ void UdpSocket::Send(UDP_HEADER* udp, uint len, bool checksum)
|
|||
udp->DestPort = __REV16(RemotePort);
|
||||
udp->Length = __REV16(sizeof(UDP_HEADER) + len);
|
||||
|
||||
// 必须在校验码之前设置,因为计算校验码需要地址
|
||||
Tip->RemoteIP = RemoteIP;
|
||||
|
||||
// 网络序是大端
|
||||
udp->Checksum = 0;
|
||||
if(checksum) udp->Checksum = __REV16((ushort)TinyIP::CheckSum((byte*)udp, sizeof(UDP_HEADER) + len, 1));
|
||||
|
||||
Tip->RemoteIP = RemoteIP;
|
||||
if(checksum) udp->Checksum = __REV16(Tip->CheckSum((byte*)udp, sizeof(UDP_HEADER) + len, 1));
|
||||
|
||||
debug_printf("SendUdp: len=%d(0x%x) %d => %d \r\n", udp->Length, udp->Length, __REV16(udp->SrcPort), __REV16(udp->DestPort));
|
||||
|
||||
|
@ -148,7 +158,7 @@ void UdpSocket::Send(const byte* buf, uint len, IPAddress ip, ushort port)
|
|||
memcpy(udp->Next(), buf, len);
|
||||
}
|
||||
|
||||
Send(udp, len, false);
|
||||
Send(udp, len, true);
|
||||
}
|
||||
|
||||
bool UdpSocket::OnWrite(const byte* buf, uint len)
|
||||
|
|
Loading…
Reference in New Issue