Beispiel #1
0
static int handle_incoming_message(struct nl_msg *msg) {
    struct nlmsghdr *nl_hdr;
    int is_genl_msg;
    int res = 0;

    is_genl_msg = 1;

    nl_hdr = nlmsg_hdr(msg);
    if ( nl_hdr->nlmsg_type == NLMSG_ERROR ) {
        struct nlmsgerr* nl_err = (struct nlmsgerr*)nlmsg_data(nlmsg_hdr(msg));
        res = nl_err->error;
        if ( res != 0 ) /* Else we got just ACK message, no special handling of those */
            printf("Error message response code: %d!!\n", nl_err->error);

        is_genl_msg = 0;
    } else if ( nl_hdr->nlmsg_type != state.gnl_fid ) {
        printf("Ignore unknown message type: %d!!\n", nl_hdr->nlmsg_type);
        is_genl_msg = 0;
    }

    if ( is_genl_msg ) {
        //printf("Handling generic netlink msg: Tx id: %d\n", nlmsg_hdr(msg)->nlmsg_seq);
        if ( res = genl_cmd_dispatch(msg) ) {
            printf("Handling generic netlink msg error %d\n", res);
            process_handle_error(res, msg);
        }
    }

    nlmsg_free(msg);

    return res;
}
int handle_immigration_request(struct nl_msg *req_msg) {
	struct nl_msg *msg = NULL;
	struct nlattr *nla;
	int ret = 0;
	int seq;
	struct internal_state* state = get_current_state();

	// In params	
	int uid;
	int slot_index;
	char* name;
	// Out params
	int accept = 1;
	
	seq = nlmsg_hdr(req_msg)->nlmsg_seq;

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_UID);
	if (nla == NULL)
		return  -EBADMSG;
	uid = nla_get_u32(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_INDEX);
	if (nla == NULL)
		return  -EBADMSG;
	slot_index = nla_get_u32(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_NAME);
	if (nla == NULL)
		return  -EBADMSG;
	//name = nl_data_get(nla_get_data(nla));
	name = nla_data(nla);

	//printf("NPM CALLED FOR NAME: %s\n", name);
	if ( immigration_request_callback )
        	immigration_request_callback(uid, slot_index, name, &accept);
	
	if ( (ret=prepare_response_message(state->handle, DIRECTOR_IMMIGRATION_REQUEST_RESPONSE, state->gnl_fid, seq, &msg) ) != 0 ) {
		goto done;
	}
	
	ret = nla_put_u32(msg,
			DIRECTOR_A_DECISION,
			accept);

	if (ret != 0)
		goto error_del_resp;

	ret = send_request_message(state->handle, msg, 0);
	goto done;	

error_del_resp:
	nlmsg_free(msg);
done:	
	return ret;
}
Beispiel #3
0
static void
ind_ovs_handle_packet_miss(struct ind_ovs_upcall_thread *thread,
                           struct ind_ovs_port *port,
                           struct nl_msg *msg, struct nlattr **attrs)
{
    struct nlmsghdr *nlh = nlmsg_hdr(msg);
    struct genlmsghdr *gnlh = (void *)(nlh + 1);

    struct nlattr *key = attrs[OVS_PACKET_ATTR_KEY];
    struct nlattr *packet = attrs[OVS_PACKET_ATTR_PACKET];
    assert(key && packet);

    struct ind_ovs_parsed_key pkey;
    ind_ovs_parse_key(key, &pkey);

    /* Lookup the flow in the userspace flowtable. */
    struct ind_ovs_flow *flow;
    if (ind_ovs_lookup_flow(&pkey, &flow) != 0) {
        ind_ovs_upcall_request_pktin(pkey.in_port, port, packet, key, OF_PACKET_IN_REASON_NO_MATCH);
        return;
    }

    /* Reuse the incoming message for the packet execute */
    gnlh->cmd = OVS_PACKET_CMD_EXECUTE;
    ind_ovs_translate_actions(&pkey, flow->of_list_action,
                              msg, OVS_PACKET_ATTR_ACTIONS);

    __sync_fetch_and_add(&flow->packets, 1);
    __sync_fetch_and_add(&flow->bytes, nla_len(packet));

