static int icmpv6_nlattr_to_tuple(struct nlattr *tb[],
				struct nf_conntrack_tuple *tuple)
{
	if (!tb[CTA_PROTO_ICMPV6_TYPE] ||
	    !tb[CTA_PROTO_ICMPV6_CODE] ||
	    !tb[CTA_PROTO_ICMPV6_ID])
		return -EINVAL;

	tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]);
	tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]);
	tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]);

	if (tuple->dst.u.icmp.type < 128 ||
	    tuple->dst.u.icmp.type - 128 >= sizeof(invmap) ||
	    !invmap[tuple->dst.u.icmp.type - 128])
		return -EINVAL;

	return 0;
}
Beispiel #2
0
static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *info)
{
	int ret = 0;
	struct l2tp_session *session;

	session = l2tp_nl_session_find(info);
	if (session == NULL) {
		ret = -ENODEV;
		goto out;
	}

	if (info->attrs[L2TP_ATTR_DEBUG])
		session->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);

	if (info->attrs[L2TP_ATTR_DATA_SEQ])
		session->data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);

	if (info->attrs[L2TP_ATTR_RECV_SEQ])
		session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);

	if (info->attrs[L2TP_ATTR_SEND_SEQ]) {
		session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
		l2tp_session_set_header_len(session, session->tunnel->version);
	}

	if (info->attrs[L2TP_ATTR_LNS_MODE])
		session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);

	if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
		session->reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);

	if (info->attrs[L2TP_ATTR_MTU])
		session->mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);

	if (info->attrs[L2TP_ATTR_MRU])
		session->mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);

	ret = l2tp_session_notify(&l2tp_nl_family, info,
				  session, L2TP_CMD_SESSION_MODIFY);

