static gboolean
nlh_setup (struct nl_sock *nlh,
           nl_recvmsg_msg_cb_t valid_func,
           gpointer cb_data,
           GError **error)
{
	int err;

	nl_socket_modify_cb (nlh, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, cb_data);

	if (valid_func)
		nl_socket_modify_cb (nlh, NL_CB_VALID, NL_CB_CUSTOM, valid_func, cb_data);

	err = nl_connect (nlh, NETLINK_ROUTE);
	if (err < 0) {
		g_set_error (error, NM_NETLINK_MONITOR_ERROR,
		             NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT,
		             _("unable to connect to netlink for monitoring link status: %s"),
		             nl_geterror (err));
		return FALSE;
	}

	/* Enable unix socket peer credentials which we use for verifying that the
	 * sender of the message is actually the kernel.
	 */
	if (nl_socket_set_passcred (nlh, 1) < 0) {
		g_set_error (error, NM_NETLINK_MONITOR_ERROR,
		             NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT,
		             _("unable to enable netlink handle credential passing: %s"),
		             nl_geterror (err));
		return FALSE;
	}

	return TRUE;
}
Exemplo n.º 2
0
void CNL80211::scan() {
	//Get interface index for device:
	unsigned int devidx = if_nametoindex(m_ifname.toAscii().constData());
	if (devidx == 0) {
		emit message("Could not get interface index");
		return;
	}
	//Allocate a new netlink message
	nl_msg * msg;
	msg = nlmsg_alloc();
	if (!msg) {
		emit message("Could not allocate netlink message");
		return;
	}
	
	//allocate the callback function with default verbosity
// 	nl_cb * cb = nl_cb_alloc(NL_CB_DEFAULT);
// 	if (!cb) {
// 		emit message("Could not allocate netlink callback");
// 		nlmsg_free(msg);
// 		return;
// 	}

	nl_socket_modify_cb(m_nlSocket, NL_CB_VALID, NL_CB_CUSTOM, &cbForScanResults, this);
	
	genlmsg_put(msg, 0, 0, genl_family_get_id(m_nlFamily), 0, (NLM_F_REQUEST | NLM_F_DUMP), NL80211_CMD_GET_SCAN, 0);
	//Set the interface we want to operate on
	nla_put_u32(msg, NL80211_ATTR_IFNAME,devidx);
	
	//hier kommt noch was rein
	
	//Send the message
	nl_send_auto_complete(m_nlSocket,msg);
	nlmsg_free(msg);
}
Exemplo n.º 3
0
int
iface_mon_start(iface_mon_cb cb)
{
    int err;

    iface_mon_sock = nl_socket_alloc();
    if (!iface_mon_sock) {
        fprintf(stderr, "Failed to allocate netlink socket.\n");
        return -ENOMEM;
    }

    nl_socket_disable_seq_check(iface_mon_sock);

    nl_socket_modify_cb(iface_mon_sock, NL_CB_VALID, NL_CB_CUSTOM, iface_mon_handler, cb);

    if (nl_connect(iface_mon_sock, NETLINK_ROUTE)) {
        fprintf(stderr, "Failed to connect to generic netlink.\n");
        err = -ENOLINK;
        goto out_handle_destroy;
    }

    nl_socket_add_membership(iface_mon_sock, RTNLGRP_LINK);

    return 0;

out_handle_destroy:
    nl_socket_free(iface_mon_sock);
    return err;
}
Exemplo n.º 4
0
int netlink_request(void *request, __u16 request_len, int (*cb)(struct nl_msg *, void *),
		void *cb_arg)
{
	struct nl_sock *sk;
	enum nl_cb_type callbacks[] = { NL_CB_VALID, NL_CB_FINISH, NL_CB_ACK };
	int i;
	int error;

	sk = nl_socket_alloc();
	if (!sk) {
		log_err(ERR_ALLOC_FAILED, "Could not allocate a socket; cannot speak to the NAT64.");
		return -ENOMEM;
	}

	for (i = 0; i < (sizeof(callbacks) / sizeof(callbacks[0])); i++) {
		error = nl_socket_modify_cb(sk, callbacks[i], NL_CB_CUSTOM, cb, cb_arg);
		if (error < 0) {
			log_err(ERR_NETLINK, "Could not register response handler. "
					"I won't be able to parse the NAT64's response, so I won't send the request.\n"
					"Netlink error message: %s (Code %d)", nl_geterror(error), error);
			goto fail_free;
		}
	}

	error = nl_connect(sk, NETLINK_USERSOCK);
	if (error < 0) {
		log_err(ERR_NETLINK, "Could not bind the socket to the NAT64.\n"
				"Netlink error message: %s (Code %d)", nl_geterror(error), error);
		goto fail_free;
	}

	error = nl_send_simple(sk, MSG_TYPE_NAT64, 0, request, request_len);
	if (error < 0) {
		log_err(ERR_NETLINK, "Could not send the request to the NAT64 (is it really up?).\n"
				"Netlink error message: %s (Code %d)", nl_geterror(error), error);
		goto fail_close;
	}

	error = nl_recvmsgs_default(sk);
	if (error < 0) {
		log_err(ERR_NETLINK, "%s (System error %d)", nl_geterror(error), error);
		goto fail_close;
	}

	nl_close(sk);
	nl_socket_free(sk);
	return 0;

fail_close:
	nl_close(sk);
	/* Fall through. */

fail_free:
	nl_socket_free(sk);
	return -EINVAL;
}
Exemplo n.º 5
0
int netlink_request(void *request, __u32 request_len,
		jool_response_cb cb, void *cb_arg)
{
	struct nl_msg *msg;
	struct response_cb callback = { .cb = cb, .arg = cb_arg };
	int error;

	error = nl_socket_modify_cb(sk, NL_CB_MSG_IN, NL_CB_CUSTOM,
			response_handler, &callback);
	if (error < 0) {
		log_err("Could not register response handler.");
		log_err("I will not be able to parse Jool's response, so I won't send the request.");
		return netlink_print_error(error);
	}

	msg = nlmsg_alloc();
	if (!msg) {
		log_err("Could not allocate the message to the kernel; it seems we're out of memory.");
		return -ENOMEM;
	}

	if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, family, 0, 0,
			JOOL_COMMAND, 1)) {
		log_err("Unknown error building the packet to the kernel.");
		nlmsg_free(msg);
		return -EINVAL;
	}

	error = nla_put(msg, ATTR_DATA, request_len, request);
	if (error) {
		log_err("Could not write on the packet to kernelspace.");
		nlmsg_free(msg);
		return netlink_print_error(error);
	}

	error = nl_send_auto(sk, msg);
	nlmsg_free(msg);
	if (error < 0) {
		log_err("Could not dispatch the request to kernelspace.");
		return netlink_print_error(error);
	}

	error = nl_recvmsgs_default(sk);
	if (error < 0) {
		if (error_handler_called) {
			error_handler_called = false;
			return error;
		}
		log_err("Error receiving the kernel module's response.");
		return netlink_print_error(error);
	}

	return 0;
}
Exemplo n.º 6
0
static bool nl_new(struct dionaea *d)
{
	g_debug("%s", __PRETTY_FUNCTION__);
	nl_runtime.sock = nl_socket_alloc();
	struct nl_sock  *sock = nl_runtime.sock;
	nl_socket_disable_seq_check(sock);
	nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, nl_event_input, NULL);
	nl_join_groups(sock, RTMGRP_LINK);
	int err;
	if ( (err = nl_connect(sock, NETLINK_ROUTE)) < 0) 
	{
		g_error("Could not connect netlink (%s)", nl_geterror(err));
	}

	nl_socket_add_membership(sock, RTNLGRP_LINK);
	nl_socket_add_membership(sock, RTNLGRP_NEIGH);
	nl_socket_add_membership(sock, RTNLGRP_IPV4_IFADDR);
	nl_socket_add_membership(sock, RTNLGRP_IPV6_IFADDR);

	if( (err=rtnl_neigh_alloc_cache(sock, &nl_runtime.neigh_cache)) != 0 )
	{
		g_error("Could not allocate neigh cache! (%s)", nl_geterror(err));
	}
#if LIBNL_RTNL_LINK_ALLOC_CACHE_ARGC == 3
	if( (err=rtnl_link_alloc_cache(sock, AF_UNSPEC, &nl_runtime.link_cache)) != 0 )
#elif LIBNL_RTNL_LINK_ALLOC_CACHE_ARGC == 2
	if( (err=rtnl_link_alloc_cache(sock, &nl_runtime.link_cache)) != 0 )
#endif
	{
		g_error("Could not allocate link cache! (%s)", nl_geterror(err));
	}

	if( (err=rtnl_addr_alloc_cache(sock, &nl_runtime.addr_cache)) != 0 )
	{
		g_error("Could not allocate addr cache! (%s)", nl_geterror(err));
	}

	nl_cache_mngt_provide(nl_runtime.neigh_cache);
	nl_cache_mngt_provide(nl_runtime.link_cache);
	nl_cache_mngt_provide(nl_runtime.addr_cache);
	
	nl_runtime.ihandler = ihandler_new("dionaea.connection.*.accept", nl_ihandler_cb, NULL);

	ev_io_init(&nl_runtime.io_in, nl_io_in_cb, nl_socket_get_fd(sock), EV_READ);
	ev_io_start(g_dionaea->loop, &nl_runtime.io_in);
	nl_runtime.link_addr_cache = g_hash_table_new(g_int_hash, g_int_equal);
	nl_cache_foreach(nl_runtime.link_cache, nl_obj_input, NULL);
	nl_cache_foreach(nl_runtime.addr_cache, nl_obj_input, NULL);
    return true;
}
Exemplo n.º 7
0
int ipvs_nl_send_message(struct nl_msg *msg, nl_recvmsg_msg_cb_t func, void *arg)
{
	int err = EINVAL;

	sock = nl_socket_alloc();
	if (!sock) {
		nlmsg_free(msg);
		return -1;
	}

	if (genl_connect(sock) < 0)
		goto fail_genl;

	family = genl_ctrl_resolve(sock, IPVS_GENL_NAME);
	if (family < 0)
		goto fail_genl;

	/* To test connections and set the family */
	if (msg == NULL) {
		nl_socket_free(sock);
		sock = NULL;
		return 0;
	}

	if (nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, func, arg) != 0)
		goto fail_genl;

	if (nl_send_auto_complete(sock, msg) < 0)
		goto fail_genl;

	if ((err = -nl_recvmsgs_default(sock)) > 0)
		goto fail_genl;

	nlmsg_free(msg);

	nl_socket_free(sock);

	return 0;

fail_genl:
	nl_socket_free(sock);
	sock = NULL;
	nlmsg_free(msg);
	errno = err;
#ifndef FALLBACK_LIBNL1
	errno = nlerr2syserr(err);
#endif
	return -1;
}
Exemplo n.º 8
0
static int get_interface_info(struct config *conf) {
	struct nl_msg *msg;

	nl802154_init(conf);

	/* Build and send message */
	nl_socket_modify_cb(conf->nl_sock, NL_CB_VALID, NL_CB_CUSTOM, nl_msg_cb, conf);
	msg = nlmsg_alloc();
	genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, conf->nl802154_id, 0, NLM_F_DUMP, NL802154_CMD_GET_INTERFACE, 0);
	nla_put_string(msg, NL802154_ATTR_IFNAME, "conf->interface");
	nl_send_sync(conf->nl_sock, msg);

	nl802154_cleanup(conf);
	return 0;
}
Exemplo n.º 9
0
Arquivo: main.c Projeto: nbastin/ivs
static void
show(void)
{
    struct nl_msg *msg = nlmsg_alloc();
    struct ovs_header *hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
                                         ovs_datapath_family, sizeof(*hdr),
                                         NLM_F_DUMP, OVS_DP_CMD_GET, OVS_DATAPATH_VERSION);
    hdr->dp_ifindex = 0;
    if (nl_send_auto(sk, msg) < 0) {
        abort();
    }

    nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, show_datapath__, NULL);
    nl_recvmsgs_default(sk);
}
Exemplo n.º 10
0
int setup_socket(struct nl_sock *sk, struct options *opt)
{
	int ret;
	nl_socket_disable_seq_check(sk);

	if((ret = nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, netlink_msg_handler, opt)) < 0)
		return ret;

	if((ret = nl_connect(sk, NETLINK_ROUTE)) < 0)
		return ret;

	if((ret = nl_socket_add_memberships(sk, RTNLGRP_TC_STATS, 0)) < 0)
		return ret;
	return 0;
}
Exemplo n.º 11
0
  /**
   * Query the wireless device for information
   * about the current connection
   */
  bool wireless_network::query(bool accumulate) {
    if (!network::query(accumulate)) {
      return false;
    }

    struct nl_sock* sk = nl_socket_alloc();
    if (sk == nullptr) {
      return false;
    }

    if (genl_connect(sk) < 0) {
      return false;
    }

    int driver_id = genl_ctrl_resolve(sk, "nl80211");
    if (driver_id < 0) {
      nl_socket_free(sk);
      return false;
    }

    if (nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, scan_cb, this) != 0) {
      nl_socket_free(sk);
      return false;
    }

    struct nl_msg* msg = nlmsg_alloc();
    if (msg == nullptr) {
      nl_socket_free(sk);
      return false;
    }

    if ((genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, driver_id, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0) == nullptr) ||
        nla_put_u32(msg, NL80211_ATTR_IFINDEX, m_ifid) < 0) {
      nlmsg_free(msg);
      nl_socket_free(sk);
      return false;
    }

    // nl_send_sync always frees msg
    if (nl_send_sync(sk, msg) < 0) {
      nl_socket_free(sk);
      return false;
    }

    nl_socket_free(sk);

    return true;
  }
Exemplo n.º 12
0
static struct nl_handle *init_netlink(void)
{
	struct nl_handle *handle;
	int ret, multicast_id;

	handle = nl_handle_alloc();
	if (!handle){
		elog("Cannot allocate netlink handle!\n");
		return NULL;
	}
	nl_disable_sequence_check(handle);
	ret = genl_connect(handle);
	if (ret < 0){
		elog("Cannot connect to netlink socket\n");
		return NULL;
	}

	/*
	familyid = genl_ctrl_resolve(handle, SAMPLE_NL_FAMILY_NAME);
	if (!familyid){
		elog("Cannot resolve family name(%s)\n", SAMPLE_NL_FAMILY_NAME);
		return NULL;
	}
	dlog("familyid %d\n", familyid);
	*/

	multicast_id = nl_get_multicast_id(handle, SAMPLE_NL_FAMILY_NAME, SAMPLE_NL_GRP_NAME);
	if (multicast_id < 0){
		elog("Cannot resolve grp name(%d)\n", SAMPLE_NL_GRP_NAME);
		return NULL;
	}

	ret = nl_socket_add_membership(handle, multicast_id);
	if (ret < 0){
		elog("Cannot join fs multicast group\n");
		return NULL;
	}

	ret = nl_socket_modify_cb(handle, NL_CB_VALID, NL_CB_CUSTOM,
			sample_nl_cb, NULL);
	if (ret < 0){
		elog("Cannot register callback for"
			 " netlink messages\n");
		return NULL;
	}

	return handle;
}
Exemplo n.º 13
0
int nf10_reg_wr(uint32_t addr, uint32_t val)
{
    struct nl_msg   *msg;
    int             err;

    err = driver_connect();
    if(err)
        return err;

    msg = nlmsg_alloc();
    if(msg == NULL) {
        driver_disconnect();
        return -NLE_NOMEM;
    }

    /* genlmsg_put will fill in the fields of the nlmsghdr and the genlmsghdr. */
    genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, nf10_genl_family, 0, 0,
            NF10_GENL_C_REG_WR, NF10_GENL_FAMILY_VERSION);

    nla_put_u32(msg, NF10_GENL_A_ADDR32, addr);
    nla_put_u32(msg, NF10_GENL_A_REGVAL32, val);

    /* nl_send_auto will automatically fill in the PID and the sequence number,
     * and also add an NLM_F_REQUEST flag. It will also add an NLM_F_ACK
     * flag unless the netlink socket has the NL_NO_AUTO_ACK flag set. */
    err = nl_send_auto(nf10_genl_sock, msg);
    if(err < 0) {
        nlmsg_free(msg);
        driver_disconnect();
        return err;
    }

    nlmsg_free(msg);

    nl_socket_modify_cb(nf10_genl_sock, NL_CB_ACK, NL_CB_CUSTOM, nf10_reg_wr_recv_ack_cb, NULL);

    /* FIXME: this function will return even if there's no ACK in the buffer. I.E. it doesn't
     * seem to wait for the ACK to be received... Ideally we'd have the behavior that getting an
     * ACK tells us everything is OK, otherwise we time out on waiting for an ACK and tell this
     * to the user. */
    err = nl_recvmsgs_default(nf10_genl_sock);

    driver_disconnect();

    return err;
}
Exemplo n.º 14
0
Arquivo: main.c Projeto: nbastin/ivs
static void
show_vports__(int dp_ifindex)
{
    struct nl_msg *msg = nlmsg_alloc();
    struct ovs_header *hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
                                         ovs_vport_family, sizeof(*hdr),
                                         NLM_F_DUMP, OVS_VPORT_CMD_GET, OVS_VPORT_VERSION);
    hdr->dp_ifindex = dp_ifindex;
    if (nl_send_auto(sk2, msg) < 0) {
        abort();
    }

    nl_socket_modify_cb(sk2, NL_CB_VALID, NL_CB_CUSTOM, show_vport__, NULL);
    nl_recvmsgs_default(sk2);

    nlmsg_free(msg);
}
Exemplo n.º 15
0
/**
 * Allocate new cache manager
 * @arg sk		Netlink socket.
 * @arg protocol	Netlink Protocol this manager is used for
 * @arg flags		Flags
 * @arg result		Result pointer
 *
 * @return 0 on success or a negative error code.
 */
int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags,
			struct nl_cache_mngr **result)
{
	struct nl_cache_mngr *mngr;
	int err = -NLE_NOMEM;

	if (sk == NULL)
		BUG();

	mngr = calloc(1, sizeof(*mngr));
	if (!mngr)
		goto errout;

	mngr->cm_handle = sk;
	mngr->cm_nassocs = 32;
	mngr->cm_protocol = protocol;
	mngr->cm_flags = flags;
	mngr->cm_assocs = calloc(mngr->cm_nassocs,
				 sizeof(struct nl_cache_assoc));
	if (!mngr->cm_assocs)
		goto errout;

	nl_socket_modify_cb(mngr->cm_handle, NL_CB_VALID, NL_CB_CUSTOM,
			    event_input, mngr);

	/* Required to receive async event notifications */
	nl_socket_disable_seq_check(mngr->cm_handle);

	if ((err = nl_connect(mngr->cm_handle, protocol) < 0))
		goto errout;

	if ((err = nl_socket_set_nonblocking(mngr->cm_handle) < 0))
		goto errout;

	NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n",
	       mngr, protocol, mngr->cm_nassocs);

	*result = mngr;
	return 0;

errout:
	nl_cache_mngr_free(mngr);
	return err;
}
Exemplo n.º 16
0
static struct nl_sock *
setup_socket (void)
{
	struct nl_sock *sk;
	int err;

	sk = nl_socket_alloc ();
	g_return_val_if_fail (sk, NULL);

	/* Only ever accept messages from kernel */
	err = nl_socket_modify_cb (sk, NL_CB_MSG_IN, NL_CB_CUSTOM, verify_source, NULL);
	g_assert (!err);

	err = nl_connect (sk, NETLINK_XFRM);
	g_assert (!err);
	err = nl_socket_set_passcred (sk, 1);
	g_assert (!err);

	return sk;
}
Exemplo n.º 17
0
int nf10_reg_rd(uint32_t addr, uint32_t *val_ptr)
{
    struct nl_msg   *msg;
    int             err;

    err = driver_connect();
    if(err)
        return err;

    msg = nlmsg_alloc();
    if(msg == NULL) {
        driver_disconnect();
        return -NLE_NOMEM;
    }

    /* genlmsg_put will fill in the fields of the nlmsghdr and the genlmsghdr. */
    genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, nf10_genl_family, 0, 0,
            NF10_GENL_C_REG_RD, NF10_GENL_FAMILY_VERSION);

    nla_put_u32(msg, NF10_GENL_A_ADDR32, addr);

    /* nl_send_auto will automatically fill in the PID and the sequence number,
     * and also add an NLM_F_REQUEST flag. It will also add an NLM_F_ACK
     * flag unless the netlink socket has the NL_NO_AUTO_ACK flag set. */
    err = nl_send_auto(nf10_genl_sock, msg);
    if(err < 0) {
        nlmsg_free(msg);
        driver_disconnect();
        return err;
    }

    nlmsg_free(msg);

    nl_socket_modify_cb(nf10_genl_sock, NL_CB_VALID, NL_CB_CUSTOM, nf10_reg_rd_recv_msg_cb, (void*)val_ptr);

    err = nl_recvmsgs_default(nf10_genl_sock);

    driver_disconnect();

    return err;
}
Exemplo n.º 18
0
int main()
{
    /* create socket */
    struct nl_sock *sk = NULL;

    sk = nl_socket_alloc();
    genl_connect(sk);
    nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, get_cw, NULL);

    /* setup message */
    int driver_id, if_index;
    struct nl_msg *msg = NULL;

    driver_id = genl_ctrl_resolve(sk, "nl80211");
    if_index = if_nametoindex("wlan0");
    msg = nlmsg_alloc();

    genlmsg_put(msg, 0, 0, driver_id, 0, 0, NL80211_CMD_GET_WIPHY, 0);
    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_index);

    //struct nlattr *nested;
    //nested = nla_nest_start(msg,NL80211_ATTR_WIPHY_TXQ_PARAMS);
    //NLA_PUT_U16(msg,NL80211_TXQ_ATTR_CWMIN,cw_min);
    //NLA_PUT_U16(msg,NL80211_TXQ_ATTR_CWMAX,cw_max);
    //nla_nest_end(msg,nested);

    /* send/recv/ack */
    int r;

    r = nl_send_auto_complete(sk, msg);
    printf("atlasd: nl_send_auto_complete returned %d\n", r);
    nl_recvmsgs_default(sk);
    nl_wait_for_ack(sk);

