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

📄 ip.c

📁 ppp拨号程序源代码采用atmel芯片c语言编
💻 C
📖 第 1 页 / 共 2 页
字号:
																				//
	for (i = 0; ; i++)
	{
		rmemcpy((char*)&dw1, AllowedIP[i], 4);									//
		if (!dw1) break;														// end of list
		if (IP_Header->SourceIP.ip32 == dw1) return false;						// allow it
	}

//	rmemcpy((char*)&dw1, SubnetMask, 4);										//
//	dw2 = IP_Header->SourceIP.ip32 & dw1;										//
//	dw1 &= PPP.OUR_IP.ip32;														//
//	if (dw1 != dw2) return true;												// different subnet - firewall it

//	return false;																	// let it thru
	return true;																	// firewall it
}

// **************************************************************************
// Calculate a checksum - used in IP packets

u32 IP_Checksum(char *p, u16 len)
{	// this one REALLY needs to be as fast as possible - best to do this in assembler code
	register u16	i;
	register u32	checksum = 0;
	register u16	*q;

	if (!p) return 0;
	if (len == 0) return 0;

	q = (u16*)p;

	for (i = 0; i < (len >> 1); i++) checksum += (u32)ntohs(*q++);
	if (len & 1) checksum += (u32)(ntohs(*q) & 0xff00);

	return checksum;
}

u16 IP_ChecksumFinalize(u32 checksum)
{
	checksum = (checksum & 0x0000ffff) + ((checksum >> 16) & 0x0000ffff);
	if (checksum & 0xffff0000) checksum++;
	checksum = ~checksum;
	return (u16)(checksum & 0x0000ffff);
}

u16 IP_Checksum1(char *p, u16 len)
{
	u32 checksum = IP_Checksum(p, len);
	return IP_ChecksumFinalize(checksum);
}

u16 IP_Checksum2(char *p, u16 len)
{
	u16		w;
	u32		checksum;

	// the tcp and udp packet checksums needs a pseudo header bringing into the calculation.
	// the header is not sent with the packet though, it's just for checksum calc.

//	 0                   1                   2                   3
//	 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//	|                         Source address                        |
//	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//	|                      Destination address                      |
//	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//	|     zero      |   Protocol    |        UDP/TCP Length         |
//	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

	checksum = IP_Checksum(p, len);												// checksum the packet
																				//
	checksum += IP_Checksum((char*)&IP_Header->SourceIP.ip32, 4);				// now pull in the pseudo header
	checksum += IP_Checksum((char*)&IP_Header->DestIP.ip32, 4);					//
	w = htons(IP_Header->Protocol); checksum += IP_Checksum((char*)&w, 2);		//
	w = htons(len); checksum += IP_Checksum((char*)&w, 2);						//
																				//
	return IP_ChecksumFinalize(checksum);										// return the final checksum value
}

// **************************************************************************

