示例#1
0
void enc424j600_receivecallback( uint16_t packetlen )
{
	uint8_t is_the_packet_for_me = 1;
	unsigned char i;
	unsigned char ipproto;

	//First and foremost, make sure we have a big enough packet to work with.
	if( packetlen < 8 )
	{
#ifdef ETH_DEBUG
		sendstr( "Runt\n" );
#endif
		return;
	}

	//macto (ignore) our mac filter handles this.
	enc424j600_dumpbytes( 6 );

	POPB( macfrom, 6 );

	//Make sure it's ethernet!
	if( POP != 0x08 )
	{
#ifdef ETH_DEBUG
		sendstr( "Not ethernet.\n" );
#endif
		return;
	}

	//Is it ARP?
	if( POP == 0x06 )
	{
		HandleArp( );
		return;
	}

	//otherwise it's standard IP

	//So, we're expecting a '45

	if( POP != 0x45 )
	{
#ifdef ETH_DEBUG
		sendstr( "Not IP.\n" );
#endif
		return;
	}

	POP; //differentiated services field.

	iptotallen = POP16;
	enc424j600_dumpbytes( 5 ); //ID, Offset+FLAGS+TTL
	ipproto = POP;

	POP16; //header checksum

	POPB( ipsource, 4 );


	for( i = 0; i < 4; i++ )
	{
		unsigned char m = ~MyMask[i];
		unsigned char ch = POP;
		if( ch == MyIP[i] || (ch & m) == 0xff  ) continue;
		is_the_packet_for_me = 0;
	}

	//Tricky, for DHCP packets, we have to detect it even if it is not to us.
	if( ipproto == 17 )
	{
		remoteport = POP16;
		localport = POP16;
#ifdef ENABLE_DHCP_CLIENT
		if( localport == 68 && !dhcp_seconds_remain )
		{
			HandleDHCP( POP16 );
			return;
		}
#endif
	}

	if( !is_the_packet_for_me )
	{
#ifdef ETH_DEBUG
		sendstr( "not for me\n" );
#endif
		return;
	}

	//XXX TODO Handle IPL > 5  (IHL?)

	switch( ipproto )
	{
	case 1: //ICMP

		HandleICMP();
		break;
#ifdef INCLUDE_UDP
	case 17:
	{
		//err is this dangerous?
		HandleUDP( POP16 );
		break;	
	}
#endif
#ifdef INCLUDE_TCP
	case 6: // TCP
	{

		remoteport = POP16;
		localport = POP16;
		iptotallen-=20;
		HandleTCP( iptotallen );
		break;
	}
#endif // HAVE_TCP_SUPPORT
	default:
		break;
	}

//finishcb:
//	enc424j600_finish_callback_now();
}
示例#2
0
void HandleDHCP( uint16_t len )
{
	uint8_t tmpip[4];
	uint8_t tmp[4];
	uint8_t optionsleft = 48; //We only allow for up to 48 options
	uint8_t is_ack_packet = 0;
	uint16_t first4, second4;

	POP16; //Clear out checksum

	//Process DHCP!
	if( POP != 2 ) return; //Not a reply?
	if( POP != 1 ) return; //Not Ethernet?
	POP16; //size of packets + Hops

	//Make sure transaction IDs match.
	enc424j600_popblob( tmp, 4 );
	if( memcmp( tmp, MyMAC, 4 ) != 0 )
	{
		//Not our request?
		return;
	}

	enc424j600_dumpbytes( 8 ); //time elapsed + bootpflags + Client IP address

	enc424j600_popblob( tmpip, 4 );	//MY IP ADDRESS!!!	
	
	enc424j600_dumpbytes( 0x18 + 0xc0 ); //Next IP + Relay IP + Mac + Padding + server name + boot name

	first4 = POP16;
	second4 = POP16;

	if( first4 != 0x6382 || second4 != 0x5363 )
	{
		return;
	}

	//Ok, we know we have a valid DHCP packet.

	//We dont want to get stuck, so we will eventually bail if we have an issue pasrsing.
	while( optionsleft-- )
	{
		uint8_t option = POP;
		uint8_t length = POP;

		switch(option)
		{
		case 0x35: //DHCP Message Type
		{
			if( length < 1 ) return;
			uint8_t rqt = POP;

			if( rqt == 0x02 ) 
			{
				//We have an offer, extend a request.
				//We will ignore the rest of the packet.
				enc424j600_finish_callback_now();
				RequestNewIP( 3, tmpip, ipsource );  //Request
				return;
			}
			else if( rqt == 0x05 ) // We received an ack, accept it.
			{
				//IP Is valid.
				is_ack_packet = 1;
				if( 0 == dhcp_seconds_remain )
					dhcp_seconds_remain = 0xffff;
				memcpy( MyIP, tmpip, 4 );
			}

			length--;
			break;
		}
		case 0x3a: //Renewal time
		{
			if( length < 4 || !is_ack_packet ) break;
			first4 = POP16;
			second4 = POP16;
//			printf( "LEASE TIME: %d %d\n", first4, second4 );
			if( first4 )
			{
				dhcp_seconds_remain = 0xffff;
			}
			else
			{
				dhcp_seconds_remain = second4;
			}

			length -= 4;
			break;
		}
		case 0x01: //Subnet mask
		{
			if( length < 4 || !is_ack_packet ) break;
			enc424j600_popblob( MyMask, 4 );
			length -= 4;
			break;
		}
		case 0x03: //Router mask
		{
			if( length < 4 || !is_ack_packet ) break;
			enc424j600_popblob( MyGateway, 4 );
			length -= 4;
			break;
		}
		case 0xff:  //End of list.
			enc424j600_finish_callback_now();
			if( is_ack_packet )
				GotDHCPLease();
			return; 
		case 0x42: //Time server
		case 0x06: //DNS server
		default:
			break;
		}
		enc424j600_dumpbytes( length );
	}
}
示例#3
0
文件: ip.c 项目: tcr/rise
int enc424j600_receivecallback( uint16_t packetlen )
{
	uint8_t is_the_packet_for_me = 1;
	unsigned char i;
	unsigned char ipproto;

	//First and foremost, make sure we have a big enough packet to work with.
	if (packetlen < 8) {
		// ERROR: Received runt packet
		return 1;
	}

	//macto (ignore) our mac filter handles this.
	enc424j600_dumpbytes( 6 );

	enc424j600_popblob( macfrom, 6 );

	//Make sure it's ethernet!
	if (enc424j600_pop8() != 0x08) {
		// ERROR: Not an ethernet packet
		return 1;
	}

	//Is it ARP?
	if (enc424j600_pop8() == 0x06) {
		HandleArp();
		return 0;
	}

	//otherwise it's standard IP

	//So, we're expecting a '45

	if (enc424j600_pop8() != 0x45) {
		// ERROR: Not an IP packet
		return 1;
	}

	enc424j600_pop8(); //differentiated services field.

	iptotallen = enc424j600_pop16();
	enc424j600_dumpbytes( 5 ); //ID, Offset+FLAGS+TTL
	ipproto = enc424j600_pop8();

	enc424j600_pop16(); //header checksum

	enc424j600_popblob( ipsource, 4 );

	for (i = 0; i < 4; i++) {
		unsigned char m = ~MyMask[i];
		unsigned char ch = enc424j600_pop8();
		if (ch == MyIP[i] || (ch & m) == 0xff) {
			continue;
		}
		is_the_packet_for_me = 0;
	}

	//Tricky, for DHCP packets, we have to detect it even if it is not to us.
	if (ipproto == 17) {
		remoteport = enc424j600_pop16();
		localport = enc424j600_pop16();
	}

	if (!is_the_packet_for_me) {
		// ERROR: Packet is not for us
		return 1;
	}

	//XXX TODO Handle IPL > 5  (IHL?)

	switch(ipproto) {
		// ICMP
		case 1: {
			HandleICMP();
			break;
		}

		// UDP
		case 17: {
			HandleUDP(enc424j600_pop16());
			break;
		}

		default: {
			break;
		}
	}

	return 0;

//finishcb:
//	enc424j600_finish_callback_now();
}