nla_put_failure: /* from NLA_PUT_* macros */
fail:
    if (sk) nl_socket_free(sk);
    if (msg) nlmsg_free(msg);
}
Exemplo n.º 19
0
Arquivo: main.c Projeto: Juankc125/ivs
static void
dump_flows(const char *datapath)
{
    unsigned int dp_ifindex = if_nametoindex(datapath);
    if (dp_ifindex == 0) {
        fprintf(stderr, "Failed: no such datapath '%s'\n", datapath);
        exit(1);
    }

    struct nl_msg *msg = nlmsg_alloc();
    struct ovs_header *hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
                                         ovs_flow_family, sizeof(*hdr),
                                         NLM_F_DUMP, OVS_FLOW_CMD_GET, OVS_FLOW_VERSION);
    hdr->dp_ifindex = dp_ifindex;
    if (nl_send_auto(sk2, msg) < 0) {
        abort();
    }

    nl_socket_modify_cb(sk2, NL_CB_VALID, NL_CB_CUSTOM, show_kflow__, NULL);
    nl_recvmsgs_default(sk2);

    nlmsg_free(msg);
}
Exemplo n.º 20
0
int main (int argc, char **argv)
{
	struct nl_sock *sk;
	int err;

	sk = setup_socket ();
	g_assert (sk);

	err = nl_send_simple (sk, XFRM_MSG_GETPOLICY, NLM_F_DUMP, NULL, 0);
	if (err < 0) {
		g_warning ("Error sending: %d %s", err, nl_geterror (err));
		return 1;
	}

	nl_socket_modify_cb (sk, NL_CB_VALID, NL_CB_CUSTOM, parse_reply, NULL);

	err = nl_recvmsgs_default (sk);
	if (err < 0) {
		g_warning ("Error parsing: %d %s", err, nl_geterror (err));
		return 1;
	}

	return 0;
}
Exemplo n.º 21
0
int main(int argc, char **argv)
{
	int c;
	int i;
	int family;
	int group;
	struct nl_sock *nl;
	struct nl_msg *msg;
	char *dummy = NULL;

	/* Currently processed command info */
	struct iz_cmd cmd;


	/* Parse options */
	while (1) {
#ifdef HAVE_GETOPT_LONG
		int opt_idx = -1;
		c = getopt_long(argc, argv, "d::vh", iz_long_opts, &opt_idx);
#else
		c = getopt(argc, argv, "d::vh");
#endif
		if (c == -1)
			break;

		switch(c) {
		case 'd':
			if (optarg) {
				i = strtol(optarg, &dummy, 10);
				if (*dummy == '\0')
					iz_debug = nl_debug = i;
				else {
					fprintf(stderr, "Error: incorrect debug level: '%s'\n", optarg);
					exit(1);
				}
			} else
				iz_debug = nl_debug = 1;
			break;
		case 'v':
			printf(	"iz " VERSION "\n"
				"Copyright (C) 2008, 2009 by Siemens AG\n"
				"License GPLv2 GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.\n"
				"This is free software: you are free to change and redistribute it.\n"
				"There is NO WARRANTY, to the extent permitted by law.\n"
				"\n"
				"Written by Dmitry Eremin-Solenikov, Sergey Lapin and Maxim Osipov\n");
			return 0;
		case 'h':
			iz_help(argv[0]);
			return 0;
		default:
			iz_help(argv[0]);
			return 1;
		}
	}
	if (optind >= argc) {
		iz_help(argv[0]);
		return 1;
	}

	memset(&cmd, 0, sizeof(cmd));

	cmd.argc = argc - optind;
	cmd.argv = argv + optind;

	/* Parse command */
	cmd.desc = get_cmd(argv[optind]);
	if (!cmd.desc) {
		printf("Unknown command %s!\n", argv[optind]);
		return 1;
	}
	if (cmd.desc->parse) {
		i = cmd.desc->parse(&cmd);
		if (i == IZ_STOP_OK) {
			return 0;
		} else if (i == IZ_STOP_ERR) {
			printf("Command line parsing error!\n");
			return 1;
		}
	}

	/* Prepare NL command */
	nl = nl_socket_alloc();
	if (!nl) {
		nl_perror(NLE_NOMEM, "Could not allocate NL handle");
		return 1;
	}
	genl_connect(nl);
	family = genl_ctrl_resolve(nl, IEEE802154_NL_NAME);
	group = nl_get_multicast_id(nl,
			IEEE802154_NL_NAME, IEEE802154_MCAST_COORD_NAME);
	if (group < 0) {
		fprintf(stderr, "Could not get multicast group ID: %s\n", strerror(-group));
		return 1;
	}
	nl_socket_add_membership(nl, group);
	iz_seq = nl_socket_use_seq(nl) + 1;
	nl_socket_modify_cb(nl, NL_CB_VALID, NL_CB_CUSTOM,
		iz_cb_valid, (void*)&cmd);
	nl_socket_modify_cb(nl, NL_CB_FINISH, NL_CB_CUSTOM,
		iz_cb_finish, (void*)&cmd);
	nl_socket_modify_cb(nl, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
		iz_cb_seq_check, (void*)&cmd);

	/* Send request, if necessary */
	if (cmd.desc->request) {
		msg = nlmsg_alloc();
		if (!msg) {
			nl_perror(NLE_NOMEM, "Could not allocate NL message!\n"); /* FIXME: err */
			return 1;
		}
		genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0,
			cmd.flags, cmd.desc->nl_cmd, 1);

		if (cmd.desc->request(&cmd, msg) != IZ_CONT_OK) {
			printf("Request processing error!\n");
			return 1;
		}

		dprintf(1, "nl_send_auto_complete\n");
		nl_send_auto_complete(nl, msg);
		cmd.seq = nlmsg_hdr(msg)->nlmsg_seq;

		dprintf(1, "nlmsg_free\n");
		nlmsg_free(msg);
	}

	/* Received message handling loop */
	while (iz_exit == IZ_CONT_OK) {
		int err = nl_recvmsgs_default(nl);
		if (err != NLE_SUCCESS) {
			nl_perror(err, "Receive failed");
			return 1;
		}
	}
	nl_close(nl);

	if (iz_exit == IZ_STOP_ERR)
		return 1;

	return 0;
}
Exemplo n.º 22
0
static void obj_input(struct nl_object *obj, void *arg)
{
	struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) obj;
	struct nl_dump_params dp = {
		.dp_type = NL_DUMP_STATS,
		.dp_fd = stdout,
		.dp_dump_msgtype = 1,
	};

	nfnl_queue_msg_set_verdict(msg, NF_ACCEPT);
	nl_object_dump(obj, &dp);
	nfnl_queue_msg_send_verdict(nfnlh, msg);
}

