2011-03-15 23 views
6

Estoy tratando de obtener y configurar la dirección IP utilizando la interfaz IOCTL en Linux. Lo puedo obtener y configurar con éxito. Cuando configuro la dirección IP, ifconfig eth0 muestra la dirección IP correcta, pero luego el sistema se desconecta. es decir, el sistema no se puede hacer ping. Aquí está mi código para configurar la dirección IP. Por favor, avíseme si me falta algo.Establecer la dirección IP utilizando SIOCSIFADDR ioctl


    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); 

Respuesta

10

Esto funcionará para interfaces o alias. Use "strace" para verificar el correcto funcionamiento:

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; 
} 
5

Quizás se haya olvidado de configurar la interfaz para arriba?

ioctl(sockfd, SIOCGIFFLAGS, &ifr); 
ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 
ioctl(sockfd, SIOCSIFFLAGS, &ifr);