In Linux, come è possibile trasmettere un pacchetto UDP utilizzando 0.0.0.0 come indirizzo di origine.Trasmissione di pacchetti UDP con indirizzo di origine 0.0.0.0
Ecco cosa ho provato finora.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
int main(int argc, const char *argv[])
{
struct sockaddr_in dst, src;
struct ifreq ifr;
int sock, tmp;
char payload[128];
memset(payload, 0, 128);
memset(&dst, 0, sizeof(dst));
dst.sin_family = AF_INET;
dst.sin_addr.s_addr = inet_addr("255.255.255.255");
dst.sin_port = htons(67);
memset(&src,0,sizeof(src));
src.sin_family = AF_INET;
src.sin_addr.s_addr = inet_addr("0.0.0.0");
src.sin_port = htons(68);
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
perror("Failed to create socket");
tmp = 1;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &tmp, sizeof(tmp)) < 0)
perror("SO_BROADCAST failed");
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)) < 0)
perror("SO_REUSEADDR failed");
if (setsockopt(sock, IPPROTO_IP, IP_FREEBIND, &tmp, sizeof(tmp)) < 0)
perror("IP_FREEBIND failed");
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth1", sizeof(ifr.ifr_name));
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0)
perror("SO_BINDTODEVICE failed");
if (bind(sock, (const struct sockaddr*)&src, sizeof(struct sockaddr_in)) < 0)
perror("bind failed");
if (connect(sock, (const struct sockaddr*)&dst, sizeof(struct sockaddr_in)) < 0)
perror("bind failed");
if (write(sock, payload, 128) < 0)
perror("Write failed");
close(sock);
return 0;
}
Il problema è l'indirizzo sorgente è impostato solo per 0.0.0.0 se nessuna interfaccia ha un indirizzo IPv4. Se solo un'interfaccia ha un indirizzo IPv4, questo indirizzo viene utilizzato come indirizzo di origine.
Ho esaminato il codice sorgente di alcuni dei client DHCP esistenti e ho scoperto che utilizzano socket RAW e creano manualmente l'intestazione IP e UDP. Questa è una possibilità, ma vorrei evitare di farlo manualmente.
Se nessuna interfaccia ha un indirizzo IPv4, non è possibile inviare il pacchetto a tutti ... – glglgl
@glglgl come si invia un riscontro DHCP (che richiede esattamente questo)? – KillianDS
Probabilmente usando le prese RAW ... – glglgl