out:
	return ret;
}
Beispiel #3
0
static int ct_parse_proto(struct nfnl_ct *ct, int repl, struct nlattr *attr)
{
	struct nlattr *tb[CTA_PROTO_MAX+1];
	int err;

	err = nla_parse_nested(tb, CTA_PROTO_MAX, attr, ct_proto_policy);
	if (err < 0)
		return err;

	if (!repl && tb[CTA_PROTO_NUM])
		nfnl_ct_set_proto(ct, nla_get_u8(tb[CTA_PROTO_NUM]));
	if (tb[CTA_PROTO_SRC_PORT])
		nfnl_ct_set_src_port(ct, repl,
			ntohs(nla_get_u16(tb[CTA_PROTO_SRC_PORT])));
	if (tb[CTA_PROTO_DST_PORT])
		nfnl_ct_set_dst_port(ct, repl,
			ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT])));

	if (ct->ct_family == AF_INET) {
		if (tb[CTA_PROTO_ICMP_ID])
			nfnl_ct_set_icmp_id(ct, repl,
				ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID])));
		if (tb[CTA_PROTO_ICMP_TYPE])
			nfnl_ct_set_icmp_type(ct, repl,
				nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]));
		if (tb[CTA_PROTO_ICMP_CODE])
			nfnl_ct_set_icmp_code(ct, repl,
				nla_get_u8(tb[CTA_PROTO_ICMP_CODE]));
	} else if (ct->ct_family == AF_INET6) {
		if (tb[CTA_PROTO_ICMPV6_ID])
			nfnl_ct_set_icmp_id(ct, repl,
			    ntohs(nla_get_u16(tb[CTA_PROTO_ICMPV6_ID])));
		if (tb[CTA_PROTO_ICMPV6_TYPE])
			nfnl_ct_set_icmp_type(ct, repl,
				nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]));
		if (tb[CTA_PROTO_ICMPV6_CODE])
			nfnl_ct_set_icmp_code(ct, repl,
				nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]));
	}

	return 0;
}
Beispiel #4
0
/* Set/clear or port flags based on attribute */
static void br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
			   int attrtype, unsigned long mask)
{
	if (tb[attrtype]) {
		u8 flag = nla_get_u8(tb[attrtype]);
		if (flag)
			p->flags |= mask;
		else
			p->flags &= ~mask;
	}
}
Beispiel #5
0
static iz_res_t assoc_response(struct iz_cmd *cmd, struct genlmsghdr *ghdr, struct nlattr **attrs)
{
	if (!attrs[IEEE802154_ATTR_SHORT_ADDR] ||
		!attrs[IEEE802154_ATTR_STATUS] )
		return IZ_STOP_ERR;

	printf("Received short address %04hx, status %02hhx\n",
		nla_get_u16(attrs[IEEE802154_ATTR_SHORT_ADDR]),
		nla_get_u8(attrs[IEEE802154_ATTR_STATUS]));

	return IZ_STOP_OK;
}
static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
{
	struct net_device *dev;
	struct ieee802154_addr addr;

	u8 channel, bcn_ord, sf_ord;
	u8 page;
	int pan_coord, blx, coord_realign;
	int ret;

	if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
	    !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] ||
	    !info->attrs[IEEE802154_ATTR_CHANNEL] ||
	    !info->attrs[IEEE802154_ATTR_BCN_ORD] ||
	    !info->attrs[IEEE802154_ATTR_SF_ORD] ||
	    !info->attrs[IEEE802154_ATTR_PAN_COORD] ||
	    !info->attrs[IEEE802154_ATTR_BAT_EXT] ||
	    !info->attrs[IEEE802154_ATTR_COORD_REALIGN]
	 )
		return -EINVAL;

	dev = ieee802154_nl_get_dev(info);
	if (!dev)
		return -ENODEV;

	addr.addr_type = IEEE802154_ADDR_SHORT;
	addr.short_addr = nla_get_u16(
			info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]);
	addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);

	channel = nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]);
	bcn_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_BCN_ORD]);
	sf_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_SF_ORD]);
	pan_coord = nla_get_u8(info->attrs[IEEE802154_ATTR_PAN_COORD]);
	blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]);
	coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]);

	if (info->attrs[IEEE802154_ATTR_PAGE])
		page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
	else
		page = 0;


	if (addr.short_addr == IEEE802154_ADDR_BROADCAST) {
		ieee802154_nl_start_confirm(dev, IEEE802154_NO_SHORT_ADDRESS);
		dev_put(dev);
		return -EINVAL;
	}

	ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, page,
		bcn_ord, sf_ord, pan_coord, blx, coord_realign);

	dev_put(dev);
	return ret;
}
Beispiel #7
0
static void ipgre_netlink_parms(struct nlattr *data[], struct nlattr *tb[],
			       struct ip_tunnel_parm *parms)
{
	memset(parms, 0, sizeof(*parms));

	parms->iph.protocol = IPPROTO_GRE;

	if (!data)
		return;

	if (data[IFLA_GRE_LINK])
		parms->link = nla_get_u32(data[IFLA_GRE_LINK]);

	if (data[IFLA_GRE_IFLAGS])
		parms->i_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_IFLAGS]));

	if (data[IFLA_GRE_OFLAGS])
		parms->o_flags = gre_flags_to_tnl_flags(nla_get_be16(data[IFLA_GRE_OFLAGS]));

	if (data[IFLA_GRE_IKEY])
		parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);

	if (data[IFLA_GRE_OKEY])
		parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);

	if (data[IFLA_GRE_LOCAL])
		parms->iph.saddr = nla_get_be32(data[IFLA_GRE_LOCAL]);

	if (data[IFLA_GRE_REMOTE])
		parms->iph.daddr = nla_get_be32(data[IFLA_GRE_REMOTE]);

	if (data[IFLA_GRE_TTL])
		parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);

	if (data[IFLA_GRE_TOS])
		parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);

	if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC]))
		parms->iph.frag_off = htons(IP_DF);
}
Beispiel #8
0
//scan netlink messages are nested (and may even be multipart) (see nl80211.c line 2591: nl80211_send_bss)
int CNL80211::parseNlScanResult(nl_msg * msg) {
	struct nlattr * attr_buffer[NL80211_ATTR_MAX + 1];
	struct nlmsghdr * msg_hdr = nlmsg_hdr(msg);
	struct genlmsghdr * msg_header = (struct genlmsghdr *) nlmsg_data(msg_hdr);
	struct nlattr * bss_buffer[NL80211_BSS_MAX + 1]; //bss = basic service set
	ScanResult scanresult;
	//This is the struct to check the validity of the attributes. See enum nl80211_bss
	struct nla_policy bss_policy[NL80211_BSS_MAX + 1];
	bss_policy[NL80211_BSS_TSF].type = NLA_U64;
	bss_policy[NL80211_BSS_FREQUENCY].type = NLA_U32;
	bss_policy[NL80211_BSS_BEACON_INTERVAL].type = NLA_U16;
	bss_policy[NL80211_BSS_SIGNAL_MBM].type = NLA_U32;
	bss_policy[NL80211_BSS_SIGNAL_UNSPEC].type = NLA_U8;

	if (msg_hdr->nlmsg_flags & NLM_F_MULTI)
		qDebug() << "netlink: Mutlipart message";

	//Parse the complete message
	nla_parse(attr_buffer, NL80211_ATTR_MAX, genlmsg_attrdata(msg_header, 0), genlmsg_attrlen(msg_header, 0), NULL);

	if (!attr_buffer[NL80211_ATTR_BSS]) { //Check if BSS
		return NL_SKIP;
	}
	//Parse the nested attributes. this is where the scan results are
	if (nla_parse_nested(bss_buffer, NL80211_BSS_MAX, attr_buffer[NL80211_ATTR_BSS], bss_policy)) {
		return NL_SKIP;
	}

	if (!bss_buffer[NL80211_BSS_BSSID])
		return NL_SKIP;

	scanresult.bssid = libnutcommon::MacAddress((ether_addr*)(bss_buffer[NL80211_BSS_BSSID]));
	scanresult.signal.bssid = scanresult.bssid;
	
	if (bss_buffer[NL80211_BSS_FREQUENCY])
		scanresult.freq = nla_get_u32(bss_buffer[NL80211_BSS_FREQUENCY]);

	if (bss_buffer[NL80211_BSS_SIGNAL_MBM]) {
		scanresult.signal.type = WSR_RCPI;
		scanresult.signal.quality.value = nla_get_u32(bss_buffer[NL80211_BSS_SIGNAL_MBM])/100;
	}
	if (bss_buffer[NL80211_BSS_SIGNAL_UNSPEC]) {
		scanresult.signal.type = WSR_UNKNOWN;
		scanresult.signal.quality.value = nla_get_u8(bss_buffer[NL80211_BSS_SIGNAL_UNSPEC]);
	}
// 	if (bss_buffer[NL80211_BSS_INFORMATION_ELEMENTS])
// 		print_ies(nla_data(bss_buffer[NL80211_BSS_INFORMATION_ELEMENTS]),
// 			  nla_len(bss_buffer[NL80211_BSS_INFORMATION_ELEMENTS]),
// 			  params->unknown, params->type);
	m_scanResults.push_back(scanresult);
	return NL_SKIP;
}
Beispiel #9
0
/*
 * Change state of port (ie from forwarding to blocking etc)
 * Used by spanning tree in user space.
 */
static int br_rtm_setlink(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
{
	struct net *net = sock_net(skb->sk);
	struct ifinfomsg *ifm;
	struct nlattr *protinfo;
	struct net_device *dev;
	struct net_bridge_port *p;
	u8 new_state;

	if (nlmsg_len(nlh) < sizeof(*ifm))
		return -EINVAL;

	ifm = nlmsg_data(nlh);
	if (ifm->ifi_family != AF_BRIDGE)
		return -EPFNOSUPPORT;

	protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO);
	if (!protinfo || nla_len(protinfo) < sizeof(u8))
		return -EINVAL;

	new_state = nla_get_u8(protinfo);
	if (new_state > BR_STATE_BLOCKING)
		return -EINVAL;

	dev = __dev_get_by_index(net, ifm->ifi_index);
	if (!dev)
		return -ENODEV;

	p = br_port_get_rtnl(dev);
	if (!p)
		return -EINVAL;

	/* if kernel STP is running, don't allow changes */
	if (p->br->stp_enabled == BR_KERNEL_STP)
		return -EBUSY;

	if (!netif_running(dev) ||
	    (!netif_carrier_ok(dev) && new_state != BR_STATE_DISABLED))
		return -ENETDOWN;

	p->state = new_state;
	br_log_state(p);

	spin_lock_bh(&p->br->lock);
	br_port_state_selection(p->br);
	spin_unlock_bh(&p->br->lock);

	br_ifinfo_notify(RTM_NEWLINK, p);

	return 0;
}
Beispiel #10
0
static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb,
                        u32 pid, u32 seq, u16 flags)
{
	int ret = -EINVAL;
	u16 id;
	u8 up, idtype;
	struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1];

	if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->setapp)
		goto out;

	ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
	                       dcbnl_app_nest);
	if (ret)
		goto out;

	ret = -EINVAL;
	/* all must be non-null */
	if ((!app_tb[DCB_APP_ATTR_IDTYPE]) ||
	    (!app_tb[DCB_APP_ATTR_ID]) ||
	    (!app_tb[DCB_APP_ATTR_PRIORITY]))
		goto out;

	/* either by eth type or by socket number */
	idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]);
	if ((idtype != DCB_APP_IDTYPE_ETHTYPE) &&
	    (idtype != DCB_APP_IDTYPE_PORTNUM))
		goto out;

	id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
	up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]);

	ret = dcbnl_reply(netdev->dcbnl_ops->setapp(netdev, idtype, id, up),
	                  RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP,
	                  pid, seq, flags);
out:
	return ret;
}
static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *info)
{
	int ret = 0;
	struct l2tp_session *session;

	session = l2tp_nl_session_find(info);
	if (session == NULL) {
		ret = -ENODEV;
		goto out;
	}

	if (info->attrs[L2TP_ATTR_DEBUG])
		session->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);

	if (info->attrs[L2TP_ATTR_DATA_SEQ])
		session->data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);

	if (info->attrs[L2TP_ATTR_RECV_SEQ])
		session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);

	if (info->attrs[L2TP_ATTR_SEND_SEQ])
		session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);

	if (info->attrs[L2TP_ATTR_LNS_MODE])
		session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);

	if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
		session->reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);

	if (info->attrs[L2TP_ATTR_MTU])
		session->mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);

	if (info->attrs[L2TP_ATTR_MRU])
		session->mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);

out:
	return ret;
}
Beispiel #12
0
static int
tunnel_key_copy_geneve_opt(const struct nlattr *nla, void *dst, int dst_len,
			   struct netlink_ext_ack *extack)
{
	struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1];
	int err, data_len, opt_len;
	u8 *data;

	err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
			       nla, geneve_opt_policy, extack);
	if (err < 0)
		return err;

	if (!tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS] ||
	    !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE] ||
	    !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]) {
		NL_SET_ERR_MSG(extack, "Missing tunnel key geneve option class, type or data");
		return -EINVAL;
	}

	data = nla_data(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
	data_len = nla_len(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
	if (data_len < 4) {
		NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is less than 4 bytes long");
		return -ERANGE;
	}
	if (data_len % 4) {
		NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is not a multiple of 4 bytes long");
		return -ERANGE;
	}

	opt_len = sizeof(struct geneve_opt) + data_len;
	if (dst) {
		struct geneve_opt *opt = dst;

		WARN_ON(dst_len < opt_len);

		opt->opt_class =
			nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]);
		opt->type = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]);
		opt->length = data_len / 4; /* length is in units of 4 bytes */
		opt->r1 = 0;
		opt->r2 = 0;
		opt->r3 = 0;

		memcpy(opt + 1, data, data_len);
	}

	return opt_len;
}
static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
{
	struct nlattr *attr = cda[CTA_PROTOINFO_DCCP];
	struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1];
	int err;

	if (!attr)
		return 0;

	err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr,
			       dccp_nla_policy);
	if (err < 0)
		return err;

	if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
	    nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE)
		return -EINVAL;

	write_lock_bh(&dccp_lock);
	ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
	write_unlock_bh(&dccp_lock);
	return 0;
}
Beispiel #14
0
static int ipip_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
				struct netlink_ext_ack *extack)
{
	u8 proto;

