2011-07-11 16 views
13

Korzystając strace i ifconfig, stwierdziliśmy, że mogę ustawić adres IP w ten sposób:Jak ustawić adres IP z C w linux

#include <sys/ioctl.h> 
#include <arpa/inet.h> 
#include <net/if.h> 
#include <string.h> 

int main(int argc, const char *argv[]) { 
    struct ifreq ifr; 
    const char * name = "eth1"; 
    int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 

    strncpy(ifr.ifr_name, name, IFNAMSIZ); 

    ifr.ifr_addr.sa_family = AF_INET; 
    inet_pton(AF_INET, "10.12.0.1", ifr.ifr_addr.sa_data + 2); 
    ioctl(fd, SIOCSIFADDR, &ifr); 

    inet_pton(AF_INET, "255.255.0.0", ifr.ifr_addr.sa_data + 2); 
    ioctl(fd, SIOCSIFNETMASK, &ifr); 

    ioctl(fd, SIOCGIFFLAGS, &ifr); 
    strncpy(ifr.ifr_name, name, IFNAMSIZ); 
    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); 

    ioctl(fd, SIOCSIFFLAGS, &ifr); 

    return 0; 
} 

Ale nie jestem bardzo zadowolony z tego rozwiązania:

inet_pton(AF_INET, "10.12.0.1", ifr.ifr_addr.sa_data + 2); 

Jaki jest "właściwy" sposób robienia tego?

+1

Czy jest to coś, czego można się spodziewać często? Nie mogę sobie wyobrazić, że jest tam "ładny" programistyczny interfejs API, szczególnie jeśli tak robi ifconfig. (Dlaczego nie przeczytać źródła ifconfig?) Czy nie byłoby bezpieczniej zmienić wartości w/etc/sysconfig/network (lub gdziekolwiek znajduje się twoja dystrybucja) i zrestartować interfejsy sieciowe? – Rup

+0

Ten kod nie działa na moim komputerze z OpenSUSE. Polecenie ifconfig wyświetla ten sam adres IP za każdym razem, gdy uruchamiam program. – 3bdalla

+0

Wygląda na to, że potrzebuje uprawnień root'a. Zadziałało. Btw, dlaczego nie jesteś zadowolony z rozwiązania, o którym wspomniałeś – 3bdalla

Odpowiedz

10

"poprawny" sposób dla IPv4 bez magii +2:

struct sockaddr_in* addr = (struct sockaddr_in*)&ifr.ifr_addr; 
inet_pton(AF_INET, "10.12.0.1", &addr->sin_addr); 

Aby korzystać z protokołu IPv6, oddanych do

+0

Ten kod nie działa na moim komputerze z OpenSUSE. Polecenie ifconfig wyświetla ten sam adres IP za każdym razem, gdy uruchamiam program po aktualizacji. – 3bdalla

+1

Wygląda na to, że potrzebuje uprawnień root'a. Zadziałało. Jaka jest różnica między Twoją sugestią a oryginalną funkcją pytania? – 3bdalla

+0

czy ioctl będzie obsługiwał ustawianie adresu IPv6? – Youda008

4

"poprawny" sposób to zrobić jest ikra kopię iproute2 "ip" program (w/sbin/ip) z odpowiednimi parametrami.

Interfejs ioctl jest zwykle przestarzały i nie pozwala skonfigurować wszystkich parametrów (na przykład nienazwanych aliasów IP).

Nawet daemony, takie jak dhcpcd, które wymagają zmiany adresu IP, robią to zwykle poprzez utworzenie zewnętrznego programu ... to nie jest tak, że robisz to bardzo często.

+3

Co robi iproute2, to musi komunikować się z jądrem w pewnym momencie – Allan

+0

Używa protokołu netlink, który jest naprawdę okropny. Nie rób tego. – MarkR