    /* Reuse the translated actions for adding the kflow. */
    struct nlattr *actions = nlmsg_find_attr(nlmsg_hdr(msg),
        sizeof(struct genlmsghdr) + sizeof(struct ovs_header),
        OVS_PACKET_ATTR_ACTIONS);

    /* Don't send the packet back out if it would be dropped. */
    if (nla_len(actions) > 0) {
        nlh->nlmsg_pid = 0;
        nlh->nlmsg_seq = 0;
        nlh->nlmsg_flags = NLM_F_REQUEST;
        struct iovec *iovec = &thread->tx_queue[thread->tx_queue_len++];
        iovec->iov_base = nlh;
        iovec->iov_len = nlh->nlmsg_len;
        if (thread->log_upcalls) {
            LOG_VERBOSE("Sending upcall reply:");
            ind_ovs_dump_msg(nlh);
        }
    }

    /* See the comment for ind_ovs_upcall_seen_key. */
    if (ind_ovs_upcall_seen_key(thread, key)) {
        /* Create a kflow with the given key and actions. */
        ind_ovs_bh_request_kflow(key, actions);
    }
}
Beispiel #4
0
static struct sk_buff *brc_send_command(struct sk_buff *request,
					struct nlattr **attrs)
{
	unsigned long int flags;
	struct sk_buff *reply;
	int error;

	mutex_lock(&brc_serial);

	/* Increment sequence number first, so that we ignore any replies
	 * to stale requests. */
	spin_lock_irqsave(&brc_lock, flags);
	nlmsg_hdr(request)->nlmsg_seq = ++brc_seq;
	INIT_COMPLETION(brc_done);
	spin_unlock_irqrestore(&brc_lock, flags);

	nlmsg_end(request, nlmsg_hdr(request));

	/* Send message. */
	error = genlmsg_multicast(request, 0, brc_mc_group.id, GFP_KERNEL);
	if (error < 0)
		goto error;

	/* Wait for reply. */
	error = -ETIMEDOUT;
	if (!wait_for_completion_timeout(&brc_done, BRC_TIMEOUT)) {
		pr_warn("timed out waiting for userspace\n");
		goto error;
    }

	/* Grab reply. */
	spin_lock_irqsave(&brc_lock, flags);
	reply = brc_reply;
	brc_reply = NULL;
	spin_unlock_irqrestore(&brc_lock, flags);

	mutex_unlock(&brc_serial);

	/* Re-parse message.  Can't fail, since it parsed correctly once
	 * already. */
	error = nlmsg_parse(nlmsg_hdr(reply), GENL_HDRLEN,
			    attrs, BRC_GENL_A_MAX, brc_genl_policy);
	WARN_ON(error);

	return reply;

error:
	mutex_unlock(&brc_serial);
	return ERR_PTR(error);
}
Beispiel #5
0
int handle_task_exitted(struct nl_msg *req_msg) {
	struct nl_msg *msg = NULL;
	struct nlattr *nla;
	int ret = 0;
	int seq;
	struct internal_state* state = get_current_state();
	struct rusage *rusage;

	// In params
	pid_t pid;
	int exit_code;
	
	seq = nlmsg_hdr(req_msg)->nlmsg_seq;

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_PID);
	if (nla == NULL)
		return  -EBADMSG;
	pid = nla_get_u32(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_EXIT_CODE);
	if (nla == NULL)
		return  -EBADMSG;
	exit_code = nla_get_u32(nla);

	nla = nlmsg_find_attr(nlmsg_hdr(req_msg), sizeof(struct genlmsghdr), DIRECTOR_A_RUSAGE);
	if (nla == NULL)
		return  -EBADMSG;
	
	//rusage = nl_data_get(nla_get_data(nla));
	rusage = nla_data(nla);

	if ( task_exitted_callback )
        	task_exitted_callback(pid, exit_code, rusage);
	
	if ( (ret=prepare_response_message(state->sk, DIRECTOR_ACK, state->gnl_fid, seq, &msg) ) != 0 ) {
		goto done;
	}
	
	if (ret != 0)
		goto error_del_resp;

	ret = send_request_message(state->sk, msg, 0);
	goto done;	

error_del_resp:
	nlmsg_free(msg);
