Linux 获得机器的IP和网卡信息
代码来自于网络, 我改写了, 有美不敢自专, 特分享之.使用方法非常easy,就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#include #include #include #include #include #include #include #include #include #include #include #ifdef SOLARIS# include #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 0typedef 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; }}