static int event_input(struct nl_msg *msg, void *arg)
{
	if (nl_msg_parse(msg, &obj_input, NULL) < 0)
		fprintf(stderr, "<<EVENT>> Unknown message type\n");

	/* Exit nl_recvmsgs_def() and return to the main select() */
	return NL_STOP;
}

int main(int argc, char *argv[])
{
	struct nl_handle *rtnlh;
	struct nl_cache *link_cache;
	struct nfnl_queue *queue;
	enum nfnl_queue_copy_mode copy_mode;
	uint32_t copy_range;
	int err = 1;
	int family;

	if (nltool_init(argc, argv) < 0)
		return -1;

	nfnlh = nltool_alloc_handle();
	if (nfnlh == NULL)
		return -1;

	nl_disable_sequence_check(nfnlh);

	nl_socket_modify_cb(nfnlh, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);

	if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) {
		printf("Usage: nf-queue family group [ copy_mode ] "
		       "[ copy_range ]\n");
		return 2;
	}

	if (nfnl_connect(nfnlh) < 0) {
		fprintf(stderr, "%s\n", nl_geterror());
		goto errout;
	}

	family = nl_str2af(argv[1]);
	if (family == AF_UNSPEC) {
		fprintf(stderr, "Unknown family: %s\n", argv[1]);
		goto errout;
	}

	nfnl_queue_pf_unbind(nfnlh, family);
	if (nfnl_queue_pf_bind(nfnlh, family) < 0) {
		fprintf(stderr, "%s\n", nl_geterror());
		goto errout;
	}

	queue = nfnl_queue_alloc();
	if (queue == NULL) {
		fprintf(stderr, "%s\n", nl_geterror());
		goto errout;
	}

	nfnl_queue_set_group(queue, atoi(argv[2]));

	copy_mode = NFNL_QUEUE_COPY_PACKET;
	if (argc > 3) {
		copy_mode = nfnl_queue_str2copy_mode(argv[3]);
		if (copy_mode < 0) {
			fprintf(stderr, "%s\n", nl_geterror());
			goto errout;
		}
	}
	nfnl_queue_set_copy_mode(queue, copy_mode);

	copy_range = 0xFFFF;
	if (argc > 4)
		copy_range = atoi(argv[4]);
	nfnl_queue_set_copy_range(queue, copy_range);

	if (nfnl_queue_create(nfnlh, queue) < 0) {
		fprintf(stderr, "%s\n", nl_geterror());
		goto errout;
	}

	rtnlh = nltool_alloc_handle();
	if (rtnlh == NULL) {
		goto errout_close;
	}

	if (nl_connect(rtnlh, NETLINK_ROUTE) < 0) {
		fprintf(stderr, "%s\n", nl_geterror());
		goto errout;
	}

	if ((link_cache = rtnl_link_alloc_cache(rtnlh)) == NULL) {
		fprintf(stderr, "%s\n", nl_geterror());
		goto errout_close;
	}

	nl_cache_mngt_provide(link_cache);

	while (1) {
		fd_set rfds;
		int nffd, rtfd, maxfd, retval;

		FD_ZERO(&rfds);

		maxfd = nffd = nl_socket_get_fd(nfnlh);
		FD_SET(nffd, &rfds);

		rtfd = nl_socket_get_fd(rtnlh);
		FD_SET(rtfd, &rfds);
		if (maxfd < rtfd)
			maxfd = rtfd;

		/* wait for an incoming message on the netlink socket */
		retval = select(maxfd+1, &rfds, NULL, NULL, NULL);

		if (retval) {
			if (FD_ISSET(nffd, &rfds))
				nl_recvmsgs_default(nfnlh);
			if (FD_ISSET(rtfd, &rfds))
				nl_recvmsgs_default(rtnlh);
		}
	}

	nl_cache_mngt_unprovide(link_cache);
	nl_cache_free(link_cache);

	nfnl_queue_put(queue);

	nl_close(rtnlh);
	nl_handle_destroy(rtnlh);
errout_close:
	nl_close(nfnlh);
	nl_handle_destroy(nfnlh);