done:	
	return ret;
}
Beispiel #6
0
/* function: get_default_route_cb
 * finds the default route with the request family and out interface and saves the gateway
 * msg  - netlink message
 * data - (struct default_route_data) requested filters and response storage
 */
static int get_default_route_cb(struct nl_msg *msg, void *data) {
  struct rtmsg *rt_p;
  struct rtattr *rta_p;
  int rta_len;
  struct default_route_data *default_route = data;
  union anyip *this_gateway = NULL;
  ssize_t this_gateway_size;
  int this_interface_id = -1;

  if(default_route->reply_found_route) { // we already found our route
    return NL_OK;
  }

  rt_p = (struct rtmsg *)nlmsg_data(nlmsg_hdr(msg));
  if(rt_p->rtm_dst_len != 0) { // not a default route
    return NL_OK;
  }
  if((rt_p->rtm_family != default_route->request_family) || (rt_p->rtm_table != RT_TABLE_MAIN)) { // not a route we care about
    return NL_OK;
  }

  rta_p = (struct rtattr *)RTM_RTA(rt_p);
  rta_len = RTM_PAYLOAD(nlmsg_hdr(msg));
  for(; RTA_OK(rta_p, rta_len); rta_p = RTA_NEXT(rta_p, rta_len)) {
    switch(rta_p->rta_type) {
      case RTA_GATEWAY:
        this_gateway = RTA_DATA(rta_p);
        this_gateway_size = RTA_PAYLOAD(rta_p);
        break;
      case RTA_OIF:
        this_interface_id = *(int *)RTA_DATA(rta_p);
        break;
      default:
        break;
    }
  }

  if(this_interface_id == default_route->request_interface_id) {
    default_route->reply_found_route = 1;
    if(this_gateway != NULL) {
      memcpy(&default_route->reply_gateway, this_gateway, this_gateway_size);
      default_route->reply_has_gateway = 1;
    } else {
      default_route->reply_has_gateway = 0;
    }
  }
  return NL_OK;
}
Beispiel #7
0
static int
show_vport__(struct nl_msg *msg, void *arg)
{
    struct nlmsghdr *nlh = nlmsg_hdr(msg);
    struct nlattr *attrs[OVS_VPORT_ATTR_MAX+1];
    if (genlmsg_parse(nlh, sizeof(struct ovs_header),
                    attrs, OVS_VPORT_ATTR_MAX,
                    NULL) < 0) {
        abort();
    }

    fprintf(stderr, "    %d %s %s\n",
            nla_get_u32(attrs[OVS_VPORT_ATTR_PORT_NO]),
            (char *)nla_data(attrs[OVS_VPORT_ATTR_NAME]),
            vport_type_str__(nla_get_u32(attrs[OVS_VPORT_ATTR_TYPE])));

    struct ovs_vport_stats *stats = nla_data(attrs[OVS_VPORT_ATTR_STATS]);
    fprintf(stderr, "      rx: packets=%"PRIu64" bytes=%"PRIu64" errors=%"PRIu64" dropped=%"PRIu64"\n",
            (uint64_t)stats->rx_packets, (uint64_t)stats->rx_bytes,
            (uint64_t)stats->rx_errors, (uint64_t)stats->rx_dropped);
    fprintf(stderr, "      tx: packets=%"PRIu64" bytes=%"PRIu64" errors=%"PRIu64" dropped=%"PRIu64"\n",
            (uint64_t)stats->tx_packets, (uint64_t)stats->tx_bytes,
            (uint64_t)stats->tx_errors, (uint64_t)stats->tx_dropped);

    return NL_OK;
}
Beispiel #8
0
static int ipvs_daemon_parse_cb(struct nl_msg *msg, void *arg)
{
	struct nlmsghdr *nlh = nlmsg_hdr(msg);
	struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1];
	struct nlattr *daemon_attrs[IPVS_DAEMON_ATTR_MAX + 1];
	ipvs_daemon_t *u = (ipvs_daemon_t *)arg;
	int i = 0;

	/* We may get two daemons.  If we've already got one, this is the second */
	if (u[0].state)
		i = 1;

	if (genlmsg_parse(nlh, 0, attrs, IPVS_CMD_ATTR_MAX, ipvs_cmd_policy) != 0)
		return -1;

	if (nla_parse_nested(daemon_attrs, IPVS_DAEMON_ATTR_MAX,
			     attrs[IPVS_CMD_ATTR_DAEMON], ipvs_daemon_policy))
		return -1;

	if (!(daemon_attrs[IPVS_DAEMON_ATTR_STATE] &&
	      daemon_attrs[IPVS_DAEMON_ATTR_MCAST_IFN] &&
	      daemon_attrs[IPVS_DAEMON_ATTR_SYNC_ID]))
		return -1;

	u[i].state = nla_get_u32(daemon_attrs[IPVS_DAEMON_ATTR_STATE]);
	strncpy(u[i].mcast_ifn,
		nla_get_string(daemon_attrs[IPVS_DAEMON_ATTR_MCAST_IFN]),
		IP_VS_IFNAME_MAXLEN);
	u[i].syncid = nla_get_u32(daemon_attrs[IPVS_DAEMON_ATTR_SYNC_ID]);

	return NL_OK;
}
Beispiel #9
0
static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
{
	if (ab) {
		struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
		nlh->nlmsg_pid = pid;
	}
}
Beispiel #10
0
static int nl80211_iface_info_handler (struct nl_msg *msg, void *arg)
{
	struct nl80211_iface_info *info = arg;
	struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg));
	struct nlattr *tb[NL80211_ATTR_MAX + 1];
                
	if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0),
		       genlmsg_attrlen (gnlh, 0), NULL) < 0)
		return NL_SKIP;

	if (!tb[NL80211_ATTR_IFTYPE])
		return NL_SKIP;

	switch (nla_get_u32 (tb[NL80211_ATTR_IFTYPE])) {
	case NL80211_IFTYPE_ADHOC:
		info->mode = NM_802_11_MODE_ADHOC;
		break;
	case NL80211_IFTYPE_AP:
		info->mode = NM_802_11_MODE_AP;
		break;
	case NL80211_IFTYPE_STATION:
		info->mode = NM_802_11_MODE_INFRA;
		break;
	}
                          
	return NL_SKIP;
}
Beispiel #11
0
/*
 * Receive events from netlink socket and generate events.
 */
