예제 #1
0
파일: ip.c 프로젝트: tcr/rise
void send_ip_header( unsigned short totallen, const unsigned char * to, unsigned char proto )
{
/*
	//This uses about 50 bytes less of flash, but 12 bytes more of ram.  You can choose that tradeoff.
	static unsigned char data[] = { 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 64, 0x00, 0x00, 0x00 };
	data[2] = totallen >> 8;
	data[3] = totallen & 0xFF;
	data[9] = proto;
	enc424j600_pushblob( data, 12 );
*/

	enc424j600_push16( 0x4500 );
	enc424j600_push16( totallen );

	enc424j600_push16( 0x0000 ); //ID
	enc424j600_push16( 0x4000 ); //Don't frgment, no fragment offset

	enc424j600_push8( 64 ); // TTL
	enc424j600_push8( proto ); // protocol

	enc424j600_push16( 0 ); //Checksum

	enc424j600_pushblob( MyIP, 4 );
	enc424j600_pushblob( to, 4 );
}
예제 #2
0
파일: ip.c 프로젝트: tcr/rise
int8_t RequestARP( uint8_t * ip )
{
	uint8_t i;

	for( i = 0; i < ARP_CLIENT_TABLE_SIZE; i++ )
	{
		if( memcmp( (char*)&ClientArpTable[i].ip, ip, 4 ) == 0 ) //XXX did I mess up my casting?
		{
			return i;
		}
	}

	SwitchToBroadcast();

	//No MAC Found.  Send an ARP request.
	enc424j600_finish_callback_now();
	enc424j600_startsend( NetGetScratch() );
	send_etherlink_header( 0x0806 );

	enc424j600_push16( 0x0001 ); //Ethernet
	enc424j600_push16( 0x0800 ); //Protocol (IP)
	enc424j600_push16( 0x0604 ); //HW size, Proto size
	enc424j600_push16( 0x0001 ); //Request

	enc424j600_pushblob( MyMAC, 6 );
	enc424j600_pushblob( MyIP, 4 );
	enc424j600_push16( 0x0000 );
	enc424j600_push16( 0x0000 );
	enc424j600_push16( 0x0000 );
	enc424j600_pushblob( ip, 4 );

	enc424j600_endsend();

	return -1;
}
예제 #3
0
파일: ip.c 프로젝트: tcr/rise
void send_etherlink_header( unsigned short type )
{
	enc424j600_pushblob( macfrom, 6 );

// The mac does this for us.
	enc424j600_pushblob( MyMAC, 6 );

	enc424j600_push16( type );
}
예제 #4
0
파일: ip.c 프로젝트: tcr/rise
void DoPing( uint8_t pingslot )
{
	unsigned short ppl;
	uint16_t seqnum = ++ClientPingEntries[pingslot].last_send_seqnum;
	uint16_t checksum = (seqnum + pingslot + 0x0800) ;

	int8_t arpslot = RequestARP( ClientPingEntries[pingslot].ip );
	if (arpslot < 0) {
		return;
	}

	//must set macfrom to be the IP address of the target.
	memcpy( macfrom, ClientArpTable[arpslot].mac, 6 );

	enc424j600_startsend( NetGetScratch() );
	send_etherlink_header( 0x0800 );
	send_ip_header( 32, ClientPingEntries[pingslot].ip, 0x01 );

	enc424j600_push16( 0x0800 ); //ping request + 0 for code
	enc424j600_push16( ~checksum ); //Checksum
	enc424j600_push16( pingslot ); //Idneitifer
	enc424j600_push16( seqnum ); //Sequence number

	enc424j600_push16( 0x0000 ); //Payload
	enc424j600_push16( 0x0000 );

	enc424j600_start_checksum( 8, 20 );
	ppl = enc424j600_get_checksum();
	enc424j600_alter_word( 18, ppl );

	enc424j600_endsend();
}
예제 #5
0
파일: iparpetc.c 프로젝트: QrackEE/avrcraft
//Mode = 1 for discover, Mode = 3 for request - if discover, dhcp_server should be 0.
void RequestNewIP( uint8_t mode, uint8_t * negotiating_ip, uint8_t * dhcp_server )
{
	uint8_t oldip[4];
	SwitchToBroadcast();

	enc424j600_stopop();
	enc424j600_startsend( NetGetScratch() );
	send_etherlink_header( 0x0800 );

	//Tricky - backup our IP - we want to spoof it to 0.0.0.0
	memcpy( oldip, MyIP, 4 );
	MyIP[0] = 0; MyIP[1] = 0; MyIP[2] = 0; MyIP[3] = 0;
	send_ip_header( 0, "\xff\xff\xff\xff", 17 ); //UDP Packet to 255.255.255.255
	memcpy( MyIP, oldip, 4 );
	
/*
	enc424j600_push16( 68 );  //From bootpc
	enc424j600_push16( 67 );  //To bootps
	enc424j600_push16( 0 ); //length for later
	enc424j600_push16( 0 ); //csum for later

	//Payload of BOOTP packet.
	//	1, //Bootp request
	//	1, //Ethernet
	enc424j600_push16( 0x0101 );
	//	6, //MAC Length
	//	0, //Hops
	enc424j600_push16( 0x0600 );
*/
	enc424j600_pushpgmblob( PSTR("\x00\x44\x00\x43\x00\x00\x00\x00\x01\x01\x06"), 12 ); //NOTE: Last digit is 0 on wire, not included in string.

	enc424j600_pushblob( MyMAC, 4 );

	enc424j600_push16( dhcp_clocking ); //seconds
	enc424j600_pushzeroes( 10 ); //unicast, CLIADDR, YIADDR
	if( dhcp_server )
		enc424j600_pushblob( dhcp_server, 4 );
	else
		enc424j600_pushzeroes( 4 );
	enc424j600_pushzeroes( 4 ); //GIADDR IP
	enc424j600_pushblob( MyMAC, 6 ); //client mac
	enc424j600_pushzeroes( 10 + 0x40 + 0x80 ); //padding + Server Host Name
	enc424j600_push16( 0x6382 ); //DHCP Magic Cookie
	enc424j600_push16( 0x5363 );

	//Now we are on our DHCP portion
	enc424j600_push8( 0x35 );  //DHCP Message Type
	enc424j600_push16( 0x0100 | mode );

	{
		enc424j600_push16( 0x3204 ); //Requested IP address. (4 length)
		enc424j600_pushblob( negotiating_ip, 4 );
	}

	if( dhcp_server ) //request
	{
		enc424j600_push16( 0x3604 );
		enc424j600_pushblob( dhcp_server, 4 );
	}

	if( DHCPName )
	{
		uint8_t namelen = strlen( DHCPName );
		enc424j600_push8( 0x0c ); //Name
		enc424j600_push8( namelen );
		enc424j600_pushblob( DHCPName, namelen );
	}

	enc424j600_push16( 0x3702 ); //Parameter request list
	enc424j600_push16( 0x0103 ); //subnet mask, router
//	enc424j600_push16( 0x2a06 ); //NTP server, DNS server  (We don't use either NTP or DNS)
	enc424j600_push8( 0xff ); //End option

	enc424j600_pushzeroes( 32 ); //Padding

	util_finish_udp_packet();
}
예제 #6
0
파일: ip.c 프로젝트: tcr/rise
static void HandleICMP()
{
	unsigned short id;
	unsigned short seqnum;
	unsigned char type;
	unsigned short payloadsize = iptotallen - SIZEOFICMP;

	unsigned short payload_from_start, payload_dest_start;

	icmp_in++;

	type = enc424j600_pop8();
	enc424j600_pop8(); //code
	enc424j600_pop16(); //Checksum

	switch( type )
	{
		// Ping Response
		case 0: {
			uint16_t id;

			id = enc424j600_pop16();
			if( id < PING_RESPONSES_SIZE )
			{
				ClientPingEntries[id].last_recv_seqnum = enc424j600_pop16(); //Seqnum
			}
			enc424j600_stopop();

			enc424j600_finish_callback_now();
			break;
		}

		// Ping Request
		case 8: {
			//Tricky: We would ordinarily POPB to read out the payload, but we're using
			//the DMA engine to copy that data.
			//	POPB( payload, payloadsize );
			//Suspend reading for now (but don't allow over-writing of the data)
			enc424j600_stopop();
			payload_from_start = enc424j600_read_ctrl_reg16( EERXRDPTL );

			enc424j600_startsend( NetGetScratch() );
			send_etherlink_header( 0x0800 );
			send_ip_header( iptotallen, ipsource, 0x01 );

			enc424j600_push16( 0 ); //ping reply + code
			enc424j600_push16( 0 ); //Checksum
		//	enc424j600_push16( id );
		//	enc424j600_push16( seqnum );

			//Packet confiugred.  Need to copy payload.
			//Ordinarily, we'd enc424j600_pushblob for the payload, but we're currently using the DMA engine for our work here.
			enc424j600_stopop();
			payload_dest_start = enc424j600_read_ctrl_reg16( EEGPWRPTL );

			//+4 = id + seqnum (we're DMAing that, too)
			enc424j600_copy_memory( payload_dest_start, payload_from_start, payloadsize + 4, RX_BUFFER_START, RX_BUFFER_END-1 );
			enc424j600_write_ctrl_reg16( EEGPWRPTL, payload_dest_start + payloadsize + 4 );

			enc424j600_finish_callback_now();

			//Calculate header and ICMP checksums
			enc424j600_start_checksum( 8+6, 20 );
			unsigned short ppl = enc424j600_get_checksum();
			enc424j600_start_checksum( 28+6, payloadsize + 8 );
			enc424j600_alter_word( 18+6, ppl );
			ppl = enc424j600_get_checksum();
			enc424j600_alter_word( 30+6, ppl );

			enc424j600_endsend();
			icmp_out++;

			break;
		}
	}
}
예제 #7
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;
		}
	}
}