Page 1 of 1

Reading the ethernet device directly

Posted: Thu Oct 23, 2008 1:25 pm
by hendrixj
I need to read the ethernet device directly (not through the IP stack). Does anyone know how to do that?
Thanks

Re: Reading the ethernet device directly

Posted: Sat Oct 25, 2008 10:16 am
by rnixon
At what level?
What is the end goal you are trying to accomplish?

Re: Reading the ethernet device directly

Posted: Sun Oct 26, 2008 1:15 pm
by hendrixj
I'd like to build a small IP packet that fits entirely in one ethernet frame, and transfer that ethernet frame as a block of bytes to the ethernet device.

Re: Reading the ethernet device directly

Posted: Sun Oct 26, 2008 9:34 pm
by Ridgeglider
It's easy to map a struct into and/or out of a UDP packet and therefore to skip all the details of the frame. Would that work? Why do you care about frames?

Re: Reading the ethernet device directly

Posted: Mon Oct 27, 2008 6:12 am
by hendrixj
I have an embedded software project to do in which I must "speak IP" over ethernet without the benefit of an IP stack.

Re: Reading the ethernet device directly

Posted: Mon Oct 27, 2008 6:50 am
by Chris Ruff
ok. i'll byte...

Why?
Does timing require this?
Are you doing this on a tiny processor?
Is your customer requiring this?
Is this a 'must hack this' project?

Since the entire world of TCP/IP, UDP, uC/OS and everything else is there in NB, why the bare metal thing?

Chris

Re: Reading the ethernet device directly

Posted: Mon Oct 27, 2008 10:24 am
by hendrixj
I simply have to.

Ether_ProcessTask() (in ethernet.cpp for MOD2370) maybe running in it's own thread to read the device.
Perhaps this call ("pool_buffer *pb = ( pool_buffer * ) OSFifoPend( &FecFifo, wait );") is getting the ethernet data from the driver.

Re: Reading the ethernet device directly

Posted: Mon Oct 27, 2008 1:50 pm
by lgitlitz
Hi,

If your packets are going to contain an IP header and checksum then you should add your code to recognize your packets in "void IPTask( void *p )" in ip.cpp. This is where we parse the IP packets to either ICMP, UDP, TCP or we throw them away.

If they are not going to have a standard IP header and checksum then you probably want to dig into the Ethernet.cpp file in the function "void DoRX( PoolPtr pp, WORD ocount )". In this function we do initial check if the packet is a valid "IP" packet with a good check sum or a valid "ARP" packet.

In the end you will want another task running similar to our TCP task. You should then have either the Ethernet or IP task relaying the packet to that task. If you simply add a new case in the switch statements in the functions I pointed out then you can have the normal network stack working with the ability to receive your special packets.

- Larry

Re: Reading the ethernet device directly

Posted: Tue Dec 09, 2008 7:35 am
by hendrixj
Here are the steps I ended up using to gain access to the Ethernet device directly:

Defined myProcessArp: void myProcessArp(PoolPtr p, PEFRAME ethernetFramePtr )
Call "FreeBuffer( p );" as final line.

Defined myProcessPacket: void myProcessPacket( PoolPtr p, PEFRAME ethernetFramePtr, WORD checksum )
Call "FreeBuffer( p );" as final line.

To set up, DO NOT invoke "InitializeStack()". Instead:
InitBuffers(); // buffers.h
InitializeNetwork( &myProcessPacket, &myProcessArp ); // netinterface.h
InterfaceBlock *pifb = GetInterFaceBlock(); // netinterface.h
if ( pifb != NULL )
{
pifb->netIP = 0xC0A8015A; // 192.168.1.90
pifb->netIpMask = 0xFFFFFF00; // 255.255.255.0
pifb->netIpGate = 0x0000; // 0.0.0.0
pifb->netDNS = 0x0000; // 0.0.0.0
}

Once you do this, ARP requests show up in the myProcessArp and IP messages show up in myProcessPacket. Both show up as Ethernet frames.

You can send an Ethernet frame out interface 1, via:
TransmitBuffer( &outbuff, 1);
where outbuff is of type pool_buffer.
You don't have to calculated the crc32 for the outgoing frame.

Pretty slick.

Re: Reading the ethernet device directly

Posted: Tue Dec 09, 2008 1:16 pm
by lgitlitz
Nicely done. To get a bit of performance boost you might want to use the check sum functions in IP.cpp:
WORD GetSum( PWORD addr, WORD count );
WORD GetSum20( PDWORD addr );
WORD GetSumHdr( PsudeoHeader &hdr, PWORD addr, WORD count );
These functions were written in Coldfire assembly and tested to get high performance.

Also, since you are no longer using the TCP or IP tasks you can remove their task stacks from SRAM. This can be done by commenting out FAST_IP_STACK and FAST_TCP_STACK in constants.h and then recompiling teh system files. The buffer system will automatically use the extra free space for additional buffers in the fast SRAM.

-Larry