errout:
	return err;
}
Exemplo n.º 23
0
int opal_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk,
                                   const char *src_ifname,
                                   uint32_t src_addr,
                                   uint32_t dst_addr, int *metric)
{
	struct nl_msg *nlm;
	struct rtmsg rmsg;
	struct nl_lookup_arg arg;
	int	msg_cnt;
	int err;
	int oif;

	oif = if_nametoindex(src_ifname);
	if (0 == oif) {
	    return errno;
	}

	arg.nh_addr 	= 0;
	arg.oif		= oif;
	arg.found	= 0;
	arg.replied	= 0;
	arg.unlsk	= unlsk;
	arg.msg_count = msg_cnt = 0;

	memset(&rmsg, 0, sizeof(rmsg));
	rmsg.rtm_family = AF_INET;
	rmsg.rtm_dst_len = sizeof(dst_addr)*8;
	rmsg.rtm_src_len = sizeof(src_addr)*8;

	nlm = nlmsg_alloc_simple(RTM_GETROUTE, 0);
	nlmsg_append(nlm, &rmsg, sizeof(rmsg), NLMSG_ALIGNTO);
	nla_put_u32(nlm, RTA_DST, dst_addr);
	nla_put_u32(nlm, RTA_SRC, src_addr);

	err = rtnl_send_ack_disable(unlsk, nlm);
	nlmsg_free(nlm);
	if (err < 0) {
		usnic_err("Failed to send nl route message to kernel, "
			"error %s\n", nl_geterror());
		return err;
	}

	err = nl_socket_modify_cb(unlsk->nlh, NL_CB_MSG_IN, NL_CB_CUSTOM,
					rtnl_raw_parse_cb, &arg);
	if (err != 0) {
		usnic_err("Failed to setup callback function, error %s\n", nl_geterror());
		return err;
	}

	while (!arg.replied) {
		err = nl_recvmsgs_default(unlsk->nlh);
		if (err < 0) {
			usnic_err("Failed to receive nl route message from "
				"kernel, error %s\n", nl_geterror());
			return err;
		}

		/*
		 * the return value of nl_recvmsgs_default does not tell
		 * whether it returns because of successful read or socket
		 * timeout. So we compare msg count before and after the call
		 * to decide if no new message arrives. In such case,
		 * this function needs to terminate to prevent the caller from
		 * blocking forever
		 * NL_CB_MSG_IN traps every received message, so
		 * there should be no premature exit
		 */
		if (msg_cnt != arg.msg_count)
			msg_cnt = arg.msg_count;
		else
			break;
	}

	if (arg.found) {
                if (metric != NULL) {
                    *metric = arg.metric;
                }
		return 0;
	}
	else {
		return -1;
	}
}
Exemplo n.º 24
0
static ni_socket_t *
__ni_rtevent_sock_open(void)
{
	unsigned int recv_buff_len = __ni_rtevent_config_recv_buff_len();
	unsigned int mesg_buff_len = __ni_rtevent_config_mesg_buff_len();
	ni_rtevent_handle_t *handle;
	ni_socket_t *sock;
	int fd, ret;

	if (!(handle = __ni_rtevent_handle_new())) {
		ni_error("Unable to allocate rtnetlink event handle: %m");
		return NULL;
	}

	if (!(handle->nlsock = nl_socket_alloc())) {
		ni_error("Cannot allocate rtnetlink event socket: %m");
		__ni_rtevent_handle_free(handle);
		return NULL;
	}

	/*
	 * Modify the callback for processing valid messages...
	 * We may pass some kind of data (event filter?) too...
	 */
	nl_socket_modify_cb(handle->nlsock, NL_CB_VALID, NL_CB_CUSTOM,
				__ni_rtevent_process_cb, NULL);

	/* Required to receive async event notifications */
	nl_socket_disable_seq_check(handle->nlsock);

	if ((ret = nl_connect(handle->nlsock, NETLINK_ROUTE)) < 0) {
		ni_error("Cannot open rtnetlink: %s", nl_geterror(ret));
		__ni_rtevent_handle_free(handle);
		return NULL;
	}

	/* Enable non-blocking processing */
	nl_socket_set_nonblocking(handle->nlsock);

	fd = nl_socket_get_fd(handle->nlsock);
	if (!(sock = ni_socket_wrap(fd, SOCK_DGRAM))) {
		ni_error("Cannot wrap rtnetlink event socket: %m");
		__ni_rtevent_handle_free(handle);
		return NULL;
	}

	if (recv_buff_len) {
		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE,
				(char *)&recv_buff_len, sizeof(recv_buff_len)) &&
		    setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
				(char *)&recv_buff_len, sizeof(recv_buff_len))) {
			ni_warn("Unable to set netlink event receive buffer to %u bytes: %m",
					recv_buff_len);
		} else {
			ni_info("Using netlink event receive buffer of %u bytes",
					recv_buff_len);
		}
	}
	if (mesg_buff_len) {
		if (nl_socket_set_msg_buf_size(handle->nlsock, mesg_buff_len)) {
			ni_warn("Unable to set netlink event message buffer to %u bytes",
					mesg_buff_len);
		} else {
			ni_info("Using netlink event message buffer of %u bytes",
					mesg_buff_len);
		}
	}

	sock->user_data	= handle;
	sock->receive	= __ni_rtevent_receive;
	sock->close	= __ni_rtevent_close;
	sock->handle_error  = __ni_rtevent_sock_error_handler;
	sock->release_user_data = __ni_rtevent_sock_release_data;
	return sock;
}
Exemplo n.º 25
0
int ompi_btl_usnic_nl_ip_rt_lookup(struct usnic_rtnl_sk *unlsk,
                                   const char *src_ifname,
                                   uint32_t src_addr,
                                   uint32_t dst_addr, int *metric)
{
	struct nl_msg 		*nlm;
	struct rtmsg 		rmsg;
	struct nl_lookup_arg    arg;
	int	msg_cnt;
	int		     	err;
	int oif;

	oif = if_nametoindex(src_ifname);
	if (0 == oif) {
	    return errno;
	}

	arg.nh_addr 	= 0;
	arg.oif		= oif;
	arg.found	= 0;
	arg.replied	= 0;
	arg.unlsk	= unlsk;
	arg.msg_count = msg_cnt = 0;

	memset(&rmsg, 0, sizeof(rmsg));
	rmsg.rtm_family = AF_INET;
	rmsg.rtm_dst_len = sizeof(dst_addr)*8;
	rmsg.rtm_src_len = sizeof(src_addr)*8;

	nlm = nlmsg_alloc_simple(RTM_GETROUTE, 0);
	nlmsg_append(nlm, &rmsg, sizeof(rmsg), NLMSG_ALIGNTO);
	nla_put_u32(nlm, RTA_DST, dst_addr);
	nla_put_u32(nlm, RTA_SRC, src_addr);

	err = rtnl_send_ack_disable(unlsk, nlm);
	nlmsg_free(nlm);
	if (err < 0) {
		usnic_err("Failed to send rtnl query %s\n", nl_geterror(err));
		return err;
	}

	err = nl_socket_modify_cb(unlsk->sock, NL_CB_MSG_IN, NL_CB_CUSTOM,
					rtnl_raw_parse_cb, &arg);
	if (err != 0) {
		usnic_err("Failed to setup callback function, error %s\n",
				nl_geterror(err));
		return err;
	}

	while (!arg.replied) {
		err = nl_recvmsgs_default(unlsk->sock);
		if (err < 0) {
			/* err will be returned as -NLE_AGAIN if the socket times out */
			usnic_err("Failed to receive rtnl query results %s\n",
					nl_geterror(err));
			return err;
		}
	}

	if (arg.found) {
                if (metric != NULL) {
                    *metric = arg.metric;
                }
		return 0;
	}
	else {
		return -1;
	}
}
Exemplo n.º 26
0
int main(int argc, char *argv[])
{
	struct nl_handle *nlh;
	struct nl_cache *link_cache, *route_cache;
	struct nl_addr *dst;
	struct rtnl_route *route;
        struct ip_lookup_res res;
	struct nl_dump_params params = {
		.dp_fd = stdout,
		.dp_type = NL_DUMP_FULL
	};
	int err = 1;

	if (argc < 2 || !strcmp(argv[1], "-h"))
		print_usage();

	if (nltool_init(argc, argv) < 0)
		goto errout;

	nlh = nltool_alloc_handle();
	if (!nlh)
		goto errout;

	route = rtnl_route_alloc();
	if (!route)
		goto errout_free_handle;

	if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
		goto errout_free_route;

	link_cache = nltool_alloc_link_cache(nlh);
	if (!link_cache)
		goto errout_close;

	dst = nltool_addr_parse(argv[1]);
	if (!dst)
		goto errout_link_cache;

	route_cache = nltool_alloc_route_cache(nlh);
	if (!route_cache)
		goto errout_addr_put;

	{
		struct nl_msg *m;
		struct rtmsg rmsg = {
			.rtm_family = nl_addr_get_family(dst),
			.rtm_dst_len = nl_addr_get_prefixlen(dst),
		};

		m = nlmsg_alloc_simple(RTM_GETROUTE, 0);
		nlmsg_append(m, &rmsg, sizeof(rmsg), NLMSG_ALIGNTO);
		nla_put_addr(m, RTA_DST, dst);

		if ((err = nl_send_auto_complete(nlh, m)) < 0) {
			nlmsg_free(m);
			fprintf(stderr, "%s\n", nl_geterror());
			goto errout_route_cache;
		}

		nlmsg_free(m);

		nl_socket_modify_cb(nlh, NL_CB_VALID, NL_CB_CUSTOM, cb,
				 route_cache);

		if (nl_recvmsgs_default(nlh) < 0) {
			fprintf(stderr, "%s\n", nl_geterror());
			goto errout_route_cache;
		}
	}

        rtnl_route_set_dst(route, dst);
	nl_cache_dump_filter(route_cache, &params, (struct nl_object *) route);
        memset(&res, 0, sizeof(res));
        nl_cache_foreach_filter(route_cache, (struct nl_object *) route, route_proc_cb,
                                &res);

        printf("ip lookup result: oif idx: %d oif name %s ",
                res.oif, res.oifname);
        if (res.nh_addr) {
                char buf[INET_ADDRSTRLEN];
                inet_ntop(AF_INET, &res.nh_addr, buf, sizeof(buf));
                printf("via %s", buf);
        }
        printf ("\n");

	err = 0;
errout_route_cache:
	nl_cache_free(route_cache);
errout_addr_put:
	nl_addr_put(dst);
errout_link_cache:
	nl_cache_free(link_cache);
errout_close:
	nl_close(nlh);
errout_free_route:
        rtnl_route_put(route);
errout_free_handle:
	nl_handle_destroy(nlh);
errout:
	return err;
}
Exemplo n.º 27
0
static struct nl_addr *process_get_neigh_mac(
		struct get_neigh_handler *neigh_handler)
{
	int err;
	struct nl_addr *ll_addr = get_neigh_mac(neigh_handler);
	struct rtnl_neigh *neigh_filter;
	fd_set fdset;
	int sock_fd;
	int fd;
	int nfds;
	int timer_fd;
	int ret;
	struct skt addr_dst;
	char buff[sizeof(SEND_PAYLOAD)] = SEND_PAYLOAD;
	int retries = 0;