	if (!data || !data[IFLA_IPTUN_PROTO])
		return 0;

	proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
	if (proto != IPPROTO_IPIP && proto != IPPROTO_MPLS && proto != 0)
		return -EINVAL;

	return 0;
}
Beispiel #15
0
static iz_res_t scan_response(struct iz_cmd *cmd, struct genlmsghdr *ghdr, struct nlattr **attrs)
{
	uint8_t status, type;
	int i;
	uint8_t edl[27];

	if (!attrs[IEEE802154_ATTR_DEV_INDEX] ||
	    !attrs[IEEE802154_ATTR_STATUS] ||
	    !attrs[IEEE802154_ATTR_SCAN_TYPE])
		return IZ_STOP_ERR;

	status = nla_get_u8(attrs[IEEE802154_ATTR_STATUS]);
	if (status != 0)
		printf("Scan failed: %02x\n", status);

	type = nla_get_u8(attrs[IEEE802154_ATTR_SCAN_TYPE]);
	switch (type) {
		case IEEE802154_MAC_SCAN_ED:
			if (!attrs[IEEE802154_ATTR_ED_LIST])
				return IZ_STOP_ERR;

			nla_memcpy(edl, attrs[IEEE802154_ATTR_ED_LIST], 27);
			printf("ED Scan results:\n");
			for (i = 0; i < 27; i++)
				printf("  Ch%2d --- ED = %02x\n", i, edl[i]);
			return IZ_STOP_OK;

		case IEEE802154_MAC_SCAN_ACTIVE:
			printf("Started active (beacons) scan...\n");
			return IZ_CONT_OK;
		default:
			printf("Unsupported scan type: %d\n", type);
			break;
	}

	return IZ_STOP_OK;
}
Beispiel #16
0
static int handle_wiphy(struct netlink_config_s *nlcfg, struct nl_msg *msg, void *arg)
{
    struct nlattr *tb[NL80211_ATTR_MAX + 1];
    struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
    struct nlattr *nl_band;
    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    struct ieee80211_band *lband;
    int rem_band;
    int bandidx = -1;

    nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
            genlmsg_attrlen(gnlh, 0), NULL);

    if (!tb[NL80211_ATTR_WIPHY_BANDS])
        return -1;

    nla_for_each_nested(nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) {
        bandidx++;
        if (!nl_band)
            continue;

        nla_parse(tb_band, NL80211_BAND_ATTR_MAX,
                  nla_data(nl_band), nla_len(nl_band), NULL);

        lband = &nlcfg->bands[bandidx];
        if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET]) {
            assert(sizeof(lband->ht_cap.mcs) == nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]));
            lband->ht_cap.ht_supported = true;
            memcpy(&lband->ht_cap.mcs,
                   nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]),
                   nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]));
            lband->ht_cap.cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]);
            lband->ht_cap.ampdu_factor = nla_get_u8(tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]);
            lband->ht_cap.ampdu_density = nla_get_u8(tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]);
        }
        /* TODO: get rates */
    }
Beispiel #17
0
static int ieee802154_associate_req(struct sk_buff *skb,
                                    struct genl_info *info)
{
    struct net_device *dev;
    struct ieee802154_addr addr;
    int ret = -EINVAL;

