📄 ip.c
字号:
// else if(ip->DestIp == PPP_HOST_IP)
// {// 使用PPP连接端口
// SetPppIp();
// }
else
{// 拒绝广播包或非本机IP包
return;
}
//读取远端的IP地址
remoteIP.Ip.l = ip->SrcIp;
AddArpTbl(remoteIP.Ip.l,remoteIP.Mac);
//读取当前IP包的数据长度
switch (ip->Protocol)
{
case 0x01: //ICMP,用于完成PING命令
DEBUGSTRING("icmp");
IcmpFun((STR_ICMP *)ip->Buffer,ip->Len-headLen);
break;
case 0x11: //UDP数据包
DEBUGSTRING("UDP");
UdpFun((STR_UDP *)ip->Buffer);
break;
default:
DEBUGSTRING("ip default");
break;
}
}
void UdpChangeEndian(STR_UDP *udp)
{
#ifdef LITTLE_ENDIAN
udp->Len = ENDIAN16(udp->Len);
udp->SrcPort = ENDIAN16(udp->SrcPort);
udp->DestPort = ENDIAN16(udp->DestPort);
#endif
}
/*
函数 UDP数据包处理程序
函数首先检查UDP数据包的合法性,然后再处理
*/
void UdpFun(STR_UDP *udp)
{
STR_UDPHEAD *UdpHead;
U16 UdpLen;
DEBUGSTRING("udpFun");
UdpLen = ENDIAN16(udp->Len);
//读取远端的IP、端口
//设置本机的接收到的数据报端口号
//填充UDP包的伪首部,因为UDP的校验和需要计算伪首部在内
UdpHead = (STR_UDPHEAD *)udp;
UdpHead--;
UdpHead->SrcIp= remoteIP.Ip.l;
UdpHead->DestIp= myIP.Ip.l;
UdpHead->Res= 0;
UdpHead->Protocol= 0x11;
UdpHead->Len = udp->Len;
//检查UDP包数据的校验和
if (GenCheckSum((U8 *)UdpHead,UdpLen+12) != 0)
{
DEBUGSTRING("udp checksum error");
#ifdef DEBUGMODE
printf("\r\nchecksum:0x%x\n\r",GenCheckSum((U8 *)UdpHead,UdpLen+12));
#endif
return;
}
UdpChangeEndian(udp);
remoteIP.Port = udp->SrcPort;
myIP.Port = udp->DestPort;
#ifdef DEBUGMODE
printf("\r\nremoteIP:%08x,RemotePort:%x,myPort:%x",remoteIP.Ip.l,remoteIP.Port,myIP.Port);
#endif
//UDP检查正确,等待处理
if (udp->DestPort == 5100)
{
}
else if (udp->DestPort == 53)
{
StatusMessage("DNS Protocol");
}
else if (udp->DestPort == 6101)
{
WantNext = 1;
}
}
/*
函数 IP包发送函数
*/
int IpSend(U8 *ipbuffer,U8 Protocol,U16 length)
{
STR_IP *ip;
CheckLocalNetWork();
ipbuffer -= headLen;
ip = (STR_IP *)ipbuffer;
memset(ip,0,headLen);
ip->VerLen = 0x45;
ip->Len = length+headLen;
ip->Life = 0x80;
ip->Protocol = Protocol;
ip->SrcIp = myIP.Ip.l;
ip->DestIp = remoteIP.Ip.l;
IpChangeEndian(ip);
//计算并填充IP数据包的校验和
ip->CheckSum = 0;
ip->CheckSum = GenCheckSum((U8 *)ip,headLen);
//填充NIC的头部
return SendTxFrame(P_IP,(void*)ip,length+headLen);
}
/*
函数 发送UDP数据包
输入 length 数据的长度
udp udp数据缓冲区
*/
int UdpSend(STR_UDP *udp,U16 length)
{
STR_UDPHEAD *UdpHead;
CheckLocalNetWork();
//填充UDP包的首部
udp->SrcPort = myIP.Port;
udp->DestPort = remoteIP.Port;
udp->Len = length+8;
udp->CheckSum = 0;
UdpChangeEndian(udp);
//填充UDP包的伪首部
UdpHead = (STR_UDPHEAD *)udp;
UdpHead--;
UdpHead->SrcIp= remoteIP.Ip.l;
UdpHead->DestIp= myIP.Ip.l;
UdpHead->Res= 0;
UdpHead->Protocol= 0x11;
UdpHead->Len = udp->Len;
//计算并填充UDP数据包的校验和,UDP的校验和包含伪首部的部分
udp->CheckSum = 0;
udp->CheckSum = GenCheckSum((U8 *)UdpHead,length+8+12);
//填充IP包的首部,含包类型
return IpSend((U8 *)udp,0x11,length+8);
}
void IcmpResponsed(STR_ICMP *icmp)
{
String str[32];
sprintf((char*)buf,"Reply From %s %u at Time %d ms\r\n",PrintIp(str,(char*)&remoteIP.Ip),invert16(icmp->Sequence),RunTimeMs);
AppendText((char*)buf);
//printf((char*)buf);
}
/*
函数 ICMP响应函数
这里ICMP只完成它的一个子集,主要用于完成PING的命令操作
*/
void IcmpFun(STR_ICMP *icmp,U16 icmplen)
{
switch(icmp->Type)
{
case 0x00: //ICMP回送回答
IcmpResponsed(icmp);
break;
case 0x08: //ICMP回送请求
//填充ICMP回送回答的数据包
icmp->Type = 0;
//填充ICMP的校验和
icmp->CheckSum = 0;
icmp->CheckSum = GenCheckSum((U8 *)icmp,icmplen);
//发送IP包
IpSend((U8 *)icmp,0x01,icmplen);
{
char str[32];
sprintf((char*)buf,"Pinged by %s at Time: %d ms\r\n",PrintIp((String*)str,(char*)&remoteIP.Ip),RunTimeMs);
AppendText((char*)buf);
}
case 0x13: //时间戳请求
break;
case 0x14: //时间戳回答
break;
default:
break;
}
}
//函数 发送通讯数据包
// 通讯数据包根据前一个包的数据来源,发送到对应的端口
//输入 length 发送数据包的长度
//输出 无
//返回 无
int SendTxFrame(U16 ProtocolType,void *buffer,U16 length)
{
return NicSendTxFrame(ProtocolType,buffer,length);
}
Menu gstr_NetMenu[] =
{
{"网络信息",0,test_net},
{"Ping主机",3,test_net},
{"本机IP",1,test_net},
{"主机IP",2,test_net},
{"Exit",0xff,0},
{0,0,0}
};
unsigned int gi_HostIp = IP_ADDR(192,168,1,175);
void ShowNetConfig(void)
{
int i,j,k = 0;
char str[32];
ClearText();
j += sprintf((char*)buf+j,"IP地址:%s\r\n",PrintIp((String*)str,(char*)myIP.Ip.b));
j += sprintf((char*)buf+j,"MAC地址:%s\r\n",PrintMac((String*)str,(char*)myIP.Mac));
for( i = 0,k = 0; k < MAX_ARP_COUNT ; k++)
{
if( gstr_arptbl[k].ip != 0)
{
i++;
j += sprintf((char*)buf+j,"ARP %d ip:%s",i,
PrintIp((String*)str,(char*)&gstr_arptbl[k].ip));
j += sprintf((char*)buf+j," mac:%s\r\n",
PrintMac((String*)str,gstr_arptbl[k].mac));
}
}
j += sprintf((char*)buf+j,"主机IP:%s\r\n",PrintIp((String*)str,(char*)&gi_HostIp));
AppendText((char*)buf);
}
unsigned int LookupMacTimeout = 0;
void LookupHost(void)
{
if( FindArp(gi_HostIp,0) == 0 && LookupMacTimeout < RunTimeMs )
{
LookupMacTimeout = RunTimeMs + 500;
LookupMac(gi_HostIp>>24);
}
}
int test_net_idle(int v)
{
ScrollShow(v);
PollintNet();
LookupHost();
}
void PingIt(unsigned int ip)
{
STR_ICMP* icmp = (STR_ICMP*)buf+64;
int icmplen;
for( icmplen = 0; icmplen < 32; icmplen++)
icmp->Buffer[icmplen] = 'a'+icmplen;
icmplen = 8 + 26;
icmp->Type = 0x08;
icmp->Code = 0;
icmp->Identifier++;
icmp->Sequence++;
//填充ICMP的校验和
icmp->CheckSum = 0;
icmp->CheckSum = GenCheckSum((U8 *)icmp,icmplen);
//发送IP包
remoteIP.Ip.l = ip;
memset(remoteIP.Mac,0,6);
IpSend((U8 *)icmp,0x01,icmplen);
{
String str[32];
sprintf((char*)buf,"Pinging %s %u at Time %d ms\r\n",PrintIp(str,(char*)&remoteIP.Ip),invert16(icmp->Sequence),RunTimeMs);
AppendText((char*)buf);
}
}
int test_net(int v)
{
switch(v)
{
case 0:
ShowNetConfig();
break;
case 1:
InputStr("本机IP",(char*)PrintIp(buf, (char *)&localIP));
if( gi_InputLen > 0 )
{
unsigned char b0,b1,b2,b3;
sscanf(gstr_Input,"%d.%d.%d.%d",&b0,&b1,&b2,&b3);
localIP = IP_ADDR(b0,b1,b2,b3);
SetLocalIp();
ClearInput();
}
break;
case 2:
InputStr("主机IP",(char*)PrintIp(buf, (char *)&gi_HostIp));
if( gi_InputLen > 0 )
{
unsigned char b0,b1,b2,b3;
sscanf(gstr_Input,"%d.%d.%d.%d",&b0,&b1,&b2,&b3);
gi_HostIp = IP_ADDR(b0,b1,b2,b3);
ClearInput();
}
break;
case 3:
PingIt(gi_HostIp);
break;
}
SetMenuReShow(0);
return MENU_RETAIN;
}
void SendImage(int v)
{
extern char buffer[1024*2];
int len = sizeof(LCD_BUFER);
char* ptr = (char*)LCD_BUFER;
unsigned int timeout,StartTimeMs=RunTimeMs;
int ch,k=0;
if(v)
{
while(len--)
{
k++;
if( (k%(18*800*2)) == 0 )
{
sprintf(buffer,"串口:已上传%d字节屏幕...",k);
StatusMessage2(buffer);
}
UART_SendByte(*ptr++);
}
}
else
{
STR_UDP * udp = (STR_UDP *)buffer+64;
timeout = RunTimeMs + 3000;
while( FindArp(gi_HostIp,0) == 0 )
{
if( RunTimeMs > timeout )
return;
LookupHost();
PollintNet();
}
while( len > 0 )
{
k += 800;
if( (k%(18*800*2)) == 0 )
{
sprintf(buffer,"UDP:已上传%d字节屏幕...",k);
StatusMessage2(buffer);
}
ch = ((len >= 800 ) ? 800 : len);
remoteIP.Ip.l = gi_HostIp;
remoteIP.Port = 6100;
myIP.Port = 6101;
memcpy(udp->Buffer,ptr,ch);
timeout = 0;
v = 0;
do
{
if( timeout < RunTimeMs)
{
if( UdpSend(udp,ch) )
break;
timeout = RunTimeMs+2;
if( v++ > 1000 )
return;
}
}while(1);
len -= ch;
ptr += ch;
WantNext = 0;
timeout = RunTimeMs + 2000;
while( WantNext == 0 && RunTimeMs < timeout)
{
PollintNet();
}
}
}
sprintf(buffer,"屏幕上传完毕,用时%dms!",RunTimeMs-StartTimeMs);
StatusMessage2(buffer);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -