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

📄 tftp.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
/* @(#)tftp.c 1.1 92/07/30 SMI *//* * Bare-bones tftp implementation for sun2's with ND in proms */#include "../lib/common/saio.h" #include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <net/if.h>#include <netinet/in_systm.h>#include <netinet/if_ether.h>#include <netinet/ip_var.h>#include <netinet/ip.h>#include <netinet/udp.h>#include <netinet/udp_var.h>#include "../lib/common/sainet.h" #include <arpa/tftp.h>#define MAXNAMELEN 8	/* 8 bytes of internet address in hex */#define UDP_OFFSET \	(sizeof(struct udphdr)+sizeof(struct ip)+sizeof(struct ether_header))#define MAXSENDSIZE	(4 + MAXNAMELEN + 1 + sizeof(mode))#define MAXRECVSIZE	(4 + SEGSIZE)#define millitime()	(*romp->v_nmiclock)#define flipit()	putchar(flip[flipc++ % 4]); putchar('\b')extern int random;char mode[] = "octet";		/* transfer mode is always octet */char flip[] = "-\\|/";		/* emulates what the proms do */int flipc = 0;			/* current location in flip */int sport = -1;			/* source port */char sendpacket[UDP_OFFSET + MAXSENDSIZE];char recvpacket[ETHERMTU];/* * Use tftp to read in a file */tftpread(rhost, rether, name, mem, timeout, retries)	struct sockaddr_in rhost;	struct ether_addr rether;	char *name;	char *mem;		int timeout;	/* timeout per request */	int retries;	/* number of retries before giving up */{	int sendsize;	int recvsize;	struct tftphdr *sendth;	struct tftphdr *recvth;	int lastblock;	int amount;	int nrecv;	int stoprecv;	int eof;	int gotblock;	int tries;	struct sockaddr_in thost;	struct ether_addr tether;	recvth = (struct tftphdr *) (recvpacket + UDP_OFFSET);	sendth = (struct tftphdr *) (sendpacket + UDP_OFFSET);	eof = 0;	tries = 0;	if (sport >= 0) {		sendth->th_opcode = htons(ACK);		sendth->th_block = 1;		sendsize = 4;		amount = SEGSIZE;		lastblock = 1;	} else {		sport = random++ & 0xffff;		amount = 0;		lastblock = 0;		rhost.sin_port = IPPORT_TFTP;		sendsize = makereq(sendth, name);	}		while ((! eof) && (tries++ < retries)) {		(void) udp_output(&rhost, &rether, (u_short) sport, sendpacket,			sendsize);		flipit();		gotblock = 0;		stoprecv = millitime() + timeout;		while ((! gotblock) && (millitime() < stoprecv)) {			recvsize = MAXRECVSIZE;			nrecv = udp_input(&thost, &tether, (u_short) sport, 				recvpacket, recvsize);			if (thost.sin_addr.s_addr == rhost.sin_addr.s_addr && 				nrecv >= 4)			{				switch (ntohs(recvth->th_opcode)) {				case DATA:					if (ntohs(recvth->th_block) == 						lastblock + 1) 					{						gotblock = 1;					}					break;				case ERROR:					return(-1);				}			}		}		if (gotblock) {			flipit();			recvsize = nrecv - 4;			bcopy(recvth->th_data, mem + amount, recvsize);			amount += recvsize;			if (recvsize == SEGSIZE) {				sendth->th_opcode = htons(ACK);				sendth->th_block = recvth->th_block;				lastblock = ntohs(recvth->th_block);				sendsize = 4;				tries = 0;			} else {				eof = 1;			}			rhost.sin_port = thost.sin_port;		} 	}	if (eof) {		printf("Downloaded %d bytes from tftp server.\n", amount);	}	return(eof ? amount : 0);}/* * Find a tftp server by broadcasting * Read in the first block, if one is received */tftpfind(rhost, rether, name, mem, timeout)	struct sockaddr_in *rhost;	struct ether_addr *rether;	char *name;	char *mem;	int timeout;{	struct tftphdr *sendth;	struct tftphdr *recvth;	struct sockaddr_in thost;	struct ether_addr tether;	extern struct sainet ether_sain;	extern struct ether_addr etherbroadcastaddr;	int nrecv;	int sendsize;	int stoprecv;	int recvsize;	recvth = (struct tftphdr *) (recvpacket + UDP_OFFSET);	sendth = (struct tftphdr *) (sendpacket + UDP_OFFSET);	sendsize = makereq(sendth, name);	sport = random++ & 0xffff;	thost.sin_port = IPPORT_TFTP;	thost.sin_addr.s_addr = ~0;	tether = etherbroadcastaddr;	(void) udp_output(&thost, &tether, (u_short) sport, sendpacket, 		sendsize);	flipit();	stoprecv = millitime() + timeout;	while (millitime() < stoprecv) {		nrecv = udp_input(rhost, rether, (u_short) sport, 			recvpacket, MAXRECVSIZE);		if (nrecv >= 4  && ntohs(recvth->th_opcode) == DATA 			&& ntohs(recvth->th_block) == 1) 		{			flipit();			recvsize = nrecv - 4;			bcopy(recvth->th_data, mem, recvsize);			return(recvsize != SEGSIZE);			}	}	return(-1);	}char *strput(dst, src)	char *dst;	char *src;{	while (*dst++ = *src++)		;	return(dst);}makereq(sendth, name)	struct tftphdr *sendth;	char *name;{	char *cp;	sendth->th_opcode = htons(RRQ);	cp = strput(sendth->th_stuff, name);	cp = strput(cp, mode);	return(sizeof(sendth->th_opcode) + (cp - sendth->th_stuff));}

⌨️ 快捷键说明

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