📄 tftp.c
字号:
/******************************************************************************
* Filename : tftp.c *
* Program : loader. *
* Copyright : Copyright (C) 2001, Young-Su, Ahn. *
* Author : Young-Su, Ahn <nurie@dreamwiz.com> *
* Description : Use Tftp. *
* Make tftp packet and transmit it. *
* Handling received Tftp packet. *
* Created at : Wed Mar 13 2001. *
* Based on : pptboot-0.5.3, CS8900A device driver. *
* Modified by : *
* Modified at : *
******************************************************************************/
/* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "main.h"
#define TFTP_PORT 69 // Well known TFTP port #
#define TFTP_TIMEOUT 5 // Seconds to tftpTimeout for a lost pkt
#define TIMEOUT_COUNT 10 // # of tftpTimeouts before giving up
// TFTP operations.
#define TFTP_RRQ 1
#define TFTP_WRQ 2
#define TFTP_DATA 3
#define TFTP_ACK 4
#define TFTP_ERROR 5
#define TFTP_NONE 0
#define TFTP_STATE_RRQ 1
#define TFTP_STATE_DATA 2
#define TFTP_STATE_TOO_LARGE 3
#define TFTP_STATE_BAD_MAGIC 4
#define TFTP_STATE_SUCCESS 5
#define TFTP_STATE_FAILURE 6
static short tftpState = 0;
static short tftpBlock = 0;
static short tftpLastBlock = 0;
static U32 loadAddr = 0;
short tftpPort = 69;
short tftpHostPort=0;
short tftpClientPort = 7777;
static char requestFile[128];
static U32 tftpTimeout;
// Prototypes.
//bool TftpStart(char *filename);
bool TftpStart(int itype);
void TftpTx(char *txBuf);
/**********************************************************************/
// 开且 : tftp [filename] [addr]狼 牢磊甫 tftp甫 角青窍扁 困茄 窃荐客
// 楷搬.
// 概俺 :
// 馆券 : 己傍窍搁 true, 角菩窍搁 false.
// 林狼 :
bool DoTftp(int itype)
{
// tftp肺 罐篮 file data甫 扁废且 林家甫 积己.
if (itype==0)
{
loadAddr = (U32)KERNEL_DRAM_BASE;
}
else if(itype==1)
{
loadAddr = (U32)RAMDISK_DRAM_BASE;
}
else
{
loadAddr = (U32)LOADER_DRAM_DOWN_BASE;
}
// IP啊 绝栏搁 bootp甫 角青窍咯 IP甫 且寸 罐澜.
if (clientIP==0){
Serial_Printf("\tNo IP. Bootp start...\n\r");
if (DoBootp()==false)
{
Serial_Printf("\tBootp failed. try again.\n\r");
return false;
}
}
return TftpStart(itype);
} // DoTftp.
// 开且 : tftp甫 角青且 券版 免仿.
// 概俺 :
// 馆券 : 己傍窍搁 true, 角菩窍搁 false.
// 林狼 :
//bool TftpStart(char *filename)
bool TftpStart(int itype)
{
char *txPktBuf, *rxPktBuf;
char *kfd="zImage";
char *rfd="ramdisk.gz";
char *bfd="kloader.bin";
txPktBuf = (char *)PktBuf;
rxPktBuf = (char *)PktBuf;
Serial_Printf("\ni-type = %d\n",itype);
// tftp 角青 券版 免仿.
Serial_Printf("TFTP Start...\n\r");
Serial_Printf("\tHost (server) IP : ");
PrintIPAddr(hostIP);
Serial_Printf("\n\r");
Serial_Printf("\tClient (target) IP : ");
PrintIPAddr(clientIP);
Serial_Printf("\n\r");
if(itype == 0) StrCpy(requestFile, kfd);
else if(itype == 1) StrCpy(requestFile, rfd);
else StrCpy(requestFile, bfd);
Serial_Printf("\tLoading Filename : %s",requestFile);
Serial_Printf("\n\r");
Serial_Printf("\tSave Address : 0x%x",loadAddr);
Serial_Printf("\n\r");
Serial_Printf("\n\r\rLoading start...\n\r");
// tftp 矫累 券版.
protocol = PROT_TFTP;
tftpState = TFTP_STATE_RRQ;
tftpHostPort = 0;
// tftp request packet 傈价.
TftpTx(txPktBuf);
// tftpTimeout篮 捞镑俊辑 沥窍哥, tftp data packet阑 罐阑 锭付促 盎脚等促.
// 矫埃捞 檬苞窍搁 tftp绰 角菩肺 埃林窍绊 吝窜茄促.
tftpTimeout = GetTime() + TFTP_TIMEOUT * HZ;
// tftp啊 己傍窍芭唱 角菩且 锭鳖瘤 tftp data pakcet阑 荐脚.
while (tftpState!=TFTP_STATE_SUCCESS && tftpState!=TFTP_STATE_FAILURE){
RxPacket(rxPktBuf);
// 矫埃 檬苞搁 角菩窍绊 吝窜.
if (GetTime()>tftpTimeout){
Serial_Printf("\n\r\tTftp is failed. Try again.\n\r\n\r");
tftpState=TFTP_STATE_FAILURE;
}
}
// 促澜 tftp 角青阑 困秦 券版阑 登倒覆.
protocol = NOPROTOCOL;
tftpState = TFTP_NONE;
tftpBlock = 0;
tftpHostPort = 0;
return true;
} // TftpStart.
// 开且 : tftp啊 鞘夸肺 窍绰 packet阑 父甸绢 傈价..
// 概俺 :
// 馆券 : 己傍窍搁 true, 角菩窍搁 false.
// 林狼 :
void TftpTx(char *txPktBuf)
{
char *pktPtr = (char *)(txPktBuf+ETHER_HDR_SIZE+IP_HDR_SIZE+UDP_HDR_SIZE);
U16 hostPort = 0;
int len = 0;
// Serial_Printf(" <TFTP Send -- %d> ",tftpState);
// MemSet(txPktBuf, 0, MAX_PKT_SIZE);
MemSet(txPktBuf-(ETHER_HDR_SIZE+IP_HDR_SIZE+UDP_HDR_SIZE), 0, MAX_PKT_SIZE);
// make tftp header.
switch (tftpState){
// tftp request packet阑 父惦.
case TFTP_STATE_RRQ:
*((U16 *)pktPtr)++ = SWAP16(TFTP_RRQ);
StrCpy((char *)pktPtr, requestFile);
pktPtr += StrLen(requestFile) + 1;
StrCpy((char *)pktPtr, "octet");
pktPtr += 5 + 1;
len = pktPtr - txPktBuf;
hostPort = tftpPort;
break;
// 荐脚茄 data packet俊 措茄 acknowledge packet阑 父惦.
case TFTP_STATE_DATA:
*((U16 *)pktPtr)++ = SWAP16(TFTP_ACK);
*((U16 *)pktPtr)++ = SWAP16(tftpBlock);
len = pktPtr - txPktBuf;
hostPort = tftpHostPort;
break;
// error packet阑 父惦.
case TFTP_STATE_TOO_LARGE:
*((U16 *)pktPtr)++ = SWAP16(TFTP_ERROR);
*((U16 *)pktPtr)++ = SWAP16(3);
StrCpy((char *)pktPtr, "File too large");
pktPtr += 14 + 1;
len = pktPtr - txPktBuf;
hostPort = tftpHostPort;
break;
// error packet阑 父惦.
case TFTP_STATE_BAD_MAGIC:
*((U16 *)pktPtr)++ = SWAP16(TFTP_ERROR);
*((U16 *)pktPtr)++ = SWAP16(2);
StrCpy((char *)pktPtr, "File has bad magic");
pktPtr += 18 + 1;
len = pktPtr - txPktBuf;
hostPort = tftpHostPort;
break;
default :
return;
}
// Ethernet, IP, UDP Header甫 父惦.
SetUdpHeader((char *)(txPktBuf+ETHER_HDR_SIZE+IP_HDR_SIZE), hostPort, tftpClientPort, len);
SetIPHeader((char *)(txPktBuf+ETHER_HDR_SIZE), clientIP, hostIP, UDP_HDR_SIZE+len);
SetEtherHeader(txPktBuf, (char *)hostEther, PROT_IP);
// tftp packet 傈价.
TxPacket(txPktBuf, ETHER_HDR_SIZE+IP_HDR_SIZE+UDP_HDR_SIZE+len);
return;
} // TftpTx.
// 开且 : tftp packet阑 罐酒 贸府.
// 概俺 :
// 馆券 : 己傍窍搁 true, 角菩窍搁 false.
// 林狼 :
bool TftpRx(char *rxPktBuf, int len){
char *pktPtr = rxPktBuf;
short value;
U32 rlen=0; // tftp肺 傈价罐篮 data狼 辨捞(烙矫 buffer).
// handling received data.
value = SWAP16(*(short *)pktPtr); // packet type.
// Serial_Printf(" <TFTP Recv - %d> ",value);
pktPtr+=2;
len-=2;
switch (value){
case TFTP_RRQ :
case TFTP_WRQ :
case TFTP_ACK :
default:
break;
// tftp data packet.
case TFTP_DATA :
// error. check data index.
if (len < 2)
{
Serial_Printf("\nLength err ");
return false;
}
//Serial_Printf("\nBlockNo - 0x%x",*(U16 *)pktPtr);
tftpBlock = SWAP16(*(U16 *)pktPtr); // tftp data packet俊辑 block 锅龋.
pktPtr += 2;
len -= 2;
// tftp receive 柳青 钎矫.
if (((tftpBlock)%128)==0){ // each 64 kbyte.
//ClearLine();
rlen = (long)tftpBlock * 512;
Serial_Printf("\n0x%08lx bytes received.", rlen);
}
// request俊 措茄 霉锅掳 data packet老锭 鞘夸茄 沥焊 汲沥.
if (tftpState == TFTP_STATE_RRQ)
{
tftpState = TFTP_STATE_DATA;
tftpLastBlock = 0;
if (tftpBlock != 1){
tftpState = TFTP_STATE_FAILURE;
return false;
}
}
// 捞傈狼 packet阑 促矫 罐疽阑 锭绰 公矫.
// Serial_Printf(" <Recv Block - %d> ", tftpBlock);
if (tftpBlock <= tftpLastBlock) break;
tftpLastBlock = tftpBlock;
// 荐脚茄 tftp packet狼 data 何盒阑 瘤沥茄 memory 康开俊 扁废. block篮 512 byte 窜困.
MemCpy((char *)(loadAddr+(tftpBlock-1)*512), (char *)pktPtr, len);
// TftpStart()俊辑 check窍绰 tftpTimeout 矫埃阑 盎脚.
tftpTimeout = GetTime() + TFTP_TIMEOUT * HZ;
// Acknowledge甫 焊晨. 捞巴阑 罐篮 饶 server绰 促澜 block狼 data甫 啊柳 packet阑 傈价.
TftpTx(rxPktBuf);
// 荐脚茄 tftp packet捞 data狼 付瘤阜 block老 锭.
if (len < 512){
// We received the whole thing. Try to run it.
//ClearLine();
rlen = ((long)tftpBlock-1) * 512 + len;
Serial_Printf("\n0x%08lx (%ld) bytes received.", rlen, rlen);
Serial_Printf("\nftp done.\n\n");
tftpState = TFTP_STATE_SUCCESS;
}
break;
// error 贸府.
case TFTP_ERROR :
// tftp RRQ or tftp ack pakcet has some error.
Serial_Printf("\n\r\rTFTP error: '");
Serial_Printf(pktPtr+2);
Serial_Printf("' (");
OutputDec(SWAP16(*(U16 *)pktPtr));
Serial_Printf(")\n\r");
tftpState = TFTP_STATE_FAILURE;
break;
}
return true;
} // TftpRx.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -