示例#1
0
int ac_kmod_init(void) {
	int result;

	/* */
	capwap_lock_init(&g_ac.kmodhandle.msglock);

	/* Configure netlink callback */
	g_ac.kmodhandle.nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!g_ac.kmodhandle.nl_cb) {
		ac_kmod_free();
		return -1;
	}

	/* Create netlink socket */
	g_ac.kmodhandle.nl = nl_create_handle(g_ac.kmodhandle.nl_cb);
	if (!g_ac.kmodhandle.nl) {
		ac_kmod_free();
		return -1;
	}

	g_ac.kmodhandle.nl_fd = nl_socket_get_fd(g_ac.kmodhandle.nl);

	/* Get nlsmartcapwap netlink family */
	g_ac.kmodhandle.nlsmartcapwap_id = genl_ctrl_resolve(g_ac.kmodhandle.nl, NLSMARTCAPWAP_GENL_NAME);
	if (g_ac.kmodhandle.nlsmartcapwap_id < 0) {
		log_printf(LOG_WARNING, "Unable to found kernel module");
		ac_kmod_free();
		return -1;
	}

	/* Configure callback function */
	nl_cb_set(g_ac.kmodhandle.nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, ac_kmod_no_seq_check, NULL);
	nl_cb_set(g_ac.kmodhandle.nl_cb, NL_CB_VALID, NL_CB_CUSTOM, ac_kmod_valid_handler, NULL);

	/* Link to kernel module */
	result = ac_kmod_link();
	if (result) {
		ac_kmod_free();
		return result;
	}

	/* Configure netlink message socket */
	g_ac.kmodhandle.nlmsg_cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!g_ac.kmodhandle.nlmsg_cb) {
		ac_kmod_free();
		return -1;
	}

	/* */
	g_ac.kmodhandle.nlmsg = nl_create_handle(g_ac.kmodhandle.nlmsg_cb);
	if (!g_ac.kmodhandle.nlmsg) {
		ac_kmod_free();
		return -1;
	}

	return 0;
}
示例#2
0
static int go_offchan_freq(struct nl80211_state *state, int devidx, int freq)
{
	struct nl_cb *cb;
	struct nl_cb *s_cb;
	struct nl_msg *msg;
	int err;

	msg = nlmsg_alloc();
	if (!msg) {
		fprintf(stderr, "failed to allocate netlink message\n");
		return 2;
	}

	cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	s_cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!cb || !s_cb) {
		fprintf(stderr, "failed to allocate netlink callbacks\n");
		err = 2;
		goto out_free_msg;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    0,
		    NL80211_CMD_REMAIN_ON_CHANNEL, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
	/* 5 seconds is the max allowed, values passed are in ms */
	NLA_PUT_U32(msg, NL80211_ATTR_DURATION, 60);

	nl_socket_set_cb(state->nl_sock, s_cb);

	err = nl_send_auto_complete(state->nl_sock, msg);
	if (err < 0)
		goto out;

	err = 1;

	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

	while (err > 0)
		nl_recvmsgs(state->nl_sock, cb);
 out:
	nl_cb_put(cb);
 out_free_msg:
	nlmsg_free(msg);
	return err;
 nla_put_failure:
	fprintf(stderr, "building message failed\n");
	return 2;
}
// Retrieve monitor interface for a given physical interface
int ret_mon_IF(struct nl80211_state *state)
{
	struct nl_msg *msg;
	struct nl_cb *cb, *s_cb;
	int err = 1;

	msg = nlmsg_alloc();
	if (!msg)
	{
		fprintf(stderr, "failed to allocate netlink message\n");
		return 2;
	}

	// Allocate a new callback handle.
	cb = nl_cb_alloc(NL_CB_DEFAULT);
	s_cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb || !s_cb)
	{
		fprintf(stderr, "failed to allocate netlink callbacks\n");
		err = 2;
		goto out_free_msg;
	}

	// Add Generic Netlink header (i.e. NL80211_CMD_GET_INTERFACE) to Netlink message
	genlmsg_put(msg, 0, 0, state->nl80211_id, 0, 768, NL80211_CMD_GET_INTERFACE, 0);

	// Set up a valid callback function
	if (nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, iface_handler, NULL))
		goto out;

	// Attach the callback function to a netlink socket
	nl_socket_set_cb(state->nl_sock, s_cb);

	// Finalize and transmit Netlink message
	if(nl_send_auto_complete(state->nl_sock, msg) < 0)
		goto out;

	// Set up error, finish and acknowledgment callback function
	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

	while (err > 0)
		nl_recvmsgs(state->nl_sock, cb);

out:
	nl_cb_put(cb);
