2011-07-11 30 views
13

Bằng cách sử dụng strace và ifconfig, tôi thấy rằng tôi có thể thiết lập địa chỉ IP theo cách này:Làm thế nào để thiết lập địa chỉ IP từ C trong 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; 
} 

Nhưng tôi không phải là rất hài lòng với giải pháp này:

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

Cách "đúng" để thực hiện việc này là gì?

+1

Đây có phải là điều bạn muốn làm thường xuyên không ?? Tôi không thể tưởng tượng có một API 'lập trình' tốt đẹp cho nó, đặc biệt nếu đó là cách ifconfig làm điều đó. (Tại sao không đọc nguồn ifconfig?) Nó sẽ không an toàn hơn để thay đổi các giá trị trong/etc/sysconfig/network (hoặc bất cứ nơi nào distro của bạn giữ nó) và khởi động lại các giao diện mạng? – Rup

+0

Mã không hoạt động trên máy openSUSE của tôi. Lệnh Ifconfig tiếp tục hiển thị cùng một IP mỗi khi tôi chạy chương trình – 3bdalla

+0

Có vẻ như nó cần quyền root. Nó đã làm việc. Btw tại sao bạn không hài lòng với giải pháp mà bạn đã đề cập – 3bdalla

Trả lời

10

"đúng" cách cho IPv4 không ma thuật 2:

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

Để sử dụng IPv6, đúc nó vào

+0

Mã không hoạt động trên máy openSUSE của tôi. Lệnh Ifconfig tiếp tục hiển thị cùng một IP mỗi khi tôi chạy chương trình sau khi cập nhật. – 3bdalla

+1

Dường như nó cần quyền root. Nó đã làm việc. Btw sự khác biệt giữa gợi ý của bạn và hàm ban đầu trong câu hỏi là gì? – 3bdalla

+0

ioctl có xử lý cài đặt địa chỉ IPv6 không? – Youda008

4

"đúng" cách để làm điều đó là để đẻ trứng một bản sao của iproute2 "ip" chương trình (trong/sbin/ip) với các tham số có liên quan.

Giao diện ioctl thường bị lỗi thời và không cho phép bạn định cấu hình tất cả các thông số (ví dụ: bí danh IP không được đặt tên).

Ngay cả các trình tiện ích như dhcpcd cần phải thay đổi địa chỉ IP, thường làm bằng cách sinh ra một chương trình bên ngoài ... nó không giống như bạn thường xuyên làm điều đó.

+3

iproute2 sau đó làm gì, nó phải liên lạc với hạt nhân tại một số điểm – Allan

+0

Nó sử dụng giao thức netlink hạt nhân, điều này thật sự kinh khủng. Đừng làm thế. – MarkR

Các vấn đề liên quan