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);開始轉向各個網卡驅動的發送函數。
?
評論
查看更多