c - 使用 SIOCSIFADDR ioctl 设置 IP 地址

标签 c ip ip-address ioctl

我正在尝试使用 Linux 上的 IOCTL 接口(interface)获取和设置 IP 地址。 我成功地获取并设置了它。当我设置IP地址时, ifconfig eth0 显示正确的 IP 地址,但随后系统断开连接。 即系统不可 ping 通。 这是我设置 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);

最佳答案

这适用于接口(interface)或别名。使用“strace”验证操作是否正确:

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

关于c - 使用 SIOCSIFADDR ioctl 设置 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5308090/

相关文章:

c - 解读现代 PC 上的 Dhrystone 基准测试结果

c# - 如何在asp.net中使用C#获取IP地址

java - 我如何检查IP是否在java中存在?

c - UNIX 先进先出 : the process hangs if I don't close the input side of the fifo

c - 在此代码中如何访问各个位?

c++ - fprintf 的成本

mysql - 有没有办法直接从 SELECT 查询中将 IP 与 IP+CIDR​​ 匹配?

mysql - 添加通配符IP如192.168.1.%时远程Mysql数据库访问错误

python - struct.error : argument for's' must be a bytes object

c++ - 与 127.0.0.1 和 INADDR_ANY 绑定(bind)