out_free_msg:
	nlmsg_free(msg);
	return err;
}
示例#4
0
static int call_survey_freq(struct nl80211_state *state, int devidx, int freq)
{
	struct nl_cb *cb;
	struct nl_cb *s_cb;
	struct nl_msg *msg;
	int err;

	msg = nlmsg_alloc();
	if (!msg) {
		fprintf(stderr, "failed to allocate netlink message\n");
		return 2;
	}

	cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	s_cb = nl_cb_alloc(nl_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!cb || !s_cb) {
		fprintf(stderr, "failed to allocate netlink callbacks\n");
		err = 2;
		goto out_free_msg;
	}

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    NLM_F_DUMP,
		    NL80211_CMD_GET_SURVEY, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handle_survey_dump, (void *) &freq);
	nl_socket_set_cb(state->nl_sock, s_cb);

	err = nl_send_auto_complete(state->nl_sock, msg);
	if (err < 0)
		goto out;

	err = 1;

	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

	while (err > 0)
		nl_recvmsgs(state->nl_sock, cb);
 out:
	nl_cb_put(cb);
 out_free_msg:
	nlmsg_free(msg);
	return err;
 nla_put_failure:
	fprintf(stderr, "building message failed\n");
	return 2;
}
示例#5
0
int unl_genl_request(struct unl *unl, struct nl_msg *msg, unl_cb handler, void *arg)
{
	struct nlmsghdr *nlh;
	struct nl_cb *cb;
	int err;

	cb = nl_cb_alloc(NL_CB_CUSTOM);
	nlh = nlmsg_hdr(msg);

	err = nl_send_auto_complete(unl->sock, msg);
	if (err < 0)
		goto out;

	err = 1;
	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
	if (handler)
		nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handler, arg);

	while (err > 0)
		nl_recvmsgs(unl->sock, cb);

out:
	nlmsg_free(msg);
	nl_cb_put(cb);
	return err;
}
int dhd_nl_sock_connect(struct dhd_netlink_info *dhd_nli)
{
	dhd_nli->nl = nl_socket_alloc();
	if (dhd_nli->nl == NULL)
		return -1;

	if (genl_connect(dhd_nli->nl) < 0) {
		fprintf(stderr, "netlink connection failed\n");
		goto err;
	}

	dhd_nli->nl_id = genl_ctrl_resolve(dhd_nli->nl, "nl80211");
	if (dhd_nli->nl_id < 0) {
		fprintf(stderr, "'nl80211' netlink not found\n");
		goto err;
	}

	dhd_nli->cb = nl_cb_alloc(NL_CB_DEBUG);
	if (dhd_nli->cb == NULL)
		goto err;

	nl_socket_set_cb(dhd_nli->nl, dhd_nli->cb);
	return 0;

err:
	nl_cb_put(dhd_nli->cb);
	nl_socket_free(dhd_nli->nl);
	fprintf(stderr, "nl80211 connection failed\n");
	return -1;
}
示例#7
0
static struct nl80211_msg_conveyor * nl80211_new(struct genl_family *family,
                                                 int cmd, int flags)
{
	static struct nl80211_msg_conveyor cv;

	struct nl_msg *req = NULL;
	struct nl_cb *cb = NULL;

	req = nlmsg_alloc();
	if (!req)
		goto err;

	cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb)
		goto err;

	genlmsg_put(req, 0, 0, genl_family_get_id(family), 0, flags, cmd, 0);

	cv.msg = req;
	cv.cb  = cb;

	return &cv;

err:
nla_put_failure:
	if (cb)
		nl_cb_put(cb);

	if (req)
		nlmsg_free(req);

	return NULL;
}
示例#8
0
文件: vport.c 项目: Sovietaced/ivs
void
ind_ovs_port_init(void)
{
    int nlerr;

    route_cache_sock = nl_socket_alloc();
    if (route_cache_sock == NULL) {
        LOG_ERROR("nl_socket_alloc failed");
        abort();
    }

    if ((nlerr = nl_cache_mngr_alloc(route_cache_sock, NETLINK_ROUTE,
                                     0, &route_cache_mngr)) < 0) {
        LOG_ERROR("nl_cache_mngr_alloc failed: %s", nl_geterror(nlerr));
        abort();
    }

    if ((nlerr = nl_cache_mngr_add(route_cache_mngr, "route/link", link_change_cb, NULL, &link_cache)) < 0) {
        LOG_ERROR("nl_cache_mngr_add failed: %s", nl_geterror(nlerr));
        abort();
    }

    if (ind_soc_socket_register(nl_cache_mngr_get_fd(route_cache_mngr),
                                (ind_soc_socket_ready_callback_f)route_cache_mngr_socket_cb,
                                NULL) < 0) {
        LOG_ERROR("failed to register socket");
        abort();
    }

    netlink_callbacks = nl_cb_alloc(NL_CB_DEFAULT);
    if (netlink_callbacks == NULL) {
        LOG_ERROR("failed to allocate netlink callbacks");
        abort();
    }
}
示例#9
0
static int
wprobe_send_msg(struct nl_msg *msg, void *callback, void *arg)
{
    struct nl_cb *cb;
    int err = 0;

    cb = nl_cb_alloc(NL_CB_DEFAULT);
    if (!cb)
        goto out_no_cb;

    if (callback)
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, arg);

    err = nl_send_auto_complete(handle, msg);
    if (err < 0)
        goto out;

    err = 1;

    nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

    while (err > 0)
        nl_recvmsgs(handle, cb);

out:
    nl_cb_put(cb);
out_no_cb:
    nlmsg_free(msg);
    return err;
}
示例#10
0
static int nl80211_add_mon_if(struct nl80211_state *state, const char *device,
			      const char *mondevice)
{
	int ifindex, ret;
	struct nl_msg *msg;
	struct nl_cb *cb = NULL;
	int finished = 0;

	ifindex = device_ifindex(device);

	msg = nl80211_nlmsg_xalloc();

	genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
		    0, NL80211_CMD_NEW_INTERFACE, 0);

	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice);
	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);

	ret = nl_send_auto_complete(state->nl_sock, msg);
	if (ret < 0) {
		if (ret == -ENFILE) {
			nlmsg_free(msg);
			return -EBUSY;
		}

		panic("Cannot send_auto_complete!\n");
	}

	cb = nl_cb_alloc(NL_CB_CUSTOM);
	if (!cb)
		panic("Cannot alloc nl_cb!\n");

	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl80211_wait_handler, &finished);
	nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_handler, NULL);

	nl_recvmsgs(state->nl_sock, cb);

	if (!finished) {
		ret = nl_wait_for_ack(state->nl_sock);
		if (ret < 0) {
			if (ret == -ENFILE) {
				nlmsg_free(msg);
				return -EBUSY;
			}

			panic("Waiting for netlink ack failed!\n");
		}
	}

	nl_cb_put(cb);
	nlmsg_free(msg);
	return 0;

nla_put_failure:
	panic("nla put failure!\n");
	return -EIO; /* dummy */
}
示例#11
0
int SoftapController::executeScanLinkCmd(const char *iface, int *iface_freq)
{
    struct nl_cb *cb;
    struct nl_msg *msg;
    int devidx = 0;
    int err;

    // initialize to non-valid freq
    *iface_freq = 0;

    devidx = if_nametoindex(iface);
    if (devidx == 0) {
        LOGE("failed to translate ifname to idx");
        return -errno;
    }

    msg = nlmsg_alloc();
    if (!msg) {
        LOGE("failed to allocate netlink message");
        return 2;
    }

    cb = nl_cb_alloc(NL_CB_DEFAULT);
    if (!cb) {
        LOGE("failed to allocate netlink callbacks");
        err = 2;
        goto out_free_msg;
    }

    genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0,
                NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0);

    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);

    // iface_freq will be filled out by the callback
    nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, linkDumpCbHandler, iface_freq);

    err = nl_send_auto_complete(nl_soc, msg);
    if (err < 0)
        goto out;

    err = 1;
    nl_cb_err(cb, NL_CB_CUSTOM, NlErrorHandler, &err);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, NlFinishHandler, &err);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, NlAckHandler, &err);

    while (err > 0)
        nl_recvmsgs(nl_soc, cb);

out:
    nl_cb_put(cb);
out_free_msg:
    nlmsg_free(msg);
    return err;
nla_put_failure:
    LOGW("building message failed");
    return 2;
}
示例#12
0
文件: mgmt.c 项目: greearb/iw-ct
static int handle_mgmt_dump(struct nl80211_state *state,
			       struct nl_msg *msg, int argc,
			       char **argv, enum id_input id)
{
	struct nl_cb *mgmt_cb;
	char *ndev = argv[0];
	int mgmt_argc = 5;
	char **mgmt_argv;
	unsigned int count = 0;
	int err = 0;
	int i;

	mgmt_argv = calloc(mgmt_argc, sizeof(char*));
	if (!mgmt_argv)
		return -ENOMEM;

	mgmt_argv[0] = ndev;
	mgmt_argv[1] = "mgmt";
	mgmt_argv[2] = "reg";

	for (i = 3; i < argc; i += 3) {
		if (strcmp(argv[i], "count") == 0) {
			count = 1 + atoi(argv[i + 1]);
			break;
		}

		if (strcmp(argv[i], "frame") != 0) {
			err = 1;
			goto out;
		}

		mgmt_argv[3] = argv[i + 1];
		mgmt_argv[4] = argv[i + 2];

		err = handle_cmd(state, II_NETDEV, mgmt_argc, mgmt_argv);
		if (err)
			goto out;
	}

	mgmt_cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!mgmt_cb) {
		err = 1;
		goto out;
	}

	/* need to turn off sequence number checking */
	nl_cb_set(mgmt_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, seq_handler, NULL);
	nl_cb_set(mgmt_cb, NL_CB_VALID, NL_CB_CUSTOM, dump_mgmt_frame, NULL);

	while (--count)
		nl_recvmsgs(state->nl_sock, mgmt_cb);

	nl_cb_put(mgmt_cb);
out:
	free(mgmt_argv);
	return err;
}
示例#13
0
static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, int flags)
{
	static struct nl80211_msg_conveyor cv;

	int ifidx = -1, phyidx = -1;
	struct nl_msg *req = NULL;
	struct nl_cb *cb = NULL;

	if (nl80211_init() < 0)
		goto err;

	if (!strncmp(ifname, "phy", 3))
		phyidx = atoi(&ifname[3]);
	else if (!strncmp(ifname, "radio", 5))
		phyidx = atoi(&ifname[5]);
	else if (!strncmp(ifname, "mon.", 4))
		ifidx = if_nametoindex(&ifname[4]);
	else
		ifidx = if_nametoindex(ifname);

	if ((ifidx < 0) && (phyidx < 0))
		return NULL;

	req = nlmsg_alloc();
	if (!req)
		goto err;

	cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb)
		goto err;

	genlmsg_put(req, 0, 0, genl_family_get_id(nls->nl80211), 0,
		flags, cmd, 0);

	if (ifidx > -1)
		NLA_PUT_U32(req, NL80211_ATTR_IFINDEX, ifidx);

	if (phyidx > -1)
		NLA_PUT_U32(req, NL80211_ATTR_WIPHY, phyidx);

	cv.msg = req;
	cv.cb  = cb;

	return &cv;

err:
nla_put_failure:
	if (cb)
		nl_cb_put(cb);

	if (req)
		nlmsg_free(req);

	return NULL;
}
/* function: alloc_ack_callbacks
 * allocates a set of netlink callbacks.  returns NULL on failure.  callbacks will modify retval with <0 meaning failure
 * retval - shared state between caller and callback functions
 */
struct nl_cb *alloc_ack_callbacks(int *retval) {
  struct nl_cb *callbacks;

  callbacks = nl_cb_alloc(NL_CB_DEFAULT);
  if(!callbacks) {
    return NULL;
  }
  nl_cb_set(callbacks, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, retval);
  nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, retval);
  return callbacks;
}
示例#15
0
/**
 * Clone an existing callback handle
 * @arg orig		original callback handle
 * @return Newly allocated callback handle being a duplicate of
 *         orig or NULL
 */
struct nl_cb *nl_cb_clone(struct nl_cb *orig)
{
	struct nl_cb *cb;
	
	cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb)
		return NULL;

	memcpy(cb, orig, sizeof(*orig));
	cb->cb_refcnt = 1;

	return cb;
}
示例#16
0
int main()
{
  struct nl_sock * sk;
  int cbarg;

  // nl_debug = 4;

  // setup netlink socket
  sk = nl_socket_alloc();
  nl_socket_disable_seq_check(sk);	// disable sequence number check
  genl_connect(sk);

  int id = genl_ctrl_resolve(sk, DEMO_FAMILY_NAME);

  struct nl_msg * msg;


  // create a messgae
  msg = nlmsg_alloc();
  genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, id, 0,	// hdrlen
                        0,	// flags
                        DEMO_CMD,	// numeric command identifier
                        DEMO_VERSION	// interface version
                       );

  nla_put_string(msg, DEMO_ATTR1_STRING, "hola");
  nla_put_u16(msg, DEMO_ATTR2_UINT16, 0xf1);

  // send it
  nl_send_auto(sk, msg);

  // handle reply
  struct nl_cb * cb = NULL;
  cb = nl_cb_alloc(NL_CB_CUSTOM);

  //nl_cb_set_all(cb, NL_CB_DEBUG, NULL, NULL);
  nl_cb_set_all(cb, NL_CB_CUSTOM, cb_handler, &cbarg);
  nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL);

  int nrecv = nl_recvmsgs_report(sk, cb);

  printf("cbarg %d nrecv %d\n", cbarg, nrecv);

  // cleanup
  nlmsg_free(msg);
  nl_close(sk);
  nl_socket_free(sk);

  return 0;
}
示例#17
0
void unl_genl_loop(struct unl *unl, unl_cb handler, void *arg)
{
	struct nl_cb *cb;

	cb = nl_cb_alloc(NL_CB_CUSTOM);
	unl->loop_done = false;
	nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handler, arg);

	while (!unl->loop_done)
		nl_recvmsgs(unl->sock, cb);

	nl_cb_put(cb);
}
示例#18
0
int nlt_get_ifinfo(struct nl_sock *sk, struct nlt_ifinfo *ifinfo)
{

	struct nl_msg *msg = nlmsg_alloc();
	if (!msg)
		return -1;

	int flags = NLM_F_DUMP;

	int family_id = genl_ctrl_resolve(sk, "nl80211");

	genlmsg_put(msg, 0, NL_AUTO_SEQ, family_id, 0, flags, NL80211_CMD_GET_INTERFACE, 0);

//      NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, 0);
	nl_send_auto(sk, msg);




	int err;

	struct nl_cb *nl_cb = nl_cb_alloc(NL_CB_CUSTOM);
	nl_cb_set(nl_cb, NL_CB_VALID, NL_CB_CUSTOM, get_ifinfo_cb, ifinfo);
	nl_cb_err(nl_cb, NL_CB_CUSTOM, error_handler, &err);


	int nlr;
//      do {
	nlr = nl_recvmsgs(sk, nl_cb);
//              printf("round %d\n",nlr);


//      }while(1);;

	//int nlr = nl_recvmsgs_default(sk);
//	cw_log(LOG_ERR, "iGet if index: Make if %d - %s", nlr, nl_geterror(nlr));




//      nla_put_failure:
	nlmsg_free(msg);
	return 0;


}
示例#19
0
文件: netlink.c 项目: aklein53/neard
static int __nl_send_msg(struct nl_sock *sock, struct nl_msg *msg,
			int (*rx_handler)(struct nl_msg *, void *),
			int (*finish_handler)(struct nl_msg *, void *),
			void *data)
{
	struct nl_cb *cb;
	int err, done;
	struct send_msg_data send_data;

	DBG("");

	cb = nl_cb_alloc(NL_CB_DEFAULT);
	if (!cb)
		return -ENOMEM;

	err = nl_send_auto_complete(sock, msg);
	if (err < 0) {
		nl_cb_put(cb);
		near_error("%s", strerror(err));

		return err;
	}

	err = done = 0;
	send_data.done = &done;
	send_data.data = data;
	send_data.finish_handler = finish_handler;

	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, __finish_handler, &send_data);
	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done);

	if (rx_handler)
		nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, rx_handler, data);

	while (err == 0 && done == 0)
		nl_recvmsgs(sock, cb);

	nl_cb_put(cb);

	return err;
}
示例#20
0
/* function: getinterface_ip
 * finds the first global non-privacy IP of the given family for the given interface, or returns NULL.  caller frees pointer
 * interface - interface to look for
 * family    - family
 */
union anyip *getinterface_ip(const char *interface, int family) {
  struct ifaddrmsg ifa;
  struct nl_cb *callbacks = NULL;
  struct target targ;
  union anyip *retval = NULL;

  targ.family = family;
  targ.foundip = 0;
  targ.ifindex = if_nametoindex(interface);
  if(targ.ifindex == 0) {
    return NULL; // interface not found
  }

  memset(&ifa, 0, sizeof(ifa));
  ifa.ifa_family = targ.family;

  callbacks = nl_cb_alloc(NL_CB_DEFAULT);
  if(!callbacks) {
    goto cleanup;
  }
  nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, getaddr_cb, &targ);
  nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, &targ);

  // sends message and waits for a response
  send_ifaddrmsg(RTM_GETADDR, NLM_F_REQUEST | NLM_F_ROOT, &ifa, callbacks);

  if(targ.foundip) {
    retval = malloc(sizeof(union anyip));
    if(!retval) {
      logmsg(ANDROID_LOG_FATAL,"getinterface_ip/out of memory");
      goto cleanup;
    }
    memcpy(retval, &targ.ip, sizeof(union anyip));
  }

