Establecer la dirección IP usando SioCsifaddr IOCTL
-
24-10-2019 - |
Pregunta
Estoy tratando de obtener y configurar la dirección IP usando la interfaz IOCTL en Linux. Puedo obtener con éxito obtenerlo y configurarlo. Cuando configure la dirección IP,ifconfig eth0
muestra una dirección IP adecuada, pero luego el sistema se desconecta. El sistema de IE no es pingable. Aquí está mi código para configurar la dirección IP. Por favor avíseme si me estoy perdiendo algo.
struct ifreq ifr;
in_addr_t in_addr;
struct sockaddr_in sin;
memset(&ifr, 0, sizeof(struct ifreq));
memset(&sin, 0, sizeof(struct sockaddr_in));
sockfd = socket(AF_INET, SOCK_STREAM, 0);
sprintf(ifr.ifr_name, "eth0");
in_addr = inet_addr("192.168.101.17");
sin.sin_addr.s_addr = in_addr;
memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
io = ioctl(sockfd, SIOCSIFADDR, (char *)&ifr);
Solución
Esto funcionará para interfaces o alias. Use "Strace" para verificar la operación correcta:
strace ./ifconfig
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 5
ioctl(5, SIOCSIFADDR, {ifr_name="eth0:8", ifr_addr={AF_INET, inet_addr("192.168.1.202")}}) = 0
ioctl(5, SIOCGIFFLAGS, {ifr_name="eth0:8", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
ioctl(5, SIOCSIFFLAGS, {ifr_name="eth0:8", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
close(5) = 0
Código fuente completo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> /* offsetof */
#include <net/if.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <asm/types.h>
#include <linux/if_ether.h>
#endif
#define IFNAME "eth0:2"
#define HOST "192.168.1.204"
#define ifreq_offsetof(x) offsetof(struct ifreq, x)
int main(int argc, char **argv) {
struct ifreq ifr;
struct sockaddr_in sai;
int sockfd; /* socket fd we use to manipulate stuff with */
int selector;
unsigned char mask;
char *p;
/* Create a channel to the NET kernel. */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
/* get interface name */
strncpy(ifr.ifr_name, IFNAME, IFNAMSIZ);
memset(&sai, 0, sizeof(struct sockaddr));
sai.sin_family = AF_INET;
sai.sin_port = 0;
sai.sin_addr.s_addr = inet_addr(HOST);
p = (char *) &sai;
memcpy( (((char *)&ifr + ifreq_offsetof(ifr_addr) )),
p, sizeof(struct sockaddr));
ioctl(sockfd, SIOCSIFADDR, &ifr);
ioctl(sockfd, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
// ifr.ifr_flags &= ~selector; // unset something
ioctl(sockfd, SIOCSIFFLAGS, &ifr);
close(sockfd);
return 0;
}
Otros consejos
¿Quizás olvidaste establecer la interfaz?
ioctl(sockfd, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
ioctl(sockfd, SIOCSIFFLAGS, &ifr);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow