Example #1
0
static int link_stat_show_cb(const struct nlmsghdr *nlh, void *data)
{
	const char *name;
	const char *link = data;
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {};
	struct nlattr *prop[TIPC_NLA_PROP_MAX + 1] = {};
	struct nlattr *stats[TIPC_NLA_STATS_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_LINK])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_LINK_NAME] || !attrs[TIPC_NLA_LINK_PROP] ||
	    !attrs[TIPC_NLA_LINK_STATS])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, prop);
	mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_STATS], parse_attrs, stats);

	name = mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]);

	/* If a link is passed, skip all but that link */
	if (link && (strcmp(name, link) != 0))
		return MNL_CB_OK;

	if (attrs[TIPC_NLA_LINK_BROADCAST]) {
		return _show_bc_link_stat(name, prop, stats);
	}

	return _show_link_stat(name, attrs, prop, stats);
}
Example #2
0
int nfct_nlmsg_parse(const struct nlmsghdr *nlh, struct nf_conntrack *ct)
{
	struct nfgenmsg *nfhdr = mnl_nlmsg_get_payload(nlh);

	return nfct_payload_parse((uint8_t *)nfhdr + sizeof(struct nfgenmsg),
				  nlh->nlmsg_len, nfhdr->nfgen_family, ct);
}
Example #3
0
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[CTA_MAX+1] = {};
	struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(*nfg), data_attr_cb, tb);
	if (tb[CTA_TUPLE_ORIG])
		print_tuple(tb[CTA_TUPLE_ORIG]);

	if (tb[CTA_MARK])
		printf("mark=%u ", ntohl(mnl_attr_get_u32(tb[CTA_MARK])));

	if (tb[CTA_SECMARK])
		printf("secmark=%u ", ntohl(mnl_attr_get_u32(tb[CTA_SECMARK])));

	if (tb[CTA_COUNTERS_ORIG]) {
		printf("original ");
		print_counters(tb[CTA_COUNTERS_ORIG]);
	}

	if (tb[CTA_COUNTERS_REPLY]) {
		printf("reply ");
		print_counters(tb[CTA_COUNTERS_REPLY]);
	}

	printf("\n");
	return MNL_CB_OK;
}
Example #4
0
static int node_list_cb(const struct nlmsghdr *nlh, void *data)
{
    uint32_t addr;
    struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
    struct nlattr *info[TIPC_NLA_MAX + 1] = {};
    struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1] = {};

    mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
    if (!info[TIPC_NLA_NODE])
        return MNL_CB_ERROR;

    mnl_attr_parse_nested(info[TIPC_NLA_NODE], parse_attrs, attrs);
    if (!attrs[TIPC_NLA_NODE_ADDR])
        return MNL_CB_ERROR;

    addr = mnl_attr_get_u32(attrs[TIPC_NLA_NODE_ADDR]);
    printf("<%u.%u.%u>: ",
           tipc_zone(addr),
           tipc_cluster(addr),
           tipc_node(addr));

    if (attrs[TIPC_NLA_NODE_UP])
        printf("up\n");
    else
        printf("down\n");

    return MNL_CB_OK;
}
Example #5
0
static int link_mon_summary_cb(const struct nlmsghdr *nlh, void *data)
{
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_MON])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs);

	open_json_object(NULL);
	print_string(PRINT_ANY, "bearer", "\nbearer %s\n",
		mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME]));

	print_uint(PRINT_ANY, "table_generation", "    table_generation %u\n",
	       mnl_attr_get_u32(attrs[TIPC_NLA_MON_LISTGEN]));
	print_uint(PRINT_ANY, "cluster_size", "    cluster_size %u\n",
		mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT]));
	print_string(PRINT_ANY, "algorithm", "    algorithm %s\n",
		attrs[TIPC_NLA_MON_ACTIVE] ? "overlapping-ring" : "full-mesh");
	close_json_object();

	return MNL_CB_OK;
}
Example #6
0
static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data)
{
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {};
	char *req_bearer = data;
	const char *bname;
	const char title[] =
	  "node          status monitored generation applied_node_status [non_applied_node:status]";

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_MON])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs);

	bname = mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME]);

	if (*req_bearer && (strcmp(req_bearer, bname) != 0))
		return MNL_CB_OK;

	open_json_object(NULL);
	print_string(PRINT_ANY, "bearer", "\nbearer %s\n", bname);
	print_string(PRINT_FP, NULL, "%s\n", title);

	open_json_array(PRINT_JSON, bname);
	if (mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT]))
		link_mon_peer_list(mnl_attr_get_u32(attrs[TIPC_NLA_MON_REF]));
	close_json_array(PRINT_JSON, bname);

	close_json_object();
	return MNL_CB_OK;
}
Example #7
0
//Function which parses the netlink message (*ADDR) we have received and extract
//relevant information, which is parsed to OS-independent
//neat_addr_update_src_list
static void neat_linux_handle_addr(struct neat_ctx *nc,
                                   struct nlmsghdr *nl_hdr)
{
    struct ifaddrmsg *ifm = (struct ifaddrmsg*) mnl_nlmsg_get_payload(nl_hdr);
    const struct nlattr *attr_table[IFA_MAX+1];
    //IFA_MAX is the largest index I can store in my array. Since arrays are
    //zero-indexed, this is IFA_MAX and not IFA_MAX + 1. However, array has to
    //be of size IFA_MAX + 1. DOH!
    struct nlattr_storage tb_storage = {attr_table, IFA_MAX};
    struct sockaddr_storage src_addr;
    struct sockaddr_in *src_addr4;
    struct sockaddr_in6 *src_addr6;
    struct ifa_cacheinfo *ci;
    uint32_t *addr6_ptr, ifa_pref = 0, ifa_valid = 0;
    uint8_t i;

