本文整理汇总了C++中NLMSG_LENGTH函数的典型用法代码示例。如果您正苦于以下问题:C++ NLMSG_LENGTH函数的具体用法?C++ NLMSG_LENGTH怎么用?C++ NLMSG_LENGTH使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NLMSG_LENGTH函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: get_response
static int get_response(struct nlmsghdr *n, void *arg)
{
struct genlmsghdr *ghdr;
struct l2tp_data *data = arg;
struct l2tp_parm *p = &data->config;
struct rtattr *attrs[L2TP_ATTR_MAX + 1];
struct rtattr *nla_stats;
int len;
/* Validate message and parse attributes */
if (n->nlmsg_type == NLMSG_ERROR)
return -EBADMSG;
ghdr = NLMSG_DATA(n);
len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*ghdr));
if (len < 0)
return -1;
parse_rtattr(attrs, L2TP_ATTR_MAX, (void *)ghdr + GENL_HDRLEN, len);
if (attrs[L2TP_ATTR_PW_TYPE])
p->pw_type = rta_getattr_u16(attrs[L2TP_ATTR_PW_TYPE]);
if (attrs[L2TP_ATTR_ENCAP_TYPE])
p->encap = rta_getattr_u16(attrs[L2TP_ATTR_ENCAP_TYPE]);
if (attrs[L2TP_ATTR_OFFSET])
p->offset = rta_getattr_u16(attrs[L2TP_ATTR_OFFSET]);
if (attrs[L2TP_ATTR_DATA_SEQ])
p->data_seq = rta_getattr_u16(attrs[L2TP_ATTR_DATA_SEQ]);
if (attrs[L2TP_ATTR_CONN_ID])
p->tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_CONN_ID]);
if (attrs[L2TP_ATTR_PEER_CONN_ID])
p->peer_tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_PEER_CONN_ID]);
if (attrs[L2TP_ATTR_SESSION_ID])
p->session_id = rta_getattr_u32(attrs[L2TP_ATTR_SESSION_ID]);
if (attrs[L2TP_ATTR_PEER_SESSION_ID])
p->peer_session_id = rta_getattr_u32(attrs[L2TP_ATTR_PEER_SESSION_ID]);
if (attrs[L2TP_ATTR_L2SPEC_TYPE])
p->l2spec_type = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_TYPE]);
if (attrs[L2TP_ATTR_L2SPEC_LEN])
p->l2spec_len = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_LEN]);
if (attrs[L2TP_ATTR_UDP_CSUM])
p->udp_csum = !!rta_getattr_u8(attrs[L2TP_ATTR_UDP_CSUM]);
p->udp6_csum_tx = !attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX];
p->udp6_csum_rx = !attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX];
if (attrs[L2TP_ATTR_COOKIE])
memcpy(p->cookie, RTA_DATA(attrs[L2TP_ATTR_COOKIE]),
p->cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_COOKIE]));
if (attrs[L2TP_ATTR_PEER_COOKIE])
memcpy(p->peer_cookie, RTA_DATA(attrs[L2TP_ATTR_PEER_COOKIE]),
p->peer_cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_PEER_COOKIE]));
if (attrs[L2TP_ATTR_RECV_SEQ])
p->recv_seq = !!rta_getattr_u8(attrs[L2TP_ATTR_RECV_SEQ]);
if (attrs[L2TP_ATTR_SEND_SEQ])
p->send_seq = !!rta_getattr_u8(attrs[L2TP_ATTR_SEND_SEQ]);
if (attrs[L2TP_ATTR_RECV_TIMEOUT])
p->reorder_timeout = rta_getattr_u64(attrs[L2TP_ATTR_RECV_TIMEOUT]);
if (attrs[L2TP_ATTR_IP_SADDR]) {
p->local_ip.family = AF_INET;
p->local_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_SADDR]);
p->local_ip.bytelen = 4;
p->local_ip.bitlen = -1;
}
if (attrs[L2TP_ATTR_IP_DADDR]) {
p->peer_ip.family = AF_INET;
p->peer_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_DADDR]);
p->peer_ip.bytelen = 4;
p->peer_ip.bitlen = -1;
}
if (attrs[L2TP_ATTR_IP6_SADDR]) {
p->local_ip.family = AF_INET6;
memcpy(&p->local_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_SADDR]),
p->local_ip.bytelen = 16);
p->local_ip.bitlen = -1;
}
if (attrs[L2TP_ATTR_IP6_DADDR]) {
p->peer_ip.family = AF_INET6;
memcpy(&p->peer_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_DADDR]),
p->peer_ip.bytelen = 16);
p->peer_ip.bitlen = -1;
}
if (attrs[L2TP_ATTR_UDP_SPORT])
p->local_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_SPORT]);
if (attrs[L2TP_ATTR_UDP_DPORT])
p->peer_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_DPORT]);
if (attrs[L2TP_ATTR_MTU])
p->mtu = rta_getattr_u16(attrs[L2TP_ATTR_MTU]);
if (attrs[L2TP_ATTR_IFNAME])
p->ifname = rta_getattr_str(attrs[L2TP_ATTR_IFNAME]);
nla_stats = attrs[L2TP_ATTR_STATS];
if (nla_stats) {
struct rtattr *tb[L2TP_ATTR_STATS_MAX + 1];
parse_rtattr_nested(tb, L2TP_ATTR_STATS_MAX, nla_stats);
//.........这里部分代码省略.........
示例2: genl_ctrl_resolve_family
int genl_ctrl_resolve_family(const char *family)
{
struct rtnl_handle rth;
struct nlmsghdr *nlh;
struct genlmsghdr *ghdr;
int ret = 0;
struct {
struct nlmsghdr n;
char buf[4096];
} req;
memset(&req, 0, sizeof(req));
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_type = GENL_ID_CTRL;
ghdr = NLMSG_DATA(&req.n);
ghdr->cmd = CTRL_CMD_GETFAMILY;
if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) {
fprintf(stderr, "Cannot open generic netlink socket\n");
exit(1);
}
addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, family, strlen(family) + 1);
if (rtnl_talk(&rth, nlh, nlh, sizeof(req)) < 0) {
fprintf(stderr, "Error talking to the kernel\n");
goto errout;
}
{
struct rtattr *tb[CTRL_ATTR_MAX + 1];
struct genlmsghdr *ghdr = NLMSG_DATA(nlh);
int len = nlh->nlmsg_len;
struct rtattr *attrs;
if (nlh->nlmsg_type != GENL_ID_CTRL) {
fprintf(stderr, "Not a controller message, nlmsg_len=%d "
"nlmsg_type=0x%x\n", nlh->nlmsg_len, nlh->nlmsg_type);
goto errout;
}
if (ghdr->cmd != CTRL_CMD_NEWFAMILY) {
fprintf(stderr, "Unknown controller command %d\n", ghdr->cmd);
goto errout;
}
len -= NLMSG_LENGTH(GENL_HDRLEN);
if (len < 0) {
fprintf(stderr, "wrong controller message len %d\n", len);
return -1;
}
attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);
if (tb[CTRL_ATTR_FAMILY_ID] == NULL) {
fprintf(stderr, "Missing family id TLV\n");
goto errout;
}
ret = rta_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]);
}
errout:
rtnl_close(&rth);
return ret;
}
示例3: tc_qdisc_modify
static int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv)
{
struct qdisc_util *q = NULL;
struct tc_estimator est;
struct {
struct tc_sizespec szopts;
__u16 *data;
} stab;
char d[16];
char k[16];
struct {
struct nlmsghdr n;
struct tcmsg t;
char buf[TCA_BUF_MAX];
} req;
memset(&req, 0, sizeof(req));
memset(&stab, 0, sizeof(stab));
memset(&est, 0, sizeof(est));
memset(&d, 0, sizeof(d));
memset(&k, 0, sizeof(k));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
req.n.nlmsg_type = cmd;
req.t.tcm_family = AF_UNSPEC;
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
if (d[0])
duparg("dev", *argv);
strncpy(d, *argv, sizeof(d)-1);
} else if (strcmp(*argv, "handle") == 0) {
__u32 handle;
if (req.t.tcm_handle)
duparg("handle", *argv);
NEXT_ARG();
if (get_qdisc_handle(&handle, *argv))
invarg("invalid qdisc ID", *argv);
req.t.tcm_handle = handle;
} else if (strcmp(*argv, "root") == 0) {
if (req.t.tcm_parent) {
fprintf(stderr, "Error: \"root\" is duplicate parent ID\n");
return -1;
}
req.t.tcm_parent = TC_H_ROOT;
#ifdef TC_H_INGRESS
} else if (strcmp(*argv, "ingress") == 0) {
if (req.t.tcm_parent) {
fprintf(stderr, "Error: \"ingress\" is a duplicate parent ID\n");
return -1;
}
req.t.tcm_parent = TC_H_INGRESS;
strncpy(k, "ingress", sizeof(k)-1);
q = get_qdisc_kind(k);
req.t.tcm_handle = 0xffff0000;
argc--; argv++;
break;
#endif
} else if (strcmp(*argv, "parent") == 0) {
__u32 handle;
NEXT_ARG();
if (req.t.tcm_parent)
duparg("parent", *argv);
if (get_tc_classid(&handle, *argv))
invarg("invalid parent ID", *argv);
req.t.tcm_parent = handle;
} else if (matches(*argv, "estimator") == 0) {
if (parse_estimator(&argc, &argv, &est))
return -1;
} else if (matches(*argv, "stab") == 0) {
if (parse_size_table(&argc, &argv, &stab.szopts) < 0)
return -1;
continue;
} else if (matches(*argv, "help") == 0) {
usage();
} else {
strncpy(k, *argv, sizeof(k)-1);
q = get_qdisc_kind(k);
argc--; argv++;
break;
}
argc--; argv++;
}
if (k[0])
addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
if (est.ewma_log)
addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est));
if (q) {
if (q->parse_qopt) {
if (q->parse_qopt(q, argc, argv, &req.n))
return 1;
} else if (argc) {
fprintf(stderr, "qdisc '%s' does not support option parsing\n", k);
return -1;
//.........这里部分代码省略.........
示例4: gre_parse_opt
static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
struct {
struct nlmsghdr n;
struct ifinfomsg i;
char buf[1024];
} req;
struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1);
struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *greinfo[IFLA_GRE_MAX + 1];
__u16 iflags = 0;
__u16 oflags = 0;
unsigned ikey = 0;
unsigned okey = 0;
unsigned saddr = 0;
unsigned daddr = 0;
unsigned link = 0;
__u8 pmtudisc = 1;
__u8 ttl = 0;
__u8 tos = 0;
int len;
if (!(n->nlmsg_flags & NLM_F_CREATE)) {
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi));
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = RTM_GETLINK;
req.i.ifi_family = preferred_family;
req.i.ifi_index = ifi->ifi_index;
if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
get_failed:
fprintf(stderr,
"Failed to get existing tunnel info.\n");
return -1;
}
len = req.n.nlmsg_len;
len -= NLMSG_LENGTH(sizeof(*ifi));
if (len < 0)
goto get_failed;
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);
if (!tb[IFLA_LINKINFO])
goto get_failed;
parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
if (!linkinfo[IFLA_INFO_DATA])
goto get_failed;
parse_rtattr_nested(greinfo, IFLA_GRE_MAX,
linkinfo[IFLA_INFO_DATA]);
if (greinfo[IFLA_GRE_IKEY])
ikey = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_IKEY]);
if (greinfo[IFLA_GRE_OKEY])
okey = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_OKEY]);
if (greinfo[IFLA_GRE_IFLAGS])
iflags = *(__u16 *)RTA_DATA(greinfo[IFLA_GRE_IFLAGS]);
if (greinfo[IFLA_GRE_OFLAGS])
oflags = *(__u16 *)RTA_DATA(greinfo[IFLA_GRE_OFLAGS]);
if (greinfo[IFLA_GRE_LOCAL])
saddr = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_LOCAL]);
if (greinfo[IFLA_GRE_REMOTE])
daddr = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_REMOTE]);
if (greinfo[IFLA_GRE_PMTUDISC])
pmtudisc = *(__u8 *)RTA_DATA(
greinfo[IFLA_GRE_PMTUDISC]);
if (greinfo[IFLA_GRE_TTL])
ttl = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_TTL]);
if (greinfo[IFLA_GRE_TOS])
tos = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_TOS]);
if (greinfo[IFLA_GRE_LINK])
link = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_LINK]);
}
while (argc > 0) {
if (!matches(*argv, "key")) {
unsigned uval;
NEXT_ARG();
iflags |= GRE_KEY;
oflags |= GRE_KEY;
if (strchr(*argv, '.'))
uval = get_addr32(*argv);
else {
//.........这里部分代码省略.........
示例5: print_ctrl
/*
* The controller sends one nlmsg per family
*/
static int print_ctrl(const struct sockaddr_nl *who,
struct rtnl_ctrl_data *ctrl,
struct nlmsghdr *n, void *arg)
{
struct rtattr *tb[CTRL_ATTR_MAX + 1];
struct genlmsghdr *ghdr = NLMSG_DATA(n);
int len = n->nlmsg_len;
struct rtattr *attrs;
FILE *fp = (FILE *) arg;
__u32 ctrl_v = 0x1;
if (n->nlmsg_type != GENL_ID_CTRL) {
fprintf(stderr, "Not a controller message, nlmsg_len=%d "
"nlmsg_type=0x%x\n", n->nlmsg_len, n->nlmsg_type);
return 0;
}
if (ghdr->cmd != CTRL_CMD_GETFAMILY &&
ghdr->cmd != CTRL_CMD_DELFAMILY &&
ghdr->cmd != CTRL_CMD_NEWFAMILY &&
ghdr->cmd != CTRL_CMD_NEWMCAST_GRP &&
ghdr->cmd != CTRL_CMD_DELMCAST_GRP) {
fprintf(stderr, "Unknown controller command %d\n", ghdr->cmd);
return 0;
}
len -= NLMSG_LENGTH(GENL_HDRLEN);
if (len < 0) {
fprintf(stderr, "wrong controller message len %d\n", len);
return -1;
}
attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);
if (tb[CTRL_ATTR_FAMILY_NAME]) {
char *name = RTA_DATA(tb[CTRL_ATTR_FAMILY_NAME]);
fprintf(fp, "\nName: %s\n",name);
}
if (tb[CTRL_ATTR_FAMILY_ID]) {
__u16 *id = RTA_DATA(tb[CTRL_ATTR_FAMILY_ID]);
fprintf(fp, "\tID: 0x%x ",*id);
}
if (tb[CTRL_ATTR_VERSION]) {
__u32 *v = RTA_DATA(tb[CTRL_ATTR_VERSION]);
fprintf(fp, " Version: 0x%x ",*v);
ctrl_v = *v;
}
if (tb[CTRL_ATTR_HDRSIZE]) {
__u32 *h = RTA_DATA(tb[CTRL_ATTR_HDRSIZE]);
fprintf(fp, " header size: %d ",*h);
}
if (tb[CTRL_ATTR_MAXATTR]) {
__u32 *ma = RTA_DATA(tb[CTRL_ATTR_MAXATTR]);
fprintf(fp, " max attribs: %d ",*ma);
}
/* end of family definitions .. */
fprintf(fp,"\n");
if (tb[CTRL_ATTR_OPS]) {
struct rtattr *tb2[GENL_MAX_FAM_OPS];
int i=0;
parse_rtattr_nested(tb2, GENL_MAX_FAM_OPS, tb[CTRL_ATTR_OPS]);
fprintf(fp, "\tcommands supported: \n");
for (i = 0; i < GENL_MAX_FAM_OPS; i++) {
if (tb2[i]) {
fprintf(fp, "\t\t#%d: ", i);
if (0 > print_ctrl_cmds(fp, tb2[i], ctrl_v)) {
fprintf(fp, "Error printing command\n");
}
/* for next command */
fprintf(fp,"\n");
}
}
/* end of family::cmds definitions .. */
fprintf(fp,"\n");
}
if (tb[CTRL_ATTR_MCAST_GROUPS]) {
struct rtattr *tb2[GENL_MAX_FAM_GRPS + 1];
int i;
parse_rtattr_nested(tb2, GENL_MAX_FAM_GRPS,
tb[CTRL_ATTR_MCAST_GROUPS]);
fprintf(fp, "\tmulticast groups:\n");
for (i = 0; i < GENL_MAX_FAM_GRPS; i++) {
if (tb2[i]) {
fprintf(fp, "\t\t#%d: ", i);
if (0 > print_ctrl_grp(fp, tb2[i], ctrl_v))
fprintf(fp, "Error printing group\n");
/* for next group */
fprintf(fp,"\n");
}
}
//.........这里部分代码省略.........
示例6: source_for_dest
/**
* In case one binds to 0.0.0.0/INADDR_ANY and wants to know which source
* address will be used when sending a message this function can be used.
* It will ask the routing code of the kernel for the PREFSRC
*/
int source_for_dest(const struct in_addr *dest, struct in_addr *loc_source)
{
int fd, rc;
struct rtmsg *r;
struct rtattr *rta;
struct {
struct nlmsghdr n;
struct rtmsg r;
char buf[1024];
} req;
memset(&req, 0, sizeof(req));
fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
if (fd < 0) {
perror("nl socket");
return -1;
}
/* Send a rtmsg and ask for a response */
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
req.n.nlmsg_type = RTM_GETROUTE;
req.n.nlmsg_seq = 1;
/* Prepare the routing request */
req.r.rtm_family = AF_INET;
/* set the dest */
rta = NLMSG_TAIL(&req.n);
rta->rta_type = RTA_DST;
rta->rta_len = RTA_LENGTH(sizeof(*dest));
memcpy(RTA_DATA(rta), dest, sizeof(*dest));
/* update sizes for dest */
req.r.rtm_dst_len = sizeof(*dest) * 8;
req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_ALIGN(rta->rta_len);
rc = send(fd, &req, req.n.nlmsg_len, 0);
if (rc != req.n.nlmsg_len) {
perror("short write");
close(fd);
return -2;
}
/* now receive a response and parse it */
rc = recv(fd, &req, sizeof(req), 0);
if (rc <= 0) {
perror("short read");
close(fd);
return -3;
}
if (!NLMSG_OK(&req.n, rc) || req.n.nlmsg_type != RTM_NEWROUTE) {
close(fd);
return -4;
}
r = NLMSG_DATA(&req.n);
rc -= NLMSG_LENGTH(sizeof(*r));
rta = RTM_RTA(r);
while (RTA_OK(rta, rc)) {
if (rta->rta_type != RTA_PREFSRC) {
rta = RTA_NEXT(rta, rc);
continue;
}
/* we are done */
memcpy(loc_source, RTA_DATA(rta), RTA_PAYLOAD(rta));
close(fd);
return 0;
}
close(fd);
return -5;
}
示例7: print_route
int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
FILE *fp = (FILE*)arg;
struct rtmsg *r = NLMSG_DATA(n);
int len = n->nlmsg_len;
struct rtattr * tb[RTA_MAX+1];
char abuf[256];
int host_len;
__u32 table;
SPRINT_BUF(b1);
static int hz;
if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
fprintf(stderr, "Not a route: %08x %08x %08x\n",
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
return 0;
}
if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
return 0;
len -= NLMSG_LENGTH(sizeof(*r));
if (len < 0) {
fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
return -1;
}
host_len = af_bit_len(r->rtm_family);
parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
table = rtm_get_table(r, tb);
if (!filter_nlmsg(n, tb, host_len))
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_DELROUTE;
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_DELROUTE)
fprintf(fp, "Deleted ");
if ((r->rtm_type != RTN_UNICAST || show_details > 0) && !filter.type)
fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
if (tb[RTA_DST]) {
if (r->rtm_dst_len != host_len) {
fprintf(fp, "%s/%u ", rt_addr_n2a(r->rtm_family,
RTA_PAYLOAD(tb[RTA_DST]),
RTA_DATA(tb[RTA_DST]),
abuf, sizeof(abuf)),
r->rtm_dst_len
);
} else {
fprintf(fp, "%s ", format_host(r->rtm_family,
RTA_PAYLOAD(tb[RTA_DST]),
RTA_DATA(tb[RTA_DST]),
abuf, sizeof(abuf))
);
}
} else if (r->rtm_dst_len) {
fprintf(fp, "0/%d ", r->rtm_dst_len);
} else {
fprintf(fp, "default ");
}
if (tb[RTA_SRC]) {
if (r->rtm_src_len != host_len) {
fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family,
RTA_PAYLOAD(tb[RTA_SRC]),
RTA_DATA(tb[RTA_SRC]),
abuf, sizeof(abuf)),
r->rtm_src_len
);
} else {
fprintf(fp, "from %s ", format_host(r->rtm_family,
RTA_PAYLOAD(tb[RTA_SRC]),
RTA_DATA(tb[RTA_SRC]),
abuf, sizeof(abuf))
);
}
} else if (r->rtm_src_len) {
fprintf(fp, "from 0/%u ", r->rtm_src_len);
}
if (tb[RTA_NEWDST]) {
fprintf(fp, "as to %s ", format_host(r->rtm_family,
RTA_PAYLOAD(tb[RTA_NEWDST]),
RTA_DATA(tb[RTA_NEWDST]),
abuf, sizeof(abuf))
);
}
//.........这里部分代码省略.........
示例8: netlink_link_add_vmac
int
netlink_link_add_vmac(vrrp_t *vrrp)
{
struct rtattr *linkinfo;
struct rtattr *data;
unsigned int base_ifindex;
interface_t *ifp;
interface_t *base_ifp;
char ifname[IFNAMSIZ];
struct {
struct nlmsghdr n;
struct ifinfomsg ifi;
char buf[256];
} req;
if (!vrrp->ifp || __test_bit(VRRP_VMAC_UP_BIT, &vrrp->vmac_flags) || !vrrp->vrid)
return -1;
if (vrrp->family == AF_INET6)
ll_addr[4] = 0x02;
else
ll_addr[4] = 0x01;
ll_addr[ETH_ALEN-1] = vrrp->vrid;
memset(&req, 0, sizeof (req));
memset(ifname, 0, IFNAMSIZ);
strncpy(ifname, vrrp->vmac_ifname, IFNAMSIZ - 1);
/*
* Check to see if this vmac interface was created
* by a previous instance.
*/
if ((ifp = if_get_by_ifname(ifname))) {
/* Check to see whether this interface has wrong mac ? */
if (memcmp((const void *) ifp->hw_addr,
(const void *) ll_addr, ETH_ALEN) != 0) {
/* We have found a VIF but the vmac do not match */
log_message(LOG_INFO, "vmac: Removing old VMAC interface %s due to conflicting "
"interface MAC for vrrp_instance %s!!!"
, vrrp->vmac_ifname, vrrp->iname);
/* Request that NETLINK remove the VIF interface first */
memset(&req, 0, sizeof (req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof (struct ifinfomsg));
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = RTM_DELLINK;
req.ifi.ifi_family = AF_INET;
req.ifi.ifi_index = IF_INDEX(ifp);
if (netlink_talk(&nl_cmd, &req.n) < 0) {
log_message(LOG_INFO, "vmac: Error removing VMAC interface %s for "
"vrrp_instance %s!!!"
, vrrp->vmac_ifname, vrrp->iname);
return -1;
}
/* Interface successfully removed, now recreate */
}
}
/* Request that NETLINK create the VIF interface */
req.n.nlmsg_len = NLMSG_LENGTH(sizeof (struct ifinfomsg));
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
req.n.nlmsg_type = RTM_NEWLINK;
req.ifi.ifi_family = AF_INET;
/* macvlan settings */
linkinfo = NLMSG_TAIL(&req.n);
addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, (void *)macvlan_ll_kind, strlen(macvlan_ll_kind));
data = NLMSG_TAIL(&req.n);
addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0);
/*
* In private mode, macvlan will receive frames with same MAC addr
* as configured on the interface.
*/
addattr32(&req.n, sizeof(req), IFLA_MACVLAN_MODE,
MACVLAN_MODE_PRIVATE);
data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data;
linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
addattr_l(&req.n, sizeof(req), IFLA_LINK, &IF_INDEX(vrrp->ifp), sizeof(uint32_t));
addattr_l(&req.n, sizeof(req), IFLA_IFNAME, ifname, strlen(ifname));
addattr_l(&req.n, sizeof(req), IFLA_ADDRESS, ll_addr, ETH_ALEN);
if (netlink_talk(&nl_cmd, &req.n) < 0) {
log_message(LOG_INFO, "vmac: Error creating VMAC interface %s for vrrp_instance %s!!!"
, ifname, vrrp->iname);
return -1;
}
log_message(LOG_INFO, "vmac: Success creating VMAC interface %s for vrrp_instance %s"
, ifname, vrrp->iname);
/*
* Update interface queue and vrrp instance interface binding.
*/
netlink_interface_lookup();
ifp = if_get_by_ifname(ifname);
//.........这里部分代码省略.........
示例9: print_route
int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
FILE *fp = (FILE*)arg;
struct rtmsg *r = NLMSG_DATA(n);
int len = n->nlmsg_len;
struct rtattr * tb[RTA_MAX+1];
char abuf[256];
inet_prefix dst;
inet_prefix src;
inet_prefix prefsrc;
inet_prefix via;
int host_len = -1;
static int ip6_multiple_tables;
__u32 table;
SPRINT_BUF(b1);
static int hz;
if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
fprintf(stderr, "Not a route: %08x %08x %08x\n",
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
return 0;
}
if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
return 0;
len -= NLMSG_LENGTH(sizeof(*r));
if (len < 0) {
fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
return -1;
}
if (r->rtm_family == AF_INET6)
host_len = 128;
else if (r->rtm_family == AF_INET)
host_len = 32;
else if (r->rtm_family == AF_DECnet)
host_len = 16;
else if (r->rtm_family == AF_IPX)
host_len = 80;
parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
table = rtm_get_table(r, tb);
if (r->rtm_family == AF_INET6 && table != RT_TABLE_MAIN)
ip6_multiple_tables = 1;
if (filter.cloned == !(r->rtm_flags&RTM_F_CLONED))
return 0;
if (r->rtm_family == AF_INET6 && !ip6_multiple_tables) {
if (filter.tb) {
if (filter.tb == RT_TABLE_LOCAL) {
if (r->rtm_type != RTN_LOCAL)
return 0;
} else if (filter.tb == RT_TABLE_MAIN) {
if (r->rtm_type == RTN_LOCAL)
return 0;
} else {
return 0;
}
}
} else {
if (filter.tb > 0 && filter.tb != table)
return 0;
}
if ((filter.protocol^r->rtm_protocol)&filter.protocolmask)
return 0;
if ((filter.scope^r->rtm_scope)&filter.scopemask)
return 0;
if ((filter.type^r->rtm_type)&filter.typemask)
return 0;
if ((filter.tos^r->rtm_tos)&filter.tosmask)
return 0;
if (filter.rdst.family &&
(r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len))
return 0;
if (filter.mdst.family &&
(r->rtm_family != filter.mdst.family ||
(filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len)))
return 0;
if (filter.rsrc.family &&
(r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len))
return 0;
if (filter.msrc.family &&
(r->rtm_family != filter.msrc.family ||
(filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len)))
return 0;
if (filter.rvia.family && r->rtm_family != filter.rvia.family)
return 0;
if (filter.rprefsrc.family && r->rtm_family != filter.rprefsrc.family)
return 0;
memset(&dst, 0, sizeof(dst));
dst.family = r->rtm_family;
if (tb[RTA_DST])
memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len+7)/8);
if (filter.rsrc.family || filter.msrc.family) {
memset(&src, 0, sizeof(src));
src.family = r->rtm_family;
if (tb[RTA_SRC])
memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), (r->rtm_src_len+7)/8);
//.........这里部分代码省略.........
示例10: format_netlink
static void
format_netlink(struct nlmsghdr *msg)
{
struct rtattr *tb[ACPI_GENL_ATTR_MAX + 1];
struct genlmsghdr *ghdr = NLMSG_DATA(msg);
int len;
struct rtattr *attrs;
len = msg->nlmsg_len;
/* if this message doesn't have the proper family ID, drop it */
if (msg->nlmsg_type != acpi_ids_getfamily()) {
if (logevents) {
acpid_log(LOG_INFO, "wrong netlink family ID.\n");
}
return;
}
len -= NLMSG_LENGTH(GENL_HDRLEN);
if (len < 0) {
acpid_log(LOG_WARNING,
"wrong netlink controller message len: %d\n", len);
return;
}
attrs = (struct rtattr *)((char *)ghdr + GENL_HDRLEN);
/* parse the attributes in this message */
parse_rtattr(tb, ACPI_GENL_ATTR_MAX, attrs, len);
/* if there's an ACPI event attribute... */
if (tb[ACPI_GENL_ATTR_EVENT]) {
/* get the actual event struct */
struct acpi_genl_event *event =
RTA_DATA(tb[ACPI_GENL_ATTR_EVENT]);
char buf[64];
/* format it */
snprintf(buf, sizeof(buf), "%s %s %08x %08x",
event->device_class, event->bus_id, event->type, event->data);
/* if we're locked, don't process the event */
if (locked()) {
if (logevents) {
acpid_log(LOG_INFO,
"lockfile present, not processing "
"netlink event \"%s\"\n", buf);
}
return;
}
if (logevents)
acpid_log(LOG_INFO,
"received netlink event \"%s\"\n", buf);
/* send the event off to the handler */
acpid_handle_event(buf);
if (logevents)
acpid_log(LOG_INFO,
"completed netlink event \"%s\"\n", buf);
}
}
示例11: recvaddrs
static void recvaddrs(int fd, struct ifaddrs **ifa, __u32 seq)
{
char buf[8192];
struct sockaddr_nl nladdr;
struct iovec iov = { buf, sizeof(buf) };
struct ifaddrmsg *m;
struct rtattr * rta_tb[IFA_MAX+1];
struct ifaddrs *I;
while (1) {
int status;
struct nlmsghdr *h;
struct msghdr msg = {
(void*)&nladdr, sizeof(nladdr),
&iov, 1,
NULL, 0,
0
};
status = recvmsg(fd, &msg, 0);
if (status < 0)
continue;
if (status == 0)
return;
if (nladdr.nl_pid) /* Message not from kernel */
continue;
h = (struct nlmsghdr*)buf;
while (NLMSG_OK(h, status)) {
if (h->nlmsg_seq != seq)
goto skip_it;
if (h->nlmsg_type == NLMSG_DONE)
return;
if (h->nlmsg_type == NLMSG_ERROR)
return;
if (h->nlmsg_type != RTM_NEWADDR)
goto skip_it;
m = NLMSG_DATA(h);
if (m->ifa_family != AF_INET &&
m->ifa_family != AF_INET6)
goto skip_it;
if (m->ifa_flags&IFA_F_TENTATIVE)
goto skip_it;
memset(rta_tb, 0, sizeof(rta_tb));
parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(m), h->nlmsg_len - NLMSG_LENGTH(sizeof(*m)));
if (rta_tb[IFA_LOCAL] == NULL)
rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
if (rta_tb[IFA_LOCAL] == NULL)
goto skip_it;
I = malloc(sizeof(struct ifaddrs));
if (!I)
return;
memset(I, 0, sizeof(*I));
I->ifa_ifindex = m->ifa_index;
I->ifa_addr = (struct sockaddr*)&I->ifa_addrbuf;
I->ifa_addr->sa_family = m->ifa_family;
if (m->ifa_family == AF_INET) {
struct sockaddr_in *sin = (void*)I->ifa_addr;
memcpy(&sin->sin_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 4);
} else {
struct sockaddr_in6 *sin = (void*)I->ifa_addr;
memcpy(&sin->sin6_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 16);
if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
sin->sin6_scope_id = I->ifa_ifindex;
}
I->ifa_next = *ifa;
*ifa = I;
skip_it:
h = NLMSG_NEXT(h, status);
}
if (msg.msg_flags & MSG_TRUNC)
continue;
}
return;
}
示例12: xfrm_policy_keep
static int xfrm_policy_keep(const struct sockaddr_nl *who,
struct nlmsghdr *n,
void *arg)
{
struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
struct rtnl_handle *rth = xb->rth;
struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(n);
int len = n->nlmsg_len;
struct rtattr *tb[XFRMA_MAX+1];
__u8 ptype = XFRM_POLICY_TYPE_MAIN;
struct nlmsghdr *new_n;
struct xfrm_userpolicy_id *xpid;
if (n->nlmsg_type != XFRM_MSG_NEWPOLICY) {
fprintf(stderr, "Not a policy: %08x %08x %08x\n",
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
return 0;
}
len -= NLMSG_LENGTH(sizeof(*xpinfo));
if (len < 0) {
fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
return -1;
}
parse_rtattr(tb, XFRMA_MAX, XFRMP_RTA(xpinfo), len);
if (tb[XFRMA_POLICY_TYPE]) {
struct xfrm_userpolicy_type *upt;
if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt)) {
fprintf(stderr, "too short XFRMA_POLICY_TYPE len\n");
return -1;
}
upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]);
ptype = upt->type;
}
if (!xfrm_policy_filter_match(xpinfo, ptype))
return 0;
if (xb->offset > xb->size) {
fprintf(stderr, "Policy buffer overflow\n");
return -1;
}
new_n = (struct nlmsghdr *)(xb->buf + xb->offset);
new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xpid));
new_n->nlmsg_flags = NLM_F_REQUEST;
new_n->nlmsg_type = XFRM_MSG_DELPOLICY;
new_n->nlmsg_seq = ++rth->seq;
xpid = NLMSG_DATA(new_n);
memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel));
xpid->dir = xpinfo->dir;
xpid->index = xpinfo->index;
xb->offset += new_n->nlmsg_len;
xb->nlmsg_count ++;
return 0;
}
示例13: xfrm_policy_modify
static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
{
struct rtnl_handle rth;
struct {
struct nlmsghdr n;
struct xfrm_userpolicy_info xpinfo;
char buf[RTA_BUF_SIZE];
} req;
char *dirp = NULL;
char *selp = NULL;
char *ptypep = NULL;
char *sctxp = NULL;
struct xfrm_userpolicy_type upt;
char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
int tmpls_len = 0;
struct xfrm_mark mark = {0, 0};
struct {
struct xfrm_user_sec_ctx sctx;
char str[CTX_BUF_SIZE];
} ctx;
memset(&req, 0, sizeof(req));
memset(&upt, 0, sizeof(upt));
memset(&tmpls_buf, 0, sizeof(tmpls_buf));
memset(&ctx, 0, sizeof(ctx));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo));
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
req.n.nlmsg_type = cmd;
req.xpinfo.sel.family = preferred_family;
req.xpinfo.lft.soft_byte_limit = XFRM_INF;
req.xpinfo.lft.hard_byte_limit = XFRM_INF;
req.xpinfo.lft.soft_packet_limit = XFRM_INF;
req.xpinfo.lft.hard_packet_limit = XFRM_INF;
while (argc > 0) {
if (strcmp(*argv, "dir") == 0) {
if (dirp)
duparg("dir", *argv);
dirp = *argv;
NEXT_ARG();
xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv);
} else if (strcmp(*argv, "ctx") == 0) {
char *context;
if (sctxp)
duparg("ctx", *argv);
sctxp = *argv;
NEXT_ARG();
context = *argv;
xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
} else if (strcmp(*argv, "mark") == 0) {
xfrm_parse_mark(&mark, &argc, &argv);
} else if (strcmp(*argv, "index") == 0) {
NEXT_ARG();
if (get_u32(&req.xpinfo.index, *argv, 0))
invarg("\"INDEX\" is invalid", *argv);
} else if (strcmp(*argv, "ptype") == 0) {
if (ptypep)
duparg("ptype", *argv);
ptypep = *argv;
NEXT_ARG();
xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
} else if (strcmp(*argv, "action") == 0) {
NEXT_ARG();
if (strcmp(*argv, "allow") == 0)
req.xpinfo.action = XFRM_POLICY_ALLOW;
else if (strcmp(*argv, "block") == 0)
req.xpinfo.action = XFRM_POLICY_BLOCK;
else
invarg("\"action\" value is invalid\n", *argv);
} else if (strcmp(*argv, "priority") == 0) {
NEXT_ARG();
if (get_u32(&req.xpinfo.priority, *argv, 0))
invarg("\"PRIORITY\" is invalid", *argv);
} else if (strcmp(*argv, "flag") == 0) {
NEXT_ARG();
xfrm_policy_flag_parse(&req.xpinfo.flags, &argc,
&argv);
} else if (strcmp(*argv, "limit") == 0) {
NEXT_ARG();
xfrm_lifetime_cfg_parse(&req.xpinfo.lft, &argc, &argv);
} else if (strcmp(*argv, "tmpl") == 0) {
struct xfrm_user_tmpl *tmpl;
if (tmpls_len + sizeof(*tmpl) > sizeof(tmpls_buf)) {
fprintf(stderr, "Too many tmpls: buffer overflow\n");
exit(1);
}
tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
tmpl->family = preferred_family;
tmpl->aalgos = (~(__u32)0);
tmpl->ealgos = (~(__u32)0);
tmpl->calgos = (~(__u32)0);
NEXT_ARG();
//.........这里部分代码省略.........
示例14: memset
char *indexp = NULL;
char *ptypep = NULL;
char *sctxp = NULL;
struct xfrm_userpolicy_type upt;
struct xfrm_mark mark = {0, 0};
struct {
struct xfrm_user_sec_ctx sctx;
char str[CTX_BUF_SIZE];
} ctx;
memset(&req, 0, sizeof(req));
memset(&upt, 0, sizeof(upt));
memset(&ctx, 0, sizeof(ctx));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid));
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = delete ? XFRM_MSG_DELPOLICY : XFRM_MSG_GETPOLICY;
while (argc > 0) {
if (strcmp(*argv, "dir") == 0) {
if (dirp)
duparg("dir", *argv);
dirp = *argv;
NEXT_ARG();
xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv);
} else if (strcmp(*argv, "ctx") == 0) {
char *context;
示例15: print_rule
int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
FILE *fp = (FILE*)arg;
struct rtmsg *r = NLMSG_DATA(n);
int len = n->nlmsg_len;
int host_len = -1;
__u32 table;
struct rtattr * tb[FRA_MAX+1];
char abuf[256];
SPRINT_BUF(b1);
if (n->nlmsg_type != RTM_NEWRULE && n->nlmsg_type != RTM_DELRULE)
return 0;
len -= NLMSG_LENGTH(sizeof(*r));
if (len < 0)
return -1;
parse_rtattr(tb, FRA_MAX, RTM_RTA(r), len);
if (r->rtm_family == AF_INET)
host_len = 32;
else if (r->rtm_family == AF_INET6)
host_len = 128;
else if (r->rtm_family == AF_DECnet)
host_len = 16;
else if (r->rtm_family == AF_IPX)
host_len = 80;
if (n->nlmsg_type == RTM_DELRULE)
fprintf(fp, "Deleted ");
if (tb[FRA_PRIORITY])
fprintf(fp, "%u:\t", *(unsigned*)RTA_DATA(tb[FRA_PRIORITY]));
else
fprintf(fp, "0:\t");
if (r->rtm_flags & FIB_RULE_INVERT)
fprintf(fp, "not ");
if (tb[FRA_SRC]) {
if (r->rtm_src_len != host_len) {
fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family,
RTA_PAYLOAD(tb[FRA_SRC]),
RTA_DATA(tb[FRA_SRC]),
abuf, sizeof(abuf)),
r->rtm_src_len
);
} else {
fprintf(fp, "from %s ", format_host(r->rtm_family,
RTA_PAYLOAD(tb[FRA_SRC]),
RTA_DATA(tb[FRA_SRC]),
abuf, sizeof(abuf))
);
}
} else if (r->rtm_src_len) {
fprintf(fp, "from 0/%d ", r->rtm_src_len);
} else {
fprintf(fp, "from all ");
}
if (tb[FRA_DST]) {
if (r->rtm_dst_len != host_len) {
fprintf(fp, "to %s/%u ", rt_addr_n2a(r->rtm_family,
RTA_PAYLOAD(tb[FRA_DST]),
RTA_DATA(tb[FRA_DST]),
abuf, sizeof(abuf)),
r->rtm_dst_len
);
} else {
fprintf(fp, "to %s ", format_host(r->rtm_family,
RTA_PAYLOAD(tb[FRA_DST]),
RTA_DATA(tb[FRA_DST]),
abuf, sizeof(abuf)));
}
} else if (r->rtm_dst_len) {
fprintf(fp, "to 0/%d ", r->rtm_dst_len);
}
if (r->rtm_tos) {
SPRINT_BUF(b1);
fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
}
if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) {
__u32 mark = 0, mask = 0;
if (tb[FRA_FWMARK])
mark = rta_getattr_u32(tb[FRA_FWMARK]);
if (tb[FRA_FWMASK] &&
(mask = rta_getattr_u32(tb[FRA_FWMASK])) != 0xFFFFFFFF)
fprintf(fp, "fwmark 0x%x/0x%x ", mark, mask);
else
fprintf(fp, "fwmark 0x%x ", mark);
}
if (tb[FRA_IFNAME]) {
fprintf(fp, "iif %s ", rta_getattr_str(tb[FRA_IFNAME]));
if (r->rtm_flags & FIB_RULE_IIF_DETACHED)
//.........这里部分代码省略.........