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 ...
随机推荐
- 趣味Python入门(一):初识Python
[编者按]本文作者是 Abhishek Jaiswal ,擅长 .NET.C#.Python 等多种语言的技术控.本文中,作者通过活泼有趣的口吻向大家介绍了 Python 语言的基础知识,后期多学习历 ...
- String及其他
String 以下例开始讲解String public class StringDemo { public static void main(String[] args) { // String s ...
- 使用load()方法异步请求数据
使用load()方法通过Ajax请求加载服务器中的数据,并把返回的数据放置到指定的元素中,它的调用格式为: load(url,[data],[callback]) 参数url为加载服务器地址,可选项d ...
- mac 下周期调度命令或脚本
crontab 是在linux服务器上部署定时任务的方法 0 5 * * * /usr/bin/python /data/www/tools/mysql_backup.py cmd之前有5个项目要填, ...
- 包含中文的字符串中截取前N个字符
package com.wangzhu.string; import java.io.UnsupportedEncodingException; public class SubStringDemo1 ...
- cojs 疯狂的魔法树 疯狂的颜色序列 题解报告
疯狂的魔法树 一个各种操作大杂烩的鬼畜数据结构题目 首先我们注意到树的形态是半随机的 我们可以树分块,对树分成若干个块 对于每个块我们维护一个add标记表示增量 维护一个vis标记表示覆盖量 注意标记 ...
- hdu 4465 Candy
题解: 由题意得 需要运用: C(m,n)=exp(logC(m,n)) f[]=; ; i<=; i++) f[i]=f[i-]+log(i*1.0); double logC(int m,i ...
- springmvc常用注解之@Controller和@RequestMapping
对于各种注解而言,排第一的当然是“@Controller”,表明某类是一个controller. “@RequestMapping”请求路径映射,如果标注在某个controller的类级别上,则表明访 ...
- Could not connect to SMTP host: smtp.***.com, port: 465, response: -1
背景 在使用javamail进行邮件发送的时候,报错: Could not connect to SMTP host: smtp.***.com, port: 465, response: -1 原因 ...
- Java API —— TreeMap类
1.TreeMap类概述 键是红黑树结构,可以保证键的排序和唯一性 2.TreeMap案例 TreeMap<String,String> T ...