linux c ioctl接口实现本地IP,子网掩码的获取与设置

阅读: 评论:0

linux c ioctl接口实现本地IP,子网掩码的获取与设置

linux c ioctl接口实现本地IP,子网掩码的获取与设置

       linux c ioctl设置获取网关,路由信息 

        在日常开发中避免不了对本地网络的设置需求,一般情况下我们使用system接口进行临时的IP修改,或者open,rend write,操作/etc/network/interface这样的网络文件实现IP的永久修改,但是这样的修改方式相较来说比较低端。

        其实在linux中有一个万能接口:ioctl函数,该函数几乎可以设置linux下的一切状态,接下来我们来了解下ioctl设置网络IP 子网掩码的方式。

        我们首先需要了解网络接口结构体: struct ifreq;

        

#if __UAPI_DEF_IF_IFREQ
struct ifreq {
#define IFHWADDRLEN     6
        union
        {
                char    ifrn_name[IFNAMSIZ];      //网卡设备名:eth0,ens33等
        } ifr_ifrn;

        union {
                struct  sockaddr ifru_addr;           //ip地址
                struct  sockaddr ifru_dstaddr;      //目标IP地址
                struct  sockaddr ifru_broadaddr; //广播地址
                struct  sockaddr ifru_netmask;    //子网掩码
                struct  sockaddr ifru_hwaddr;      //MAC地址
                short   ifru_flags;                          //网络接口标记
                int     ifru_ivalue;                          //请求不通含义不同
                int     ifru_mtu;                              //网卡地址映射
                struct  ifmap ifru_map;                 //最大传输单元
                char    ifru_slave[IFNAMSIZ];      //占位符
                char    ifru_newname[IFNAMSIZ];//新名称
                void __user *   ifru_data;               //用户数据
                struct  if_settings ifru_settings;     //设备协议设置
        } ifr_ifru;
};
#endif /* __UAPI_DEF_IF_IFREQ */

        利用ioctl就可以获取或者设置上面的结构体信息,达到网络IP,子网掩码的获取与设置的目的:

当然是用ioctl接口少不了请求码;网络的相关请求码request如下:

类别请求码描述请求数据类型
套接口SIOCATMARK是否位于带外标记int
SIOCGPGRP获取套接口的进程id或者进程组idint
SIOCSPGRP设置套接口的进程id或者进程组idint
网络接口SIOCGIFCONF获取所有接口的清单struct ifconf
SIOCSIFADDR设置本地IP地址stuct ifreq
SIOCGIFADDR获取本地IP地址struct ifreq

SIOCSIFNETMASK

设置本地子网掩码struct ifreq

SIOCGIFNETMASK

获取本地子网掩码struct ifreq
SIOCSIFBRDADDR设置广播地址struct ifreq
SIOCGIFBRDADDR获取广播地址struct ifreq
SIOCSIFDSTADDR设置点对点地址struct ifreq
SIOCGIFDSTADDR获取点对点地址struct ifreq
SIOCGIFMTU获取接口MTUstruct ifreq
SIOCSIFFLAGS设置接口标识struct ifreq
SIOCGIFFLAGS获取接口标识struct ifreq
文件FIONBIN设置/清除非阻塞I/O标志int
FIOASYNC设置/清除信号驱动异步I/O标志int
FIONREAD获取接收缓存区中的字节数int

具体的获取和设置网络的IP实现如下:

        获取本地IP地址:

        

/********************************************************* 描述:*  获取ethName网卡的IP地址* 参数:*  ethName:网卡名称* 返回值:*  获取到的IP地址*********************************************************/std::string NetHelper::GetIPAdderss(std::string ethName)
{int ret;int fd;struct ifreq ifreq;char ip[12] = {0};std::string myip;std::string ERROR = "ERROR";//创建套接字fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);//填充网卡设备名属性,ethName:网卡设备名:eth0 ens33等memset(&ifreq, 0x00, sizeof(struct ifreq));strcpy(ifreq.ifr_name, ethName.c_str());//通过网卡名获取网卡网络数据保存至结构体ret = ioctl(fd, SIOCGIFADDR, &ifreq);if (ret < 0){perror("SIOCGIFADDR: ");close(fd);return ERROR;}if (ifreq.ifr_addr.sa_family != AF_INET){close(fd);return ERROR;}//将获取的ip地址转化为字符串struct sockaddr_in *addr = (struct sockaddr_in *)&(ifreq.ifr_addr);strcpy(ip, inet_ntoa(addr->sin_addr));myip = ip;printf("ip = %sn", ip);close(fd);return myip;
}

