<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    Linux下通過ioctl系統調用來獲取和設置網絡信息

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    #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,上網查也似乎沒能找到什么比較好的現成函數,所以最后只好自己寫了

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全