    //On Linux, lo has a fixed index. We have no interest in that interface
    //TODO: Consider other filters - bridges, ifb, ...
    if (ifm->ifa_index == LO_DEV_IDX)
        return;

    if (ifm->ifa_scope == RT_SCOPE_LINK)
        return;

    memset(attr_table, 0, sizeof(attr_table));
    memset(&src_addr, 0, sizeof(src_addr));

    if (mnl_attr_parse(nl_hdr, sizeof(struct ifaddrmsg),
                neat_linux_parse_nlattr, &tb_storage) != MNL_CB_OK) {
        fprintf(stderr, "Failed to parse nlattr for msg of type %d\n",
                nl_hdr->nlmsg_type);
        return;
    }

    //v4 and v6 has to be handled differently, both due to address size and
    //available information
    if (ifm->ifa_family == AF_INET) {
        src_addr4 = (struct sockaddr_in*) &src_addr;
        src_addr4->sin_family = AF_INET;
        src_addr4->sin_addr.s_addr = mnl_attr_get_u32(attr_table[IFA_LOCAL]);
    } else {
        src_addr6 = (struct sockaddr_in6*) &src_addr;
        src_addr6->sin6_family = AF_INET6;
        addr6_ptr = (uint32_t*) mnl_attr_get_payload(attr_table[IFA_ADDRESS]);

        for (i=0; i<4; i++)
            src_addr6->sin6_addr.s6_addr32[i] = *(addr6_ptr + i);

        ci = (struct ifa_cacheinfo*) mnl_attr_get_payload(attr_table[IFA_CACHEINFO]);
        ifa_pref = ci->ifa_prefered;
        ifa_valid = ci->ifa_valid;
    }

    //TODO: Should this function be a callback instead? Will we have multiple
    //addresses handlers/types of context?
    neat_addr_update_src_list(nc, &src_addr, ifm->ifa_index,
            nl_hdr->nlmsg_type == RTM_NEWADDR, ifa_pref, ifa_valid);
}
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr **tb = (struct nlattr **)data;
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(*genl), parse_attr_cb, tb);

	return MNL_CB_OK;
}
Example #9
0
static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data)
{
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *attrs[TIPC_NLA_MON_PEER_MAX + 1] = {};
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	uint16_t member_cnt;
	uint32_t applied;
	uint32_t dom_gen;
	uint64_t up_map;
	char status[16];
	char monitored[16];

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_MON_PEER])
		return MNL_CB_ERROR;

	open_json_object(NULL);
	mnl_attr_parse_nested(info[TIPC_NLA_MON_PEER], parse_attrs, attrs);

	(attrs[TIPC_NLA_MON_PEER_LOCAL] || attrs[TIPC_NLA_MON_PEER_HEAD]) ?
		strcpy(monitored, "direct") :
		strcpy(monitored, "indirect");

	attrs[TIPC_NLA_MON_PEER_UP] ?
		strcpy(status, "up") :
		strcpy(status, "down");

	dom_gen = attrs[TIPC_NLA_MON_PEER_DOMGEN] ?
		mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_DOMGEN]) : 0;

	link_mon_print_peer_state(mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_ADDR]),
				  status, monitored, dom_gen);

	applied = mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_APPLIED]);

	if (!applied)
		goto exit;

	up_map = mnl_attr_get_u64(attrs[TIPC_NLA_MON_PEER_UPMAP]);

	member_cnt = mnl_attr_get_payload_len(attrs[TIPC_NLA_MON_PEER_MEMBERS]);

	/* each tipc address occupies 4 bytes of payload, hence compensate it */
	member_cnt /= sizeof(uint32_t);

	link_mon_print_applied(applied, up_map);

	link_mon_print_non_applied(applied, member_cnt, up_map,
				   mnl_attr_get_payload(attrs[TIPC_NLA_MON_PEER_MEMBERS]));