	if (NULL != ll_addr)
		return ll_addr;

	err = nl_socket_add_membership(neigh_handler->sock,
				       RTNLGRP_NEIGH);
	if (err < 0)
		return NULL;

	neigh_filter = create_filter_neigh_for_dst(neigh_handler->dst,
						   neigh_handler->oif);
	if (neigh_filter == NULL)
		return NULL;

	set_neigh_filter(neigh_handler, neigh_filter);

	nl_socket_disable_seq_check(neigh_handler->sock);
	nl_socket_modify_cb(neigh_handler->sock, NL_CB_VALID, NL_CB_CUSTOM,
			    &get_neigh_cb, neigh_handler);

	fd = nl_socket_get_fd(neigh_handler->sock);

	err = create_socket(neigh_handler, &addr_dst, &sock_fd);

	if (err)
		return NULL;

	err = try_send_to(sock_fd, buff, sizeof(buff), &addr_dst);
	if (err)
		goto close_socket;

	timer_fd = create_timer(neigh_handler);
	if (timer_fd < 0)
		goto close_socket;

	nfds = MAX(fd, timer_fd) + 1;

	while (1) {
		FD_ZERO(&fdset);
		FD_SET(fd, &fdset);
		FD_SET(timer_fd, &fdset);

		/* wait for an incoming message on the netlink socket */
		ret = select(nfds, &fdset, NULL, NULL, NULL);
		if (ret == -1) {
			goto select_err;
		} else if (ret) {
			if (FD_ISSET(fd, &fdset)) {
				nl_recvmsgs_default(neigh_handler->sock);
				if (neigh_handler->found_ll_addr)
					break;
			} else {
				nl_cache_refill(neigh_handler->sock,
						neigh_handler->neigh_cache);
				ll_addr = get_neigh_mac(neigh_handler);
				if (NULL != ll_addr) {
					break;
				} else if (FD_ISSET(timer_fd, &fdset) &&
					   retries < NUM_OF_RETRIES) {
					try_send_to(sock_fd, buff, sizeof(buff),
						    &addr_dst);
				}
			}

			if (FD_ISSET(timer_fd, &fdset)) {
				uint64_t read_val;
				ssize_t rc;

				rc =
				    read(timer_fd, &read_val, sizeof(read_val));
				assert(rc == sizeof(read_val));
				if (++retries >=  NUM_OF_TRIES) {
					if (!errno)
						errno = EDESTADDRREQ;
					break;
				}
			}
		}
	}
select_err:
	close(timer_fd);
close_socket:
	close(sock_fd);
	return ll_addr ? ll_addr : neigh_handler->found_ll_addr;
}
Exemplo n.º 28
0
static void obj_input(struct nl_object *obj, void *arg)
{
	struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) obj;
	struct nl_dump_params dp = {
		.dp_type = NL_DUMP_STATS,
		.dp_fd = stdout,
		.dp_dump_msgtype = 1,
	};

	nfnl_queue_msg_set_verdict(msg, NF_ACCEPT);
	nl_object_dump(obj, &dp);
	nfnl_queue_msg_send_verdict(nf_sock, msg);
}

static int event_input(struct nl_msg *msg, void *arg)
{
	if (nl_msg_parse(msg, &obj_input, NULL) < 0)
		fprintf(stderr, "<<EVENT>> Unknown message type\n");

	/* Exit nl_recvmsgs_def() and return to the main select() */
	return NL_STOP;
}