static int
__ni_rtevent_process_cb(struct nl_msg *msg, void *ptr)
{
	const struct sockaddr_nl *sender = nlmsg_get_src(msg);
	struct nlmsghdr *nlh;
	ni_netconfig_t *nc;

	if ((nc = ni_global_state_handle(0)) == NULL)
		return NL_SKIP;

	if (sender->nl_pid != 0) {
		ni_error("ignoring rtnetlink event message from PID %u",
			sender->nl_pid);
		return NL_SKIP;
	}

	nlh = nlmsg_hdr(msg);
	if (__ni_rtevent_process(nc, sender, nlh) < 0) {
		ni_debug_events("ignoring %s rtnetlink event",
			ni_rtnl_msg_type_to_name(nlh->nlmsg_type, "unknown"));
		return NL_SKIP;
	}

	return NL_OK;
}
Beispiel #12
0
static int dump_mgmt_frame(struct nl_msg *msg, void *arg)
{
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];

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

	if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
		uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);
		printf("freq %u MHz\n", freq);
	}

	if (tb_msg[NL80211_ATTR_RX_SIGNAL_DBM]) {
		/* nl80211_send_mgmt sends signed dBm value as u32 */
		int dbm = nla_get_u32(tb_msg[NL80211_ATTR_RX_SIGNAL_DBM]);
		printf("rssi %d dBm\n", dbm);
	}

	if (tb_msg[NL80211_ATTR_FRAME]) {
		int len = nla_len(tb_msg[NL80211_ATTR_FRAME]);
		uint8_t *data = nla_data(tb_msg[NL80211_ATTR_FRAME]);
		iw_hexdump("mgmt", data, len);
	}

	return 0;
}
Beispiel #13
0
static int _list(struct nl_msg *nl_msg, void *arg)
{
	struct nlmsghdr *nlh = nlmsg_hdr(nl_msg);
	struct nlattr *info[TIPC_NLA_MAX + 1];
	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];

	genlmsg_parse(nlh, 0, info, TIPC_NLA_MAX, NULL);

	if (!info[TIPC_NLA_BEARER]) {
		log_err("no bearer received from kernel\n");
		return NL_STOP;
	}

	if (nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
			     info[TIPC_NLA_BEARER], NULL)) {
		log_err("parsing nested bearer properties\n");
		return NL_STOP;
	}

	if (!attrs[TIPC_NLA_BEARER_NAME]) {
		log_err("no bearer name received from kernel\n");
		return NL_STOP;
	}

	printf("%s\n", nla_get_string(attrs[TIPC_NLA_BEARER_NAME]));

	return NL_OK;
}
// valid interface callback handler
static int iface_handler(struct nl_msg *msg, void *arg)
{
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];

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

	if (tb_msg[NL80211_ATTR_WIPHY])
	{
		char wiphy[IFNAMSIZ];
		sprintf(wiphy, "phy%d", nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]));

		// If selected physical interface matches the result, search for a monitor interface and copy the name
		if(strcmp(phy_name, wiphy) == 0)
		{
			if (tb_msg[NL80211_ATTR_IFTYPE] && tb_msg[NL80211_ATTR_IFNAME])
			{
				// If the interface type is monitor
				if(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]) == 6)
					strcpy(IF_name, nla_get_string(tb_msg[NL80211_ATTR_IFNAME]));
			}
		}
	}

	return NL_SKIP;
}
Beispiel #15
0
void kernel_receive(struct sk_buff *__skb) //内核从用户空间接收数据
{
    struct sk_buff *skb;
    struct nlmsghdr *nlh = NULL;

    char *data = "This is eric's test message from kernel";

    printk( "[kernel recv] begin kernel_receive\n");
    skb = skb_get(__skb);

    if(skb->len >= sizeof(struct nlmsghdr)){
        nlh = (struct nlmsghdr *)skb->data;
        if((nlh->nlmsg_len >= sizeof(struct nlmsghdr))
            && (__skb->len >= nlh->nlmsg_len)){
            user_process.pid = nlh->nlmsg_pid;
            printk( "[kernel recv] data receive from user are:%s\n", (char *)NLMSG_DATA(nlh));
            printk( "[kernel recv] user_pid:%d\n", user_process.pid);
//            send_to_user(data);
        }
    }else{
        printk( "[kernel recv] data receive from user are:%s\n",(char *)NLMSG_DATA(nlmsg_hdr(__skb)));
//        send_to_user(data);
    }

    kfree_skb(skb);
}
Beispiel #16
0
static int get_devices_handler(struct nl_msg *n, void *arg)
{
	struct nlmsghdr *nlh = nlmsg_hdr(n);
	struct nlattr *attrs[NFC_ATTR_MAX + 1];
	char *name;
	uint32_t idx, protocols;
	bool powered;

	DBG("");

	genlmsg_parse(nlh, 0, attrs, NFC_ATTR_MAX, NULL);

	if (!attrs[NFC_ATTR_DEVICE_INDEX] ||
	    !attrs[NFC_ATTR_DEVICE_NAME] ||
	    !attrs[NFC_ATTR_PROTOCOLS]) {
		nl_perror(NLE_MISSING_ATTR, "NFC_CMD_GET_DEVICE");
		return NL_STOP;
	}

	idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]);
	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]);

	__near_manager_adapter_add(idx, name, protocols, powered);

	return NL_SKIP;
}
Beispiel #17
0
static int
show_datapath__(struct nl_msg *msg, void *arg)
{
    struct nlmsghdr *nlh = nlmsg_hdr(msg);
    struct genlmsghdr *gnlh = nlmsg_data(nlh);
    struct ovs_header *hdr = (void *)(gnlh + 1);
    struct nlattr *attrs[OVS_DP_ATTR_MAX+1];
    if (genlmsg_parse(nlh, sizeof(struct ovs_header),
                    attrs, OVS_DP_ATTR_MAX,
                    NULL) < 0) {
        abort();
    }

    struct ovs_dp_stats *stats = nla_data(attrs[OVS_DP_ATTR_STATS]);

    fprintf(stderr, "%s:\n", (char *)nla_data(attrs[OVS_DP_ATTR_NAME]));
    fprintf(stderr, "  kernel lookups: hit=%"PRIu64" missed=%"PRIu64" lost=%"PRIu64"\n",
            (uint64_t)stats->n_hit, (uint64_t)stats->n_missed,
            (uint64_t)stats->n_lost);
    fprintf(stderr, "  kernel flows=%"PRIu64"\n", (uint64_t)stats->n_flows);
    fprintf(stderr, "  ports:\n");
    show_vports__(hdr->dp_ifindex);

    return NL_OK;
}
Beispiel #18
0
static void kernel_receive(struct sk_buff *skb)
{
    struct nlmsghdr *nlh = NULL;
    int len;
    nlh = nlmsg_hdr(skb);
    len = skb->len;

    while(nlmsg_ok(nlh, len)) {
        if (down_trylock(&receive_sem)) {
            return;
        }

        if (nlh->nlmsg_type == NL_U_PID) {
            write_lock_bh(&user_proc.lock);
            user_proc.pid = nlh->nlmsg_pid;
            write_unlock_bh(&user_proc.lock);
        } else if (nlh->nlmsg_type == NL_CLOSE) {
            write_lock_bh(&user_proc.lock);
            if (nlh->nlmsg_pid == user_proc.pid) {
                user_proc.pid = 0;
            }
            write_unlock_bh(&user_proc.lock);
        }

        up(&receive_sem);
        nlh = nlmsg_next(nlh, &len);
    }

}
Beispiel #19
0
int mac80211_get_coverageclass(char *interface) {
	struct nlattr *tb[NL80211_ATTR_MAX + 1];
	struct nl_msg *msg;
	struct genlmsghdr *gnlh;
	int phy;
	unsigned char coverage=0;

	phy = mac80211_get_phyidx_by_vifname(interface);
	if (phy == -1) return 0;

	msg = unl_genl_msg(&unl, NL80211_CMD_GET_WIPHY, false);
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, phy);
	if (unl_genl_request_single(&unl, msg, &msg) < 0)
		return 0;
	if (!msg) return 0;
	gnlh=nlmsg_data(nlmsg_hdr(msg));
	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
		  genlmsg_attrlen(gnlh, 0), NULL);
	if (tb[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
		coverage = nla_get_u8(tb[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
		/* See handle_distance() for an explanation where the '450' comes from */
		// printf("\tCoverage class: %d (up to %dm)\n", coverage, 450 * coverage);
	}
	// printf ("%d\n", coverage);
	nlmsg_free(msg);
	return coverage;
nla_put_failure:
	nlmsg_free(msg);
	return 0;
}
static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
{
	struct sk_buff *rep_buf;
	struct nlmsghdr *rep_nlh;
	struct nlmsghdr *req_nlh = info->nlhdr;
	struct tipc_genlmsghdr *req_userhdr = info->userhdr;
	int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN);
	u16 cmd;

	if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
		cmd = TIPC_CMD_NOT_NET_ADMIN;
	else
		cmd = req_userhdr->cmd;

	rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd,
			nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
			nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
			hdr_space);

	if (rep_buf) {
		skb_push(rep_buf, hdr_space);
		rep_nlh = nlmsg_hdr(rep_buf);
		memcpy(rep_nlh, req_nlh, hdr_space);
		rep_nlh->nlmsg_len = rep_buf->len;
		genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).portid);
	}

	return 0;
}
static int get_noise_for_scan_results(struct nl_msg *msg, void *arg)
{
	struct nlattr *tb[NL80211_ATTR_MAX + 1];
	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
	struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
	static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
		[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
Beispiel #22
0
int nl_send_auto_complete_apda(struct nl_handle *handle,struct nl_msg *msg)
{
	struct nlmsghdr *nlh;
	struct nl_cb *cb = handle->h_cb;
        int ret = 0;
	nlh = nlmsg_hdr(msg);
        if (nlh->nlmsg_pid == 0)
                nlh->nlmsg_pid = handle->h_local.nl_pid;
 
        if (nlh->nlmsg_seq == 0)
                 nlh->nlmsg_seq = handle->h_seq_next++;
 	if (msg->nm_protocol == -1)
                 msg->nm_protocol = handle->h_proto;
	//msg->nm_flags |= (NLM_F_REQUEST | NLM_F_ACK);
	if (cb->cb_send_ow)
                return cb->cb_send_ow(handle, msg);
        else {
	int ret1;
	ret1 = adapter_socket_init();
	if(ret1 < 0) {
		printf("adapter_socket_init fail\n");
		close(listenfd);
		return -1;
	}
	char sendbuf[2048];
	pduFormat(sendbuf,msg);
	ret = send(listenfd,sendbuf,2048,0);
	if (ret < 0){
		printf("nl80211: NL_SEND_AUTO_COMPLETE failed\n");
		close(listenfd);
	}
	return ret ;
	}
}
Beispiel #23
0
static int usnic_nl_send_query(struct usnic_nl_sk *unlsk, struct nl_msg *msg,
				int protocol, int flag)
{
	int ret, retry;
	struct nlmsghdr *nlhdr;

	nlhdr = nlmsg_hdr(msg);
	while (1) {
		nlhdr->nlmsg_pid = nl_socket_get_local_port(unlsk->nlh);
		nlhdr->nlmsg_seq = ++unlsk->seq;
		nlmsg_set_proto(msg, protocol);
		nlhdr->nlmsg_flags = flag;

		/* Sometimes nl_send() can fail simply because the
		 * kernel is temporarily out of resources, and we
		 * should just try again.  libnl1 and libnl3 handle
		 * this case a little differently, so use the
		 * USD_NL_SEND() macro to hide the differences.  If
		 * retry comes back as true, then sleep a little and
		 * try again. */
		USD_NL_SEND(unlsk->nlh, msg, ret, retry);
		if (retry) {
			usleep(5);
			continue;
		}
		break;
	}

	return ret;
}
Beispiel #24
0
int pool6_display(void)
{
	struct request_hdr request = {
			.length = sizeof(request),
			.mode = MODE_POOL6,
			.operation = OP_DISPLAY,
	};
	int row_count = 0;
	int error;

	error = netlink_request(&request, request.length, pool6_display_response, &row_count);
	if (!error) {
		if (row_count > 0)
			log_info("  (Fetched %u prefixes.)", row_count);
		else
			log_info("  (empty)");
	}

	return error;
}

static int pool6_count_response(struct nl_msg *msg, void *arg)
{
	__u64 *conf = nlmsg_data(nlmsg_hdr(msg));
	printf("%llu\n", *conf);
	return 0;
}
int connection_process(struct connection *conn, struct sk_buff *skb)
{
	int ret = 0;
	do {
		if (mutex_lock_interruptible(&(conn->data_lock))) {
			MCDRV_DBG_ERROR("Interrupted getting data semaphore!");
			ret = -1;
			break;
		}

		kfree_skb(conn->skb);

		/* Get a reference to the incomming skb */
		conn->skb = skb_get(skb);
		if (conn->skb) {
			conn->data_msg = nlmsg_hdr(conn->skb);
			conn->data_len = NLMSG_PAYLOAD(conn->data_msg, 0);
			conn->data_start = NLMSG_DATA(conn->data_msg);
			up(&(conn->data_available_sem));
		}
		mutex_unlock(&(conn->data_lock));
		ret = 0;
	} while (0);
	return ret;
}
Beispiel #26
0
static int sample_nl_cb(struct nl_msg *msg, void *arg)
{
	struct nlmsghdr *nlh = nlmsg_hdr(msg);
	struct nlattr *attrs_echo[SAMPLE_ECHO_ATTR_MAX + 1];
	struct nlattr *attrs_info[SAMPLE_INFO_ATTR_MAX + 1];
	struct sample_nla sn;


	if (genlmsg_parse(nlh, 0, attrs_echo, SAMPLE_ECHO_ATTR_MAX,
				sample_echo_policy) != 0){
		return -1;
	}

	if (!attrs_echo[SAMPLE_ECHO_ATTR_INFO] || !attrs_echo[SAMPLE_ECHO_ATTR_DATA]){
		elog("attrs null\n");
		return -1;
	}

	strncpy(sn.data, nla_get_string(attrs_echo[SAMPLE_ECHO_ATTR_DATA]), sizeof(sn.data));

	if(nla_parse_nested(attrs_info, SAMPLE_INFO_ATTR_MAX, 
				attrs_echo[SAMPLE_ECHO_ATTR_INFO], sample_info_policy))
		return -1;

	sn.info.x = nla_get_u32(attrs_info[SAMPLE_INFO_ATTR_X]);
	sn.info.y = nla_get_u32(attrs_info[SAMPLE_INFO_ATTR_Y]);
	sample_nl_dump(&sn);
	return NL_OK;
}
Beispiel #27
0
static int eam_display_response(struct nl_msg *msg, void *arg)
{
	struct nlmsghdr *hdr;
	struct eamt_entry *entries;
	struct display_params *params = arg;
	__u16 entry_count, i;

	hdr = nlmsg_hdr(msg);
	entries = nlmsg_data(hdr);
	entry_count = nlmsg_datalen(hdr) / sizeof(*entries);

	if (params->csv_format) {
		for (i = 0; i < entry_count; i++) {
			print_eamt_entry(&entries[i], ",");
		}
	} else {
		for (i = 0; i < entry_count; i++) {
			print_eamt_entry(&entries[i], " - ");
		}
	}

	params->row_count += entry_count;
	params->req_payload->display.prefix4_set = hdr->nlmsg_flags & NLM_F_MULTI;
	if (entry_count > 0)
		params->req_payload->display.prefix4 = entries[entry_count - 1].prefix4;
	return 0;
}
static void
netlink_notification (NMNetlinkMonitor *monitor, struct nl_msg *msg, gpointer user_data)
{
	NMIP6Manager *manager = (NMIP6Manager *) user_data;
	NMIP6Device *device;
	struct nlmsghdr *hdr;

	hdr = nlmsg_hdr (msg);
	nm_log_dbg (LOGD_HW, "netlink event type %d", hdr->nlmsg_type);
	switch (hdr->nlmsg_type) {
	case RTM_NEWADDR:
	case RTM_DELADDR:
		device = process_address_change (manager, msg);
		break;
	case RTM_NEWROUTE:
	case RTM_DELROUTE:
		device = process_route_change (manager, msg);
		break;
	case RTM_NEWNDUSEROPT:
		device = process_nduseropt (manager, msg);
		break;
	case RTM_NEWLINK:
		device = process_newlink (manager, msg);
		break;
	default:
		return;
	}

	if (device) {
		nm_ip6_device_sync_from_netlink (device);
	}
}
Beispiel #29
0
/* Callback for sequence number check */
static int iz_cb_seq_check(struct nl_msg *msg, void *arg)
{
	uint32_t seq;

	if(nlmsg_get_src(msg)->nl_groups)
		return NL_OK;

	seq = nlmsg_hdr(msg)->nlmsg_seq;
	if (seq == iz_seq) {
		if (!(nlmsg_hdr(msg)->nlmsg_flags & NLM_F_MULTI))
			iz_seq ++;
		return NL_OK;
	}
	printf("Sequence number mismatch (%i, %i)!", seq, iz_seq);
	return NL_SKIP;
}
static NMIP6Device *
process_address_change (NMIP6Manager *manager, struct nl_msg *msg)
{
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	NMIP6Device *device;
	struct nlmsghdr *hdr;
	struct rtnl_addr *rtnladdr;
	int old_size;

	hdr = nlmsg_hdr (msg);
	rtnladdr = NULL;
	nl_msg_parse (msg, ref_object, &rtnladdr);
	if (!rtnladdr) {
		nm_log_dbg (LOGD_IP6, "error processing netlink new/del address message");
		return NULL;
	}

	device = nm_ip6_manager_get_device (manager, rtnl_addr_get_ifindex (rtnladdr));

	old_size = nl_cache_nitems (priv->addr_cache);
	nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL, NULL);

	/* The kernel will re-notify us of automatically-added addresses
	 * every time it gets another router advertisement. We only want
	 * to notify higher levels if we actually changed something.
	 */
	nm_log_dbg (LOGD_IP6, "(%s): address cache size: %d -> %d:",
		    device_get_iface (device), old_size, nl_cache_nitems (priv->addr_cache));
	dump_address_change (device, hdr, rtnladdr);
	rtnl_addr_put (rtnladdr);
	if (nl_cache_nitems (priv->addr_cache) == old_size)
		return NULL;

	return device;
}