void IP_dec(void)
{
	// IP packet

	// RFC 791
	// http://www.freesoft.org/CIE/Course/Section3/

	u8		type, len;
	u16		w;

	IP_Header = (T_IP_Header*)(MainBuffer + MainBufferRd_Rx);				// point to the IP header
																			//
	w = MainBufferWr_Rx - MainBufferRd_Rx;									// number of bytes we have
	if (w < sizeof(T_IP_Header)) return;									// we don't have enough bytes for the ip header - drop the packet
																			//
	if ((IP_Header->VerLen & 0xf0) != 0x40) return;							// drop the packet as we're only programmed to deal with IP V4
																			//
	w = (IP_Header->VerLen & 0x0f) << 2;									// i = length of header in bytes
	if (w < sizeof(T_IP_Header)) return;									// error
	if (MainBufferWr_Rx < (MainBufferRd_Rx + w)) return;					// we still don't have enough bytes for the ip header - drop the packet
																			//
	if ((!IP_Header->Checksum) || (IP_Checksum1((char *)IP_Header, w)))		//
	{																		// invalid checksum
		#ifdef Debug														//
			SendDebugRStr(ip_str16);										//
		#endif																//
		return;																//
	}																		//
																			//
	w = ntohs(IP_Header->TotalLength);										// total packet length
	if (MainBufferWr_Rx < (MainBufferRd_Rx + w)) return;					// we still don't have enough bytes for the ip header - drop the packet
	MainBufferWr_Rx = MainBufferRd_Rx + w;									// just incase they have padded the packet out - this will drop the padding
																			//
	if (IP_Header->SourceIP.ip32 == PPP.OUR_IP.ip32) return;				// ahmmmmm, we sent this packet - must be in loop-back mode - drop it

	// ********************************

	#ifdef Debug
		IP_DisplayProtocol(false, MainBufferWr_Rx);
		IP_DisplayHeader(MainBufferRd_Rx, MainBufferWr_Rx);
	#endif

	// ********************************

	w = (u16)(IP_Header->VerLen & 0x0f) << 2;						// w = length of header in bytes
	w += MainBufferRd_Rx;											// point to data (immediately follows the IP header)
	MainBufferRd_Rx += sizeof(T_IP_Header);							// point to header options
	while (MainBufferRd_Rx < w)										//
	{																// go thru each IP header option
		type = MainBuffer[MainBufferRd_Rx++];						// option type
		len = 0;													//
		if (!type) break;											// end of option list
		if (type == 1) continue;									// no length byte (NOP option)
		len = MainBuffer[MainBufferRd_Rx++];						// option length
		if (len < 2) len = 2;										//
																	//

																	//
		MainBufferRd_Rx += (len - 2);								//
	}																//
	MainBufferRd_Rx = w;											// point to IP data

	// ********************************

	if ((IP_Header->DestIP.ip32 != 0xffffffff) && (IP_Header->DestIP.ip32 != PPP.OUR_IP.ip32)) return;	 	// it's not for us so drop it now

	// ********************************
	// check for fragmentation

	w = ntohs(IP_Header->Fragment);		//
										//
	if (w & IP_FRAGMENTED)				//
	{									//
		#ifdef Debug
			SendDebugRStr(ip_str17);	//
		#endif
		return;							// we don't yet deal with fragmentation - just not got the ram available :(
	}									// .. but how do we force the other end to set the "don't fragment" flag when sending packets ?
										//
//	w &= IP_FRAGMENT_OFFSET;			// w = fragment offset


	// ********************************

	#ifdef IncludeICMP
	if (IP_Header->Protocol == IP_PROTO_ICMP) ICMP_In();			//
	#endif
	#ifdef IncludeUDP
	else															//
	if (IP_Header->Protocol == IP_PROTO_UDP) UDP_In();				//
	#endif
	#ifdef IncludeTCP
	else															//
	if (IP_Header->Protocol == IP_PROTO_TCP) TCP_In();				//
	#endif

	// ********************************
}

// **************************************************************************
// start an IP packet

void IP_StartPacket(u8 Protocol, u32 IP)
{
	PPP_StartPacket(PPP_IP);										//
																	//
	IP_Header = (T_IP_Header*)(MainBuffer + MainBufferWr_Tx);		// point to the IP header
	memset(IP_Header, 0, sizeof(T_IP_Header));						// clear it
																	//
	IP_Header->VerLen = 0x40 | (sizeof(T_IP_Header) >> 2);			//
	IP_Header->TOS = 0x04;											// make it high-reliable
//	IP_Header->TOS = 0x08;											// make it high-throughput - suseptable to retires though
	IP_Header->TotalLength = sizeof(T_IP_Header);					//
	IP_Header->ID = IP_ID++;										//
	IP_Header->Fragment = IP_DONT_FRAGMENT;							//
	IP_Header->TTL = 128;											//
	IP_Header->Protocol = Protocol;									//
	IP_Header->SourceIP.ip32 = PPP.OUR_IP.ip32;						//
	IP_Header->DestIP.ip32 = IP;									//
																	//
	MainBufferWr_Tx += sizeof(T_IP_Header);							// update index
}

void IP_EndPacket(void)
{
	u16 w;															//
																	//
	IP_Header->ID = htons(IP_Header->ID);							//
	IP_Header->Fragment = htons(IP_Header->Fragment);				//
	IP_Header->TotalLength = htons(IP_Header->TotalLength);			//
																	//
	w = (u16)(IP_Header->VerLen & 0x0f);							// number of 32-bit words to the ip header
	w <<= 2;														// now number of bytes
	w = IP_Checksum1((char*)IP_Header, w);							// update the IP header checksum
//	if (!w) w = 0xffff;												//
	IP_Header->Checksum = htons(w);									//
}

// **************************************************************************
// this is called from the ppp module - every 10ms

void IP_10ms_Timer(void)
{
	#ifdef IncludeICMP
	ICMP_10ms_Timer();												//
	#endif

	#ifdef IncludeUDP
	UDP_10ms_Timer();												//
	#endif

	#ifdef IncludeTCP
	TCP_10ms_Timer();												//
	#endif
}

// **************************************************************************
// this is called from the ppp module - as often as pos

void IP_Process(void)
{
	#ifdef IncludeTCP
	TCP_Process();													//
	#endif
}

// **************************************************************************

⌨️ 快捷键说明

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