tools.h

#ifndef ARP_TOOLS_H
#define ARP_TOOLS_H

#include <net/if.h>
#include <net/ethernet.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#define IP_ALEN 16
/*
* 定义接口的基本信息类型
*/
struct ifi_rinfo {
    char ifname[IF_NAMESIZE];  // 接口名字
    struct sockaddr_in *ipaddr;  // 接口的ip地址网络字节序
    uint8_t hwaddr[ETHER_ADDR_LEN];  // 接口硬件地址
    char ipaddr_str[IF_NAMESIZE];  // 接口的点分十进制ip地址
    int ifindex;  // 接口索引
    int flags;  // 接口标志
};

struct ifi_rinfo * get_ifi_rinfo(char *); 

#endif

tools.c

#include <tools.h>

/*
*获取指定接口的基本信息
*/
struct ifi_rinfo * get_ifi_rinfo(char * ifname) {
    struct ifreq ifr;
    int sockfd;
    struct ifi_rinfo *rinfo;
    struct sockaddr_in *sinptr;
    char ipstr[IP_ALEN];  // 存放点分十进制的ip地址
    if(-1 == (sockfd = socket(AF_INET, SOCK_DGRAM, 0))) {
        perror("socket");
        return NULL;
    }
    rinfo = (struct ifi_rinfo *)malloc(sizeof(struct ifi_rinfo));
    memset(rinfo, 0, sizeof(struct ifi_rinfo));
    memset(&ifr, 0, sizeof(struct ifreq));

    strcpy(ifr.ifr_name, ifname);

    // 获取ifindex
    if ( ioctl(sockfd, SIOCGIFINDEX, &ifr) < 0 ) {
        perror("ioctl SIOCGIFINDEX error");
        return NULL;
    }
    rinfo->ifindex = ifr.ifr_ifindex;
    //  获取ip地址
    if ( ioctl(sockfd, SIOCGIFADDR, &ifr) < 0 ) {
        perror("ioctl SIOCGIFADDR error");
        return NULL;
    }
    sinptr = (struct sockaddr_in *)&ifr.ifr_addr;
    rinfo->ipaddr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
    inet_ntop(AF_INET, &sinptr->sin_addr, ipstr, sizeof(ipstr) );
    strcpy(rinfo->ipaddr_str, ipstr);
    memcpy(rinfo->ipaddr, sinptr, sizeof(struct sockaddr_in));

    // 获取硬件地址
    if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
        free(rinfo);
        perror("ioctl SIOCGIFHWADDR error");
        return NULL;
    }
    memcpy(rinfo->hwaddr, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
    // 获取flags
    if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
        free(rinfo);
        printf("ioctl SIOCGIFFLAGS error");
        return NULL;
    }
    rinfo->flags = ifr.ifr_flags;
    // 成功将ifname复制到rinfo中
    strcpy(rinfo->ifname, ifname);
    return rinfo;
}
文档更新时间: 2021-02-04 19:16   作者:周国强