Linux 获取本机IP、MAC地址用法大全
getifaddrs()和struct ifaddrs的使用,获取本机IP
ifaddrs结构体定义如下:
struct ifaddrs
{
struct ifaddrs *ifa_next; /* Next item in list */
char *ifa_name; /* Name of interface */
unsigned int ifa_flags; /* Flags from SIOCGIFFLAGS */
struct sockaddr *ifa_addr; /* Address of interface */
struct sockaddr *ifa_netmask; /* Netmask of interface */
union
{
struct sockaddr *ifu_broadaddr; /* Broadcast address of interface */
struct sockaddr *ifu_dstaddr; /* Point-to-point destination address */
} ifa_ifu;
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
void *ifa_data; /* Address-specific data */
};
ifa_next指向链表的下一个成员;ifa_name是接口名称,以0结尾的字符串,比如eth0,lo;ifa_flags是接口的标识位(比如当IFF_BROADCAST或IFF_POINTOPOINT设置到此标识位时,影响联合体变量ifu_broadaddr存储广播地址或ifu_dstaddr记录点对点地址);ifa_netmask存储该接口的子网掩码;结构体变量存储广播地址或点对点地址(见括弧介绍ifa_flags);ifa_data存储了该接口协议族的特殊信息,它通常是NULL(一般不关注他)。
函数getifaddrs(int getifaddrs (struct ifaddrs **__ifap))获取本地网络接口信息,将之存储于链表中,链表头结点指针存储于__ifap中带回,函数执行成功返回0,失败返回-1,且为errno赋值。
很显然,函数getifaddrs用于获取本机接口信息,比如最典型的获取本机IP地址。
linux编程获取本机IP地址的三种方法
这 是一项不太清晰而且没有多大意义的工作。一个原因是网络地址的设置非常灵活而且都是允许用户进行个性化设置的,比如一台计算机上可以有多块物理网卡或者虚 拟网卡,一个网卡上可以绑定多个IP地址,用户可以为网卡设置别名,可以重命名网卡,用户计算机所在网络拓扑结构未知,主机名设置是一个可选项并且同样可 以为一个计算机绑定多个主机名等,这些信息都会有影响。脱离了网络连接,单独的网络地址没有任何意义。编程中遇到必须获取计算机IP的场景,应该考虑将这 一选项放到配置文件中,由用户自己来选择。
通过google,编程获取IP地址大约有以下三种思路:
. 通过gethostname()和gethostbyname() #include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> int main() {
char hname[];
struct hostent *hent;
int i; gethostname(hname, sizeof(hname)); //hent = gethostent();
hent = gethostbyname(hname); printf("hostname: %s/naddress list: ", hent->h_name);
for(i = ; hent->h_addr_list[i]; i++) {
printf("%s/t", inet_ntoa(*(struct in_addr*)(hent->h_addr_list[i])));
}
return ;
} 运行:
[whb@jcwkyl c]$ ./local_ip
hostname: jcwkyl.jlu.edu.cn
address list: 10.60.56.90 . 通过枚举网卡,API接口可查看man netdevice /*代码来自StackOverflow: http://stackoverflow.com/questions/212528/linux-c-get-the-ip-address-of-local-computer */
#include <stdio.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h> int main (int argc, const char * argv[]) {
struct ifaddrs * ifAddrStruct=NULL;
void * tmpAddrPtr=NULL; getifaddrs(&ifAddrStruct); while (ifAddrStruct!=NULL) {
if (ifAddrStruct->ifa_addr->sa_family==AF_INET) { // check it is IP4
// is a valid IP4 Address
tmpAddrPtr=&((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
printf("%s IP Address %s/n", ifAddrStruct->ifa_name, addressBuffer);
} else if (ifAddrStruct->ifa_addr->sa_family==AF_INET6) { // check it is IP6
// is a valid IP6 Address
tmpAddrPtr=&((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
char addressBuffer[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
printf("%s IP Address %s/n", ifAddrStruct->ifa_name, addressBuffer);
}
ifAddrStruct=ifAddrStruct->ifa_next;
}
return ;
} 运行 :
[whb@jcwkyl c]$ ./local_ip2
lo IP Address 127.0.0.1
eth0 IP Address 10.60.56.90
eth0: IP Address 192.168.1.3
lo IP Address ::
eth0 IP Address :::da8:b000::20f:1fff
eth0 IP Address ::fe80::20f:1fff . 打开一个对外界服务器的网络连接,通过getsockname()反查自己的IP
linux下获取IP等信息函数
在linux下 获取,修改本机IP地址的两个函数
//获取本机IP地址函数
QString GetLocalIp()
{ int sock_get_ip;
char ipaddr[]; struct sockaddr_in *sin;
struct ifreq ifr_ip; if ((sock_get_ip=socket(AF_INET, SOCK_STREAM, )) == -)
{
printf("socket create failse...GetLocalIp!/n");
return "";
} memset(&ifr_ip, , sizeof(ifr_ip));
strncpy(ifr_ip.ifr_name, "eth0", sizeof(ifr_ip.ifr_name) - ); if( ioctl( sock_get_ip, SIOCGIFADDR, &ifr_ip) < )
{
return "";
}
sin = (struct sockaddr_in *)&ifr_ip.ifr_addr;
strcpy(ipaddr,inet_ntoa(sin->sin_addr)); printf("local ip:%s /n",ipaddr);
close( sock_get_ip ); return QString( ipaddr );
}
//修改本机IP地址的函数
int SetLocalIp( const char *ipaddr )
{ int sock_set_ip; struct sockaddr_in sin_set_ip;
struct ifreq ifr_set_ip; bzero( &ifr_set_ip,sizeof(ifr_set_ip)); if( ipaddr == NULL )
return -; if(sock_set_ip = socket( AF_INET, SOCK_STREAM, ) == -);
{
perror("socket create failse...SetLocalIp!/n");
return -;
} memset( &sin_set_ip, , sizeof(sin_set_ip));
strncpy(ifr_set_ip.ifr_name, "eth0", sizeof(ifr_set_ip.ifr_name)-); sin_set_ip.sin_family = AF_INET;
sin_set_ip.sin_addr.s_addr = inet_addr(ipaddr);
memcpy( &ifr_set_ip.ifr_addr, &sin_set_ip, sizeof(sin_set_ip)); if( ioctl( sock_set_ip, SIOCSIFADDR, &ifr_set_ip) < )
{
perror( "Not setup interface/n");
return -;
} //设置激活标志
ifr_set_ip.ifr_flags |= IFF_UP |IFF_RUNNING; //get the status of the device
if( ioctl( sock_set_ip, SIOCSIFFLAGS, &ifr_set_ip ) < )
{
perror("SIOCSIFFLAGS");
return -;
} close( sock_set_ip );
return ;
}
在linux下 获取本机MAC地址的函数
获取本机MAC地址函数
QString GetLocalMac()
{
int sock_mac; struct ifreq ifr_mac;
char mac_addr[]; sock_mac = socket( AF_INET, SOCK_STREAM, );
if( sock_mac == -)
{
perror("create socket falise...mac/n");
return "";
} memset(&ifr_mac,,sizeof(ifr_mac));
strncpy(ifr_mac.ifr_name, "eth0", sizeof(ifr_mac.ifr_name)-); if( (ioctl( sock_mac, SIOCGIFHWADDR, &ifr_mac)) < )
{
printf("mac ioctl error/n");
return "";
} sprintf(mac_addr,"%02x%02x%02x%02x%02x%02x",
(unsigned char)ifr_mac.ifr_hwaddr.sa_data[],
(unsigned char)ifr_mac.ifr_hwaddr.sa_data[],
(unsigned char)ifr_mac.ifr_hwaddr.sa_data[],
(unsigned char)ifr_mac.ifr_hwaddr.sa_data[],
(unsigned char)ifr_mac.ifr_hwaddr.sa_data[],
(unsigned char)ifr_mac.ifr_hwaddr.sa_data[]); printf("local mac:%s /n",mac_addr); close( sock_mac );
return QString( mac_addr );
}
在linux下 获取,修改子网掩码NETMASK的两个函数
//获取子网掩码的函数
QString GetLocalNetMask()
{
int sock_netmask;
char netmask_addr[]; struct ifreq ifr_mask;
struct sockaddr_in *net_mask; sock_netmask = socket( AF_INET, SOCK_STREAM, );
if( sock_netmask == -)
{
perror("create socket failture...GetLocalNetMask/n");
return "";
} memset(&ifr_mask, , sizeof(ifr_mask));
strncpy(ifr_mask.ifr_name, ifname, sizeof(ifr_mask.ifr_name )-); if( (ioctl( sock_netmask, SIOCGIFNETMASK, &ifr_mask ) ) < )
{
printf("mac ioctl error/n");
return "";
} net_mask = ( struct sockaddr_in * )&( ifr_mask.ifr_netmask );
strcpy( netmask_addr, inet_ntoa( net_mask -> sin_addr ) ); printf("local netmask:%s/n",netmask_addr); close( sock_netmask );
return QString( netmask_addr );
}
//修改子NETMASK的函数
QString SetLocalNetMask(const char *szNetMask)
{
int sock_netmask;
char netmask_addr[]; struct ifreq ifr_mask;
struct sockaddr_in *sin_net_mask; sock_netmask = socket( AF_INET, SOCK_STREAM, );
if( sock_netmask == -)
{
perror("Not create network socket connect/n");
return "";
} memset(&ifr_mask, , sizeof(ifr_mask));
strncpy(ifr_mask.ifr_name, "eth0", sizeof(ifr_mask.ifr_name )-);
sin_net_mask = (struct sockaddr_in *)&ifr_mask.ifr_addr;
sin_net_mask -> sin_family = AF_INET;
inet_pton(AF_INET, szNetMask, &sin_net_mask ->sin_addr); if(ioctl(sock_netmask, SIOCSIFNETMASK, &ifr_mask ) < )
{
printf("sock_netmask ioctl error/n");
return "";
}
}
//获去GateWay
QString GetGateWay()
{
FILE *fp;
char buf[];
char cmd[];
char gateway[];
char *tmp; strcpy(cmd, "ip route");
fp = popen(cmd, "r");
if(NULL == fp)
{
perror("popen error");
return "";
}
while(fgets(buf, sizeof(buf), fp) != NULL)
{
tmp =buf;
while(*tmp && isspace(*tmp))
++ tmp;
if(strncmp(tmp, "default", strlen("default")) == )
break;
}
sscanf(buf, "%*s%*s%s", gateway);
printf("default gateway:%s/n", gateway);
pclose(fp); return QString(gateway);
}
//设置网关
int SetGateWay(const char *szGateWay)
{
int ret = ;
char cmd[];
QString DefGW = GetGateWay(); const char *strGW = DefGW.latin1(); strcpy(cmd, "route del default gw ");
strcat(cmd, strGW);
ret = system(cmd);
if(ret < )
{
perror("route error");
return -;
}
strcpy(cmd, "route add default gw ");
strcat(cmd, szGateWay); ret = system(cmd);
if(ret < )
{
perror("route error");
return -;
} return ret;
}
Linux下如何获取网卡信息
有时候,写程序的时候需要获取计算机的网络信息,比如IP地址、电脑名称、DNS等信息。IP地址和电脑名称是比较容易获取到的,而要想获取地址掩码、DNS、网关等信息就有些麻烦了。
在Windows下我们一般都是通过从注册表读取这些信息。在Linux怎么做呢?其实,Linux下更加容易一些。因为我们可以拿现成的程序看它的源代码。通过阅读其源代码找到解决该问题的方法。那么,看哪个程序的源代码呢?如果你使用过Linux,并且比较熟悉的话就肯定知道一个命令ifconfig。这个命令和Windows下的ipconfig差不多,都可以输出网卡的信息,其中就包含DNS、掩码等信息。所以,我们可以通过看它的源代码来找到解决该问题的方法。
获取系统中的网卡数量
并没有那个系统调用提供网卡数量的获取。但是,我们可以通过强大的proc文件系统获取网卡数量的信息。实际上,ifconfig也是这样做的,请看示例代码如下:
#include <stdio.h>
#include <string.h>
#include <errno.h> int GetNetCardCount()
{
int nCount = ;
FILE* f = fopen("/proc/net/dev", "r");
if (!f)
{
fprintf(stderr, "Open /proc/net/dev failed!errno:%d\n", errno);
return nCount;
} char szLine[]; fgets(szLine, sizeof(szLine), f); /* eat line */
fgets(szLine, sizeof(szLine), f); while(fgets(szLine, sizeof(szLine), f))
{
char szName[] = {};
sscanf(szLine, "%s", szName);
int nLen = strlen(szName);
if (nLen <= )continue;
if (szName[nLen - ] == ':') szName[nLen - ] = ;
if (strcmp(szName, "lo") == )continue;
nCount++;
} fclose(f);
f = NULL;
return nCount;
} int main(int argc, char* argv[])
{
printf("NetCardCount: %d\n", GetNetCardCount());
return ;
}
获取IP、掩码、MAC及网关
获取IP、掩码、MAC和广播地址是比较容易的,只需要调用对应的IOCTL即可。只是大家对Linux下的IOCTL可能不太熟悉。却看示例代码:
void DispNetInfo(const char* szDevName)
{
int s = socket(AF_INET, SOCK_DGRAM, );
if (s < )
{
fprintf(stderr, "Create socket failed!errno=%d", errno);
return;
} struct ifreq ifr;
unsigned char mac[];
unsigned long nIP, nNetmask, nBroadIP; printf("%s:\n", szDevName); strcpy(ifr.ifr_name, szDevName);
if (ioctl(s, SIOCGIFHWADDR, &ifr) < )
{
return;
}
memcpy(mac, ifr.ifr_hwaddr.sa_data, sizeof(mac));
printf("\tMAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
mac[], mac[], mac[], mac[], mac[], mac[]); strcpy(ifr.ifr_name, szDevName);
if (ioctl(s, SIOCGIFADDR, &ifr) < )
{
nIP = ;
}
else
{
nIP = *(unsigned long*)&ifr.ifr_broadaddr.sa_data[];
}
printf("\tIP: %s\n", inet_ntoa(*(in_addr*)&nIP)); strcpy(ifr.ifr_name, szDevName);
if (ioctl(s, SIOCGIFBRDADDR, &ifr) < )
{
nBroadIP = ;
}
else
{
nBroadIP = *(unsigned long*)&ifr.ifr_broadaddr.sa_data[];
}
printf("\tBroadIP: %s\n", inet_ntoa(*(in_addr*)&nBroadIP)); strcpy(ifr.ifr_name, szDevName);
if (ioctl(s, SIOCGIFNETMASK, &ifr) < )
{
nNetmask = ;
}
else
{
nNetmask = *(unsigned long*)&ifr.ifr_netmask.sa_data[];
}
printf("\tNetmask: %s\n", inet_ntoa(*(in_addr*)&nNetmask));
close(s);
}
那么如何获取网关地址呢?更加容易,但是,好像很少有人知道。反正我在网上没有找到有人知道。最后看了nslookup的源代码以后才知道正确的做法。代码如下:
res_init();
for (int i = ; i < _res.nscount; i++)
{
struct sockaddr* server = (struct sockaddr*)&_res.nsaddr_list[i];
printf("Server: %s\n", inet_ntoa(*(in_addr*)&(server->sa_data[])));
}
代码很简单,就不做解释了。
怎么获取网关呢?这个稍微有点麻烦一些,不过和获取网卡数量相似,都是通过proc文件系统。这次分析的/proc/net/route文件。我就不再贴出示例代码了。
最后,我把运行示例程序获取到的信息附上,以供大家有个直观的认识:
eth0:
MAC: ----bf-f3
IP: 192.168.1.106
BroadIP: 255.255.255.255
Netmask: 255.255.255.0
Gateway: 192.168.1.1
eth1:
MAC: ----f4-bf
IP: 192.168.1.108
BroadIP: 192.168.1.255
Netmask: 255.255.255.0
Gateway: 0.0.0.0
eth2:
MAC: ----9c-
IP: 0.0.0.0
BroadIP: 0.0.0.0
Netmask: 0.0.0.0
Gateway: 0.0.0.0
eth3:
MAC: ---5a-d2-
IP: 0.0.0.0
BroadIP: 0.0.0.0
Netmask: 0.0.0.0
Gateway: 0.0.0.0
NetCardCount:
DNS : 218.2.135.1
DNS : 61.147.37.1
Linux下C语言配置网络与获取网络配置信息的方法
Linux下的网络配置包含三个要素,分别是IP地址、子网掩码和网关。本文将介绍如何在C语言中进行网络的配置和配置信息的获取。 【配置】 方法一 使用system()或exec*()调用ifconfig和route命令进行配置。这种方法的优点是使用简单,缺点是效率比较低,且依赖于ifconfig与route命令。 示例: 见所附代码中的函数ip_config_system()和ip_config_exec()。 方法二 建立一个socket,用ioctl()进行配置。这种方法的优点是效率较高,缺点是程序实现起来比较麻烦。 示例: 见所附代码中的函数ip_config_ioctl()。 【获取】 方法一 用popen()建立一个管道,管道的一端执行命令ifconfig和route,管道的另一端读取收到的数据并进行相应的解析。这种方法的优点是使用简单,缺点是效率比较低,且依赖于ifconfig与route命令。 示例: 见所附代码中的函数ip_get_pipe()。 方法二 用fopen()打开/proc/net/route,可以获取网关(在/proc/net中尚未发现比较好的获取IP地址和掩码的方法,知道的请发邮件至cugfeng at gamil.com,谢谢)。这种方法的优点是使用简单,效率比执行命令高,缺点是依赖于proc文件系统。 示例: 见所附代码中的函数ip_get_proc()。 方法三 建立一个socket,用ioctl()进行获取(用ioctl()尚未发现比较好的获取网关的方法,知道的请发邮件至cugfeng at gamil.com,谢谢)。这种方法的优点是效率较高,缺点是程序实现起来比较麻烦。 示例: 见所附代码中的函数ip_get_ioctl()。 BTW,用ioctl()的方法还可以获取MAC地址,ioctl()命令为SIOCGIFHWADDR,具体用法与ioctl()获取IP地址的方法相同,这里就不多说了。
Linux 获取本机IP、MAC地址用法大全的更多相关文章
- JAVA获取本机的MAC地址
/** * 获取本机的Mac地址 * @return */ public String getMac() { InetAddress ia; byte[] mac = null; try { // 获 ...
- Delphi获取本机的MAC地址
Delphi获取本机的MAC地址: uses NB30; function GetAdaPterInfo(lana: Char): string; var Adapter: TAdapterS ...
- java 获取计算机名称, ip, mac地址
写在前面 通常所说查询本机mac地址是以以太网为准的, 也就是网线那个口..这种描述略捞. 但是通过java的getHostAddress获取ip以及getHardwareAddress()方法获取m ...
- C#获取本机的MAC地址
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.M ...
- linux获取本机ip
int get_ip ( in_addr_t addrs[], int asize ) { int MAXINTERFACES=16; int i = 0; ...
- [记]WIndow/Linux 获取本机(全部)IPv4、IPv6、MAC地址方法 (C/C++)
Linux 获取本机IP.MAC地址用法大全 //#include <sys/types.h> #include <ifaddrs.h> #include <sys/io ...
- QT5下获取本机IP地址、计算机名、网络连接名、MAC地址、子网掩码、广播地址
获取主机名称 /* * 名称:get_localmachine_name * 功能:获取本机机器名称 * 参数:no * 返回:QString */ QString CafesClient::get_ ...
- JAVA获取本机IP和Mac地址
在项目中,时常需要获取本机的Ip或是Mac地址,进行身份和权限验证,本文就是通过java代码获取ip和Mac. package com.svse.query;import java.net.In ...
- 获取本机IP、mac地址、计算机名
python获取本机IP.mac地址.计算机名 在python中获取ip地址和在php中有很大不同,我们先来看一下python 获得本机MAC地址: >>> import uuid ...
随机推荐
- ThinkPhp 添加模型类
----------------------------------------------- <?phpnamespace app\common\model;use traits\model\ ...
- sql子查询
一.子查询入门: 1.单值子查询: 单值子查询的唯一限制:子查询的返回值必须只有一行记录,而且只能有一列(又被称为标量子查询). 可以使用在select语句的列表.表达式中,以及where语句中等. ...
- Android-第三天
今天开始做一个提交的页面,本来是用LinearLayout,但是这种布局要使用到多组LinearLayout,于是采用表格布局+相对布局的方式. <TableLayout> <Tab ...
- jquery mobile-按钮控件
jQuery Mobile 中的按钮会自动获得样式,这增强了他们在移动设备上的交互性和可用性.我们推荐您使用 data-role="button" 的 <a> 元素来创 ...
- bootstrap-multiselect 的简单使用,样式修改,动态创建option
1.bootstrap-multiselect 顾名思义基于bootstrap,bootstrap基于jquery,所以第一步,引入文件 bootstrap.css/ juery.js /bootst ...
- eclipse 按住ctrl 按钮没有反映
以下是修改为XML Editior打开方法Window -> Preferences -> General -> Editors -> File Associations Fi ...
- IIS命令行管理工具使用
AppCmd.exe工具所在目录 C:\windows\sytstem32\inetsrv\目录下 一条命令批量添加应用程序 c:\Windows\System32\inetsrv>for /d ...
- WPF 简易新手引导
这两天不忙,所以,做了一个简易的新手引导小Demo.因为,不是项目上应用,所以,做的很粗糙,也就是给需要的人,一个思路而已. 新手引导功能的话,就是告诉用户,页面上操作的顺序,第一步要做什么,第二步要 ...
- redis 安装实战(10步完成安装)
1 下载zip :https://redis.io/download ---->redis-4.0.6 2 上传:利用wcp 上传到/usr/local/soft/ 3 解压:tar -zv ...
- BSA Network Shell系列-nexec命令
# nexec ## 1 说明:nexec是远程命令接口引擎 ,用于在远程主机执行命令 nexec [-?] [-t term] [-o] [-i] [-l] [-nohup hostname &qu ...