cleanup:
  if(callbacks)
    nl_cb_put(callbacks);

  return retval;
}
示例#21
0
文件: iwraw.c 项目: erstrom/iwraw
static int do_listen_events(void)
{
	struct nl_cb *cb = nl_cb_alloc((log_level > LOG_WARNING) ?
				       NL_CB_DEBUG : NL_CB_DEFAULT);

	if (!cb) {
		LOG_ERR_("failed to allocate netlink callbacks\n");
		return -ENOMEM;
	}

	/* no sequence checking for multicast messages */
	nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL);

	for (;;)
		nl_recvmsgs(state.nl_sock, cb);

	nl_cb_put(cb);

	return 0;
}
示例#22
0
文件: netlink.c 项目: aklein53/neard
static gboolean __nfc_netlink_event(GIOChannel *channel,
				GIOCondition cond, gpointer data)
{
	struct nl_cb *cb;
	struct nlnfc_state *state = data;

	if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
		return FALSE;

	cb = nl_cb_alloc(NL_CB_VERBOSE);
	if (!cb)
		return TRUE;

	nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nfc_netlink_event, data);

	nl_recvmsgs(state->event_sock, cb);

	nl_cb_put(cb);

	return TRUE;
}
示例#23
0
/* function: get_default_route
 * finds the first default route with the given family and interface, returns the gateway (if it exists) in the struct
 * default_route - requested family and interface, and response storage
 */
int get_default_route(struct default_route_data *default_route) {
  struct rtmsg msg;
  struct nl_cb *callbacks = NULL;
  struct nl_msg *nlmsg = NULL;
  int retval = 0;

  default_route->reply_has_gateway = 0;
  default_route->reply_found_route = 0;

  memset(&msg,'\0',sizeof(msg));
  msg.rtm_family = default_route->request_family;
  msg.rtm_table = RT_TABLE_MAIN;
  msg.rtm_protocol = RTPROT_KERNEL;
  msg.rtm_scope = RT_SCOPE_UNIVERSE;

  callbacks = nl_cb_alloc(NL_CB_DEFAULT);
  if(!callbacks) {
    retval = -ENOMEM;
    goto cleanup;
  }
  // get_default_route_cb sets the response fields in default_route
  nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, get_default_route_cb, default_route);
  nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, &retval);

  nlmsg = nlmsg_alloc_rtmsg(RTM_GETROUTE, NLM_F_REQUEST | NLM_F_ROOT, &msg);
  if(!nlmsg) {
    retval = -ENOMEM;
    goto cleanup;
  }
  send_netlink_msg(nlmsg, callbacks);