exit:
	print_string(PRINT_FP, NULL, "\n", "");

	close_json_object();
	return MNL_CB_OK;
}
Example #10
0
int nfexp_nlmsg_parse(const struct nlmsghdr *nlh, struct nf_expect *exp)
{
	struct nlattr *tb[CTA_EXPECT_MAX+1] = {};
	struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(struct nfgenmsg),
			nlmsg_parse_expection_attr_cb, tb);

	if (tb[CTA_EXPECT_MASTER]) {
		exp->expected.orig.l3protonum = nfg->nfgen_family;
		set_bit(ATTR_ORIG_L3PROTO, exp->expected.set);

		nfct_parse_tuple(tb[CTA_EXPECT_MASTER], &exp->master.orig,
				__DIR_ORIG, exp->master.set);
		set_bit(ATTR_EXP_MASTER, exp->set);
	}
	if (tb[CTA_EXPECT_TUPLE]) {
		exp->mask.orig.l3protonum = nfg->nfgen_family;
		set_bit(ATTR_ORIG_L3PROTO, exp->mask.set);

		nfct_parse_tuple(tb[CTA_EXPECT_TUPLE], &exp->expected.orig,
				  __DIR_ORIG, exp->expected.set);
		set_bit(ATTR_EXP_EXPECTED, exp->set);
	}
	if (tb[CTA_EXPECT_MASK]) {
		exp->master.orig.l3protonum = nfg->nfgen_family;
		set_bit(ATTR_ORIG_L3PROTO, exp->master.set);

		nfct_parse_tuple(tb[CTA_EXPECT_MASK], &exp->mask.orig,
				  __DIR_ORIG, exp->mask.set);
		set_bit(ATTR_EXP_MASK, exp->set);
	}
	if (tb[CTA_EXPECT_TIMEOUT]) {
		exp->timeout = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_TIMEOUT]));
		set_bit(ATTR_EXP_TIMEOUT, exp->set);
	}

	if (tb[CTA_EXPECT_ZONE]) {
		exp->zone = ntohs(mnl_attr_get_u16(tb[CTA_EXPECT_ZONE]));
		set_bit(ATTR_EXP_ZONE, exp->set);
	}

	if (tb[CTA_EXPECT_FLAGS]) {
		exp->flags = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_FLAGS]));
		set_bit(ATTR_EXP_FLAGS, exp->set);
	}

	if (tb[CTA_EXPECT_HELP_NAME]) {
		strncpy(exp->helper_name,
			mnl_attr_get_str(tb[CTA_EXPECT_HELP_NAME]),
			NFCT_HELPER_NAME_MAX);
		set_bit(ATTR_EXP_HELPER_NAME, exp->set);
	}
	return 0;
}
static int cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[NLE_MAX];
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb);
	if (tb[NLE_MYVAR])
		printf("myvar=%d\n", mnl_attr_get_u32(tb[NLE_MYVAR]));

	return MNL_CB_OK;
}
Example #12
0
File: mnlg.c Project: dtaht/tc-adv
static int get_group_id_cb(const struct nlmsghdr *nlh, void *data)
{
	struct group_info *group_info = data;
	struct nlattr *tb[CTRL_ATTR_MAX + 1] = {};
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(*genl), get_group_id_attr_cb, tb);
	if (!tb[CTRL_ATTR_MCAST_GROUPS])
		return MNL_CB_ERROR;
	parse_genl_mc_grps(tb[CTRL_ATTR_MCAST_GROUPS], group_info);
	return MNL_CB_OK;
}
Example #13
0
File: mnlg.c Project: dtaht/tc-adv
static int get_family_id_cb(const struct nlmsghdr *nlh, void *data)
{
	uint32_t *p_id = data;
	struct nlattr *tb[CTRL_ATTR_MAX + 1] = {};
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(*genl), get_family_id_attr_cb, tb);
	if (!tb[CTRL_ATTR_FAMILY_ID])
		return MNL_CB_ERROR;
	*p_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
	return MNL_CB_OK;
}
Example #14
0
int nftnl_gen_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_gen *gen)
{
	struct nlattr *tb[NFTA_GEN_MAX + 1] = {};
	struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);

	if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_gen_parse_attr_cb, tb) < 0)
		return -1;

	if (tb[NFTA_GEN_ID]) {
		gen->id = ntohl(mnl_attr_get_u32(tb[NFTA_GEN_ID]));
		gen->flags |= (1 << NFTNL_GEN_ID);
	}
	return 0;
}
Example #15
0
static int genl_ctrl_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[CTRL_ATTR_MAX + 1] = {};
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	int32_t *genl_id = data;

	mnl_attr_parse(nlh, sizeof(*genl), genl_ctrl_validate_cb, tb);
	if (tb[CTRL_ATTR_FAMILY_ID])
		*genl_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
	else
		*genl_id = -1;

	return MNL_CB_OK;
}
Example #16
0
//Function which parses the netlink message (*ADDR) we have received and extract
//relevant information, which is parsed to OS-independent
//neat_addr_update_src_list
static neat_error_code
nt_linux_handle_addr(struct neat_ctx *ctx, struct nlmsghdr *nl_hdr)
{
    struct ifaddrmsg *ifm = (struct ifaddrmsg*) mnl_nlmsg_get_payload(nl_hdr);
    const struct nlattr *attr_table[IFA_MAX+1];
    //IFA_MAX is the largest index I can store in my array. Since arrays are
    //zero-indexed, this is IFA_MAX and not IFA_MAX + 1. However, array has to
    //be of size IFA_MAX + 1. DOH!
    struct nlattr_storage tb_storage = {attr_table, IFA_MAX};
    struct sockaddr_storage src_addr;
    struct sockaddr_in *src_addr4;
    struct sockaddr_in6 *src_addr6;
    struct ifa_cacheinfo *ci;
    uint32_t ifa_pref = 0, ifa_valid = 0;

    if (ifm->ifa_scope == RT_SCOPE_LINK)
        return NEAT_ERROR_OK;

    memset(attr_table, 0, sizeof(attr_table));
    memset(&src_addr, 0, sizeof(src_addr));

    if (mnl_attr_parse(nl_hdr, sizeof(struct ifaddrmsg),
                neat_linux_parse_nlattr, &tb_storage) != MNL_CB_OK) {
        nt_log(ctx, NEAT_LOG_ERROR, "Failed to parse nlattr for msg of type %d",
                __func__, nl_hdr->nlmsg_type);
        return NEAT_ERROR_OK;
    }

    //v4 and v6 has to be handled differently, both due to address size and
    //available information
    if (ifm->ifa_family == AF_INET) {
        src_addr4 = (struct sockaddr_in*) &src_addr;
        src_addr4->sin_family = AF_INET;
        src_addr4->sin_addr.s_addr = mnl_attr_get_u32(attr_table[IFA_LOCAL]);
    } else {
        src_addr6 = (struct sockaddr_in6*) &src_addr;
        src_addr6->sin6_family = AF_INET6;
        memcpy(&src_addr6->sin6_addr, mnl_attr_get_payload(attr_table[IFA_ADDRESS]), sizeof(struct in6_addr));

        ci = (struct ifa_cacheinfo*) mnl_attr_get_payload(attr_table[IFA_CACHEINFO]);
        ifa_pref = ci->ifa_prefered;
        ifa_valid = ci->ifa_valid;
    }

    //TODO: Should this function be a callback instead? Will we have multiple
    //addresses handlers/types of context?
    return nt_addr_update_src_list(ctx, (struct sockaddr*) &src_addr, ifm->ifa_index,
                                     nl_hdr->nlmsg_type == RTM_NEWADDR,
                                     ifm->ifa_prefixlen, ifa_pref, ifa_valid);
}
Example #17
0
File: mnlg.c Project: dtaht/tc-adv
static int mnlg_cb_error(const struct nlmsghdr *nlh, void *data)
{
	const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);

	/* Netlink subsystems returns the errno value with different signess */
	if (err->error < 0)
		errno = -err->error;
	else
		errno = err->error;

	if (nl_dump_ext_ack(nlh, NULL))
		return MNL_CB_ERROR;

	return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
}
Example #18
0
static int mnl_cb_error(const struct nlmsghdr *nlh, void *data)
{
	const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);

	if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr))) {
		errno = EBADMSG; 
		return MNL_CB_ERROR;
	}
	/* Netlink subsystems returns the errno value with different signess */
	if (err->error < 0)
		errno = -err->error;
	else
		errno = err->error;

	return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
}
Example #19
0
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
	struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);

	printf("index=%d type=%d flags=%d family=%d ", 
		ifm->ifi_index, ifm->ifi_type,
		ifm->ifi_flags, ifm->ifi_family);

	if (ifm->ifi_flags & IFF_RUNNING)
		printf("[RUNNING] ");
	else
		printf("[NOT RUNNING] ");

	mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, NULL);
	printf("\n");
	return MNL_CB_OK;
}
Example #20
0
static int nametable_show_cb(const struct nlmsghdr *nlh, void *data)
{
	int *iteration = data;
	char port_id[PORTID_STR_LEN];
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_NAME_TABLE_MAX + 1] = {};
	struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1] = {};
	const char *scope[] = { "", "zone", "cluster", "node" };

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_NAME_TABLE])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_NAME_TABLE], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_NAME_TABLE_PUBL])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(attrs[TIPC_NLA_NAME_TABLE_PUBL], parse_attrs, publ);
	if (!publ[TIPC_NLA_NAME_TABLE_PUBL])
		return MNL_CB_ERROR;

	if (!*iteration)
		printf("%-10s %-10s %-10s %-26s %-10s\n",
		       "Type", "Lower", "Upper", "Port Identity",
		       "Publication Scope");
	(*iteration)++;

	snprintf(port_id, sizeof(port_id), "<%u.%u.%u:%u>",
		 tipc_zone(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])),
		 tipc_cluster(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])),
		 tipc_node(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])),
		 mnl_attr_get_u32(publ[TIPC_NLA_PUBL_REF]));

	printf("%-10u %-10u %-10u %-26s %-12u",
	       mnl_attr_get_u32(publ[TIPC_NLA_PUBL_TYPE]),
	       mnl_attr_get_u32(publ[TIPC_NLA_PUBL_LOWER]),
	       mnl_attr_get_u32(publ[TIPC_NLA_PUBL_UPPER]),
	       port_id,
	       mnl_attr_get_u32(publ[TIPC_NLA_PUBL_KEY]));

	printf("%s\n", scope[mnl_attr_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]);

	return MNL_CB_OK;
}
Example #21
0
static int netid_get_cb(const struct nlmsghdr *nlh, void *data)
{
    struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
    struct nlattr *info[TIPC_NLA_MAX + 1] = {};
    struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};

    mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
    if (!info[TIPC_NLA_NET])
        return MNL_CB_ERROR;

    mnl_attr_parse_nested(info[TIPC_NLA_NET], parse_attrs, attrs);
    if (!attrs[TIPC_NLA_NET_ID])
        return MNL_CB_ERROR;

    printf("%u\n", mnl_attr_get_u32(attrs[TIPC_NLA_NET_ID]));

    return MNL_CB_OK;
}
/**
 * nfacct_nlmsg_parse_payload - set accounting object attributes from message
 * \param nlh: netlink message that you want to use to add the payload.
 * \param nfacct: pointer to a accounting object
 *
 * This function returns -1 in case that some mandatory attributes are
 * missing. On sucess, it returns 0.
 */
