sock_stream - sockets c++ windows
El socket C++ DGRAM obtiene la dirección del RECEPTOR (2)
En Linux, desea utilizar la opción IP_PKTINFO
, ver ip(7)
y la recvmsg(2)
.
Stevens tiene ejemplos de hacerlo pero con las opciones IP_RECVDSTADDR
e IP_RECVIF
que no están disponibles en Linux.
En C ++,
¿Cómo puedo obtener la dirección del receptor del paquete UDP que he recibido usando recvfrom? Sé que debería ser el mismo host en el que estoy recibiendo el paquete, pero necesito extraerlo del paquete recibido para verificar algo. ¿Cómo puedo hacer esto?
Encontré que una forma de hacer esto es:
int r = getsockopt(receiver_sock, SOL_IP, SO_ORIGINAL_DST, (struct sockaddr *) &sender_addr, (socklen_t *)&addr_len);`
Pero me sale el error:
error: ‘SO_ORIGINAL_DST’ was not declared in this scope
Estoy usando los encabezados apropiados
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include </usr/src/linux-headers-2.6.32-21/include/linux/netfilter_ipv4.h>
#include <arpa/inet.h>
#include <linux/netfilter.h>
Usar netfilter_ipv4 da otros errores como INT_MIN no declarado. Sin embargo, creo que el error es algo más fundamental que la inclusión del encabezado correcto.
Por favor ayuda.
Construí un ejemplo que extrae las direcciones de origen, destino e interfaz. Por brevedad, no se proporciona ninguna verificación de errores. Vea este duplicado: obtenga la dirección de destino de un paquete UDP recibido .
// sock is bound AF_INET socket, usually SOCK_DGRAM
// include struct in_pktinfo in the message "ancilliary" control data
setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt));
// the control data is dumped here
char cmbuf[0x100];
// the remote/source sockaddr is put here
struct sockaddr_in peeraddr;
// if you want access to the data you need to init the msg_iovec fields
struct msghdr mh = {
.msg_name = &peeraddr,
.msg_namelen = sizeof(peeraddr),
.msg_control = cmbuf,
.msg_controllen = sizeof(cmbuf),
};
recvmsg(sock, &mh, 0);
for ( // iterate through all the control headers
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);
cmsg != NULL;
cmsg = CMSG_NXTHDR(&mh, cmsg))
{
// ignore the control headers that don''t match what we want
if (cmsg->cmsg_level != IPPROTO_IP ||
cmsg->cmsg_type != IP_PKTINFO)
{
continue;
}
struct in_pktinfo *pi = CMSG_DATA(cmsg);
// at this point, peeraddr is the source sockaddr
// pi->ipi_spec_dst is the destination in_addr
// pi->ipi_addr is the receiving interface in_addr
}