int main(int argc, char *argv[])
{
	struct nl_sock *rt_sock;
	struct nl_cache *link_cache;
	struct nfnl_queue *queue;
	enum nfnl_queue_copy_mode copy_mode;
	uint32_t copy_range;
	int err = 1;
	int family;

	nf_sock = nfnl_queue_socket_alloc();
	if (nf_sock == NULL)
		nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket");

	nl_socket_disable_seq_check(nf_sock);
	nl_socket_modify_cb(nf_sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);

	if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) {
		printf("Usage: nf-queue family group [ copy_mode ] "
		       "[ copy_range ]\n");
		printf("family: [ inet | inet6 | ... ] \n");
		printf("group: the --queue-num arg that you gave to iptables\n");
		printf("copy_mode: [ none | meta | packet ] \n");
		return 2;
	}

	nl_cli_connect(nf_sock, NETLINK_NETFILTER);

	if ((family = nl_str2af(argv[1])) == AF_UNSPEC)
		nl_cli_fatal(NLE_INVAL, "Unknown family \"%s\"", argv[1]);

	nfnl_queue_pf_unbind(nf_sock, family);
	if ((err = nfnl_queue_pf_bind(nf_sock, family)) < 0)
		nl_cli_fatal(err, "Unable to bind logger: %s",
			     nl_geterror(err));

	queue = alloc_queue();
	nfnl_queue_set_group(queue, atoi(argv[2]));

	copy_mode = NFNL_QUEUE_COPY_PACKET;
	if (argc > 3) {
		copy_mode = nfnl_queue_str2copy_mode(argv[3]);
		if (copy_mode < 0)
			nl_cli_fatal(copy_mode,
				     "Unable to parse copy mode \"%s\": %s",
				     argv[3], nl_geterror(copy_mode));
	}
	nfnl_queue_set_copy_mode(queue, copy_mode);

	copy_range = 0xFFFF;
	if (argc > 4)
		copy_range = atoi(argv[4]);
	nfnl_queue_set_copy_range(queue, copy_range);

	if ((err = nfnl_queue_create(nf_sock, queue)) < 0)
		nl_cli_fatal(err, "Unable to bind queue: %s", nl_geterror(err));

	rt_sock = nl_cli_alloc_socket();
	nl_cli_connect(rt_sock, NETLINK_ROUTE);
	link_cache = nl_cli_link_alloc_cache(rt_sock);

	nl_socket_set_buffer_size(nf_sock, 1024*127, 1024*127);

	while (1) {
		fd_set rfds;
		int nffd, rtfd, maxfd, retval;

		FD_ZERO(&rfds);

		maxfd = nffd = nl_socket_get_fd(nf_sock);
		FD_SET(nffd, &rfds);

		rtfd = nl_socket_get_fd(rt_sock);
		FD_SET(rtfd, &rfds);
		if (maxfd < rtfd)
			maxfd = rtfd;

		/* wait for an incoming message on the netlink socket */
		retval = select(maxfd+1, &rfds, NULL, NULL, NULL);

		if (retval) {
			if (FD_ISSET(nffd, &rfds))
				nl_recvmsgs_default(nf_sock);
			if (FD_ISSET(rtfd, &rfds))
				nl_recvmsgs_default(rt_sock);
		}
	}

	return 0;
}
Exemplo n.º 29
0
int usnic_nl_rt_lookup(uint32_t src_addr, uint32_t dst_addr, int oif,
			uint32_t *nh_addr)
{
	struct usnic_nl_sk	*unlsk;
	struct nl_msg		*nlm;
	struct rtmsg		rmsg;
	struct usnic_rt_cb_arg	arg;
	int			err;

retry:
	unlsk = NULL;
	err = usnic_nl_sk_alloc(&unlsk, NETLINK_ROUTE);
	if (err)
		return err;

	memset(&rmsg, 0, sizeof(rmsg));
	rmsg.rtm_family = AF_INET;
	rmsg.rtm_dst_len = sizeof(dst_addr) * CHAR_BIT;
	rmsg.rtm_src_len = sizeof(src_addr) * CHAR_BIT;

	nlm = nlmsg_alloc_simple(RTM_GETROUTE, 0);
	if (!nlm) {
		usnic_err("Failed to alloc nl message, %s\n",
				NL_GETERROR(err));
		err = ENOMEM;
		goto out;
	}
	nlmsg_append(nlm, &rmsg, sizeof(rmsg), NLMSG_ALIGNTO);
	nla_put_u32(nlm, RTA_DST, dst_addr);
	nla_put_u32(nlm, RTA_SRC, src_addr);

	err = usnic_nl_send_query(unlsk, nlm, NETLINK_ROUTE, NLM_F_REQUEST);
	nlmsg_free(nlm);
	if (err < 0) {
		usnic_err("Failed to send RTM_GETROUTE query message, error %s\n",
				NL_GETERROR(err));
                err = EINVAL;
		goto out;
	}

	memset(&arg, 0, sizeof(arg));
	arg.oif		= oif;
	arg.unlsk	= unlsk;
	err = nl_socket_modify_cb(unlsk->nlh, NL_CB_MSG_IN, NL_CB_CUSTOM,
					usnic_rt_raw_parse_cb, &arg);
	if (err != 0) {
		usnic_err("Failed to setup callback function, error %s\n",
				NL_GETERROR(err));
                err = EINVAL;
		goto out;
	}

	/* Sometimes the recvmsg can fail because something is
	 * temporarily out of resources.  In this case, delay a little
	 * and try again. */
	do {
		err = 0;
		NL_RECVMSGS(unlsk->nlh, arg, EAGAIN, err, out);
		if (err == EAGAIN) {
			usleep(5);
		}
	} while (err == EAGAIN);

	/* If we got a reply back that indicated that the kernel was
	 * too busy to handle this request, delay a little and try
	 * again. */
        if (arg.retry) {
            usleep(5);
            goto retry;
        }

	if (arg.found) {
		*nh_addr = arg.nh_addr;
		err = 0;
	} else {
		err = EHOSTUNREACH;
	}

out:
	usnic_nl_sk_free(unlsk);
	return err;
}
Exemplo n.º 30
0
static void obj_input(struct nl_object *obj, void *arg)
{
	struct nl_dump_params dp = {
		.dp_type = NL_DUMP_STATS,
		.dp_fd = stdout,
		.dp_dump_msgtype = 1,
	};

	nl_object_dump(obj, &dp);
}

static int event_input(struct nl_msg *msg, void *arg)
{
	if (nl_msg_parse(msg, &obj_input, NULL) < 0)
		fprintf(stderr, "<<EVENT>> Unknown message type\n");

	/* Exit nl_recvmsgs_def() and return to the main select() */
	return NL_STOP;
}

int main(int argc, char *argv[])
{
	struct nl_sock *nf_sock;
	struct nl_sock *rt_sock;
        struct nl_cache *link_cache;
	struct nfnl_log *log;
	enum nfnl_log_copy_mode copy_mode;
	uint32_t copy_range;
	int err;
	int family;

	nf_sock = nl_cli_alloc_socket();
	nl_socket_disable_seq_check(nf_sock);
	nl_socket_modify_cb(nf_sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);

	if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) {
		printf("Usage: nf-log family group [ copy_mode ] "
		       "[copy_range] \n");
		return 2;
	}

	nl_cli_connect(nf_sock, NETLINK_NETFILTER);

	family = nl_str2af(argv[1]);
	if (family == AF_UNSPEC)
		nl_cli_fatal(NLE_INVAL, "Unknown family \"%s\": %s",
			     argv[1], nl_geterror(family));

	nfnl_log_pf_unbind(nf_sock, family);
	if ((err = nfnl_log_pf_bind(nf_sock, family)) < 0)
		nl_cli_fatal(err, "Unable to bind logger: %s",
			     nl_geterror(err));

	log = alloc_log();
	nfnl_log_set_group(log, atoi(argv[2]));

	copy_mode = NFNL_LOG_COPY_META;
	if (argc > 3) {
		copy_mode = nfnl_log_str2copy_mode(argv[3]);
		if (copy_mode < 0)
			nl_cli_fatal(copy_mode,
				     "Unable to parse copy mode \"%s\": %s",
				     argv[3], nl_geterror(copy_mode));
	}
	nfnl_log_set_copy_mode(log, copy_mode);

	copy_range = 0xFFFF;
	if (argc > 4)
		copy_mode = atoi(argv[4]);
	nfnl_log_set_copy_range(log, copy_range);

	if ((err = nfnl_log_create(nf_sock, log)) < 0)
		nl_cli_fatal(err, "Unable to bind instance: %s",
			     nl_geterror(err));

	{
		struct nl_dump_params dp = {
			.dp_type = NL_DUMP_STATS,
			.dp_fd = stdout,
			.dp_dump_msgtype = 1,
		};

		printf("log params: ");
		nl_object_dump((struct nl_object *) log, &dp);
	}

	rt_sock = nl_cli_alloc_socket();
	nl_cli_connect(rt_sock, NETLINK_ROUTE);
	link_cache = nl_cli_link_alloc_cache(rt_sock);

	while (1) {
		fd_set rfds;
		int nffd, rtfd, maxfd, retval;

		FD_ZERO(&rfds);

		maxfd = nffd = nl_socket_get_fd(nf_sock);
		FD_SET(nffd, &rfds);

		rtfd = nl_socket_get_fd(rt_sock);
		FD_SET(rtfd, &rfds);
		if (maxfd < rtfd)
			maxfd = rtfd;

		/* wait for an incoming message on the netlink nf_socket */
		retval = select(maxfd+1, &rfds, NULL, NULL, NULL);

		if (retval) {
			if (FD_ISSET(nffd, &rfds))
				nl_recvmsgs_default(nf_sock);
			if (FD_ISSET(rtfd, &rfds))
				nl_recvmsgs_default(rt_sock);
		}
	}

	return 0;
}