int
nfacct_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfacct *nfacct)
{
	struct nlattr *tb[NFACCT_MAX+1] = {};
	struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(*nfg), nfacct_nlmsg_parse_attr_cb, tb);
	if (!tb[NFACCT_NAME] && !tb[NFACCT_PKTS] && !tb[NFACCT_BYTES])
		return -1;

	nfacct_attr_set_str(nfacct, NFACCT_ATTR_NAME,
			    mnl_attr_get_str(tb[NFACCT_NAME]));
	nfacct_attr_set_u64(nfacct, NFACCT_ATTR_PKTS,
			    be64toh(mnl_attr_get_u64(tb[NFACCT_PKTS])));
	nfacct_attr_set_u64(nfacct, NFACCT_ATTR_BYTES,
			    be64toh(mnl_attr_get_u64(tb[NFACCT_BYTES])));

	return 0;
}
Example #23
0
static int link_mon_get_cb(const struct nlmsghdr *nlh, void *data)
{
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_MON])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD])
		return MNL_CB_ERROR;

	new_json_obj(json);
	print_uint(PRINT_ANY, "threshold", "%u\n",
			   mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]));
	delete_json_obj();

	return MNL_CB_OK;
}
Example #24
0
static int link_get_cb(const struct nlmsghdr *nlh, void *data)
{
	int *prop = data;
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {};
	struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_LINK])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_LINK_PROP])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, props);
	if (!props[*prop])
		return MNL_CB_ERROR;

	new_json_obj(json);
	open_json_object(NULL);
	switch (*prop) {
		case TIPC_NLA_PROP_PRIO:
			print_uint(PRINT_ANY, PRIORITY_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
		break;
		case TIPC_NLA_PROP_TOL:
			print_uint(PRINT_ANY, TOLERANCE_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
		break;
		case TIPC_NLA_PROP_WIN:
			print_uint(PRINT_ANY, WINDOW_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
		break;
		default:
			break;
	}
	close_json_object();
	delete_json_obj();
	return MNL_CB_OK;
}
Example #25
0
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[CTRL_ATTR_MAX+1] = {};
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb);
	if (tb[CTRL_ATTR_FAMILY_NAME]) {
		printf("name=%s\t",
			mnl_attr_get_str(tb[CTRL_ATTR_FAMILY_NAME]));
	}
	if (tb[CTRL_ATTR_FAMILY_ID]) {
		printf("id=%u\t",
			mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]));
	}
	if (tb[CTRL_ATTR_VERSION]) {
		printf("version=%u\t",
			mnl_attr_get_u32(tb[CTRL_ATTR_VERSION]));
	}
	if (tb[CTRL_ATTR_HDRSIZE]) {
		printf("hdrsize=%u\t",
			mnl_attr_get_u32(tb[CTRL_ATTR_HDRSIZE]));
	}
	if (tb[CTRL_ATTR_MAXATTR]) {
		printf("maxattr=%u\t",
			mnl_attr_get_u32(tb[CTRL_ATTR_MAXATTR]));
	}
	printf("\n");
	if (tb[CTRL_ATTR_OPS]) {
		printf("ops:\n");
		parse_genl_family_ops(tb[CTRL_ATTR_OPS]);
	}
	if (tb[CTRL_ATTR_MCAST_GROUPS]) {
		printf("grps:\n");
		parse_genl_mc_grps(tb[CTRL_ATTR_MCAST_GROUPS]);
	}
	printf("\n");
	return MNL_CB_OK;
}
Example #26
0
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[IFLA_MAX+1] = {};
	struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);

	printf("index=%d type=%d flags=%d family=%d ", 
		ifm->ifi_index, ifm->ifi_type,
		ifm->ifi_flags, ifm->ifi_family);

	if (ifm->ifi_flags & IFF_RUNNING)
		printf("[RUNNING] ");
	else
		printf("[NOT RUNNING] ");

	mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb);
	if (tb[IFLA_MTU]) {
		printf("mtu=%d ", mnl_attr_get_u32(tb[IFLA_MTU]));
	}
	if (tb[IFLA_IFNAME]) {
		printf("name=%s", mnl_attr_get_str(tb[IFLA_IFNAME]));
	}
	printf("\n");
	return MNL_CB_OK;
}
Example #27
0
static int link_list_cb(const struct nlmsghdr *nlh, void *data)
{
	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
	struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {};

	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
	if (!info[TIPC_NLA_LINK])
		return MNL_CB_ERROR;

	mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs);
	if (!attrs[TIPC_NLA_LINK_NAME])
		return MNL_CB_ERROR;

	print_string(PRINT_FP, NULL, "%s: ",
			     mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]));
	if (attrs[TIPC_NLA_LINK_UP])
		print_string(PRINT_ANY,
			 mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]),"%s\n", "up");
	else
		print_string(PRINT_ANY,
			 mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]), "%s\n", "down");
	return MNL_CB_OK;
}
Example #28
0
static void multi_link_modify_link(const struct nlmsghdr *nlh, 
        uint32_t probe_pipe, uint8_t unique){
    struct ifinfomsg *ifi = mnl_nlmsg_get_payload(nlh);
    struct nlattr *tb[IFLA_MAX + 1] = {};
    uint8_t iface_state = 0;
    struct multi_link_info *li = NULL;
	struct multi_link_info_static *li_static = NULL;
    pthread_attr_t detach_attr;
    uint8_t wireless_mode = 0;
    uint8_t *if_name;

    mnl_attr_parse(nlh, sizeof(*ifi), multi_link_fill_rtattr, tb);

    if (!tb[IFLA_IFNAME]) {
        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Missing interface name\n");
        return;
    }

    if_name = (uint8_t*) mnl_attr_get_str(tb[IFLA_IFNAME]);

    if (!strncmp(if_name, "veth", 4) ||
        ifi->ifi_type == ARPHRD_VOID ||
        (ifi->ifi_type == ARPHRD_NONE && strncmp(if_name,"wwan", 4)) ||
        ifi->ifi_type == ARPHRD_TUNNEL ||
        ifi->ifi_flags & IFF_LOOPBACK)
        return;

    if(tb[IFLA_OPERSTATE]){
        iface_state = mnl_attr_get_u8(tb[IFLA_OPERSTATE]);

        /* Check linux/Documentation/networking/operstates.txt. IFF_RUNNING 
         * wraps both UP and UNKNOWN*/
        if (ifi->ifi_flags & IFF_RUNNING){
        //IF_OPER_UP == 6, defined in linux/if.h, chaos with includes
        //if(iface_state == 6){
            MULTI_DEBUG_PRINT_SYSLOG(stderr, "Interface %s (%u) is RUNNING, "
                    "length %u\n", if_name, ifi->ifi_index,
                    multi_link_num_links);
 
            if((wireless_mode = multi_link_check_wlan_mode(if_name)))
                if(wireless_mode == 6){
                    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Interface %s is monitor, "
                            "ignoring\n", if_name);
                    return;
                }
 
            LIST_FIND_CUSTOM(li, &multi_link_links_2, next, &(ifi->ifi_index),
                    multi_cmp_ifidx);

            if(li != NULL){
                if(li->state == LINK_UP_STATIC_IFF){
                    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Interface %s (idx %u) has "
                        "gone from UP to RUNNING\n", if_name, ifi->ifi_index);
                    li->state = GOT_IP_STATIC;
                } else
                    MULTI_DEBUG_PRINT_SYSLOG(stderr,"Interface %s (idx %u) has "
                        "already been seen. Ignoring event\n", if_name, 
                        ifi->ifi_index);
                return;
            }

            if(multi_link_num_links < MAX_NUM_LINKS){
                TAILQ_FIND_CUSTOM(li_static, &multi_shared_static_links,
                        list_ptr, if_name, multi_cmp_devname);

                if(li_static != NULL){
                    if(li_static->proto == PROTO_IGNORE){
                        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Ignoring %s\n", if_name);
                        return;
                    } else
                        li = multi_link_create_new_link(if_name, 
                                li_static->metric);
                } else {
                    /* Allocate a new link, add to list and start DHCP */
                    li = multi_link_create_new_link(if_name, 0);
                }

                if (!li) {
                    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not create link\n");
                    return;
                }
                
                //Insert link into link list
                LIST_INSERT_HEAD(&multi_link_links_2, li, next);
                ++multi_link_num_links;

                /* Add as a case here! The check for point to point  */
                if(li_static != NULL && li_static->proto == PROTO_STATIC){
					MULTI_DEBUG_PRINT_SYSLOG(stderr, "Link %s found in static list\n", 
                            if_name);
                    li->state = GOT_IP_STATIC;
					li->cfg = li_static->cfg_static;
				} else if (ifi->ifi_type == ARPHRD_PPP){
                    /* PPP will be dealt with separatley, since they get the IP
                     * remotely by themself */
                    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Link %s (%u) is PPP! state "
                            "%u %u\n", if_name, ifi->ifi_index, iface_state, 
                            IFF_RUNNING);
                    li->state = LINK_DOWN_PPP;
                    multi_link_get_iface_info(li);

                    if(li->state != GOT_IP_PPP){
                        //Need to treat this in a special way! Remove li, keep
                        //li and have some sort of timeout?
                        MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not get info for PPP "
                                "link %u (first look)!\n", ifi->ifi_index);
                    } else {
                        //Clean the information that is automatically added to
                        //routing table
                        multi_link_remove_ppp(li);
                    }

                } else if(wireless_mode){ 
                    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Link %s is wlan access point\n",
                            if_name);
                    li->state = LINK_DOWN_AP;
                    multi_link_get_iface_info(li);

                    //Remove the automatic route
                    multi_link_remove_ap(li);
                } else {
					pthread_attr_init(&detach_attr);
					pthread_attr_setdetachstate(&detach_attr, 
                            PTHREAD_CREATE_DETACHED);
					pthread_create(&(li->dhcp_thread), &detach_attr, 
                            multi_dhcp_main, (void *) li);
				}
            } else
                MULTI_DEBUG_PRINT_SYSLOG(stderr, "Limit reached, cannot add more links\n");
        } else if(ifi->ifi_flags & IFF_UP){ //Might replace with IF_OPER_DOWN
            //Check if interface has already been seen
            LIST_FIND_CUSTOM(li, &multi_link_links_2, next, &(ifi->ifi_index),
                    multi_cmp_ifidx);

            //Interface is already seen as UP, so clean up, no matter if static
            //or not. Static is a special case: remove routes, li from list
            //and free li
            if(li != NULL){
                //Need a generic cleanup, move the next "else" into a separate
                //function
                MULTI_DEBUG_PRINT_SYSLOG(stderr,"Interface %s (idx %u) has already "
                    "been seen as UP, will clean\n", if_name, ifi->ifi_index);
                multi_link_delete_link(li, probe_pipe);
                return;
            }

            //Check if interface is in static list
            TAILQ_FIND_CUSTOM(li_static, &multi_shared_static_links, list_ptr, 
                    if_name, multi_cmp_devname);

            if(li_static != NULL && li_static->proto == PROTO_STATIC){
                //Allocate a new link
                MULTI_DEBUG_PRINT_SYSLOG(stderr, "Link %s is UP\n", if_name);
                li = multi_link_create_new_link(if_name, li_static->metric);

                if (li == NULL) {
                    MULTI_DEBUG_PRINT_SYSLOG(stderr, "Failed to create new link\n");
                    return;
                }

                li->state = GOT_IP_STATIC_UP;
                li->cfg = li_static->cfg_static;
                LIST_INSERT_HEAD(&multi_link_links_2, li, next);
                ++multi_link_num_links;
            }
        } else {
            uint32_t dev_idx = ifi->ifi_index;
            LIST_FIND_CUSTOM(li, &multi_link_links_2, next, &dev_idx,
                    multi_cmp_ifidx);

            MULTI_DEBUG_PRINT_SYSLOG(stderr, "Interface %s (index %u) is down, "
                "length %u\n", if_name, ifi->ifi_index, 
                multi_link_num_links);

            if(li == NULL){
                MULTI_DEBUG_PRINT_SYSLOG(stderr, "Could not find %s (index %u), "
                    "length %u\n", if_name, ifi->ifi_index, 
                    multi_link_num_links);
            } else{
                multi_link_delete_link(li, probe_pipe);
            }
        }
    }
}
int main(int argc, char *argv[]){
    struct mnl_socket *nl_sock = NULL;
    struct nlmsghdr *nlh = NULL;
    struct nlmsgerr *nlerr = NULL;
    struct nlattr *linkinfo = NULL, *tunnelinfo = NULL;
    struct ifinfomsg *ifinfo = NULL;
    uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
    size_t numbytes = 0;
    struct in_addr addr;

    memset(buf, 0, sizeof(buf));

    if((nl_sock = mnl_socket_open(NETLINK_ROUTE)) == NULL){
        perror("mnl_socket_open: ");
        exit(EXIT_FAILURE);
    }

    //Add and configure header
    nlh = mnl_nlmsg_put_header(buf);
    //Create only if interface does not exists from before (EXCL)
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
    nlh->nlmsg_type = RTM_NEWLINK; 

    //see rtnl_newlink in net/core/rtnetlink.c for observing how this function
    //works
    ifinfo = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifinfomsg));
    ifinfo->ifi_family = AF_UNSPEC;

    //Add a name and mtu, for testing
    mnl_attr_put_str(nlh, IFLA_IFNAME, "kre2");
    mnl_attr_put_u32(nlh, IFLA_MTU, 1234);
  
    //Type is required, set to IPIP
    linkinfo = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
    mnl_attr_put_str(nlh, IFLA_INFO_KIND, "ipip");

    //Add information about the tunnel
    tunnelinfo = mnl_attr_nest_start(nlh, IFLA_INFO_DATA);
    inet_pton(AF_INET, "192.168.203.19", &addr);
    mnl_attr_put_u32(nlh, IFLA_IPTUN_LOCAL, addr.s_addr);
    inet_pton(AF_INET, "10.0.0.2", &addr);
    mnl_attr_put_u32(nlh, IFLA_IPTUN_REMOTE, addr.s_addr);

    mnl_attr_nest_end(nlh, tunnelinfo);
    mnl_attr_nest_end(nlh, linkinfo);

    numbytes = mnl_socket_sendto(nl_sock, nlh, nlh->nlmsg_len);
    numbytes = mnl_socket_recvfrom(nl_sock, buf, sizeof(buf));

    nlh = (struct nlmsghdr*) buf;

    if(nlh->nlmsg_type == NLMSG_ERROR){
        nlerr = mnl_nlmsg_get_payload(nlh);
        //error==0 for ack
        if(nlerr->error)
            printf("Error: %s\n", strerror(-nlerr->error));
    } else {
        printf("Link added\n");
    }

    return EXIT_FAILURE;
}
Example #30
0
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[RTA_MAX+1] = {};
	struct rtmsg *rm = mnl_nlmsg_get_payload(nlh);

	/* protocol family = AF_INET | AF_INET6 */
	printf("family=%u ", rm->rtm_family);

	/* destination CIDR, eg. 24 or 32 for IPv4 */
	printf("dst_len=%u ", rm->rtm_dst_len);

	/* source CIDR */
	printf("src_len=%u ", rm->rtm_src_len);

	/* type of service (TOS), eg. 0 */
	printf("tos=%u ", rm->rtm_tos);

	/* table id:
	 *	RT_TABLE_UNSPEC		= 0
	 *
	 * 	... user defined values ...
	 *
	 *	RT_TABLE_COMPAT		= 252
	 *	RT_TABLE_DEFAULT	= 253
	 *	RT_TABLE_MAIN		= 254
	 *	RT_TABLE_LOCAL		= 255
	 *	RT_TABLE_MAX		= 0xFFFFFFFF
	 *
	 * Synonimous attribute: RTA_TABLE.
	 */
	printf("table=%u ", rm->rtm_table);

	/* type:
	 * 	RTN_UNSPEC	= 0
	 * 	RTN_UNICAST	= 1
	 * 	RTN_LOCAL	= 2
	 * 	RTN_BROADCAST	= 3
	 *	RTN_ANYCAST	= 4
	 *	RTN_MULTICAST	= 5
	 *	RTN_BLACKHOLE	= 6
	 *	RTN_UNREACHABLE	= 7
	 *	RTN_PROHIBIT	= 8
	 *	RTN_THROW	= 9
	 *	RTN_NAT		= 10
	 *	RTN_XRESOLVE	= 11
	 *	__RTN_MAX	= 12
	 */
	printf("type=%u ", rm->rtm_type);

	/* scope:
	 * 	RT_SCOPE_UNIVERSE	= 0   : everywhere in the universe
	 *
	 *      ... user defined values ...
	 *
	 * 	RT_SCOPE_SITE		= 200
	 * 	RT_SCOPE_LINK		= 253 : destination attached to link
	 * 	RT_SCOPE_HOST		= 254 : local address
	 * 	RT_SCOPE_NOWHERE	= 255 : not existing destination
	 */
	printf("scope=%u ", rm->rtm_scope);

	/* protocol:
	 * 	RTPROT_UNSPEC	= 0
	 * 	RTPROT_REDIRECT = 1
	 * 	RTPROT_KERNEL	= 2 : route installed by kernel
	 * 	RTPROT_BOOT	= 3 : route installed during boot
	 * 	RTPROT_STATIC	= 4 : route installed by administrator
	 *
	 * Values >= RTPROT_STATIC are not interpreted by kernel, they are
	 * just user-defined.
	 */
	printf("proto=%u ", rm->rtm_protocol);

	/* flags:
	 * 	RTM_F_NOTIFY	= 0x100: notify user of route change
	 * 	RTM_F_CLONED	= 0x200: this route is cloned
	 * 	RTM_F_EQUALIZE	= 0x400: Multipath equalizer: NI
	 * 	RTM_F_PREFIX	= 0x800: Prefix addresses
	 */
	printf("flags=%x\n", rm->rtm_flags);

	switch(rm->rtm_family) {
	case AF_INET:
		mnl_attr_parse(nlh, sizeof(*rm), data_ipv4_attr_cb, tb);
		attributes_show_ipv4(tb);
		break;
	case AF_INET6:
		mnl_attr_parse(nlh, sizeof(*rm), data_ipv6_attr_cb, tb);
		attributes_show_ipv6(tb);
		break;
	}

	return MNL_CB_OK;
}