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

📄 tftp.c

📁 学习嵌入式LINUX的好东西
💻 C
字号:
#include <setup.h>#include <stdio.h>#include <command.h>#include <time.h>#include <network.h>#include <string.h>//#define TIMEOUT						1#define TIMEOUT						(CLOCKS_PER_SEC * 2)// 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_SUCCESS			3#define TFTP_STATE_FAILURE			4#define PORT_TFTPS					69#define report(fmt, args...)		printf(fmt, ##args)#define assert(fmt, args...)		printf(fmt, ##args)#define failed(fmt, args...)		printf(fmt, ##args)static uint32 destip;static uint16 destport;//static int  tftpState;static bool wait;static uint16 lastblk;static void *tftpbuff;static ulong maxsize;static ulong received; clock_t timeout;static bool tftp_start(char *filename);static bool do_tftp(int argc, char **argv);static void tftp_usage(void);static bool tftp_send_packet(int dport, void *packet, int len);static bool send_tftp_request_packet(char *filename);static bool send_tftp_ack_packet(int blknum);struct command_t cmd_tftp = {	.name  = "tftp",	.run   = do_tftp,	.usage = tftp_usage};static void tftp_usage(void){	usage_format("tftp filename {loader/kernel/root/ramdisk}", "");	return;}static bool do_tftp(int argc, char **argv){	bool res;	ulong tmp;	char *filename;	struct map *mp;   	/* destination ip address */	if (argc == 4){		destip = inet_addr(argv[1]);		argc--; argv++;	} else {		destip = setup->destipaddr;	}	if (argc != 3) goto invalid;	/* filename */	filename = argv[1];	/* buff address */	mp = find_map(argv[2]);	if (mp){		tftpbuff = (void *)mp->dramb;		maxsize  = mp->maxs;	} else if (strtoul(argv[2], &tmp, 16)){		tftpbuff = (void *)tmp;		maxsize = -1;	} else goto invalid;	if (!destip){ printf(" error : invalid ip address\n"); goto invalid; }	res = tftp_start(filename);	if (mp) mp->drams = received;	return res;invalid :	tftp_usage();	return false;}static bool tftp_start(char *filename){ 	report(" tftp start...\n");	report(" my ip address     : %s\n", inet_ntoa(setup->myipaddr));	report(" server ip address : %s\n", inet_ntoa(destip));	report(" filename          : %s\n", filename);	report(" store at          : 0x%08lX\n", (ulong)tftpbuff);	report(" loading start...\n");	wait = true;	timeout = clock() + TIMEOUT ;	received = lastblk = destport = 0; 	send_tftp_request_packet(filename);      //  printf("tftp start() begin receive true packe\n");             	while (clock() < timeout){             		net_recv_poll();		if (!wait) break;	}	if (wait) report(" error : timed out.\n");	return received ? true : false;}static inline bool tftp_send_packet(int dport, void *packet, int len){	int n;	void *dmac;	dmac = find_mac_addr(destip);	if (!dmac) return false;	n = set_udp_header(packet, dport, PORT_TFTP_CLIENT, len);	packet -= n; len += n;	n = set_ip_header(packet, setup->myipaddr, destip, IP_P_UDP, len);	packet -= n; len += n;	n = set_ether_header(packet, dmac, PROT_IP);	packet -= n; len += n;	return net_send_packet(packet, len);}static bool send_tftp_request_packet(char *filename){	int len;	uchar buff[1024], *packet, *s;	packet = buff + 100;	s = packet;	*(uint16 *)s = htons(TFTP_RRQ);	s += 2;	strcpy(s, filename);	s += strlen(filename) + 1;	strcpy(s, "octet");	s += strlen("octet") + 1;	len = s - packet;	return tftp_send_packet(PORT_TFTPS, packet, len);}static bool send_tftp_ack_packet(int blknum){	int len;	uchar buff[1024], *packet, *s;	packet = buff + 100;	s = packet;	*(uint16 *)s = htons(TFTP_ACK);	s += 2;	*(uint16 *)s = htons(blknum);	s += 2;	len = s - packet;	return tftp_send_packet(destport, packet, len);}bool tftp_recv(int port, void *packet, int len){	uint16 ptype, blknum;	uchar *s = packet;       // printf("tftp_recv()\n");	if (!wait) return false;	if (!destport) destport = port;	if (port != destport) return false;	// handling received data.	ptype = ntohs(*(uint16 *)s);	s += 2; len -= 2;	switch (ptype){		case TFTP_DATA :			if (len < 2) break;			blknum = ntohs(*(uint16 *)s);			s += 2; len -= 2;			/* check expected block number */			if (blknum != lastblk + 1) break;			lastblk = blknum;			timeout = clock() + TIMEOUT;			/* check remained buff size */			if (blknum * 512 > maxsize){				report(" error : size too big(cur=0x%lx, max=0x%lx)\n", (ulong)blknum * 512, maxsize);				wait = false;			}			/* store received data */			memcpy((void *)(tftpbuff+(blknum-1)*512), s, len);			/* display progress */			if (!((blknum) % 128)){				int total = blknum * 512;				report("\r %d (0x%08X) bytes received.", total, total);			}			/* send ack packet */			send_tftp_ack_packet(blknum);			/* we received the whole thing */			if (len < 512){				int total = (blknum-1) * 512 + len;				report("\r %d (0x%08X) bytes received. done.\n", total, total);				received = total;				wait = false;			}			break;		case TFTP_ERROR :			report(" error : '%s' (%d)\n", s+2, ntohs(*(uint16 *)s));			wait = false;			break;		default:			break;	}	return true;}

⌨️ 快捷键说明

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