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 ...
随机推荐
- nginx模块开发(18)—日志分析
1.日志简介 nginx日志主要有两种:访问日志和错误日志.访问日志主要记录客户端访问nginx的每一个请求,格式可以自定义:错误日志主要记录客户端访问nginx出错时的日志,格式不支持自定义.两种日 ...
- Project Euler 96:Su Doku 数独
Su Doku Su Doku (Japanese meaning number place) is the name given to a popular puzzle concept. Its o ...
- *[codility]MinAvgTwoSlice
https://codility.com/demo/take-sample-test/min_avg_two_slice 此题要求一个数组子段的最小的平均数(返回第一个数字的index).刚开始想记录 ...
- React组件测试(模拟组件、函数和事件)
一.模拟组件 1.用到的工具 (1)browerify (2)jasmine-react-helpers (3)rewireify(依赖注入) (4)命令:browserify - t reactif ...
- Ado.Net小练习03(省市联动)
前台界面: 后台代码: namespace _04省市联动 { public partial class Form1 : Form { public ...
- 在java程序中访问windows有用户名和密码保护的共享目录
在java程序中访问windows有用户名和密码保护的共享目录 Posted on 2015-11-20 14:03 云自无心水自闲 阅读(3744) 评论(0) 编辑 收藏 --> Jav ...
- openCv 图像顺时针、逆时针旋转
通过下面这个函数调用 Rotate90(workImg,270); //顺时针旋转 Rotate90(workImg,90); //逆时针旋转 实现,其实用该函数旋转任意度数对正方形图都ok,只是长方 ...
- Ubuntu链接ubuntu服务器
以前在windows下用ssh工具putty连接 linux服务器, 很简单,在linux下要连接linux的服务器, 找了下,果然putty在linux中也行1,sudo apt-get insta ...
- Android权限安全(8)ContentProvider基于URI的安全
一.provider可以通过binder得到客户的uid,然后进程权限检查. 二,provider临时权限 场景: Email的内容在provider中提供,Email的客户端可读基其内容,现在一封 ...
- javascript 字符转义汇总
在开发中经常遇到需要字符转义的,我将一一把遇到的转义列举出来 1.今天中午做项目的时候遇到一个字符串链接的问题,需要链接的的是一个函数的参数 时间字符串:"2014-04-08 16:37: ...