    if (!info->attrs[IEEE802154_ATTR_CHANNEL] ||
            !info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
            (!info->attrs[IEEE802154_ATTR_COORD_HW_ADDR] &&
             !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]) ||
            !info->attrs[IEEE802154_ATTR_CAPABILITY])
        return -EINVAL;

    dev = ieee802154_nl_get_dev(info);
    if (!dev)
        return -ENODEV;

    if (info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]) {
        addr.addr_type = IEEE802154_ADDR_LONG;
        nla_memcpy(addr.hwaddr,
                   info->attrs[IEEE802154_ATTR_COORD_HW_ADDR],
                   IEEE802154_ADDR_LEN);
    } else {
        addr.addr_type = IEEE802154_ADDR_SHORT;
        addr.short_addr = nla_get_u16(
                              info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]);
    }
    addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);

    ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr,
            nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]),
            nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY]));

    dev_put(dev);
    return ret;
}
static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
{
	struct nlattr *attr = cda[CTA_PROTOINFO_DCCP];
	struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1];
	int err;

	if (!attr)
		return 0;

	err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr,
			       dccp_nla_policy);
	if (err < 0)
		return err;

	if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
	    !tb[CTA_PROTOINFO_DCCP_ROLE] ||
	    nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) > CT_DCCP_ROLE_MAX ||
	    nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE) {
		return -EINVAL;
	}

	spin_lock_bh(&ct->lock);
	ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
	if (nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) == CT_DCCP_ROLE_CLIENT) {
		ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
		ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
	} else {
		ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER;
		ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT;
	}
	if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) {
		ct->proto.dccp.handshake_seq =
		be64_to_cpu(nla_get_be64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]));
	}
	spin_unlock_bh(&ct->lock);
	return 0;
}
Beispiel #19
0
static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
{
	struct net_device *dev;
	int ret = -EOPNOTSUPP;
	u8 type;
	u32 channels;
	u8 duration;
	u8 page;

	if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] ||
	    !info->attrs[IEEE802154_ATTR_CHANNELS] ||
	    !info->attrs[IEEE802154_ATTR_DURATION])
		return -EINVAL;

	dev = ieee802154_nl_get_dev(info);
	if (!dev)
		return -ENODEV;
	if (!ieee802154_mlme_ops(dev)->scan_req)
		goto out;

	type = nla_get_u8(info->attrs[IEEE802154_ATTR_SCAN_TYPE]);
	channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]);
	duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]);

	if (info->attrs[IEEE802154_ATTR_PAGE])
		page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
	else
		page = 0;


	ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, page,
			duration);

out:
	dev_put(dev);
	return ret;
}
Beispiel #20
0
static iz_res_t set_response(struct iz_cmd *cmd, struct genlmsghdr *ghdr, struct nlattr **attrs)
{
	uint8_t status;
	
	if (!attrs[IEEE802154_ATTR_STATUS])
		return IZ_STOP_ERR;
	
	status = nla_get_u8(attrs[IEEE802154_ATTR_STATUS]);
	if (status != 0) {
		printf("Operation Failed. Check channel and PAN ID\n");
		return IZ_STOP_ERR;
	}

	return IZ_STOP_OK;
}
Beispiel #21
0
static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])
{
	int buf_len, ret, len;
	struct sk_buff *skb;
	void *buf;
	u8 answer = 0;

	wl1271_debug(DEBUG_TESTMODE, "testmode cmd test");

	if (!tb[WL1271_TM_ATTR_DATA])
		return -EINVAL;

	buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
	buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);

	if (tb[WL1271_TM_ATTR_ANSWER])
		answer = nla_get_u8(tb[WL1271_TM_ATTR_ANSWER]);

	if (buf_len > sizeof(struct wl1271_command))
		return -EMSGSIZE;

	mutex_lock(&wl->mutex);
	ret = wl1271_cmd_test(wl, buf, buf_len, answer);
	mutex_unlock(&wl->mutex);

	if (ret < 0) {
		wl1271_warning("testmode cmd test failed: %d", ret);
		return ret;
	}

	if (answer) {
		len = nla_total_size(buf_len);
		skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len);
		if (!skb)
			return -ENOMEM;

		NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf);
		ret = cfg80211_testmode_reply(skb);
		if (ret < 0)
			return ret;
	}

	return 0;

nla_put_failure:
	kfree_skb(skb);
	return -EMSGSIZE;
}
/**
 * netlbl_unlabel_accept - Handle an ACCEPT message
 * @skb: the NETLINK buffer
 * @info: the Generic NETLINK info block
 *
 * Description:
 * Process a user generated ACCEPT message and set the accept flag accordingly.
 * Returns zero on success, negative values on failure.
 *
 */
