本地网卡信息获取的 方法

一、通过流套接字去底层获取:

1、创建流套接字;

        2、使用ioctl()和获取匹配指定的宏获取 指定的信息;

        3、取出信息进行存储 和 使用。


int netGetMac(char *pinterface, unsigned char *pMac)
{
struct ifreq ifreq;
int sockfd = 0;
unsigned char mac[6] = {};

//创建与底层交互的套接字
if((sockfd = socket(ASF_INET, SOCK_STREAM, 0)) < 0)
{
perror("netGetMac socket");
return -1;
}
strcpy(ifreq.ifr_name, pinterface);

通过ioctl()获取指定信息
if(icotl(sockfd, SIOCGIFHWADDR, &ifreq) < 0)
{
perror("netGetMac icotl");
close(sockfd);
return -1;
}

//存储信息

memcpy(mac, ifreq.ifr_hwaddr.sa_data, 6);
printf("MAC:02x-02x-02x-02x-02x-02x\n");
if(NULL != pMac)
{
memcpy(pMac, mac, 6);
}
close(sockfd);
return 0;
}


int netGetIp(char *interface, unsigned int *ip)
{
int sockfd = -1;
struct ifreq ifr;

if((NULL == interface) || ('\0' == interface))
{
printf("get ip :interface == NULL\r\n");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, interface, IFNAMSIZ);

//创建与底层交互的套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd <= 0)
{
printf("get ip:sock error\n");
return -1;
}
((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = PF_INET;

通过ioctl()获取指定信息
if(ioctl(sockfd, SIOCGIFADDR, &ifr) < 0)
{
printf("get ip ioctl error\n");
close(sockfd);
return -1;
}
else
{
*ip = ((struct sockaddr_sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;

printf("ip is %s\n", inet_ntoa(((struct sockaddr_sockaddr_in *)&ifr.ifr_addr)->sin_addr));
}
close(sockfd);
return 0;
}


方法二:使用getifaddrs(&ifaddr)

getifaddrs(&ifaddr) 必须与 freeifaddrs(ifaddr);配套使用

int getINCInfo()

struct ifaddrs *ifaddr =NULL, *ifa = NULL; 

 if (getifaddrs(&ifaddr) == -1) {          

perror("getifaddrs");          

return -1;

}  

 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) 

{         

if (ifa->ifa_addr == NULL)              

continue;  

printf("network name is %s\n", ifa_name);

printf("network addr is %s\n", inet_ntoa((((struct sockaddr_in *)(ifa_addr)).sin_addr)));

}

return 0;



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 */ 
}; 


struct sockaddr与struct sockaddr_in ,struct sockaddr_un的区别和联系

在linux环境下,结构体struct sockaddr在/usr/include/linux/socket.h中定义,具体如下:
typedef unsigned short sa_family_t;
struct sockaddr {
        sa_family_t     sa_family;    /* address family, AF_xxx       */
        char            sa_data[14];    /* 14 bytes of protocol address */

在linux环境下,结构体struct sockaddr_in在/usr/include/netinet/in.h中定义,具体如下:
/* Structure describing an Internet socket address. */
struct sockaddr_in
{
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;                     /* Port number. */
    struct in_addr sin_addr;            /* Internet address. */

    /* Pad to size of `struct sockaddr'. */
    unsigned char sin_zero[sizeof (struct sockaddr) -
                           __SOCKADDR_COMMON_SIZE -
                           sizeof (in_port_t) -
                           sizeof (struct in_addr)];     
                           /* 字符数组sin_zero[8]的存在是为了保证结构体struct sockaddr_in的大小和结构体struct sockaddr的大小相等 */
};
struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,二者长度一样,都是16个字节。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值