Linux下通过ioctl系统调用来获取和设置网络信息
#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,上网查也似乎没能找到什么比较好的现成函数,所以最后只好自己写了
Linux下通过ioctl系统调用来获取和设置网络信息的更多相关文章
- Linux下利用ioctl函数获取网卡信息
linux下的ioctl函数原型如下: #include <sys/ioctl.h> int ioctl(int handle, int cmd, [int *argc, int argv ...
- Linux下Wireshark普通用户不能获取网络接口问题
Linux下Wireshark普通用户不能获取网络接口问题 1.安装setcap, setcap 是libcap2-bin包的一部分,一般来说,这个包默认会已经装好. sudo apt-get ins ...
- linux下的CPU、内存、IO、网络的压力测试
linux下的CPU.内存.IO.网络的压力测试 要远程测试其实很简单了,把结果放到一个微服务里直接在web里查看就可以了,或者同步到其他服务器上 一.对CPU进行简单测试: 1.通过bc命令计算特 ...
- [转帖]linux下的CPU、内存、IO、网络的压力测试
linux下的CPU.内存.IO.网络的压力测试 https://www.cnblogs.com/zhuochong/p/10185881.html 一.对CPU进行简单测试: 1.通过bc命令计算特 ...
- linux下生成core dump文件方法及设置
linux下生成core dump文件方法及设置 from:http://www.cppblog.com/kongque/archive/2011/03/07/141262.html core ...
- 详解Linux下iptables中的DNAT与SNAT设置(转)
详解Linux下iptables中的DNAT与SNAT设置 这篇文章主要介绍了Linux下iptables中的DNAT与SNAT设置,是Linux网络配置中的基础知识,需要的朋友可以参考下 原文连 ...
- Linux下Tomcat端口、进程以及防火墙设置
Linux下Tomcat端口.进程以及防火墙设置 1,查看tomcat进程: #ps -aux | grep tomcat(或者ps -ef | grep tomcat都行) 可以看到现在运行着两个 ...
- 转:Linux下同时启动两个Tomcat进行设置
转: Linux下同时启动两个Tomcat进行设置 解压tar.gz:tar -zxvf apache-tomcat-6.0.41.tar.gz 至相应的路径下,可解压至两个不同的路径或者相同的路径下 ...
- Qt5获取本机网络信息
获取本机网络信息 在pro文件中加入如下代码 QT += network widget.h中的代码如下 #ifndef WIDGET_H #define WIDGET_H #include <Q ...
随机推荐
- unity与Android相互调用
原地址:http://www.cnblogs.com/ayanmw/p/3727782.html 现在unity 导出的android客户端需要调用 Android 的支付SDK,但是unity与an ...
- JavaScript 隐式转换
javascript 中的怪癖,js运算符隐式类型转换 x + "" //等价于 String(x) + x //等价于 Number(x),也可以写成x-0 !!x //等价于 ...
- POJ3083Children of the Candy Corn
题意:给你一个迷宫,入口处标为S,出口处标为E,可以走的地方为“.”,不可以走的地方为#,求左转优先时从出口到入口的路程,再求右转优先时,出口到入口的路程,最后求从出口到入口的最短路程. 思路:求前两 ...
- hdu 2065 "红色病毒"问题
指数型母函数的应用 求A B C D 在规定条件下n个元素的排列个数,先写出指数型母函数 G(X) = ( 1 + x + x^2/2! + x^3/3! +... )^2 * ( 1+ x^2/2! ...
- Win7-其中的文件夹或文件已在另一个程序中打开
Win7-其中的文件夹或文件已在另一个程序中打开 如何解决Win7系统在删除或移动文件时提示,“操作无法完成,因为其中的文件夹或文件已在另一个程序中打开,请关闭该文件夹或文件,然后重试”. 步骤阅 ...
- lintcode:数字三角形
题目: 数字三角形 给定一个数字三角形,找到从顶部到底部的最小路径和.每一步可以移动到下面一行的相邻数字上. 样例 比如,给出下列数字三角形: [ [2], [3,4], [6 ...
- PCB板的价格是怎么算出来的?
Part 1 :影响一块PCB板价格的各种因素 PCB的价格是很多采购者一直很困惑的事情,很多人在线下单时也会疑问这些价格是怎么算出来的,下面我们就一起谈论一下PCB价格的组成因素. 1.PCB所用材 ...
- Android:AlertDialog对话框
1.简单的ALertDialog: Dialog alertDialog = new AlertDialog.Builder(this) .setTitle("标题") .setM ...
- MySQL登录报错"Access denied for user 'root'@'localhost' (using password: YES)"
最近登录MySQL时候总报错: # mysql -uroot -p Enter password: ERROR (): Access denied for user 'root'@'localhost ...
- MyEclipse +Tomcat 异常操作
安装完MyEclipse 2014,用JAX-WS的方式写了一个小段Web Service,用MyEclipse 自带的 Tomcat 部署没有问题,用我自己的,却出现下面的错误: java.lang ...