static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info)
{
	u8 value;
	struct netlbl_audit audit_info;

	if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) {
		value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]);
		if (value == 1 || value == 0) {
			netlbl_netlink_auditinfo(skb, &audit_info);
			netlbl_unlabel_acceptflg_set(value, &audit_info);
			return 0;
		}
	}

	return -EINVAL;
}
Beispiel #23
0
/* handler for SET messages via NETLINK */
int ipctl_set(struct sk_buff *skb, struct genl_info *info)
{
	/* message handling code goes here; return 0 on success, negative
	 * values on failure */

	int property = nla_get_u32(info->attrs[IPCTL_ATTR_PROPERTY]);
	int ifIndex = nla_get_u32(info->attrs[IPCTL_ATTR_IFINDEX]);
	int value = nla_get_u8(info->attrs[IPCTL_ATTR_VALUE]);

	pr_debug("ipctl: set p=%d i=%d v=%d\n", property, ifIndex, value);

	if (property == IPCTL_PROPERTY_PROXYARP)
		return ipctl_set_proxyarp_by_ifindex(ifIndex, value);

	return 0;
}
Beispiel #24
0
static int ct_parse_protoinfo_tcp(struct nfnl_ct *ct, struct nlattr *attr)
{
	struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
	int err;

	err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr,
			       ct_protoinfo_tcp_policy);
	if (err < 0)
		return err;

	if (tb[CTA_PROTOINFO_TCP_STATE])
		nfnl_ct_set_tcp_state(ct,
				nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]));

	return 0;
}
Beispiel #25
0
static int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb,
                          u32 pid, u32 seq, u16 flags)
{
	int ret = -EINVAL;
	u8 value;

	if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->setstate)
		return ret;

	value = nla_get_u8(tb[DCB_ATTR_STATE]);

	ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value),
	                  RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE,
	                  pid, seq, flags);

	return ret;
}
Beispiel #26
0
static int ixgbe_dcb_slink_spd(struct sk_buff *skb, struct genl_info *info)
{
	struct net_device *netdev = NULL;
	struct ixgbe_adapter *adapter = NULL;
	int ret = -EINVAL;
	u8 value;

	if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_LINK_SPD])
		goto err;

	netdev = dev_get_by_name(&init_net,
				 nla_data(info->attrs[DCB_A_IFNAME]));
	if (!netdev)
		goto err;

	ret = ixgbe_dcb_check_adapter(netdev);
	if (ret)
		goto err_out;
	else
		adapter = netdev_priv(netdev);

	value = nla_get_u8(info->attrs[DCB_A_LINK_SPD]);
	if (value > 9) {
		DPRINTK(DRV, ERR, "Value is not 0 thru 9, it is %d.\n", value);
	} else {
		if (!adapter->dcb_set_bitmap &&
		   ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg,
				adapter->ring_feature[RING_F_DCB].indices)) {
			ret = -EINVAL;
			goto err_out;
		}

		adapter->temp_dcb_cfg.link_speed = value;
		adapter->dcb_set_bitmap |= BIT_LINKSPEED;
	}

	ret = ixgbe_nl_reply(0, DCB_C_SLINK_SPD, DCB_A_LINK_SPD, info);
	if (ret)
		goto err_out;

err_out:
	dev_put(netdev);
err:
	return ret;
}
Beispiel #27
0
/*
 * Change state of port (ie from forwarding to blocking etc)
 * Used by spanning tree in user space.
 */
