Linux下通过ioctl系统调用来获取和设置网络信息

简介: #include  #include  #include  #include  #include  #include  #include  #include  #include   // 获取IP地址,子网掩码,MAC地址 int GetLocalNetInfo(     const char* l...

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/ioctl.h> 
#include <net/if.h> 
#include <arpa/inet.h> 
#include <linux/netlink.h> 
#include <linux/rtnetlink.h> 
 
// 获取IP地址,子网掩码,MAC地址 
int GetLocalNetInfo( 
    const char* lpszEth, 
    char* szIpAddr, 
    char* szNetmask, 
    char* szMacAddr 


    int ret = 0; 
 
    struct ifreq req; 
    struct sockaddr_in* host = NULL; 
 
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if ( -1 == sockfd ) 
    { 
        return -1; 
    } 
 
    bzero(&req, sizeof(struct ifreq)); 
    strcpy(req.ifr_name, lpszEth); 
    if ( ioctl(sockfd, SIOCGIFADDR, &req) >= 0 ) 
    { 
        host = (struct sockaddr_in*)&req.ifr_addr; 
        strcpy(szIpAddr, inet_ntoa(host->sin_addr)); 
    } 
    else 
    { 
        ret = -1; 
    } 
 
    bzero(&req, sizeof(struct ifreq)); 
    strcpy(req.ifr_name, lpszEth); 
    if ( ioctl(sockfd, SIOCGIFNETMASK, &req) >= 0 ) 
    { 
        host = (struct sockaddr_in*)&req.ifr_addr; 
        strcpy(szNetmask, inet_ntoa(host->sin_addr)); 
    } 
    else 
    { 
        ret = -1; 
    } 
 
    bzero(&req, sizeof(struct ifreq)); 
    strcpy(req.ifr_name, lpszEth); 
    if ( ioctl(sockfd, SIOCGIFHWADDR, &req) >= 0 ) 
    { 
        sprintf( 
            szMacAddr, "%02x:%02x:%02x:%02x:%02x:%02x", 
            (unsigned char)req.ifr_hwaddr.sa_data[0], 
            (unsigned char)req.ifr_hwaddr.sa_data[1], 
            (unsigned char)req.ifr_hwaddr.sa_data[2], 
            (unsigned char)req.ifr_hwaddr.sa_data[3], 
            (unsigned char)req.ifr_hwaddr.sa_data[4], 
            (unsigned char)req.ifr_hwaddr.sa_data[5] 
        ); 
    } 
    else 
    { 
        ret = -1; 
    } 
 
    if ( sockfd != -1 ) 
    { 
        close(sockfd); 
        sockfd = -1; 
    } 
 
    return ret; 

 
// ------------------------------------------------------ 
 
#define BUFSIZE 8192 
 
struct route_info  

    char ifName[IF_NAMESIZE]; 
    u_int gateWay; 
    u_int srcAddr; 
    u_int dstAddr; 
}; 
 
