示例#1
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();
}
示例#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
static void HandleArp (void)
{
	unsigned short i;
	unsigned char sendermac_ip_and_targetmac[16];
//	unsigned char senderip[10]; //Actually sender ip + target mac, put in one to shrink code.

	unsigned short proto;
	unsigned char opcode;
//	unsigned char ipproto;

	enc424j600_pop16(); //Hardware type
	proto = enc424j600_pop16();
	enc424j600_pop16(); //hwsize, protosize
	opcode = enc424j600_pop16();  //XXX: This includes "code" as well, it seems.

	switch( opcode )
	{
		// ARP Request
		case 1: {
			unsigned char match;

			enc424j600_popblob( sendermac_ip_and_targetmac, 16 );

			match = 1;
	//sendhex2( 0xff );

			//Target IP (check for copy)
			for( i = 0; i < 4; i++ )
				if( enc424j600_pop8() != MyIP[i] )
					match = 0;

			if( match == 0 )
				return;

			//We must send a response, so we termiante the packet now.
			enc424j600_finish_callback_now();
			enc424j600_startsend( NetGetScratch() );
			send_etherlink_header( 0x0806 );

			enc424j600_push16( 0x0001 ); //Ethernet
			enc424j600_push16( proto );  //Protocol
			enc424j600_push16( 0x0604 ); //HW size, Proto size
			enc424j600_push16( 0x0002 ); //Reply

			enc424j600_pushblob( MyMAC, 6 );
			enc424j600_pushblob( MyIP, 4 );
			enc424j600_pushblob( sendermac_ip_and_targetmac, 10 ); // do not send target mac.

			enc424j600_endsend();

			// Have a match!
			break;
		}

		// ARP Reply
		case 2: {
			uint8_t sender_mac_and_ip_and_comp_mac[16];
			enc424j600_popblob( sender_mac_and_ip_and_comp_mac, 16 );
			enc424j600_finish_callback_now();


			//First, make sure that we're the ones who are supposed to receive the ARP.
			for( i = 0; i < 6; i++ )
			{
				if( sender_mac_and_ip_and_comp_mac[i+10] != MyMAC[i] )
					break;
			}

			if( i != 6 )
				break;

			//We're the right recipent.  Put it in the table.
			memcpy( &ClientArpTable[ClientArpTablePointer], sender_mac_and_ip_and_comp_mac, 10 );

			ClientArpTablePointer = (ClientArpTablePointer+1)%ARP_CLIENT_TABLE_SIZE;
			break;
		}

		default: {
			//???? don't know what to do.
			return;
		}
	}
}