static int br_rtm_setlink(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
{
	struct ifinfomsg *ifm;
	struct nlattr *protinfo;
	struct net_device *dev;
	struct net_bridge_port *p;
	u8 new_state;

	if (nlmsg_len(nlh) < sizeof(*ifm))
		return -EINVAL;

	ifm = nlmsg_data(nlh);
	if (ifm->ifi_family != AF_BRIDGE)
		return -EPFNOSUPPORT;

	protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO);
	if (!protinfo || nla_len(protinfo) < sizeof(u8))
		return -EINVAL;

	new_state = nla_get_u8(protinfo);
	if (new_state > BR_STATE_BLOCKING)
		return -EINVAL;

	dev = __if_dev_get_by_index(ifm->ifi_index);
	if (!dev)
		return -ENODEV;

	p = dev->br_port;
	if (!p)
		return -EINVAL;

	/* if kernel STP is running, don't allow changes */
	if (p->br->stp_enabled)
		return -EBUSY;

	if (!if_dev_admin_up(dev) ||
	    (!if_dev_running(dev) && new_state != BR_STATE_DISABLED))
		return -ENETDOWN;

	p->state = new_state;
	br_log_state(p);
	return 0;
}
Beispiel #28
0
static int
save_attribute_handler(struct nl_msg *msg, void *arg)
{
    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    const char *name = "N/A";
    struct wprobe_attribute *attr;
    int type = 0;
    struct wprobe_attr_cb *cb = arg;

    nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0),
              genlmsg_attrlen(gnlh, 0), attribute_policy);

    if (tb[WPROBE_ATTR_NAME])
        name = nla_data(tb[WPROBE_ATTR_NAME]);

    attr = malloc(sizeof(struct wprobe_attribute) + strlen(name) + 1);
    if (!attr)
        return -1;

    memset(attr, 0, sizeof(struct wprobe_attribute));

    if (tb[WPROBE_ATTR_ID])
        attr->id = nla_get_u32(tb[WPROBE_ATTR_ID]);

    if (tb[WPROBE_ATTR_MAC] && cb->addr)
        memcpy(cb->addr, nla_data(tb[WPROBE_ATTR_MAC]), 6);

    if (tb[WPROBE_ATTR_FLAGS])
        attr->flags = nla_get_u32(tb[WPROBE_ATTR_FLAGS]);

    if (tb[WPROBE_ATTR_TYPE])
        type = nla_get_u8(tb[WPROBE_ATTR_TYPE]);

    if ((type < WPROBE_VAL_STRING) ||
            (type > WPROBE_VAL_U64))
        type = 0;

    attr->type = type;
    strcpy(attr->name, name);
    INIT_LIST_HEAD(&attr->list);
    list_add(&attr->list, cb->list);
    return 0;
}
Beispiel #29
0
/*
 * This function handles the user application switch ucode ownership.
 *
 * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
 * decide who the current owner of the uCode
 *
 * If the current owner is OWNERSHIP_TM, then the only host command
 * can deliver to uCode is from testmode, all the other host commands
 * will dropped.
 *
 * default driver is the owner of uCode in normal operational mode
 *
 * @hw: ieee80211_hw object that represents the device
 * @tb: gnl message fields from the user space
 */
static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
{
	struct iwl_priv *priv = hw->priv;
	u8 owner;

	if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
		IWL_DEBUG_INFO(priv, "Error finding ucode owner\n");
		return -ENOMSG;
	}

	owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
	if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
		priv->shrd->ucode_owner = owner;
	else {
		IWL_DEBUG_INFO(priv, "Invalid owner\n");
		return -EINVAL;
	}
	return 0;
}
Beispiel #30
0
static int nfc_netlink_event_adapter(struct genlmsghdr *gnlh, bool add)
{
	struct nlattr *attrs[NFC_ATTR_MAX + 1];
	uint32_t idx;

	DBG("");

	nla_parse(attrs, NFC_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
		  genlmsg_attrlen(gnlh, 0), NULL);
	if (!attrs[NFC_ATTR_DEVICE_INDEX]) {
		near_error("Missing device index");
		return -ENODEV;
	}

	idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]);

	if (add &&
		(!attrs[NFC_ATTR_DEVICE_NAME] ||
			!attrs[NFC_ATTR_PROTOCOLS])) {
		near_error("Missing attributes");
		return -EINVAL;
	}

	if (add) {
		char *name;
		uint32_t protocols;
		bool powered;

		name = nla_get_string(attrs[NFC_ATTR_DEVICE_NAME]);
		protocols = nla_get_u32(attrs[NFC_ATTR_PROTOCOLS]);
		if (!attrs[NFC_ATTR_DEVICE_POWERED])
			powered = false;
		else
			powered = nla_get_u8(attrs[NFC_ATTR_DEVICE_POWERED]);

		return __near_manager_adapter_add(idx, name,
						protocols, powered);
	} else {
		__near_manager_adapter_remove(idx);
	}

	return 0;
}