tftp

 int tftp_download(char *filename, ulong msec_max, int cnt_max, ulong addr)

{

  ...

  TftpRRQTimeoutMSecs = msec_max;   //100

  TftpRRQTimeoutCountMax = cnt_max;  //0

  setenv("netretry", "no");

  load_addr = addr;             //下载到内存的地址

  copy_filename(BootFile, filename, sizeof(BootFile));

  size = NetLoop(TFTP);

  if(size < 0)

    return ERROR;

  else

    flush_cache(addr,size);

 

  ...

}

int NetLoop(proto_t protocol)

{

  ...

  switch (protocol)
  {

    case TFTP:
      TftpStart();
      break;

    case DHCP:
      BootpTry = 0;
      NetOurIP = 0;
      DhcpRequest(); 
      break;
    case BOOTP:

      BootpTry = 0;
      NetOurIP = 0;
      BootpRequest ();
      break;

    case RARP:
      RarpTry = 0;
      NetOurIP = 0;
      RarpRequest ();
      break;
    case PING:
      PingStart();
      break;
    case NFS:
      NfsStart();
      break;
    case CDP:
      CDPStart();
      break;
    case NETCONS:
      NcStart();
      break;
    case SNTP:
      SntpStart();
      break;
    case DNS:
      DnsStart();
      break;

  }

  ...

}

void TftpStart (void)

{

  ...

  //设置参数

  NetSetTimeout (TftpTimeoutMSecs * CFG_HZ, TftpTimeout);
  NetSetHandler (TftpHandler);

  ...

  //发送

  TftpSend ();

  ...

}

static void TftpSend (void)

{

  ...

  //容错

  //开始组包

  pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;

  //针对各种状态组包

  switch (TftpState) 

  {

    case STATE_RRQ:

      xp = pkt;

      s = (ushort *)pkt;
      if(TftpState == STATE_WRQ)
        *s++ = htons(TFTP_WRQ);
      else

        *s++ = htons(TFTP_RRQ);
      pkt = (uchar *)s;
      strcpy ((char *)pkt, tftp_filename);
      pkt += strlen(tftp_filename) + 1;
      strcpy ((char *)pkt, "octet");
      pkt += 5 /*strlen("octet")*/ + 1;
      strcpy ((char *)pkt, "timeout");
      pkt += 7 /*strlen("timeout")*/ + 1;
      sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000);
      pkt += strlen((char *)pkt) + 1;
      memcpy((char *)pkt, "tsize\0000\0", 8);
      pkt += 8;
      if(TftpState == STATE_WRQ)
        pkt += sprintf((char *)pkt,"blksize%c%d%c", 0,TftpBlkSizeOption,0);
      else
        pkt += sprintf((char *)pkt,"blksize%c%d%c", 0,TftpBlkSizeOption,0);
      if (!ProhibitMcast && (Bitmap=malloc(Mapsize)) && eth_get_dev()->mcast)
      {
        free(Bitmap);
        Bitmap=NULL;
        pkt += sprintf((char *)pkt,"multicast%c%c",0,0);
      }
      len = pkt - xp;
      break;

    case STATE_WRQ:

      ...

    case STATE_OACK:

      ...

    case STATE_DATA:

      ...

    case STATE_TOO_LARGE:

      ...

    case STATE_BAD_MAGIC:

      ...

    case STATE_ACK:

      ...

  }

  //发送

  NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, TftpOurPort, len);

}

int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)

{

  //容错:目标IP 

  //容错:ether 发ARP

  if (memcmp(ether, NetEtherNullAddr, 6) == 0) 

  {

    NetArpWaitPacketIP = dest;
    NetArpWaitPacketMAC = ether;

    pkt = NetArpWaitTxPacket;
    pkt += NetSetEther (pkt, NetArpWaitPacketMAC, PROT_IP);

    NetSetIP (pkt, dest, dport, sport, len);
    memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len);

    NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len;

    NetArpWaitTry = 1;
    NetArpWaitTimerStart = get_timer(0);
    ArpRequest();
    return 1; 

  }

  //容错:time 发ARP

  if (times == 10000)
  {
    times = 0;

    NetArpWaitPacketIP = dest;

    NetArpWaitPacketMAC = ether;

    pkt = NetArpWaitTxPacket;
    pkt += NetSetEther(pkt, NetArpWaitPacketMAC, PROT_IP);

    NetSetIP(pkt, dest, dport, sport, len);
    memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len);

    NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len;

    NetArpWaitTry = 1;
    NetArpWaitTimerStart = get_timer(0);
    ArpRequest();
  }

  //组包发送

  times++;

  pkt = (uchar *)NetTxPacket;

  pkt += NetSetEther (pkt, ether, PROT_IP);
  NetSetIP (pkt, dest, dport, sport, len);
  (void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len);

  ...

}

至此,(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len);开始转向各个网卡驱动的发送函数。

 

posted @   扑克face  阅读(747)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示