- 论坛徽章:
- 0
|
我自己来回答吧,可以参考iproute中关于获取网络接口信息的方法处理。
以下代码是摘自iproute2-4.0源码
int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
void *arg)
{
FILE *fp = arg;
struct ifaddrmsg *ifa = NLMSG_DATA(n);
int len = n->nlmsg_len;
int deprecated = 0;
/* Use local copy of ifa_flags to not interfere with filtering code */
unsigned int ifa_flags;
struct rtattr * rta_tb[IFA_MAX+1];
char abuf[256];
SPRINT_BUF(b1);
if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) // 判断netlink消息类型
return 0;
len -= NLMSG_LENGTH(sizeof(*ifa));
if (len < 0) {
fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
return -1;
}
if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
return 0;
parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), //解析消息属性
n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]);
if (!rta_tb[IFA_LOCAL])
rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
if (!rta_tb[IFA_ADDRESS])
rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
// 针对过滤条件进行筛选
if (filter.ifindex && filter.ifindex != ifa->ifa_index)
return 0;
if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
return 0;
if ((filter.flags ^ ifa_flags) & filter.flagmask)
return 0;
if (filter.label) {
SPRINT_BUF(b1);
const char *label;
if (rta_tb[IFA_LABEL])
label = RTA_DATA(rta_tb[IFA_LABEL]);
else
label = ll_idx_n2a(ifa->ifa_index, b1);
if (fnmatch(filter.label, label, 0) != 0)
return 0;
}
if (filter.pfx.family) {
if (rta_tb[IFA_LOCAL]) {
inet_prefix dst;
memset(&dst, 0, sizeof(dst));
dst.family = ifa->ifa_family;
memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
return 0;
}
}
if (filter.family && filter.family != ifa->ifa_family)
return 0;
if (filter.flushb) {
struct nlmsghdr *fn;
if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
if (flush_update())
return -1;
}
fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
memcpy(fn, n, n->nlmsg_len);
fn->nlmsg_type = RTM_DELADDR;
fn->nlmsg_flags = NLM_F_REQUEST;
fn->nlmsg_seq = ++rth.seq;
filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
filter.flushed++;
if (show_stats < 2)
return 0;
}
if (n->nlmsg_type == RTM_DELADDR)
fprintf(fp, "Deleted ");
if (filter.oneline || filter.flushb)
fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
if (ifa->ifa_family == AF_INET)
fprintf(fp, " inet ");
else if (ifa->ifa_family == AF_INET6)
fprintf(fp, " inet6 ");
else if (ifa->ifa_family == AF_DECnet)
fprintf(fp, " dnet ");
else if (ifa->ifa_family == AF_IPX)
fprintf(fp, " ipx ");
else
fprintf(fp, " family %d ", ifa->ifa_family);
if (rta_tb[IFA_LOCAL]) { //获取本地IP地址信息
fprintf(fp, "%s", format_host(ifa->ifa_family,
RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
RTA_DATA(rta_tb[IFA_LOCAL]),
abuf, sizeof(abuf)));
if (rta_tb[IFA_ADDRESS] == NULL ||
memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]),
ifa->ifa_family == AF_INET ? 4 : 16) == 0) {
fprintf(fp, "/%d ", ifa->ifa_prefixlen); //获取本地IP地址的子网掩码长度
} else {
fprintf(fp, " peer %s/%d ", //点对点类型的peer端IP地址及子网掩码长度
format_host(ifa->ifa_family,
RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
RTA_DATA(rta_tb[IFA_ADDRESS]),
abuf, sizeof(abuf)),
ifa->ifa_prefixlen);
}
}
if (rta_tb[IFA_BROADCAST]) {
fprintf(fp, "brd %s ",
format_host(ifa->ifa_family,
RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
RTA_DATA(rta_tb[IFA_BROADCAST]),
abuf, sizeof(abuf)));
}
if (rta_tb[IFA_ANYCAST]) {
fprintf(fp, "any %s ",
format_host(ifa->ifa_family,
RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
RTA_DATA(rta_tb[IFA_ANYCAST]),
abuf, sizeof(abuf)));
}
fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
if (ifa_flags & IFA_F_SECONDARY) {
ifa_flags &= ~IFA_F_SECONDARY;
if (ifa->ifa_family == AF_INET6)
fprintf(fp, "temporary ");
else
fprintf(fp, "secondary ");
}
if (ifa_flags & IFA_F_TENTATIVE) {
ifa_flags &= ~IFA_F_TENTATIVE;
fprintf(fp, "tentative ");
}
if (ifa_flags & IFA_F_DEPRECATED) {
ifa_flags &= ~IFA_F_DEPRECATED;
deprecated = 1;
fprintf(fp, "deprecated ");
}
if (ifa_flags & IFA_F_HOMEADDRESS) {
ifa_flags &= ~IFA_F_HOMEADDRESS;
fprintf(fp, "home ");
}
if (ifa_flags & IFA_F_NODAD) {
ifa_flags &= ~IFA_F_NODAD;
fprintf(fp, "nodad ");
}
if (ifa_flags & IFA_F_MANAGETEMPADDR) {
ifa_flags &= ~IFA_F_MANAGETEMPADDR;
fprintf(fp, "mngtmpaddr ");
}
if (ifa_flags & IFA_F_NOPREFIXROUTE) {
ifa_flags &= ~IFA_F_NOPREFIXROUTE;
fprintf(fp, "noprefixroute ");
}
if (!(ifa_flags & IFA_F_PERMANENT)) {
fprintf(fp, "dynamic ");
} else
ifa_flags &= ~IFA_F_PERMANENT;
if (ifa_flags & IFA_F_DADFAILED) {
ifa_flags &= ~IFA_F_DADFAILED;
fprintf(fp, "dadfailed ");
}
if (ifa_flags)
fprintf(fp, "flags %02x ", ifa_flags);
if (rta_tb[IFA_LABEL]) //名字,在ip aliases时代,它是ethx:y的形式,在secondary ip时代,它统一就是ethx
fprintf(fp, "%s", rta_getattr_str(rta_tb[IFA_LABEL]));
if (rta_tb[IFA_CACHEINFO]) {
struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
fprintf(fp, "%s", _SL_);
fprintf(fp, " valid_lft ");
if (ci->ifa_valid == INFINITY_LIFE_TIME)
fprintf(fp, "forever");
else
fprintf(fp, "%usec", ci->ifa_valid);
fprintf(fp, " preferred_lft ");
if (ci->ifa_prefered == INFINITY_LIFE_TIME)
fprintf(fp, "forever");
else {
if (deprecated)
fprintf(fp, "%dsec", ci->ifa_prefered);
else
fprintf(fp, "%usec", ci->ifa_prefered);
}
}
fprintf(fp, "\n");
fflush(fp);
return 0;
} |
评分
-
查看全部评分
|