Ejemplo n.º 1
0
static int idiagnl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
		struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
	struct idiagnl_msg *msg = NULL;
	int err = 0;

	if ((err = idiagnl_msg_parse(nlh, &msg)) < 0)
		return err;

	err = pp->pp_cb((struct nl_object *) msg, pp);
	idiagnl_msg_put(msg);

	return err;
}
Ejemplo n.º 2
0
inline void cleanup(struct idiagnl_msg* msg) { idiagnl_msg_put(msg); }
Ejemplo n.º 3
0
int idiagnl_msg_parse(struct nlmsghdr *nlh, struct idiagnl_msg **result)
{
	struct idiagnl_msg *msg = NULL;
	struct inet_diag_msg *raw_msg = NULL;
	struct nl_addr *src = NULL, *dst = NULL;
	struct nlattr *tb[IDIAG_ATTR_MAX];
	int err = 0;

	msg = idiagnl_msg_alloc();
	if (!msg)
		goto errout_nomem;

	err = nlmsg_parse(nlh, sizeof(struct inet_diag_msg), tb, IDIAG_ATTR_MAX,
			ext_policy);
	if (err < 0)
		goto errout;

	raw_msg = nlmsg_data(nlh);
	msg->idiag_family = raw_msg->idiag_family;
	msg->idiag_state = raw_msg->idiag_state;
	msg->idiag_timer = raw_msg->idiag_timer;
	msg->idiag_retrans = raw_msg->idiag_retrans;
	msg->idiag_expires = raw_msg->idiag_expires;
	msg->idiag_rqueue = raw_msg->idiag_rqueue;
	msg->idiag_wqueue = raw_msg->idiag_wqueue;
	msg->idiag_uid = raw_msg->idiag_uid;
	msg->idiag_inode = raw_msg->idiag_inode;
	msg->idiag_sport = raw_msg->id.idiag_sport;
	msg->idiag_dport = raw_msg->id.idiag_dport;
	msg->idiag_ifindex = raw_msg->id.idiag_if;

	dst = nl_addr_build(raw_msg->idiag_family, raw_msg->id.idiag_dst,
			sizeof(raw_msg->id.idiag_dst));
	if (!dst)
		goto errout_nomem;

	err = idiagnl_msg_set_dst(msg, dst);
	if (err < 0)
		goto errout;

	nl_addr_put(dst);

	src = nl_addr_build(raw_msg->idiag_family, raw_msg->id.idiag_src,
			sizeof(raw_msg->id.idiag_src));
	if (!src)
		goto errout_nomem;

	err = idiagnl_msg_set_src(msg, src);
	if (err < 0)
		goto errout;

	nl_addr_put(src);

	if (tb[IDIAG_ATTR_TOS])
		msg->idiag_tos = nla_get_u8(tb[IDIAG_ATTR_TOS]);

	if (tb[IDIAG_ATTR_TCLASS])
		msg->idiag_tclass = nla_get_u8(tb[IDIAG_ATTR_TCLASS]);

	if (tb[IDIAG_ATTR_SHUTDOWN])
		msg->idiag_shutdown = nla_get_u8(tb[IDIAG_ATTR_SHUTDOWN]);

	if (tb[IDIAG_ATTR_CONG])
		msg->idiag_cong = nla_strdup(tb[IDIAG_ATTR_CONG]);

	if (tb[IDIAG_ATTR_INFO])
		nla_memcpy(&msg->idiag_tcpinfo, tb[IDIAG_ATTR_INFO],
				sizeof(msg->idiag_tcpinfo));

	if (tb[IDIAG_ATTR_MEMINFO]) {
		struct idiagnl_meminfo *minfo = idiagnl_meminfo_alloc();
		struct inet_diag_meminfo *raw_minfo = NULL;

		if (!minfo)
			goto errout_nomem;

		raw_minfo = (struct inet_diag_meminfo *)
			nla_data(tb[IDIAG_ATTR_MEMINFO]);

		idiagnl_meminfo_set_rmem(minfo, raw_minfo->idiag_rmem);
		idiagnl_meminfo_set_wmem(minfo, raw_minfo->idiag_wmem);
		idiagnl_meminfo_set_fmem(minfo, raw_minfo->idiag_fmem);
		idiagnl_meminfo_set_tmem(minfo, raw_minfo->idiag_tmem);

		msg->idiag_meminfo = minfo;
	}

	if (tb[IDIAG_ATTR_VEGASINFO]) {
		struct idiagnl_vegasinfo *vinfo = idiagnl_vegasinfo_alloc();
		struct tcpvegas_info *raw_vinfo = NULL;

		if (!vinfo)
			goto errout_nomem;

		raw_vinfo = (struct tcpvegas_info *)
			nla_data(tb[IDIAG_ATTR_VEGASINFO]);

		idiagnl_vegasinfo_set_enabled(vinfo, raw_vinfo->tcpv_enabled);
		idiagnl_vegasinfo_set_rttcnt(vinfo, raw_vinfo->tcpv_rttcnt);
		idiagnl_vegasinfo_set_rtt(vinfo, raw_vinfo->tcpv_rtt);
		idiagnl_vegasinfo_set_minrtt(vinfo, raw_vinfo->tcpv_minrtt);

		msg->idiag_vegasinfo = vinfo;
	}

	if (tb[IDIAG_ATTR_SKMEMINFO])
		nla_memcpy(&msg->idiag_skmeminfo, tb[IDIAG_ATTR_SKMEMINFO],
				sizeof(msg->idiag_skmeminfo));

	*result = msg;
	return 0;

errout:
	idiagnl_msg_put(msg);
	return err;

errout_nomem:
	err = -NLE_NOMEM;
	goto errout;
}