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

📄 tcpip.java

📁 Java Op Processor java vhdl processor
💻 JAVA
字号:
package tcpip;/***	TcpIp.java: A minimalistic TCP/IP stack (with ICMP).**	Copyright Martin Schoeberl.**   This software may be used and distributed according to the terms*   of the GNU General Public License, incorporated herein by reference.**   The author may be reached as martin.schoeberl@chello.at**	It's enough to handel a HTTP request (and nothing more)!***   Changelog:*		2002-03-16	works with ethernet*		2002-10-21	use Packet buffer, 4 bytes in one word***/import util.*;public class TcpIp {	private static final int PROT_ICMP = 1;	private static final int PROT_TCP = 6;	static final int FL_URG = 0x20;	static final int FL_ACK = 0x10;	static final int FL_PSH = 0x8;	static final int FL_RST = 0x4;	static final int FL_SYN = 0x2;	static final int FL_FIN = 0x1;	static int ip_id, tcb_port;	// ip id, tcp port	static int tcb_st;	// state	static final int ST_LISTEN = 0;	static final int ST_ESTAB = 2;	static final int ST_FW1 = 3;	static final int ST_FW2 = 4;    static final int MTU = 1500-8;    static final int WINDOW = 2680;/***	calc ip header check sum.*	assume (32 bit) word boundries. rest of buffer is 0.*	off offset in buffer (in words)*	cnt length in bytes*/	// static int chkSum(int[] buf, int off, int cnt) {// for OEBBpublic static int chkSum(int[] buf, int off, int cnt) {		int i;		int sum = 0;		cnt = (cnt+3)>>2;		// word count		while (cnt != 0) {			i = buf[off];			sum += i & 0xffff;			sum += i>>>16;			++off;			--cnt;		}		while ((sum>>16) != 0) sum = (sum & 0xffff) + (sum >> 16);		sum = (~sum) & 0xffff;		return sum;	}	public static void init() {		tcb_st = ST_LISTEN;		// select();		ip_id = 0x12340000;		Html.init();	}/***	process one ip packet.*	change buffer and set length to get a packet sent back.*	called from Eth.process().*/	public static void receive(Packet p) {		int i, j;		int ret = 0;		int[] buf = p.buf;		int len;/* Dbg.wr('\n'); Dbg.wr('I'); for (i=0; i<(p.len+3)>>2; ++i) { Dbg.hexVal(p.buf[i]); }*/		i = buf[0];		len = i & 0xffff;		// len from IP header// NO options are assumed in ICMP/TCP/IP...//		=> copy it options present		if (len > p.len || (i>>>24!=0x45)) {			p.len = 0;					// packet to short or ip options => drop it			return;		} else {			p.len = len;				// correct for to long packets		}		// TODO check version, header checksum		// TODO fragmentation		// TODO unique id for sent packet		int prot = (buf[2]>>16) & 0xff;		// protocol		if (prot==PROT_ICMP) {			doICMP(p);		} else if (prot==PROT_TCP) {			doTCP(p);		} else if (prot==Udp.PROTOCOL) {			Udp.process(p);		} else {			p.len = 0;		}		len = p.len;		if (len != 0) {			buf[0] = 0x45000000 + len;			// ip length	(header without options)			buf[1] = ip_id;						// identification, no fragmentation			ip_id += 0x10000;					// increment id (upper part of word)			buf[2] = (0x20<<24) + (prot<<16);	// ttl, protocol, clear checksum			i = buf[3];							// swap ip addresses			buf[3] = buf[4];			buf[4] = i;			buf[2] |= chkSum(buf, 0, 20);/* Dbg.wr('\n'); Dbg.wr('i'); for (i=0; i<(p.len+3)>>2; ++i) { Dbg.hexVal(p.buf[i]); } Dbg.wr('\n');*/		} else {			p.len = 0;			// no response		}		return;	}/***	the famous ping.*/	private static void doICMP(Packet p) {Dbg.wr('P');		if (p.buf[5]>>>16 == 0x0800) {			// TODO check checksum			p.buf[5] = 0;							// echo replay plus clear checksu,			p.buf[5] = chkSum(p.buf, 5, p.len-20);	// echo replay (0x0000) plus checksum		} else {			p.len = 0;		}	}// TODO:!!!!!! do a real state machine,// end is wrong (sending ack in fw1 !!!) makes remote site crazy	static void doTCP(Packet p) {		int i;		int datlen;		int[] buf = p.buf;		int rcvcnt, sndcnt;		int fl;Dbg.wr('T');		// Find the payload		i = buf[8]>>>16;		int flags = i & 0xff;		int hlen = i>>>12;		datlen = p.len - 20 - (hlen<<2);		// "TCB"		// In a full tcp implementation we would keep track of this per connection.		// This implementation only handles one connection at a time.		// As a result, very little of this state is actually used after		// the reply packet has been sent.//		if (datlen < 0) return 0;		// If it's not http, just drop it		i = buf[5];		if ((i & 0xffff) != 80) {			p.len = 0;			return;		}		// Get source port		tcb_port = i>>>16;		rcvcnt = buf[6];		// sequence number		sndcnt = buf[7];		// acknowledge number		// sndcnt has to be incremented for SYN!!!				fl = FL_ACK;		p.len = 40;				// Figure out what kind of packet this is, and respond		if ((flags & FL_SYN) != 0) {				// SYN			sndcnt = -1;		// start with -1 for SYN 			rcvcnt++;			fl |= FL_SYN;//			tcb_st = ST_ESTAB;			} else if (datlen > 0) {				// incoming data			rcvcnt += datlen;				// TODO get url			if (sndcnt==0) {				p.len += Html.setText(buf, 5+hlen, datlen, 10);				// Send reply packet//				if (len > MTU) len = MTU;	// TODO MTU should be taken from tcp options				// Read next segment of data into buffer			} else {				fl |= FL_FIN;//				tcb_st = ST_FW1;			}				fl |= FL_PSH;			} else if ((flags & FL_FIN) != 0) {				// FIN			rcvcnt++;			// Don't bother with FIN-WAIT-2, TIME-WAIT, or CLOSED; they just cause trouble//			tcb_st = ST_LISTEN;			} else if ((flags & FL_ACK) != 0) {				// ack with no data			if (sndcnt > 0) {				// calculate no of bytes left to send// i = len2send - sndnxti = 0;				if (i == 0) {					// EOF; send FIN					fl |= FL_FIN;//					tcb_st = ST_FW1;				} else if (i > 0) {					// not EOF; send next segment//					len += i;					fl |= FL_PSH;				} else {						// ***** this is never used! thats bad					// ack of FIN; no reply					p.len = 0;					return;				}			} else {				p.len = 0;				return;					// No reply packet			}			} else {			p.len = 0;			return;						// drop it		}			// Fill in TCP header		buf[5] = (80<<16) + tcb_port;		buf[6] = sndcnt;		buf[7] = rcvcnt;		buf[8] = 0x50000000 + (fl<<16) + WINDOW;	// hlen = 20, no options		buf[9] = 0;									// clear checksum field		buf[2] = (PROT_TCP<<16) + p.len - 20; 		// set protocol and tcp length in iph checksum for tcp checksum		buf[9] = chkSum(buf, 2, p.len-8)<<16;		}	private static final int IO_STATUS = 1;	private static final int IO_UART = 2;	private static final int IO_UART2 = 3;	private static final int MSK_UA_TDRE = 1;	private static final int MSK_UA2_TDRE = 4;	static void xxx(int c) {		while ((com.jopdesign.sys.Native.rd(IO_STATUS)&MSK_UA_TDRE)==0) ;		com.jopdesign.sys.Native.wr(c, IO_UART);	}}

⌨️ 快捷键说明

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