⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip.c

📁 uccos2的的源码文件
💻 C
📖 第 1 页 / 共 2 页
字号:
//    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 + -