1.- Wireshark, sin duda. La distro de Kali Linux para RPi lo incluye, pero no va bien, hay pérdida de paquetes y una dificultad considerable para hacerlo funcionar en modo monitor.
¿ quiere esto decir que no se envíen los paquetes a la dirección 255.255.255.255, ni a otra dirección de la misma red, acabada en 255, para que los paquetes no lleguen a todos los dispositivos conectados en la misma red ?. Esto es lo que he entendido que es el Broadcast en UDP, enviar paquetes de datos sin destinatario concreto, todos los nodos de la misma red los pueden leer.
/*
UDPSendReceiveString:
This sketch receives UDP message strings, prints them to the serial port
and sends an "acknowledge" string back to the sender
A Processing sketch is included at the end of file that can be used to send
and received messages for testing with a computer.
created 21 Aug 2010
by Michael Margolis
This code is in the public domain.
*/
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac, ip);
Udp.begin(localPort);
Serial.begin(9600);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i=0; i < 4; i++) {
Serial.print(remote[i], DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
/*
Processing sketch to run with this example
=====================================================
// Processing UDP example to send and receive string data from Arduino
// press any key to send the "Hello Arduino" message
import hypermedia.net.*;
UDP udp; // define the UDP object
void setup() {
udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000
//udp.log( true ); // <-- printout the connection activity
udp.listen( true ); // and wait for incoming message
}
void draw()
{
}
void keyPressed() {
String ip = "192.168.1.177"; // the remote IP address
int port = 8888; // the destination port
udp.send("Hello World", ip, port ); // the message to send
}
void receive( byte[] data ) { // <-- default handler
//void receive( byte[] data, String ip, int port ) { // <-- extended handler
for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}
*/
Vos vas a tener una IP propia seguramente automatica dada por DHCP, Luego a quien le vas a enviar el paquete es al IP que vos quieras, y como dijo tsk como no es un protocolo orientado a la conexion, es enviar, si llega o no, a nadie le importa. Ya que no tenes acuse de recibo.
El puerto de origen es opcional y podes usar 0 para omitirlo, recuerdo que una persona tuvo problemas con eso, pero al ponerle 0 se soluciono, o no recuerdo si era algo de TCP.
La dirección MAC is una dirección única que representa al adaptador de Red (NIC), de esta no puede haber duplicados en tu red. Esta puede ser manejada de forma local o universal. En la local tu le asignas la dirección siguiendo ciertos patrones, y en la Universal compras los rangos de direcciones.
Si quieres obtener una dirección MAC valida, existen unas memorias eeprom que salen bastante económicas que contienen una dirección MAC, uno de ellos es el 25aa02e48 y se conecta por SPI, con esta memoria tienes el espacio suficiente para almacenar la IP, el puerto y algunas otras configuraciones.
También te recomiendo que le des un vistazo al proyecto de tu cliente, tal vez existan mejores y más robustas formas de resolver su proyecto. Por ejemplo existe CoAP(UDP) y MQTT(TCP). Estos son protocolos enfocados a la comunicacion Máquina a Máquina, por lo que podrías implementar sistemas más complejos que el que podrías al usar sólamente UDP. A mi me gusta usar más MQTT, pero es sólo cuestion de gustos.
http://coap.technology/
http://mqtt.org/
https://eclipse.org/community/eclipse_newsletter/2014/february/article2.php
//******************************************************************************
//******************************************************************************
//******** Programa TEST UDP Kinetis MK64 **************************************
//******************************************************************************
//******************************************************************************
#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>
#include "Watchdog.h" // Watchdog, añadido
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 189); // La IP de esta placa
IPAddress IP_Remote(192, 168, 1, 255); // IP para Broadcast
unsigned int localPort = 8888; // local port to listen on
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// Patilla Chip Select en 6 (PTD4)
#define W5500_CS 6
//*** Leds DEBUG y test actividad **
int Led1 = 37; // PTC10, DEBUG
int Led2 = 38; // PTC11, DEBUG
int state = 0; // Variable para parpadear LED (toggle)
//**********************************************************
//**********************************************************
//********** Configuracion inicial ************************
//**********************************************************
//**********************************************************
void setup() {
// Inicializa pines PTC10 y PTC11, para leds rojo y verde en placa
pinMode(Led1, OUTPUT); // pin37 de Arduino/Teensy, LED ROJO en PTC10
pinMode(Led2, OUTPUT); // pin38 de Arduino/Teensy, LED VERDE en PTC11
// Configuro pines alternativos SPI
SPI.setMOSI(7);
SPI.setMISO(8);
SPI.setSCK(14);
Ethernet.init(W5500_CS); //Configuro el chip select alternativo en pin6 (PTD4)
// start the Ethernet and UDP:
Ethernet.begin(mac, ip);
Udp.begin(localPort);
Serial.begin(9600);
}
//**********************************************************
//**********************************************************
//********** Bucle Principal ******************************
//**********************************************************
//**********************************************************
void loop() {
// Añado control de Watchdog
kickWatchdog();
// DEBUG Parpadeo LED en PC11, led verde en placa
state++;
if (state==1) digitalWriteFast(Led2, HIGH);
if (state==15) {digitalWriteFast(Led2, LOW);}
if (state== 30) state=0;
// DEBUG, envia un paquete UDP, puerto 8888
// Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.beginPacket(IP_Remote, localPort);
Udp.write("hello");
Udp.endPacket();
delay(10);
}
envío 4096 bytes y recibo solo 2132 bytes en dos trozos (1514+618).