2011-03-15 2 views
6

Linux에서 IOCTL 인터페이스를 사용하여 IP 주소를 가져오고 설정하려고합니다. 성공적으로 가져 와서 설정할 수 있습니다. IP 주소를 설정하면 ifconfig eth0에 올바른 IP 주소가 표시되지만 시스템 연결이 끊어집니다. 즉 시스템이 ping 할 수 없습니다. 다음은 IP 주소 설정을위한 코드입니다. 제가 뭔가를 놓치고 있다면 알려주세요.SIOCSIFADDR ioctl을 사용하여 IP 주소 설정


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

답변

10

이것은 인터페이스 또는 별칭에 대해 작동합니다.

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 

완전한 소스 코드 :

#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; 
} 
올바른 작동을 확인하기 위해 "strace를"을 사용하여
5

아마도 인터페이스를 설정하는 것을 잊었습니까?

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