tftp.c

来自「ADS下的bios工程」· C语言 代码 · 共 192 行

C
192
字号
#include <bios/netdev.h>#include <bios/boot.h>#include <bios/string.h>#include <bios/time.h>#include <bios/stdio.h>#include <bios/config.h>   #undef DEBUG_S3C4_TFTP#ifdef DEBUG_S3C4_TFTP	#define DEBUG_TFTP(fmt, args...)   printf("%s-%s()[%d]: " fmt, __FILE__, __FUNCTION__, __LINE__, args)#else	#define DEBUG_TFTP(fmt, args...)#endif/* extern functions */extern int udp_send(struct netdev *nd, struct sin *from, struct sin *to, struct buflist *data);extern int udp_recv(struct netdev *nd, struct sin *from, struct sin *to,void *buffer, int size);extern u32               bios_recv_bytes;/* global variables */static struct sin	 tftp_me, tftp_serv;/* function proto types */int do_tftp(struct netdev *dev);static int tftp_send_rrq(struct netdev *dev){	static struct tftp_rrq rrq;	static struct buflist bl;	tftp_me.sin_addr = dev->ip_addr;	tftp_me.sin_port = htons(0x8000);	tftp_serv.sin_addr = dev->serv_ip_addr;	tftp_serv.sin_port = htons(0x45);	memzero(&rrq, sizeof(rrq));	rrq.cmd = htons(TFTP_RRQ);	sprintf(rrq.filename, "%s%c%s", dev->boot_file, 0, "octet");	bl.data = &rrq;	bl.size = 102;	bl.next = NULL;	return udp_send(dev, &tftp_me, &tftp_serv, &bl);}static int tftp_send_ack(struct netdev *dev, int *block){	static struct tftp_ack ack;	static struct buflist bl;	ack.cmd   = htons(TFTP_ACK);	ack.block = htons(*block);	bl.data = &ack;	bl.size = 102;	bl.next = NULL;	return udp_send(dev, &tftp_me, &tftp_serv, &bl);}static int tftp_recv_data(struct netdev *dev, int *block, void *buffer){	static struct tftp_data data;	static int recvd_block;  /* 2001-2-24 */	int bytes;	if (*block == 1)		tftp_serv.sin_port = 0;    DEBUG_TFTP("\n%s", "->");	bytes = udp_recv(dev, &tftp_serv, &tftp_me, &data, sizeof(data));    DEBUG_TFTP("BYTES(%d)\n", bytes);	if (!bytes)		return 0;	if (data.cmd != htons(TFTP_DATA)) {            printf("TFTP_ERROR: %x\n",data.cmd);             if(data.cmd == htons(TFTP_ERROR)) {                printf("TFTP_ERROR: %x\n",data.cmd);             }            return 0;        }	recvd_block = htons(data.block);	if (recvd_block <= *block) {        DEBUG_TFTP("RECV BLOCK(%d)<=BLOCK(%d)\n", recvd_block, *block);		*block = recvd_block; /* 2001-2-24 */		tftp_send_ack(dev, &recvd_block);  /* 2001-2-24 */	}	if (recvd_block != *block)  /* Need Check 2001-2-24 */		return 0;    DEBUG_TFTP("TFTP PKT RECV OK(BLOCK = %d)\n", recvd_block);	memcpy(buffer, data.data, bytes - 4);	return bytes - 4;}#define TWIDDLE_IDX(x)	  (((x) >> 16) & 3)#define TWIDDLE_UPDATE(x) (((x) & 0xffff) == 0)int do_tftp(struct netdev *dev){	static const char twiddle[] = { '|', '/', '-', '\\' };	static unsigned char *data;	static int block;	int targ, error, bytes;	int timeout;	int retries;	int total_bytes;		block = 1;	bytes = 0;	timeout = CONF_TIMEOUT_MAJOR_BASE;	retries = CONF_RETRIES;	total_bytes = 0;	data = (unsigned char *)load_addr;	printf("\nTFTP Boot image(%s) loading at 0x%x...",dev->boot_file, (int)load_addr);	do {		if (block == 1) {			error = tftp_send_rrq(dev);			if(error) printf("tftp_send_rrq_error\n");		}		else { 			error = tftp_send_ack(dev, &block);			if(error) printf("tftp_send_ack_error\n");                }		if (error)			break;		targ = centisecs + timeout;		while (centisecs < targ) {			bytes = tftp_recv_data(dev, &block, data + total_bytes);                        DEBUG_TFTP("RECVD BYTES(%d),BLOCK = %d\n", bytes, block);			//printf("7");			if (bytes) {				retries = CONF_RETRIES;				timeout = CONF_TIMEOUT_MINOR_BASE;				targ = centisecs + timeout;				if (TWIDDLE_UPDATE(total_bytes)) 				      printf("%c\010", twiddle[TWIDDLE_IDX(total_bytes)]);				total_bytes += bytes;				if (bytes == 512)					block ++;				else 					break;			}		}		if (timeout == CONF_TIMEOUT_MINOR_BASE)			timeout = CONF_TIMEOUT_MAJOR_BASE;		if (bytes)			break;		if (!--retries) {			printf("\010 timed out   ");			error = 1;			break;		}		timeout = timeout * CONF_TIMEOUT_MULT;		if (timeout > CONF_TIMEOUT_MAX)			timeout = CONF_TIMEOUT_MAX;	} while (1);	if (error) {		printf("\010 Error\n");		return 1;	}	printf("\010 %d Bytes \n", total_bytes);        bios_recv_bytes = total_bytes;	return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?