cleanup:
  if(callbacks)
    nl_cb_put(callbacks);
  if(nlmsg)
    nlmsg_free(nlmsg);

  return retval;
}
示例#24
0
bool CNL80211::open() {
	if (m_connected)
		return true;
	m_nlCallback = nl_cb_alloc(NL_CB_DEFAULT);
	m_nlSocket = nl_socket_alloc();
	if(!m_nlSocket) {
		emit message("Could not create netlink socket");
		return false;
	}
	if (!genl_connect(m_nlSocket)) {
		emit message("Could not connect to generic netlink interface");
		close();
		return false;
	}
	if (genl_ctrl_alloc_cache(m_nlSocket, &m_nlCache)) {
		emit message("Could not allocate generic netlink cache.");
		close();
		return false;
	}

	m_nlFamily = genl_ctrl_search_by_name(m_nlCache, "nl80211");
	if (!m_nlFamily) {
		emit message("Could not find nl80211");
		close();
		return false;
	}
	
	m_nlFd = nl_socket_get_fd(m_nlSocket);
	m_nlSn = new QSocketNotifier(m_nlFd,QSocketNotifier::Read,this);
	connect(m_nlSn,SIGNAL(activated(int)), this, SLOT(readNlMessage(void)));
	
	//Start Signal Quality polling
	m_sqTimerId = startTimer(m_sqPollrate);
	
	m_connected = true;
	return true;
}
示例#25
0
static struct nl_cb *gen_cb(){
  struct nl_cb *ret = nl_cb_alloc(NL_CB_DEFAULT);
  if(!ret)
    flooder_log(FLOODER_DEBUG, "Failed to allocate a callback");
  return ret;
}
示例#26
0
文件: iwraw.c 项目: erstrom/iwraw
static int send_recv_nlcmd(void *nla, size_t nla_len)
{
	int err, nla_offset = 0;
	struct nl_cb *cb;
	struct nl_cb *s_cb;
	struct nl_msg *msg;

	if (cur_cmd <= NL80211_CMD_UNSPEC) {
		LOG_ERR_("Unsupported nl command: %d\n", cur_cmd);
		return 1;
	}

	if (devidx_set)
		/* Since devidx is a uint32_t the attribute will consume 8
		 * bytes. The nla input stream must be appended after this
		 * attribute.
		 */
		nla_offset = 8;

	LOG_DBG_("%s: Allocating %d bytes for nlmsg\n", __func__,
		  nla_len + nla_offset + NLMSG_HDRLEN + GENL_HDRLEN);
	msg = nlmsg_alloc_size(nla_len + nla_offset + NLMSG_HDRLEN + GENL_HDRLEN);
	if (!msg) {
		LOG_ERR_("failed to allocate netlink message\n");
		return 2;
	}

	cb = nl_cb_alloc((log_level > LOG_WARNING) ?
			 NL_CB_DEBUG : NL_CB_DEFAULT);
	s_cb = nl_cb_alloc((log_level > LOG_WARNING) ?
			   NL_CB_DEBUG : NL_CB_DEFAULT);
	if (!cb || !s_cb) {
		LOG_ERR_("failed to allocate netlink callbacks\n");
		err = 2;
		goto out;
	}

	genlmsg_put(msg, 0, 0, state.nl80211_id, 0, 0, cur_cmd, 0);

	if (devidx_set) {
		LOG_DBG_("%s: Adding devidx %d attribute\n", __func__, devidx);
		if (dev_by_phy)
			NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx);
		else
			NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
	}

	add_nla_stream_to_msg(msg, nla, nla_len);

	nl_socket_set_cb(state.nl_sock, s_cb);

	err = nl_send_auto_complete(state.nl_sock, msg);
	if (err < 0) {
		LOG_ERR_("nl_send_auto_complete %d\n", err);
		goto out;
	}

	err = 1;

	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL);

	while (err > 0)
		nl_recvmsgs(state.nl_sock, cb);
 out:
	nl_cb_put(cb);
	nl_cb_put(s_cb);
	nlmsg_free(msg);
	return err;
 nla_put_failure:
	LOG_ERR_("building message failed\n");
	return 2;
}
示例#27
0
int main(int argc, char *argv[])
{
	int opt;

	while ((opt = getopt(argc, argv, PARAMS)) != -1) {
		switch (opt) {
			case 'h':
				fprintf(stdout, HELP, argv[0]);
				exit(EXIT_SUCCESS);
			default:
				fprintf(stderr, USAGE, argv[0]);
				exit(EXIT_FAILURE);
		}
	}

	if (optind >= argc - 3) {
		fprintf(stderr, USAGE, argv[0]);
		exit(EXIT_FAILURE);
	}

	pthread_create(&monthread, NULL, mon_run, NULL);

	ifacename = argv[optind];
	monifname = argv[optind+1];
	ssid = argv[optind+2];
	int chan = atoi(argv[optind+3]);

	struct ifreq s;
	int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
	strcpy(s.ifr_name, ifacename);
	if (ioctl(fd, SIOCGIFHWADDR, &s)) {
		die("Unable to retrieve hardware address");
	}
	close(fd);
	memcpy(stamac, s.ifr_addr.sa_data, 6);

	int iface = if_nametoindex(ifacename);

	struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
	if(!cb)
		die("Can't allocate cb");
	struct nl_handle *handle;
	handle = nl_handle_alloc_cb(cb);
	if(!handle)
		die("Can't allocate handle");
	if(genl_connect(handle))
		die("Can't connect to generic netlink");

	if ((handle_id = genl_ctrl_resolve(handle, "nl80211")) < 0)
		die("Can't resolve generic netlink");
	
	usleep(100000);

	int ret;
	struct nl_msg* msg;
	do {
		msg = gen_msg(iface, ssid, chan);
		ret = send_and_recv(handle, msg, cb);
	}while(ret == DEVICE_BUSY);
	
	if (ret)
		printf("Sending failed %s\n", strerror(-ret));
	
	int ctr = 0;
	while(state != 2) {
		usleep(100);
		ctr++;
		if(ctr == 40000) {
			die("No probe response within timeout");
		}
	}

}
示例#28
0
static int execute_nl_interface_cmd(const char *iface,
                                    enum nl80211_iftype type,
                                    uint8_t cmd)
{
    struct nl_cb *cb;
    struct nl_msg *msg;
    int devidx = 0;
    int err;
    int add_interface = (cmd == NL80211_CMD_NEW_INTERFACE);

    if (add_interface) {
        devidx = phy_lookup();
    } else {
        devidx = if_nametoindex(iface);
        if (devidx == 0) {
            ALOGE("failed to translate ifname to idx");
            return -errno;
        }
    }

    msg = nlmsg_alloc();
    if (!msg) {
        ALOGE("failed to allocate netlink message");
        return 2;
    }

    cb = nl_cb_alloc(NL_CB_DEFAULT);
    if (!cb) {
        ALOGE("failed to allocate netlink callbacks");
        err = 2;
        goto out_free_msg;
    }

    genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, cmd, 0);

    if (add_interface) {
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx);
    } else {
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
    }

    if (add_interface) {
        NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, iface);
        NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type);
    }

    err = nl_send_auto_complete(nl_soc, msg);
    if (err < 0)
        goto out;

    err = 1;

    nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &err);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &err);

    while (err > 0)
        nl_recvmsgs(nl_soc, cb);
out:
    nl_cb_put(cb);
out_free_msg:
    nlmsg_free(msg);
    return err;
nla_put_failure:
    ALOGW("building message failed");
    return 2;
}
示例#29
0
int nl80211_get_chanlist(const char *interface, int *ret_num_chans, int **ret_chan_list,
						  char *errstr) {
	nl80211_channel_block_t cblock;

#ifndef HAVE_LINUX_NETLINK
	snprintf(errstr, LORCON_STATUS_MAX, "LORCON was not compiled with netlink/nl80211 "
			 "support, check the output of ./configure for why");
	return NL80211_CHANLIST_NOT_NL80211;
#else
	void *handle, *cache, *family;
	struct nl_cb *cb;
	int err;
	struct nl_msg *msg;

	cblock.phyname = nl80211_find_parent(interface);
	if (strlen(cblock.phyname) == 0) {
		if (if_nametoindex(interface) <= 0) {
			snprintf(errstr, LORCON_STATUS_MAX, "Interface %s doesn't exist", interface);
			return NL80211_CHANLIST_NO_INTERFACE;
		} 

		snprintf(errstr, LORCON_STATUS_MAX, "LORCON could not find a parent phy device "
				 "for interface %s, it isn't nl80211?", interface);
		return NL80211_CHANLIST_NOT_NL80211;
	}

	if (nl80211_connect(interface, &handle, &cache, &family, errstr) < 0) {
		return NL80211_CHANLIST_GENERIC;
	}

	msg = nlmsg_alloc();
	cb = nl_cb_alloc(NL_CB_DEFAULT);

	err = 1;

	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_freqlist_cb, &cblock);
	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_finish_cb, &err);
	nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_cb, &err);

	genlmsg_put(msg, 0, 0, genl_family_get_id((struct genl_family *) family),
			  0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);

	if (nl_send_auto_complete((struct nl_sock *) handle, msg) < 0) {
		snprintf(errstr, LORCON_STATUS_MAX, "%s: Failed to write nl80211 message",
				__FUNCTION__);
		nl80211_disconnect(handle);
		return NL80211_CHANLIST_GENERIC;
	}

	while (err)
		nl_recvmsgs((struct nl_sock *) handle, cb);

	nl80211_disconnect(handle);
	(*ret_num_chans) = cblock.nfreqs;
	(*ret_chan_list) = (int *) malloc(sizeof(int) * cblock.nfreqs);
	memcpy(*ret_chan_list, cblock.channel_list, sizeof(int) * cblock.nfreqs);

	free(cblock.channel_list);
	free(cblock.phyname);

	return (*ret_num_chans);
#endif
}
示例#30
0
文件: iw.c 项目: vcgomes/powertop
static int __handle_cmd(struct nl80211_state *state, const char *iface, int get)
{
    struct nl_cb *cb;
    struct nl_msg *msg;
    int devidx = 0;
    int err;

    devidx = if_nametoindex(iface);
    if (devidx == 0)
        devidx = -1;
    if (devidx < 0)
        return -errno;

    msg = nlmsg_alloc();
    if (!msg) {
        fprintf(stderr, "failed to allocate netlink message\n");
        return 2;
    }

    cb = nl_cb_alloc(NL_CB_DEFAULT);
    if (!cb) {
        fprintf(stderr, "failed to allocate netlink callbacks\n");
        err = 2;
        goto out_free_msg;
    }

    if (get)
        genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
                    0, NL80211_CMD_GET_POWER_SAVE, 0);
    else
        genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
                    0, NL80211_CMD_SET_POWER_SAVE, 0);


    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);

    if (get)
        err = get_power_save(state, cb, msg);
    else
        err = set_power_save(state, cb, msg);

    if (err)
        goto out;

    err = nl_send_auto_complete(state->nl_sock, msg);
    if (err < 0)
        goto out;

    err = 1;

    nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);

    while (err > 0)
        nl_recvmsgs(state->nl_sock, cb);
out:
    nl_cb_put(cb);
out_free_msg:
    nlmsg_free(msg);
    return err;
nla_put_failure:
    fprintf(stderr, "building message failed\n");
    return 2;
}