Ethernet Raw Socket

Hi,

i'm looking for a way to send raw data (e.g. arp-packets) over the ethernet port. The default functions only seem to contain support for udp/tcp, are there any other possibilities to implement this? Thanks for reading :)

here is one possibility :slight_smile:

/*
  raw.pde:
  sending random raw packets
*/

#include <SPI.h>         // needed for Ethernet library communication with the W5100 (Arduino ver>0018)
#include <Ethernet.h>
#include <utility/w5100.h>

SOCKET s; // our socket that will be opened in RAW mode
byte buf[1500+14]; // buffer to send through socket
int buflen; // length of data to send

void setup() {

  // initialize the w5100 chip and open a RAW socket  
  W5100.init();
  W5100.writeSnMR(s, SnMR::MACRAW); 
  W5100.execCmdSn(s, Sock_OPEN);

}

void loop() {

  buflen=60; // we will be sending 'buflen' bytes across the wire 
 
  // filling buffer with some data ...
  for (int i=0; i<buflen; i++) {
    buf[i]=random(256);
  }
  
  // sending buffer
  W5100.send_data_processing(s, buf, buflen);
  W5100.execCmdSn(s, Sock_SEND_MAC);
 
  delay(1000);
}

works like a charm, thank you so much:D

i have some trouble now receiving packets. i don't exactly know, what the right functions are. read_data/recv_data_processing? would be nice, if you could help me with that little problem too;)

frozen1: Hi,

i'm looking for a way to send raw data (e.g. arp-packets) over the ethernet port. The default functions only seem to contain support for udp/tcp, are there any other possibilities to implement this? Thanks for reading :)

The hardware can do it but the standard driver won't.

You'll have to write your own driver (which isn't very hard...google for the W5100 datasheet and see what you think)

nb. There may already be raw drivers out there on the web, search for those, too.

OK … Here is a quick and dirty example for receiving and sending some raw ethernet packets :wink:

/*
  echo.pde:
  echo incoming packets back to the wire after changing their mac addresses
*/

#include <SPI.h>         // needed for Ethernet library communication with the W5100 (Arduino ver>0018)
#include <Ethernet.h>
#include <utility/w5100.h>

SOCKET s; // our socket that will be opened in RAW mode
byte rbuf[1500+14]; // receive buffer 
byte sbuf[1500+14]; // send buffer 
int rbuflen; // length of data to receive
int sbuflen; // length of data to send

void setup() {
 
  // initialize the w5100 chip and open a RAW socket  
  W5100.init();
  W5100.writeSnMR(s, SnMR::MACRAW); 
  W5100.execCmdSn(s, Sock_OPEN);
  
}

void loop() {
  // check if we have received something
  rbuflen = W5100.getRXReceivedSize(s);
  
  if (rbuflen>0) {
    // receive packet 
    W5100.recv_data_processing(s, rbuf, rbuflen);
    W5100.execCmdSn(s, Sock_RECV);
   
    // offset 2 ... because the first two bytes in 'rbuf' contain the packet length
    sbuflen=rbuflen-2; // we will be sending 'sbuflen' bytes across the wire 
    
    for (int i=0; i<= 5; i++) sbuf[i]=255; // changing dst mac address to broadcast 
    for (int i=6; i<=11; i++) sbuf[i]=random(256); // changing src mac address to a random address 

    // filling send buffer with some data from the receive buffer ...
    for (int i=12; i<sbuflen; i++) {
      sbuf[i]=rbuf[i+2]; // offset 2 !!!   
    }
  
    // sending packet
    W5100.send_data_processing(s, sbuf, sbuflen);
    W5100.execCmdSn(s, Sock_SEND_MAC);
  }
  
}

x421: byte rbuf[1500+14]; // receive buffer byte sbuf[1500+14]; // send buffer

Is this right? 3k byte buffer?

bubulindo: Is this right? 3k byte buffer?

Depending on your application you might wish to change the size of the buffers ... Our particular value was chosen because the maximum length of the data field of an Ethernet 802.3 frame is 1500 bytes.

Please note, that we have also not coded any sanity checks to see if the size of the received packets is larger than our buffer (e.g. jumbo-frame) or something similar - you would have to code it in yourself ;)

Also, we do not handle the case where more than one packet arrive in-between our reads in the loop-routine ... etc.

It's just a proof of concept how to send some user-defined raw packets - nothing less, nothing more ... Please feel free to stretch or modify the code as rubber :D

Can you do the same but to receive text from a RAW tcp Socket connection?

I found this post very helpful as I am trying to do some Ethernet level comms that doesn't use IP.

I am using this code below to check for and receive Ethernet data:

rbuflen = W5100.getRXReceivedSize(s);
  
  if (rbuflen>0) {
    // receive packet 
    W5100.recv_data_processing(s, rbuf, rbuflen);
    W5100.execCmdSn(s, Sock_RECV);

However one thing I have seen is that the received data does not include the preamble or start of frame delimiter. I am guessing this is stripped out by the MAC on the Ethernet shield. However I don't see how I can then analyse the incoming data to look for individual frames of data. Any ideas from anyone?

I have noticed that whenever the receive buffer is pulled in that this does seem to align with the beginning of a frame, it's just that the buffer can contain more than a single frame at a time.

Very helpful post. Thank you!

hello

I just want so modify IP header, I need to just use IP addresses nothing else in IP header, can anyone tell how can i achieve this?

Hi everybody,

calling the function

W5100.getRXReceivedSize(s);

just tell us that there is one or more packet in the receive buffer, but we have to separate the packets.

In the buffer, every received packet is preceded by two bytes that tell us his lenght plus 2, so we have to read first these two bytes and than read the corrisponding number of bytes to discard the packet.

I think that something like this can do the job:

byte SocketBuffer[1500];
unsigned int     RxBuffLen;     
unsigned int     RxPacketSize;


if  ((RxBuffLen = w5500.getRXReceivedSize(s)) != 0)          // is there something in the receive buffer?
{      
    w5500.recv_data_processing(s, SocketBuffer, 2); // read the first two bytes
    w5500.execCmdSn(s, Sock_RECV);                               // that tell us the lenght of the packet + 2 
      
    RxPacketSize = SocketBuffer[0];                                   // hight byte 
    RxPacketSize  <<= 8;                                                  //
    RxPacketSize  |= SocketBuffer[1] & 0x00FF);                // low byte

    RxPacketSize  -= 2;                                                     //  packet lenght
    
    w5500.recv_data_processing(s, SocketBuffer, RxPacketSize);  // read the packet
    w5500.execCmdSn(s, Sock_RECV);
}

We have to procede in this way until W5100.getRXReceivedSize(s); return us “zero”.

Marco

Dear Arduino Community

I have the same issue as frozen1 had nine years ago: I would like to send raw data (no read required) by using the Arduino Ethernet Shield 2.

Unfortunately, the code examples in this thread are not working anymore as the latest W5100.h version is not providing send_data_processing anymore. It seems that the function has been removed in a refactoring in the year 2018…

Does anybody know what to do - how can I get the code example running?

Any help is highly appreciated!

Greetings
M.

x421:
here is one possibility :slight_smile:

  // ...

#include <utility/w5100.h>

//  …

// sending buffer
  W5100.send_data_processing(s, buf, buflen);
  W5100.execCmdSn(s, Sock_SEND_MAC);
  //  …

If anybody is struggling with the same issue, I found a solution now:

The official W5500 library from Wiznet works fine and is still providing the send_data_processing functionalities :-)

Greetings, M.