//通过ifreq结构体来获取接口信息
struct ifreq
{
# define IFHWADDRLEN 6
# define IFNAMSIZ IF_NAMESIZE
union
{
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
} ifr_ifrn;
union
{
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short int ifru_flags;
/*
enum net_device_flags {
IFF_UP = 1<<0, /* sysfs */
IFF_BROADCAST = 1<<1, /* __volatile__ */
IFF_DEBUG = 1<<2, /* sysfs */
IFF_LOOPBACK = 1<<3, /* __volatile__ */
IFF_POINTOPOINT = 1<<4, /* __volatile__ */
IFF_NOTRAILERS = 1<<5, /* sysfs */
IFF_RUNNING = 1<<6, /* __volatile__ */
IFF_NOARP = 1<<7, /* sysfs */
IFF_PROMISC = 1<<8, /* sysfs */
IFF_ALLMULTI = 1<<9, /* sysfs */
IFF_MASTER = 1<<10, /* __volatile__ */
IFF_SLAVE = 1<<11, /* __volatile__ */
IFF_MULTICAST = 1<<12, /* sysfs */
IFF_PORTSEL = 1<<13, /* sysfs */
IFF_AUTOMEDIA = 1<<14, /* sysfs */
IFF_DYNAMIC = 1<<15, /* sysfs */
IFF_LOWER_UP = 1<<16, /* __volatile__ */
IFF_DORMANT = 1<<17, /* __volatile__ */
IFF_ECHO = 1<<18, /* __volatile__ */
};
*/
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
__caddr_t ifru_data;
} ifr_ifru;
};
int connman_inet_ifindex(const char *name)
{
struct ifreq ifr;
int sk, err;
if (!name)
return -1;
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
return -1;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
err = ioctl(sk, SIOCGIFINDEX, &ifr);
close(sk);
if (err < 0)
return -1;
return ifr.ifr_ifindex;
}
char *connman_inet_ifname(int index)
{
struct ifreq ifr;
int sk, err;
if (index < 0)
return NULL;
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
return NULL;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_ifindex = index;
err = ioctl(sk, SIOCGIFNAME, &ifr);
close(sk);
if (err < 0)
return NULL;
return strdup(ifr.ifr_name); //需要手动释放内存 free
}
int connman_inet_ifup(int index) //类似于 ifconfig up
{
struct ifreq ifr;
int sk, err;
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
return -errno;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_ifindex = index;
if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
err = -errno;
goto done;
}
if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
err = -errno;
goto done;
}
if (ifr.ifr_flags & IFF_UP) {
err = -EALREADY;
goto done;
}
ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
err = -errno;
goto done;
}
err = 0;
done:
close(sk);
return err;
}
///sys/class/net/xxx/flags 最终就是修改内核,在应用层映射出来就是这个配置文件 内核映射在sys文件中
int connman_inet_ifdown(int index) //类似于 ifconfig down
{
struct ifreq ifr, addr_ifr;
struct sockaddr_in *addr;
int sk, err;
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
return -errno;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_ifindex = index;
if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
err = -errno;
goto done;
}
if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
err = -errno;
goto done;
}
memset(&addr_ifr, 0, sizeof(addr_ifr));
memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
addr->sin_family = AF_INET;
if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
connman_warn("Could not clear IPv4 address index %d", index);
if (!(ifr.ifr_flags & IFF_UP)) {
err = -EALREADY;
goto done;
}
ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
err = -errno;
else
err = 0;
done:
close(sk);
return err;
}
ifreq ifr 配置网口信息
最新推荐文章于 2023-09-27 14:11:16 发布