static int ReadNlSock( 
    int sockFd, 
    char* bufPtr, 
    int seqNum, 
    int pId 


    struct nlmsghdr* nlHdr = NULL; 
    int readLen = 0, msgLen = 0; 
 
    while (true) 
    { 
        if ( (readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0 ) 
        { 
            return -1; 
        } 
 
        nlHdr = (struct nlmsghdr *)bufPtr; 
 
        if ( (NLMSG_OK(nlHdr, (unsigned int)readLen) == 0) 
                || (nlHdr->nlmsg_type == NLMSG_ERROR) ) 
        { 
            return -1; 
        } 
 
        if ( nlHdr->nlmsg_type == NLMSG_DONE ) 
        { 
            break; 
        } 
        else 
        { 
            bufPtr += readLen; 
            msgLen += readLen; 
        } 
 
        if ( (nlHdr->nlmsg_flags & NLM_F_MULTI) == 0 ) 
        { 
            break; 
        } 
 
        if ( (nlHdr->nlmsg_seq != (unsigned int)seqNum) 
                || (nlHdr->nlmsg_pid != (unsigned int)pId) ) 
        { 
            break; 
        } 
    } 
 
    return msgLen; 

 
static int ParseRoutes( 
    struct nlmsghdr* nlHdr, 
    struct route_info* rtInfo, 
    char* default_gateway 


    int rtLen = 0; 
    struct in_addr dst; 
    struct in_addr gate; 
    struct rtmsg* rtMsg = NULL; 
    struct rtattr* rtAttr = NULL; 
 
    rtMsg = (struct rtmsg*)NLMSG_DATA(nlHdr); 
 
    if ( (rtMsg->rtm_family != AF_INET) 
            || (rtMsg->rtm_table != RT_TABLE_MAIN) ) 
    { 
        return -1; 
    } 
 
    rtAttr = (struct rtattr*)RTM_RTA(rtMsg); 
    rtLen = RTM_PAYLOAD(nlHdr); 
    for ( ; RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen) ) 
    { 
        switch (rtAttr->rta_type) 
        { 
        case RTA_OIF: 
            if_indextoname(*(int*)RTA_DATA(rtAttr), rtInfo->ifName); 
            break; 
        case RTA_GATEWAY: 
            rtInfo->gateWay = *(u_int*)RTA_DATA(rtAttr); 
            break; 
        case RTA_PREFSRC: 
            rtInfo->srcAddr = *(u_int*)RTA_DATA(rtAttr); 
            break; 
        case RTA_DST: 
            rtInfo->dstAddr = *(u_int*)RTA_DATA(rtAttr); 
            break; 
        } 
    } 
 
    dst.s_addr = rtInfo->dstAddr; 
    if (strstr((char*)inet_ntoa(dst), "0.0.0.0")) 
    { 
        gate.s_addr = rtInfo->gateWay; 
        strcpy(default_gateway, (char*)inet_ntoa(gate)); 
    } 
 
    return 0; 

 
// 获取默认网关 
int GetDefaultGateway( 
    const char* lpszEth, 
    char* szDefaultGateway 


    static char szGatewayTemp[32] = {0}; 
    static char msgBuf[BUFSIZE] = {0}; 
    static struct route_info ri; 
 
    int ret = -1; 
 
    struct nlmsghdr* nlMsg = NULL; 
    struct rtmsg* rtMsg = NULL; 
    struct route_info* rtInfo = &ri; 
 
    int len = 0, msgSeq = 0; 
 
    int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); 
    if ( -1 == sock ) 
    { 
        goto END; 
    } 
 
    nlMsg = (struct nlmsghdr*)msgBuf; 
    rtMsg = (struct rtmsg*)NLMSG_DATA(nlMsg); 
 
    nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); 
    nlMsg->nlmsg_type = RTM_GETROUTE; 
    nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; 
    nlMsg->nlmsg_seq = msgSeq++; 
    nlMsg->nlmsg_pid = getpid(); 
 
    if ( send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0 ) 
    { 
        goto END; 
    } 
 
    if ( (len = ReadNlSock(sock, msgBuf, msgSeq, getpid())) < 0 ) 
    { 
        goto END; 
    } 
 
    if ( rtInfo != NULL ) 
    { 
        for ( ; NLMSG_OK(nlMsg, (unsigned int)len); nlMsg = NLMSG_NEXT(nlMsg, len) ) 
        { 
            memset(szGatewayTemp, 0, 64); 
            memset(rtInfo, 0, sizeof(struct route_info)); 
            if ( 0 == ParseRoutes(nlMsg, rtInfo, szGatewayTemp) ) 
            { 
                if ( strcmp(rtInfo->ifName, lpszEth) == 0 
                        && strcmp(szGatewayTemp, "0.0.0.0") != 0 
                        && strlen(szGatewayTemp) > 0 ) 
                { 
                    strcpy(szDefaultGateway, szGatewayTemp); 
                    ret = 0; 
                }  
            } 
        } 
    } 
 
END: 
 
    if ( sock != -1 ) 
    { 
        close(sock); 
        sock = -1; 
    } 
 
    return ret; 

 
// ------------------------------------------------------ 
 
// 设置IP地址和子网掩码 
int SetLocalNetInfo( 
    const char* lpszEth, 
    const char* lpszIpAddr, 
    const char* lpszNetmask 


    int ret = -1; 
 
    struct ifreq req; 
    struct sockaddr_in* host = NULL; 
 
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if ( -1 == sockfd ) 
    { 
        goto END; 
    } 
 
    bzero(&req, sizeof(struct ifreq)); 
    strcpy(req.ifr_name, lpszEth); 
    host = (struct sockaddr_in*)&req.ifr_addr; 
    host->sin_family = AF_INET; 
    if ( 1 != inet_pton(AF_INET, lpszIpAddr, &(host->sin_addr)) ) 
    { 
        goto END; 
    } 
    if ( ioctl(sockfd, SIOCSIFADDR, &req) < 0 ) 
    { 
        goto END; 
    } 
 
    bzero(&req, sizeof(struct ifreq)); 
    strcpy(req.ifr_name, lpszEth); 
    host = (struct sockaddr_in*)&req.ifr_addr; 
    host->sin_family = AF_INET; 
    if ( 1 != inet_pton(AF_INET, lpszNetmask, &(host->sin_addr)) ) 
    { 
        goto END; 
    } 
    if ( ioctl(sockfd, SIOCSIFNETMASK, &req) < 0 ) 
    { 
        goto END; 
    } 
 
    ret = 0; 
 
END: 
 
    if ( sockfd != -1 ) 
    { 
        close(sockfd); 
        sockfd = -1; 
    } 
 
    return ret; 

 
// 设置指定网口的mtu值 
int SetMTU(const char* lpszEth, unsigned int mtu) 

    int ret = -1; 
 
    struct ifreq ifr; 
 
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if ( -1 == sockfd ) 
    { 
        goto END; 
    } 
 
    strcpy(ifr.ifr_name, lpszEth); 
    ifr.ifr_ifru.ifru_mtu = mtu; 
    if ( ioctl(sockfd, SIOCSIFMTU, &ifr) < 0 ) 
    { 
        goto END; 
    } 
 
    ret = 0; 
 
END: 
 
    if ( sockfd != -1 ) 
    { 
        close(sockfd); 
        sockfd = -1; 
    } 
 
    return ret; 

 
// 关闭指定网口 
int SetIfDown(const char* lpszEth) 

    int ret = -1; 
 
    struct ifreq ifr; 
 
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if ( -1 == sockfd ) 
    { 
        goto END; 
    } 
 
    strcpy(ifr.ifr_name, lpszEth); 
 
    if ( ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0 ) 
    { 
        goto END; 
    } 
 
    ifr.ifr_flags &= ~IFF_UP; 
 
    if ( ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0 ) 
    { 
        goto END; 
    } 
 
    ret = 0; 
 
END: 
 
    if ( sockfd != -1 ) 
    { 
        close(sockfd); 
        sockfd = -1; 
    } 
 
    return ret; 

 
// 打开指定网口 
int SetIfUp(const char* lpszEth) 

    int ret = -1; 
 
    struct ifreq ifr; 
 
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if ( -1 == sockfd ) 
    { 
        goto END; 
    } 
 
    strcpy(ifr.ifr_name, lpszEth); 
 
    if ( ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0 ) 
    { 
        goto END; 
    } 
 
    ifr.ifr_flags |= IFF_UP; 
 
    if ( ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0 ) 
    { 
        goto END; 
    } 
 
    ret = 0; 
 
END: 
 
    if ( sockfd != -1 ) 
    { 
        close(sockfd); 
        sockfd = -1; 
    } 
 
    return ret; 

 
小记:前端时间因为需要在Linux下获取和设置网络信息,所以就简单的学习了一下,写出了以上的几个工具函数。最开始是用了一种比较土的方式,就是通过system函数执行命令,然后命令是通过调用ifconfig这个程序来到达设置网络信息的目的,但是感觉很别扭,还是应该使用相应的API比较好,但是又没有找到Linux有对应的API,上网查也似乎没能找到什么比较好的现成函数,所以最后只好自己写了

目录
相关文章
|
9月前
|
Ubuntu Linux Anolis
Linux系统禁用swap
本文介绍了在新版本Linux系统(如Ubuntu 20.04+、CentOS Stream、openEuler等)中禁用swap的两种方法。传统通过注释/etc/fstab中swap行的方式已失效,现需使用systemd管理swap.target服务或在/etc/fstab中添加noauto参数实现禁用。方法1通过屏蔽swap.target适用于新版系统,方法2通过修改fstab挂载选项更通用,兼容所有系统。
857 3
Linux系统禁用swap
|
9月前
|
Linux
Linux系统修改网卡名为eth0、eth1
在Linux系统中,可通过修改GRUB配置和创建Udev规则或使用systemd链接文件,将网卡名改为`eth0`、`eth1`等传统命名方式,适用于多种发行版并支持多网卡配置。
1436 3
|
Ubuntu Linux 网络安全
Linux系统初始化脚本
一款支持Rocky、CentOS、Ubuntu、Debian、openEuler等主流Linux发行版的系统初始化Shell脚本,涵盖网络配置、主机名设置、镜像源更换、安全加固等多项功能,适配单/双网卡环境,支持UEFI引导,提供多版本下载与持续更新。
924 3
Linux系统初始化脚本
|
9月前
|
安全 Linux Shell
Linux系统提权方式全面总结:从基础到高级攻防技术
本文全面总结Linux系统提权技术,涵盖权限体系、配置错误、漏洞利用、密码攻击等方法,帮助安全研究人员掌握攻防技术,提升系统防护能力。
1076 1
|
9月前
|
监控 安全 Linux
Linux系统提权之计划任务(Cron Jobs)提权
在Linux系统中,计划任务(Cron Jobs)常用于定时执行脚本或命令。若配置不当,攻击者可利用其提权至root权限。常见漏洞包括可写的Cron脚本、目录、通配符注入及PATH变量劫持。攻击者通过修改脚本、创建恶意任务或注入命令实现提权。系统管理员应遵循最小权限原则、使用绝对路径、避免通配符、设置安全PATH并定期审计,以防范此类攻击。
1367 1
|
SQL 监控 安全
网络安全与信息安全:漏洞、加密与安全意识
随着互联网的迅猛发展,网络安全和信息安全问题日益受到关注。本文深入探讨了网络安全漏洞、加密技术以及提高个人和组织的安全意识的重要性。通过分析常见的网络攻击手段如缓冲区溢出、SQL注入等,揭示了计算机系统中存在的缺陷及其潜在威胁。同时,详细介绍了对称加密和非对称加密算法的原理及应用场景,强调了数字签名和数字证书在验证信息完整性中的关键作用。此外,还讨论了培养良好上网习惯、定期备份数据等提升安全意识的方法,旨在帮助读者更好地理解和应对复杂的网络安全挑战。
|
SQL 安全 网络安全
网络安全与信息安全:知识分享####
【10月更文挑战第21天】 随着数字化时代的快速发展,网络安全和信息安全已成为个人和企业不可忽视的关键问题。本文将探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供一些实用的建议,帮助读者提高自身的网络安全防护能力。 ####
493 17
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
371 10
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的内容,并提供一些实用的代码示例。通过阅读本文,您将了解到如何保护自己的网络安全,以及如何提高自己的信息安全意识。
361 10