etherspam shows how to send an Ethernet packet. It simply sends ARP Who is messages for every IP.

Dependencies:   mbed

main.cpp

Committer:
rolf
Date:
2009-09-04
Revision:
0:852db76de235

File content as of revision 0:852db76de235:

#include "mbed.h"                                      // Importing the mbed classes and tools.
#include "Ethernet.h"

using namespace mbed;

__packed                                               // A __packed struct to have no gaps between the members http://en.wikipedia.org/wiki/Data_structure_alignment
struct ethpkt {                                        // Ethernet layer: http://en.wikipedia.org/wiki/Ethernet#Physical_layer
  unsigned char   dest[6];                             //   Destination MAC
  unsigned char   src[6];                              //   Source MAC
  unsigned short  type;                                //   Payload type. ARP is 0x0806
                                                       // ARP layer: http://en.wikipedia.org/wiki/Address_Resolution_Protocol
  unsigned short  hwtype;                              //   Each data link layer protocol is assigned a number used in this field. Ethernet is 0x0001
  unsigned short  proto;                               //   Each protocol is assigned a number used in this field. IP is 0x0800.
  unsigned char   hwlen;                               //   Length in bytes of a hardware address. Ethernet addresses are 6 bytes long.
  unsigned char   protolen;                            //   Length in bytes of a logical address. IPv4 address are 4 bytes long.
  unsigned short  opcode;                              //   Specifies the operation the sender is performing: 
                                                       //     1 for request, 2 for reply, 3 for RARP request, and 4 for RARP reply.
  unsigned char   shwaddr[6];                          //   Hardware address of the sender.
  unsigned char   sipaddr[4];                          //   Protocol address of the sender.
  unsigned char   dhwaddr[6];                          //   Hardware address of the intended receiver. This field is ignored in requests.
  unsigned char   dipaddr[4];                          //   Protocol address of the intended receiver.
};

Ethernet eth;                                          // The ethernet device
DigitalOut led4(LED4);                                 // A LED for showing activity

unsigned short htons(unsigned short n) {               // Host short to network shor
  return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);      // Byte swapping
}

void send(const char *ipaddr) {
  static char data[0x600];                             // Packet buffer
  const unsigned char arplen = 6;                      // Hardware address length
  const unsigned char ethlen = 4;                      // IP address length
  char hwaddr[arplen];                                 // Hardware address buffer
  struct ethpkt *pkg   = (struct ethpkt *) &data[0];   // Force the buffer to an ethpkg
  unsigned char pos    = arplen;                       // Hardware/IP address position

  eth.address(hwaddr);                                 // Get own hardware address

  pkg->type            = htons(0x0806);                // Set type to ARP (0x0806)
  pkg->hwtype          = htons(0x0001);                // Hardware type is Ethernet (0x0001)
  pkg->proto           = htons(0x0800);                // Protocol is ARP Request (0x0800)
  pkg->hwlen           = arplen;                       // Hardware addresses are 6 Bytes long
  pkg->protolen        = ethlen;                       // And protocol addresses 4 Bytes
  pkg->opcode          = htons(0x0001);                // Send: whois XX:XX:XX:XX:XX:XX?
  
  while(pos-- > 0) {                                   // Write IP/MAC-Addresses (combined loop for all addresses)
    pkg->src[pos]        = hwaddr[pos];                // Set source MAC address to hwaddr on ethernet layer
    pkg->dest[pos]       = 0xFF;                       // Set destination MAC address to everybody (FF:FF:FF:FF:FF:FF) on ethernet layer
    pkg->shwaddr[pos]    = hwaddr[pos];                // Set source MAC address on ARP layer
    pkg->dhwaddr[pos]    = 0xFF;                       // Set destination MAC address on ARP layer
    if(pos < ethlen) {                                 // Check if we can copy IP addresses too.
      pkg->sipaddr[pos]  = 0xFF;                       // Set source ip address to 255.255.255.255
      pkg->dipaddr[pos]  = ipaddr[pos];                // Set destination ip address to ipaddr
    }
  }

  eth.write(data, 60);                                 // Write the package
  eth.send();                                          // Send the package
}
                                                       // In this example we would like to make ARP requests to ask for every ip address.
int main() {                                           // The programm starts here!
  unsigned int i = 1;                                  // The integer we use as counter and target IP address.
  char *c        = (char *)&i;                         // We cast the integer to an array of char c[4] to handle it as IP address.
  
  printf("Lowlevel Ethernet Spammer\n\n");             // Print out that the programm has been started.

  while(1) {                                           // Do forever:
    send(c);                                           //   Assamble and send our request. See eth_send function!
    i++;                                               //   Increment counter. What will increment the IP (c[4]) address as well.
    
    led4 = 1;                                          //   Show activity, by blinking with led 4:
    wait(0.02);                                        //   
    led4 = 0;                                          //     Put the led on and wait for 0.2 seconds
    wait(0.02);                                        //     Put the led off and wait for 0.2 seconds
  }
}