设置本地IP:

/********************************************************* 描述:*  设置ethName网卡的IP地址* 参数:*  ethName:网卡名称*  IP:要设置的IP地址* 返回值:*  设置成功返回:true,失败返回:false*********************************************************/
bool NetHelper::SetIPAdress(std::string ethName, std::string IP)
{int ret = 0;int fd = 0;int first = 0;int second = 0;int third = 0;int four = 0;struct ifreq ifreq;uint8_t ip[4] = {0};fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);if (fd < 0){std::cout << "create socket fd error!" << std::endl;close(fd);return false;}memset(&ifreq, 0, sizeof(ifreq));strcpy(ifreq.ifr_name, ethName.c_str());sscanf(IP.c_str(), "%d.%d.%d.%d", &first, &second, &third, &four);ip[0] = (uint8_t)first;ip[1] = (uint8_t)second;ip[2] = (uint8_t)third;ip[3] = (uint8_t)four;//设置IP属性ifreq.ifr_addr.sa_family = AF_INET;struct sockaddr_in *addr = (struct sockaddr_in *)&(ifreq.ifr_addr);memcpy(&(addr->sin_addr.s_addr), ip, 4);ret = ioctl(fd, SIOCSIFADDR, &ifreq);if (ret < 0){perror("set ip ioctl error:");close(fd);return false;}close(fd);return true;
}

获取子网掩码:

/********************************************************* 描述:*  获取ethName网卡的子网掩码* 参数:*  ethName:网卡名称* 返回值:*  获取到的子网掩码*********************************************************/
std::string NetHelper::GetNetmask(std::string ethName)
{int ret;int fd;struct ifreq ifreq;char mask[12] = {0};std::string mymask;std::string ERROR = "ERROR";fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);memset(&ifreq, 0x00, sizeof(struct ifreq));strcpy(ifreq.ifr_name, ethName.c_str());/** 获取子网掩码*/ret = ioctl(fd, SIOCGIFNETMASK, &ifreq);if (ret < 0){perror("SIOCGIFNETMASK: ");close(fd);return ERROR;}if (ifreq.ifr_addr.sa_family != AF_INET){close(fd);return ERROR;}struct sockaddr_in *addr = (struct sockaddr_in *)&(ifreq.ifr_addr);strcpy(mask, inet_ntoa(addr->sin_addr));mymask = mask;printf("mask = %sn", mask);close(fd);return mymask;
}

设置值子网掩码:

/********************************************************* 描述:*  设置ethName网卡的子网掩码* 参数:*  ethName:网卡名称*  mask:要设置的子网掩码* 返回值:*  设置成功返回:true,失败返回:false*********************************************************/
bool NetHelper::SetNetmask(std::string ethName, std::string mask)
{int ret = 0;int fd = 0;int first = 0;int second = 0;int third = 0;int four = 0;struct ifreq ifreq;uint8_t mymask[4] = {0};fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);if (fd < 0){std::cout << "create socket fd error!" << std::endl;close(fd);return false;}mymask[0] = (uint8_t)first;mymask[1] = (uint8_t)second;mymask[2] = (uint8_t)third;mymask[3] = (uint8_t)four;memset(&ifreq, 0, sizeof(ifreq));strcpy(ifreq.ifr_name, ethName.c_str());ifreq.ifr_addr.sa_family = AF_INET;struct sockaddr_in *addr = (struct sockaddr_in *)&(ifreq.ifr_addr);memcpy(&(addr->sin_addr.s_addr), mymask, 4);ret = ioctl(fd, SIOCSIFNETMASK, &ifreq);if (ret < 0){perror("maks set error : ");close(fd);return false;}printf("set ip : %d.%d.%d.%dn", (int)mymask[0], (int)mymask[1], (int)mymask[2], (int)mymask[3]);close(fd);return true;
}

        以上就是通过ioctl获取,设置网络信息的详细步骤,至于网关的设置和获取就涉及到路由相关,请参考我的下篇博文。

本文发布于:2024-02-04 12:03:04,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170706756255389.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:子网掩码   接口   linux   ioctl   IP
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23