您的位置:首页 > 运维架构 > Linux

linux 下C实现获取网卡IP和MAC地址

2014-05-21 23:27 1061 查看
本文使用getifaddrs 函数获取网卡的IP和MAC地址。getifaddrs函数有个特点,就是获取地址时以链表方式返回,且每个链表节点要么是IP,要么是MAC,所以如果要将网卡的IP和MAC地址同时返回的话,需要对对返回链表进行查找和重新组合。本文实现目的,在于以网卡名方式返回IP和MAC地址。代码如下:

#ifndef _MYLIB_H
#define _MYLIB_H
#include <stdlib.h>
#include <errno.h>

#define error_report(msg) \
do { perror(msg); \
exit (EXIT_FAILURE) \
}while (0)

//clean the stdin cach
void clean_cach (void);

//get a string from stdin
int getstring (char *str, int num);

/* define a get if info struct */
struct if_ipv4_info {
char if_name[10];;
unsigned char ip_addr[20];
unsigned char hd_addr[20];

struct if_ipv4_info *next;
};
#endif

函数实现
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <ifaddrs.h>
#include <net/ethernet.h>
#include <stdio.h>
#include <stdlib.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <errno.h>
#include <netinet/in.h>
#include <netinet/ip.h>

#include "mylib.h"

#define DEBUG 0

struct if_ipv4_info *if_info = NULL;

/*
** add ip to a linklist
*/
static int  add_to_link (struct ifaddrs *ifap, char *buf)
{
struct if_ipv4_info *p, *q;

if (if_info == NULL) {
if_info = malloc (sizeof (struct if_ipv4_info));
/* init head */
if_info->next = NULL;
if_info->ip_addr[0] = '\0';
if_info->hd_addr[0] = '\0';

if (if_info == NULL) {
fprintf (stderr, "malloc failed\n");
exit (EXIT_FAILURE);
}
strcpy (if_info->if_name, ifap->ifa_name);
switch (ifap->ifa_addr->sa_family) {
case AF_INET:
strcpy (if_info->ip_addr, buf);
//   printf ("head %s", if_info->ip_addr);
break;
case AF_PACKET:
strcpy (if_info->hd_addr, buf);
//  printf ("head %s", if_info->hd_addr);
break;
default:
break;
} //switch
}else {
for (p = if_info; p != NULL; p = p->next) {
q = p;
if (strcmp (p->if_name, ifap->ifa_name) == 0) {
break;
}
}
if (p != NULL) {
switch (ifap->ifa_addr->sa_family) {
case AF_INET:
strcpy (p->ip_addr, buf);
//   printf ("p %s\n", p->ip_addr);
break;
case AF_PACKET:
strcpy (p->hd_addr, buf);
//  printf ("p %s\n", p->hd_addr);
break;
default:
break;
} //switch
} else {
p = malloc (sizeof (struct if_ipv4_info));
/* init node */
p->next = NULL;
p->ip_addr[0] = '\0';
p->hd_addr[0] = '\0';

if (p == NULL) {
fprintf (stderr, "malloc failled");
exit (EXIT_FAILURE);
}
strcpy (p->if_name, ifap->ifa_name);
switch (ifap->ifa_addr->sa_family) {
case AF_INET:
strcpy (p->ip_addr, buf);
// printf ( "else p %s\n", p->ip_addr);
break;
case AF_PACKET:
strcpy (p->hd_addr, buf);
//printf ( "else p %s\n", p->hd_addr);
break;
default:
break;
}
q->next = p;
}//else
}
return 0;
}

int prt_if_info (struct sockaddr *ifa_addr, char *addrbuf, int bufsize)
{
memset (addrbuf, 0, bufsize);
struct sockaddr_ll *s;
int i;
int len;
int family = ifa_addr->sa_family;

int ret = 0;

switch (family) {
case AF_INET:
inet_ntop (ifa_addr->sa_family, &((struct sockaddr_in *)ifa_addr)->sin_addr,
addrbuf, sizeof (struct sockaddr_in));
break;
case AF_PACKET:
s = (struct sockaddr_ll *)ifa_addr;
for (i=0,len=0; i<6; i++) {
len += sprintf (addrbuf+len, "%02x%s", s->sll_addr[i], i<5?":":" ");
}
break;
default:
ret = -1;
break;
}
return ret;
}

int get_if_info (void)
{
struct ifaddrs *ifa, *ifap;
int family;  /* protocl family */

if (getifaddrs (&ifa) == -1) {
perror (" getifaddrs\n");
exit (EXIT_FAILURE);
}
char buf[20];

for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
if (strcmp (ifap->ifa_name, "lo") == 0) {
continue; /* skip the lookback card */
}

if (ifap->ifa_addr == NULL)
continue; /* if addr is NULL, this must be no ip address */

if (prt_if_info (ifap->ifa_addr, buf, 20) == 0) {
// printf ("%s: %s\n", ifap->ifa_name, buf);
add_to_link (ifap, buf);
}
}

/* printf all of them */
struct if_ipv4_info *p = NULL;
for (p = if_info; p != NULL; p = p->next) {
printf ("%s: %s\t%s\n", p->if_name, strlen(p->ip_addr)>0?p->ip_addr: "No ip addr", p->hd_addr);
}

/* free link list */
struct if_ipv4_info *q = NULL;
for (p = if_info; p != NULL; ) {
q = p;
p = p->next;
free (q);
}
freeifaddrs (ifa);
return 0;
}

/*
** test code
*/

int main (int argc, char **argv)
{
get_if_info ();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: