Linux 获得机器的IP和网卡信息
Linux 获得机器的IP和网卡信息
代码来自于网络, 我改写了, 有美不敢自专, 特分享之.用法很简单,就3个函数.
头文件getmac.h:
/**
* getmac.h
*
* 2014-07-08: init created
*/
#ifndef GETMAC_H_INCLUDED
#define GETMAC_H_INCLUDED
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <unistd.h>
#ifdef SOLARIS
# include <sys/sockio.h>
#endif
#define GETMAC_MAX_INTERFACES 16
#define GETMAC_MAX_MSGLEN 256
#define GETMAC_NOERROR 0
#define GETMAC_SUCCESS GETMAC_NOERROR
#define GETMAC_ERROR (-1)
#define GETMAC_EATTR (-2)
typedef int GETMAC_BOOL;
#define GETMAC_TRUE 1
#define GETMAC_FALSE 0
typedef struct
{
int fd;
struct ifreq buf[GETMAC_MAX_INTERFACES];
struct arpreq arp;
int ifaces;
} getmac_info_t;
typedef struct
{
int errcode;
char errmsg[GETMAC_MAX_MSGLEN];
} getmac_error_t;
#define GETMAC_ATTR_IFF_UP 1 /* Interface is up */
#define GETMAC_ATTR_IFF_BROADCAST 2 /* Broadcast address valid */
#define GETMAC_ATTR_IFF_DEBUG 3 /* Turn on debugging */
#define GETMAC_ATTR_IFF_LOOPBACK 4 /* Is a loopback net */
#define GETMAC_ATTR_IFF_POINTOPOINT 5 /* Interface is point-to-point link */
#define GETMAC_ATTR_IFF_NOTRAILERS 6 /* Avoid use of trailers */
#define GETMAC_ATTR_IFF_RUNNING 7 /* Resources allocated */
#define GETMAC_ATTR_IFF_NOARP 8 /* No address resolution protocol */
#define GETMAC_ATTR_IFF_PROMISC 9 /* Receive all packets */
#define GETMAC_ATTR_IFNAME 10 /* Interface name, e.g. "en0". */
#define GETMAC_ATTR_IPADDR 11 /* Address of interface */
#define GETMAC_ATTR_HWADDR 12 /* MAC address */
extern int getmac_init (getmac_info_t * mi, getmac_error_t * err);
extern int getmac_attr (getmac_info_t * mi, int i, int attr, void * value, getmac_error_t * err);
extern void getmac_fini (getmac_info_t * mi);
#if defined(__cplusplus)
}
#endif
#endif /* GETMAC_H_INCLUDED */
C文件getmac.c:
/**
* getmac.c
*
* 2014-07-08: init created
*/
#include "getmac.h"
int getmac_init (getmac_info_t * mi, getmac_error_t * err)
{
int fd;
struct ifconf ifc;
bzero (mi, sizeof(getmac_info_t));
mi->fd = -1;
fd = socket (AF_INET, SOCK_DGRAM, 0);
if (fd == -1) {
err->errcode = errno;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "socket() error (%d): %s", strerror(errno));
return GETMAC_ERROR;
}
/* prepare to get mac numb */
ifc.ifc_len = sizeof(mi->buf);
ifc.ifc_buf = (caddr_t) mi->buf;
if (ioctl (fd, SIOCGIFCONF, (char *) &ifc)) {
err->errcode = errno;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl() error (%d): %s", strerror(errno));
close (fd);
return GETMAC_ERROR;
}
mi->ifaces = ifc.ifc_len / sizeof (struct ifreq);
mi->fd = fd;
/* return numb of mac */
return mi->ifaces;
}
int getmac_attr (getmac_info_t * mi, int i, int attr, void * value, getmac_error_t * err)
{
if (mi->fd == -1) {
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "getmac_init should be invoked first");
return GETMAC_ERROR;
}
/* initialize if not a valid name */
if (! mi->buf[i].ifr_name[0]) {
if (ioctl (mi->fd, SIOCGIFFLAGS, (char *) & mi->buf[i])) {
err->errcode = errno;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGIFFLAGS) error (%d): %s", strerror(errno));
return GETMAC_ERROR;
}
if (ioctl (mi->fd, SIOCGIFADDR, (char *) & mi->buf[i])) {
err->errcode = errno;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGIFADDR) error (%d): %s", strerror(errno));
return GETMAC_ERROR;
}
/* get Hardware Address */
#ifdef SOLARIS
do {
mi->arp.arp_pa.sa_family = AF_INET;
mi->arp.arp_ha.sa_family = AF_INET;
((struct sockaddr_in *) & mi->arp.arp_pa)->sin_addr.s_addr = ((struct sockaddr_in*)(& buf[i].ifr_addr))->sin_addr.s_addr;
if ((ioctl (mi->fd, SIOCGARP, (char *) & mi->arp))) {
err->errcode = errno;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGARP) error (%d): %s", strerror(errno));
return GETMAC_ERROR;
}
} while (0);
#else
#if 0
do {
/* get HW ADDRESS of the net card */
if (ioctl (mi->fd, SIOCGENADDR, (char *) & buf[i])) {
err->errcode = errno;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGENADDR) error (%d): %s", strerror(errno));
return GETMAC_ERROR;
}
} while (0);
#else
do {
if (ioctl (mi->fd, SIOCGIFHWADDR, (char *) & mi->buf[i])) {
err->errcode = errno;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGIFHWADDR) error (%d): %s", strerror(errno));
return GETMAC_ERROR;
}
} while (0);
#endif
#endif
}
err->errcode = GETMAC_NOERROR;
/* get net attribute */
switch (attr) {
case GETMAC_ATTR_IFF_UP: /* Interface is up */
if (mi->buf[i].ifr_flags & IFF_UP) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface is up");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface is not up");
}
break;
case GETMAC_ATTR_IFF_BROADCAST: /* Broadcast address valid */
if (mi->buf[i].ifr_flags & IFF_BROADCAST) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Broadcast address valid");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Broadcast address invalid");
}
break;
case GETMAC_ATTR_IFF_DEBUG: /* Turn on debugging */
if (mi->buf[i].ifr_flags & IFF_DEBUG) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Turn on debugging");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Turn off debugging");
}
break;
case GETMAC_ATTR_IFF_LOOPBACK: /* Is a loopback net */
if (mi->buf[i].ifr_flags & IFF_LOOPBACK) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Is a loopback net");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Not a loopback net");
}
break;
case GETMAC_ATTR_IFF_POINTOPOINT: /* Interface is point-to-point link */
if (mi->buf[i].ifr_flags & IFF_POINTOPOINT) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface is point-to-point link");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface is not point-to-point link");
}
break;
case GETMAC_ATTR_IFF_NOTRAILERS: /* Avoid use of trailers */
if (mi->buf[i].ifr_flags & IFF_NOTRAILERS) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Avoid use of trailers");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Not Avoid use of trailers");
}
break;
case GETMAC_ATTR_IFF_RUNNING: /* Resources allocated */
if (mi->buf[i].ifr_flags & IFF_RUNNING) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Resources allocated");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Resources not allocated");
}
break;
case GETMAC_ATTR_IFF_NOARP: /* No address resolution protocol */
if (mi->buf[i].ifr_flags & IFF_NOARP) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "No address resolution protocol");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Has address resolution protocol");
}
break;
case GETMAC_ATTR_IFF_PROMISC: /* Receive all packets */
if (mi->buf[i].ifr_flags & IFF_PROMISC) {
* ((GETMAC_BOOL *) value) = GETMAC_TRUE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Receive all packets");
} else {
* ((GETMAC_BOOL *) value) = GETMAC_FALSE;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Not a promisc mode");
}
break;
case GETMAC_ATTR_IFNAME: /* Interface name, e.g. "en0" */
strcpy (value, mi->buf[i].ifr_name);
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface name");
break;
case GETMAC_ATTR_IPADDR: /* Interface address */
strcpy (value, inet_ntoa (((struct sockaddr_in*) (& mi->buf[i].ifr_addr))->sin_addr));
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "Interface address");
break;
case GETMAC_ATTR_HWADDR:
#ifdef SOLARIS
do {
mi->arp.arp_pa.sa_family = AF_INET;
mi->arp.arp_ha.sa_family = AF_INET;
((struct sockaddr_in *) & mi->arp.arp_pa)->sin_addr.s_addr = ((struct sockaddr_in*)(& buf[i].ifr_addr))->sin_addr.s_addr;
if ((ioctl (mi->fd, SIOCGARP, (char *) & mi->arp))) {
err->errcode = errno;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "ioctl(SIOCGARP) error (%d): %s", strerror(errno));
return GETMAC_ERROR;
} else {
sprintf (value, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char) mi->arp.arp_ha.sa_data[0],
(unsigned char) mi->arp.arp_ha.sa_data[1],
(unsigned char) mi->arp.arp_ha.sa_data[2],
(unsigned char) mi->arp.arp_ha.sa_data[3],
(unsigned char) mi->arp.arp_ha.sa_data[4],
(unsigned char) mi->arp.arp_ha.sa_data[5] );
}
} while (0);
#else
#if 0
do {
sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char) mi->buf[i].ifr_enaddr[0],
(unsigned char) mi->buf[i].ifr_enaddr[1],
(unsigned char) mi->buf[i].ifr_enaddr[2],
(unsigned char) mi->buf[i].ifr_enaddr[3],
(unsigned char) mi->buf[i].ifr_enaddr[4],
(unsigned char) mi->buf[i].ifr_enaddr[5]);
} while (0);
#else
do {
sprintf (value, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char) mi->buf[i].ifr_hwaddr.sa_data[0],
(unsigned char) mi->buf[i].ifr_hwaddr.sa_data[1],
(unsigned char) mi->buf[i].ifr_hwaddr.sa_data[2],
(unsigned char) mi->buf[i].ifr_hwaddr.sa_data[3],
(unsigned char) mi->buf[i].ifr_hwaddr.sa_data[4],
(unsigned char) mi->buf[i].ifr_hwaddr.sa_data[5]);
} while (0);
#endif
#endif
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "MAC address");
break;
default:
err->errcode = GETMAC_EATTR;
snprintf (err->errmsg, GETMAC_MAX_MSGLEN, "error attr specified");
return GETMAC_EATTR;
}
return GETMAC_SUCCESS;
}
void getmac_fini (getmac_info_t * mi)
{
if (mi->fd != -1) {
close (mi->fd);
mi->fd = -1;
}
}
Linux 获得机器的IP和网卡信息的更多相关文章
- Linux查询一台机器的IP地址和其对应的域名
Linux查询一台机器的IP地址和其对应的域名 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ nslookup > 127.0.0.1 Server: ...
- java获取本机器的IP(linux和windows)
目录 描述 方案描述 获取Windows下的IP 获取linux下的IP 判断操作系统的类型 最后将上面三个方法进行整合 参考 描述 由于项目是部署在集群上的,需要项目能够自动采集各机器的信息.jav ...
- 修改ip 在linux上永久修改IP地址 子网掩码
小结: 1. 子网掩码.子网IP计算 2. linux centos 修改ip地址细节介绍_LINUX_操作系统_脚本之家 http://www.jb51.net/LINUXjishu/66509.h ...
- Linux 单网卡多 IP 的配置方法
Linux 单网卡多 IP 的配置方法 1 .永久配置的方法: 知道在 Linux 下网卡被称为 eth0,eth1,eth2..... ,所有网卡的配置文件都存储在 /etc/sysconfi ...
- Linux 高性能服务器编程——IP协议详解
1 IP服务特点 IP协议是TCP/IP协议族的动力,它为上层协议提供无状态.无连接.不可靠的服务. 无状态:IP通信双方不同步传输数据的状态信息,因此IP数据包的发送.传输和接收都是无序的. ...
- linux操作系统-设置静态ip
在使用linux虚拟机的时候因为经常有关机的需求,然后重新开机后可能面临这上一次获取的ip被改变,在这里我分享一下在linux 下设置静态ip的经验 1.查看路由状态 [root@localhost ...
- VMWare中Linux虚拟机设置静态IP上网的设置方法
VMWare中Linux虚拟机设置静态IP上网的设置方法 标签: vmwareLinux虚拟机securecrt静态IP上网 2016-05-18 02:30 702人阅读 评论(0) 收藏 举报 ...
- linux常用命令:ip 命令
ip命令是Linux下较新的功能强大的网络配置工具. 1.命令格式: ip [OPTIONS] OBJECT [COMMAND [ARGUMENTS]] 2.命令功能: ip命令用来显示或操纵L ...
- linux命令总结之ip命令
Linux的ip命令和ifconfig类似,但前者功能更强大,并旨在取代后者.使用ip命令,只需一个命令,你就能很轻松地执行一些网络管理任务.ifconfig是net-tools中已被废弃使用的一个命 ...
随机推荐
- 音乐API
博主在前几篇博客中介绍了小Q聊天机器人的源码及其包含的一些功能,并在应用市场上上线了一个版本,其中有一个功能是歌曲搜索,即输入格式为"歌曲#歌曲名#歌手"即可搜索出相应的歌曲并进行 ...
- javaRMI详解
前几天在阿里内推一面的时候,面试官问到了一个关于java中RMI(Remote Method Invocation)的问题,当时感觉自己回答的还比较好,他比较满意,但那是因为他问的比较浅,所以自己看了 ...
- UNIX环境高级编程——线程和fork
当线程调用fork时,就为子进程创建了整个进程地址空间的副本.子进程通过继承整个地址空间的副本,也从父进程那里继承了所有互斥量.读写锁和条件变量的状态.如果父进程包含多个线程,子进程在fork返回以后 ...
- Mat, IplImage, CvMat, Cvarr关系及元素获取
自己目前正打算整理opencv数据结构之间关系,寻寻觅觅之间,发现这篇博文很全面,总结得很好,故转之.红色部分不对,自己已修改! 原文地址:http://blog.csdn.net/abcjennif ...
- 【一天一道LeetCode】#108. Convert Sorted Array to Binary Search Tree
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- 匿名内部类使用外面的类为什么要用final型
从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变量(形式参数或局部变量)是天经地义的.是很自然的 为 ...
- JSP标签JSTL(4)--URL
<c:url>标签作用是将一个URL地址格式化为一个字符串,并且保存在一个变量当中.它具有URL自动重写功能.value指定的URL可以是当前工程的一个URL地址,也可以是其他web工程的 ...
- iOS中 百度地图详解 韩俊强的博文
需要准备工作按照下图引进类库 需要添加 添加的两个字符串为:NSLocationWhenInUseUsageDescription / NSLocationAlwaysUsageDescripti ...
- 【一天一道LeetCode】#101. Symmetric Tree
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- android实现gif动态图的使用
在android中显示一个静态图片比如png jpg等等都很方便,但是如果要显示一个gif 动态图片就需要进行一些处理. 本文是采用自定义view 然后进行重新onDraw方法来实现 首先自定义Vie ...