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

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

 http://blog.csdn.net/leng_que/article/details/7200690

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <unistd.h>  
  5. #include <sys/ioctl.h>  
  6. #include <net/if.h>  
  7. #include <arpa/inet.h>  
  8. #include <linux/netlink.h>  
  9. #include <linux/rtnetlink.h>  
  10.   
  11. // 获取IP地址,子网掩码,MAC地址  
  12. int GetLocalNetInfo(  
  13.     const char* lpszEth,  
  14.     char* szIpAddr,  
  15.     char* szNetmask,  
  16.     char* szMacAddr  
  17. )  
  18. {  
  19.     int ret = 0;  
  20.   
  21.     struct ifreq req;  
  22.     struct sockaddr_in* host = NULL;  
  23.   
  24.     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  25.     if ( -1 == sockfd )  
  26.     {  
  27.         return -1;  
  28.     }  
  29.   
  30.     bzero(&req, sizeof(struct ifreq));  
  31.     strcpy(req.ifr_name, lpszEth);  
  32.     if ( ioctl(sockfd, SIOCGIFADDR, &req) >= 0 )  
  33.     {  
  34.         host = (struct sockaddr_in*)&req.ifr_addr;  
  35.         strcpy(szIpAddr, inet_ntoa(host->sin_addr));  
  36.     }  
  37.     else  
  38.     {  
  39.         ret = -1;  
  40.     }  
  41.   
  42.     bzero(&req, sizeof(struct ifreq));  
  43.     strcpy(req.ifr_name, lpszEth);  
  44.     if ( ioctl(sockfd, SIOCGIFNETMASK, &req) >= 0 )  
  45.     {  
  46.         host = (struct sockaddr_in*)&req.ifr_addr;  
  47.         strcpy(szNetmask, inet_ntoa(host->sin_addr));  
  48.     }  
  49.     else  
  50.     {  
  51.         ret = -1;  
  52.     }  
  53.   
  54.     bzero(&req, sizeof(struct ifreq));  
  55.     strcpy(req.ifr_name, lpszEth);  
  56.     if ( ioctl(sockfd, SIOCGIFHWADDR, &req) >= 0 )  
  57.     {  
  58.         sprintf(  
  59.             szMacAddr, "%02x:%02x:%02x:%02x:%02x:%02x",  
  60.             (unsigned char)req.ifr_hwaddr.sa_data[0],  
  61.             (unsigned char)req.ifr_hwaddr.sa_data[1],  
  62.             (unsigned char)req.ifr_hwaddr.sa_data[2],  
  63.             (unsigned char)req.ifr_hwaddr.sa_data[3],  
  64.             (unsigned char)req.ifr_hwaddr.sa_data[4],  
  65.             (unsigned char)req.ifr_hwaddr.sa_data[5]  
  66.         );  
  67.     }  
  68.     else  
  69.     {  
  70.         ret = -1;  
  71.     }  
  72.   
  73.     if ( sockfd != -1 )  
  74.     {  
  75.         close(sockfd);  
  76.         sockfd = -1;  
  77.     }  
  78.   
  79.     return ret;  
  80. }  
  81.   
  82. // ------------------------------------------------------  
  83.   
  84. #define BUFSIZE 8192  
  85.   
  86. struct route_info  
  87. {  
  88.     char ifName[IF_NAMESIZE];  
  89.     u_int gateWay;  
  90.     u_int srcAddr;  
  91.     u_int dstAddr;  
  92. };  
  93.   
  94. static int ReadNlSock(  
  95.     int sockFd,  
  96.     char* bufPtr,  
  97.     int seqNum,  
  98.     int pId  
  99. )  
  100. {  
  101.     struct nlmsghdr* nlHdr = NULL;  
  102.     int readLen = 0, msgLen = 0;  
  103.   
  104.     while (true)  
  105.     {  
  106.         if ( (readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0 )  
  107.         {  
  108.             return -1;  
  109.         }  
  110.   
  111.         nlHdr = (struct nlmsghdr *)bufPtr;  
  112.   
  113.         if ( (NLMSG_OK(nlHdr, (unsigned int)readLen) == 0)  
  114.                 || (nlHdr->nlmsg_type == NLMSG_ERROR) )  
  115.         {  
  116.             return -1;  
  117.         }  
  118.   
  119.         if ( nlHdr->nlmsg_type == NLMSG_DONE )  
  120.         {  
  121.             break;  
  122.         }  
  123.         else  
  124.         {  
  125.             bufPtr += readLen;  
  126.             msgLen += readLen;  
  127.         }  
  128.   
  129.         if ( (nlHdr->nlmsg_flags & NLM_F_MULTI) == 0 )  
  130.         {  
  131.             break;  
  132.         }  
  133.   
  134.         if ( (nlHdr->nlmsg_seq != (unsigned int)seqNum)  
  135.                 || (nlHdr->nlmsg_pid != (unsigned int)pId) )  
  136.         {  
  137.             break;  
  138.         }  
  139.     }  
  140.   
  141.     return msgLen;  
  142. }  
  143.   
  144. static int ParseRoutes(  
  145.     struct nlmsghdr* nlHdr,  
  146.     struct route_info* rtInfo,  
  147.     char* default_gateway  
  148. )  
  149. {  
  150.     int rtLen = 0;  
  151.     struct in_addr dst;  
  152.     struct in_addr gate;  
  153.     struct rtmsg* rtMsg = NULL;  
  154.     struct rtattr* rtAttr = NULL;  
  155.   
  156.     rtMsg = (struct rtmsg*)NLMSG_DATA(nlHdr);  
  157.   
  158.     if ( (rtMsg->rtm_family != AF_INET)  
  159.             || (rtMsg->rtm_table != RT_TABLE_MAIN) )  
  160.     {  
  161.         return -1;  
  162.     }  
  163.   
  164.     rtAttr = (struct rtattr*)RTM_RTA(rtMsg);  
  165.     rtLen = RTM_PAYLOAD(nlHdr);  
  166.     for ( ; RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen) )  
  167.     {  
  168.         switch (rtAttr->rta_type)  
  169.         {  
  170.         case RTA_OIF:  
  171.             if_indextoname(*(int*)RTA_DATA(rtAttr), rtInfo->ifName);  
  172.             break;  
  173.         case RTA_GATEWAY:  
  174.             rtInfo->gateWay = *(u_int*)RTA_DATA(rtAttr);  
  175.             break;  
  176.         case RTA_PREFSRC:  
  177.             rtInfo->srcAddr = *(u_int*)RTA_DATA(rtAttr);  
  178.             break;  
  179.         case RTA_DST:  
  180.             rtInfo->dstAddr = *(u_int*)RTA_DATA(rtAttr);  
  181.             break;  
  182.         }  
  183.     }  
  184.   
  185.     dst.s_addr = rtInfo->dstAddr;  
  186.     if (strstr((char*)inet_ntoa(dst), "0.0.0.0"))  
  187.     {  
  188.         gate.s_addr = rtInfo->gateWay;  
  189.         strcpy(default_gateway, (char*)inet_ntoa(gate));  
  190.     }  
  191.   
  192.     return 0;  
  193. }  
  194.   
  195. // 获取默认网关  
  196. int GetDefaultGateway(  
  197.     const char* lpszEth,  
  198.     char* szDefaultGateway  
  199. )  
  200. {  
  201.     static char szGatewayTemp[32] = {0};  
  202.     static char msgBuf[BUFSIZE] = {0};  
  203.     static struct route_info ri;  
  204.   
  205.     int ret = -1;  
  206.   
  207.     struct nlmsghdr* nlMsg = NULL;  
  208.     struct rtmsg* rtMsg = NULL;  
  209.     struct route_info* rtInfo = &ri;  
  210.   
  211.     int len = 0, msgSeq = 0;  
  212.   
  213.     int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);  
  214.     if ( -1 == sock )  
  215.     {  
  216.         goto END;  
  217.     }  
  218.   
  219.     nlMsg = (struct nlmsghdr*)msgBuf;  
  220.     rtMsg = (struct rtmsg*)NLMSG_DATA(nlMsg);  
  221.   
  222.     nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));  
  223.     nlMsg->nlmsg_type = RTM_GETROUTE;  
  224.     nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;  
  225.     nlMsg->nlmsg_seq = msgSeq++;  
  226.     nlMsg->nlmsg_pid = getpid();  
  227.   
  228.     if ( send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0 )  
  229.     {  
  230.         goto END;  
  231.     }  
  232.   
  233.     if ( (len = ReadNlSock(sock, msgBuf, msgSeq, getpid())) < 0 )  
  234.     {  
  235.         goto END;  
  236.     }  
  237.   
  238.     if ( rtInfo != NULL )  
  239.     {  
  240.         for ( ; NLMSG_OK(nlMsg, (unsigned int)len); nlMsg = NLMSG_NEXT(nlMsg, len) )  
  241.         {  
  242.             memset(szGatewayTemp, 0, 32);  
  243.             memset(rtInfo, 0, sizeof(struct route_info));  
  244.             if ( 0 == ParseRoutes(nlMsg, rtInfo, szGatewayTemp) )  
  245.             {  
  246.                 if ( strcmp(rtInfo->ifName, lpszEth) == 0  
  247.                         && strcmp(szGatewayTemp, "0.0.0.0") != 0  
  248.                         && strlen(szGatewayTemp) > 0 )  
  249.                 {  
  250.                     strcpy(szDefaultGateway, szGatewayTemp);  
  251.                     ret = 0;  
  252.                 }  
  253.             }  
  254.         }  
  255.     }  
  256.   
  257. END:  
  258.   
  259.     if ( sock != -1 )  
  260.     {  
  261.         close(sock);  
  262.         sock = -1;  
  263.     }  
  264.   
  265.     return ret;  
  266. }  
  267.   
  268. // ------------------------------------------------------  
  269.   
  270. // 设置IP地址和子网掩码  
  271. int SetLocalNetInfo(  
  272.     const char* lpszEth,  
  273.     const char* lpszIpAddr,  
  274.     const char* lpszNetmask  
  275. )  
  276. {  
  277.     int ret = -1;  
  278.   
  279.     struct ifreq req;  
  280.     struct sockaddr_in* host = NULL;  
  281.   
  282.     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  283.     if ( -1 == sockfd )  
  284.     {  
  285.         goto END;  
  286.     }  
  287.   
  288.     bzero(&req, sizeof(struct ifreq));  
  289.     strcpy(req.ifr_name, lpszEth);  
  290.     host = (struct sockaddr_in*)&req.ifr_addr;  
  291.     host->sin_family = AF_INET;  
  292.     if ( 1 != inet_pton(AF_INET, lpszIpAddr, &(host->sin_addr)) )  
  293.     {  
  294.         goto END;  
  295.     }  
  296.     if ( ioctl(sockfd, SIOCSIFADDR, &req) < 0 )  
  297.     {  
  298.         goto END;  
  299.     }  
  300.   
  301.     bzero(&req, sizeof(struct ifreq));  
  302.     strcpy(req.ifr_name, lpszEth);  
  303.     host = (struct sockaddr_in*)&req.ifr_addr;  
  304.     host->sin_family = AF_INET;  
  305.     if ( 1 != inet_pton(AF_INET, lpszNetmask, &(host->sin_addr)) )  
  306.     {  
  307.         goto END;  
  308.     }  
  309.     if ( ioctl(sockfd, SIOCSIFNETMASK, &req) < 0 )  
  310.     {  
  311.         goto END;  
  312.     }  
  313.   
  314.     ret = 0;  
  315.   
  316. END:  
  317.   
  318.     if ( sockfd != -1 )  
  319.     {  
  320.         close(sockfd);  
  321.         sockfd = -1;  
  322.     }  
  323.   
  324.     return ret;  
  325. }  
  326.   
  327. // 设置指定网口的mtu值  
  328. int SetMTU(const char* lpszEth, unsigned int mtu)  
  329. {  
  330.     int ret = -1;  
  331.   
  332.     struct ifreq ifr;  
  333.   
  334.     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  335.     if ( -1 == sockfd )  
  336.     {  
  337.         goto END;  
  338.     }  
  339.   
  340.     strcpy(ifr.ifr_name, lpszEth);  
  341.     ifr.ifr_ifru.ifru_mtu = mtu;  
  342.     if ( ioctl(sockfd, SIOCSIFMTU, &ifr) < 0 )  
  343.     {  
  344.         goto END;  
  345.     }  
  346.   
  347.     ret = 0;  
  348.   
  349. END:  
  350.   
  351.     if ( sockfd != -1 )  
  352.     {  
  353.         close(sockfd);  
  354.         sockfd = -1;  
  355.     }  
  356.   
  357.     return ret;  
  358. }  
  359.   
  360. // 关闭指定网口  
  361. int SetIfDown(const char* lpszEth)  
  362. {  
  363.     int ret = -1;  
  364.   
  365.     struct ifreq ifr;  
  366.   
  367.     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  368.     if ( -1 == sockfd )  
  369.     {  
  370.         goto END;  
  371.     }  
  372.   
  373.     strcpy(ifr.ifr_name, lpszEth);  
  374.   
  375.     if ( ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0 )  
  376.     {  
  377.         goto END;  
  378.     }  
  379.   
  380.     ifr.ifr_flags &= ~IFF_UP;  
  381.   
  382.     if ( ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0 )  
  383.     {  
  384.         goto END;  
  385.     }  
  386.   
  387.     ret = 0;  
  388.   
  389. END:  
  390.   
  391.     if ( sockfd != -1 )  
  392.     {  
  393.         close(sockfd);  
  394.         sockfd = -1;  
  395.     }  
  396.   
  397.     return ret;  
  398. }  
  399.   
  400. // 打开指定网口  
  401. int SetIfUp(const char* lpszEth)  
  402. {  
  403.     int ret = -1;  
  404.   
  405.     struct ifreq ifr;  
  406.   
  407.     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
  408.     if ( -1 == sockfd )  
  409.     {  
  410.         goto END;  
  411.     }  
  412.   
  413.     strcpy(ifr.ifr_name, lpszEth);  
  414.   
  415.     if ( ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0 )  
  416.     {  
  417.         goto END;  
  418.     }  
  419.   
  420.     ifr.ifr_flags |= IFF_UP;  
  421.   
  422.     if ( ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0 )  
  423.     {  
  424.         goto END;  
  425.     }  
  426.   
  427.     ret = 0;  
  428.   
  429. END:  
  430.   
  431.     if ( sockfd != -1 )  
  432.     {  
  433.         close(sockfd);  
  434.         sockfd = -1;  
  435.     }  
  436.   
  437.     return ret;  
  438. }  

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值