ifconfig 的简单实现

本文介绍了ifconfig命令如何通过ioctl系统调用对网络接口进行配置,包括查询和设置IP地址、子网掩码等参数,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般,用户在shell中使用ifconfig命令对网络接口进行参数配置,及接口的打开,关闭等操作。ifconfig实现网络接口配置的原理在于代表网络接口的结构体struct net_device的成员ip_ptr。前文已经讲过,ip_ptr实际指向的是一个结构体struct in_device,in_device有一个成员struct in_ifaddr *ifa_list,它指向一个链表,链表的每一项代表一个IP地址。对这个链表操作即可实现对网络接口的配置。
    网络接口的操作命令按功能可以分为两组,第一组为查询命令:SIOCGIFADDR,SIOCGIFBRDADDR,SIOCGIFDSTADDR, SIOCGIFNETMASK。分别用于查询网络接口的IP地址,广播地址,目的地址,子网掩码。第二组为设置命令:SIOCSIFADDR, SIOCSIFFLAGS,SIOCSIFBRDADDR,SIOCSIFNETMASK,SIOCSIFDSTADDR。分别用于设置网络接口的IP地址,标志位,广播地址,子网掩码,目的地址。这些命令所要查询和设置的信息全部在结构体struct in_ifaddr中。
    用户空间的应用程序通过系统调用ioctl使用这些命令,ioctl的函数原型如下:
        #include <sys/ioctl.h>
        int ioctl(int d, int request, ...);
    以上九个命令使用的参数为同一类型,即struct ifreq,其定义可在include/linux/if.h中找到。
    下面是两组命令在my_inet模块中的使用示例,因为整个my_inet模块代码还很不完善,通过my_inet模块新添加的IP地址并不能正常使用。
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include "my_inet.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main()
{
    struct ifreq req;
    strncpy( req.ifr_name, "eth0", IFNAMSIZ );
    struct sockaddr_in *sin;

    int fd = socket( MY_PF_INET, SOCK_RAW, MY_IPPROTO_ICMP );
    if( fd < 0 ){
        perror("error: ");
        return -1;
    }

    sin = (struct sockaddr_in *)&req.ifr_addr;
    if( ioctl( fd, SIOCGIFADDR, &req) == 0 )
        printf("%s/n", inet_ntoa(sin->sin_addr.s_addr) );
    else
        perror("ioctl error: ");

    sin = (struct sockaddr_in *)&req.ifr_broadaddr;
    if( ioctl( fd, SIOCGIFBRDADDR, &req) == 0 )
        printf("%s/n", inet_ntoa(sin->sin_addr.s_addr) );
    else
        perror("ioctl error: ");

    sin = (struct sockaddr_in *)&req.ifr_dstaddr;
    if( ioctl( fd, SIOCGIFDSTADDR, &req) == 0 )
        printf("%s/n", inet_ntoa(sin->sin_addr.s_addr) );
    else
        perror("ioctl error: ");

    sin = (struct sockaddr_in *)&req.ifr_netmask;
    if( ioctl( fd, SIOCGIFNETMASK, &req) == 0 )
        printf("%s/n", inet_ntoa(sin->sin_addr.s_addr) );
    else
        perror("ioctl error: ");

    close( fd );
    return 0;
}

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include "my_inet.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main()
{
    struct ifreq req;
    strncpy( req.ifr_name, "eth0:0", IFNAMSIZ );
    struct sockaddr_in *sin;

    int fd = socket( MY_PF_INET, SOCK_RAW, MY_IPPROTO_ICMP );
    if( fd < 0 ){
        perror("error: ");
        return -1;
    }

    sin = (struct sockaddr_in *)&req.ifr_addr;
    sin->sin_family = MY_PF_INET;
    if( inet_aton("172.16.48.10", &sin->sin_addr) == 0 ){
        perror("inet_aton error: ");
        return -1;
    }
    if( ioctl( fd, SIOCSIFADDR, &req ) == 0 ){
        printf("success!/n");
    }else{
        perror("ioctl failed: ");
    }

    req.ifr_flags = IFF_UP;
    if( ioctl( fd, SIOCSIFFLAGS, &req ) == 0 ){
        printf("success!/n");
    }else{
        perror("ioctl failed: ");
    }

    sin->sin_family = MY_PF_INET;
    if( inet_aton("172.16.48.255", &sin->sin_addr) == 0 ){
        perror("inet_aton error: ");
        return -1;
    }
    if( ioctl( fd, SIOCSIFBRDADDR, &req ) == 0 ){
        printf("success!/n");
    }else{
        perror("ioctl failed: ");
    }

    sin->sin_family = MY_PF_INET;
    if( inet_aton("255.255.255.0", &sin->sin_addr) == 0 ){
        perror("inet_aton error: ");
        return -1;
    }
    if( ioctl( fd, SIOCSIFNETMASK, &req ) == 0 ){
        printf("success!/n");
    }else{
        perror("ioctl failed: ");
    }

    close( fd );
    return 0;
}
    要想让上述的代码发挥实际的作用,只要把所有的MY_PF_INET改成PF_INET即可。功能再作增强,就是一个ifconfig程序了。

### 使用 `ifconfig` 配置网络接口硬件地址 在网络管理中,`ifconfig` 是一个常用的工具,可用于查看和修改网络接口的状态以及属性。其中,通过指定参数 `hw ether`,可以用来设置或显示网络接口的硬件地址(MAC 地址)。以下是关于如何使用该命令的具体说明: #### 命令语法 基本语法如下所示: ```bash ifconfig interface hw ether MAC_ADDRESS ``` - **interface**: 表示要操作的网络接口名称,例如 `eth0` 或 `wlan0`。 - **hw ether**: 指定更改的是硬件地址中的以太网部分。 - **MAC_ADDRESS**: 新的 MAC 地址,格式应为六个由冒号分隔的十六进制数对,例如 `00:1A:2B:3C:4D:5E`。 #### 设置新的硬件地址 如果需要临时更改某个网络接口的 MAC 地址,可以通过以下方式实现: 1. 关闭目标网络接口: ```bash ifconfig eth0 down ``` 2. 修改其硬件地址: ```bash ifconfig eth0 hw ether 00:AA:BB:CC:DD:EE ``` 3. 启动网络接口并验证新设置: ```bash ifconfig eth0 up ifconfig eth0 ``` 以上步骤会将 `eth0` 的 MAC 地址更改为 `00:AA:BB:CC:DD:EE` 并重新激活接口[^1]。 需要注意的是,这种更改仅在当前会话期间有效;重启系统后,原始 MAC 地址将会恢复。永久性改变通常涉及编辑特定于发行版的网络配置文件或者利用其他高级技术完成。 #### 显示现有硬件地址 当不带任何额外选项运行时,`ifconfig` 将打印出所有活动接口的信息,其中包括它们各自的物理层地址即 MAC 地址。例如执行下面这条简单的指令即可看到相关信息: ```bash ifconfig ``` 每一块已启用的网卡旁边都会附有对应的 HWaddr 字段来表示它的实际 MAC 地址[^2]。 另外提醒一点,在现代 Linux 发行版本里推荐采用 iproute2 工具集下的 `ip link` 子命令作为替代方案因为后者提供了更加一致性和扩展性的 API 接口设计[^3]。 ```bash ip link set dev eth0 address 00:AA:BB:CC:DD:EE ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值