Esempio n. 1
0
int main(int argc, char *argv[])
{
	int i;

	test_init(argc, argv);

	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
	if (fd<0){
		pr_perror("socket");
		goto out;
	}
	// setup local address & bind using
	// this address
	bzero(&la, sizeof(la));
	la.nl_family = AF_NETLINK;
	la.nl_pid = getpid();
	if (bind(fd, (struct sockaddr*) &la, sizeof(la))){
		pr_perror("bind failed");
		goto out;
	}
	//Preperation:
	form_request_del();
	send_request();
	recv_reply();

	test_daemon();

	while (test_go()){
		for (i=0; i < CMD_NUM; i++){
			cmd[i]();
			if (send_request() < 0){
				fail("send_request failed");
				goto out;
			};
			if (recv_reply() < 0){
				fail("RTNETLINK answers: %m");
				goto out;
			};

#ifdef DEBUG
			if (read_reply() < 0){
				fail("read_reply failed");
				goto out;
			}
#endif
		}
	}

	pass();

out:
	return 0;
}
Esempio n. 2
0
/*
 * Send index to the relayd.
 */
int relayd_send_index(struct lttcomm_relayd_sock *rsock,
		struct ctf_packet_index *index, uint64_t relay_stream_id,
		uint64_t net_seq_num)
{
	int ret;
	struct lttcomm_relayd_index msg;
	struct lttcomm_relayd_generic_reply reply;

	/* Code flow error. Safety net. */
	assert(rsock);

	if (rsock->minor < 4) {
		DBG("Not sending indexes before protocol 2.4");
		ret = 0;
		goto error;
	}

	DBG("Relayd sending index for stream ID %" PRIu64, relay_stream_id);

	memset(&msg, 0, sizeof(msg));
	msg.relay_stream_id = htobe64(relay_stream_id);
	msg.net_seq_num = htobe64(net_seq_num);

	/* The index is already in big endian. */
	msg.packet_size = index->packet_size;
	msg.content_size = index->content_size;
	msg.timestamp_begin = index->timestamp_begin;
	msg.timestamp_end = index->timestamp_end;
	msg.events_discarded = index->events_discarded;
	msg.stream_id = index->stream_id;

	/* Send command */
	ret = send_command(rsock, RELAYD_SEND_INDEX, &msg, sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(rsock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code != LTTNG_OK) {
		ret = -1;
		ERR("Relayd send index replied error %d", reply.ret_code);
	} else {
		/* Success */
		ret = 0;
	}

error:
	return ret;
}
Esempio n. 3
0
/*
 * Send a RELAYD_CREATE_SESSION command to the relayd with the given socket and
 * set session_id of the relayd if we have a successful reply from the relayd.
 *
 * On success, return 0 else a negative value which is either an errno error or
 * a lttng error code from the relayd.
 */
int relayd_create_session(struct lttcomm_relayd_sock *rsock, uint64_t *session_id,
		char *session_name, char *hostname, int session_live_timer,
		unsigned int snapshot)
{
	int ret;
	struct lttcomm_relayd_status_session reply;

	assert(rsock);
	assert(session_id);

	DBG("Relayd create session");

	switch(rsock->minor) {
		case 1:
		case 2:
		case 3:
			ret = relayd_create_session_2_1(rsock, session_id);
			break;
		case 4:
		default:
			ret = relayd_create_session_2_4(rsock, session_id, session_name,
					hostname, session_live_timer, snapshot);
			break;
	}

	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(rsock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	reply.session_id = be64toh(reply.session_id);
	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code != LTTNG_OK) {
		ret = -1;
		ERR("Relayd create session replied error %d", reply.ret_code);
		goto error;
	} else {
		ret = 0;
		*session_id = reply.session_id;
	}

	DBG("Relayd session created with id %" PRIu64, reply.session_id);

error:
	return ret;
}
Esempio n. 4
0
int search_mrr_device(SEARCH_RESULT_T **ppresult_out)
{
	unsigned char reply_buf[MAX_BUFFER_LEN] = {0};

	struct sockaddr_in addr_dest;
	bzero(&addr_dest, sizeof(struct sockaddr_in));
	addr_dest.sin_family=AF_INET;
	addr_dest.sin_addr.s_addr=htonl(INADDR_BROADCAST);
	addr_dest.sin_port=htons(DEST_PORT);

	int sock = create_udp_socket();

	//从广播地址发送搜索指令
	int recv_len = 0;
	unsigned char cmd[] = {"0123456789012345678901234567890123456789"};

	int ret = send_boardcast_cmd(sock, (struct sockaddr*)&addr_dest, cmd, strlen((char*)cmd));
	if(ret<0)
	{
		printf("send search cmd error....\n");
		return -1;
	}
	else
	{		
		printf("send search cmd ok!\n");	
	}

	while(1)
	{
		recv_len = recv_reply(sock, (struct sockaddr*)&addr_dest, reply_buf);
		if(recv_len <= 0)
		{
			printf("recv error....\n");
			break;
		}
		else if(recv_len % SEARCH_REPLY_LEN == 0)
		{
			ret = parse_search_result(reply_buf, recv_len, ppresult_out);
			if(ret >= 0)
				break;
		}

		sleep(1);

	}

	close_udp_socket(sock);

	return 0;
}
Esempio n. 5
0
/*
 * Add stream on the relayd and assign stream handle to the stream_id argument.
 *
 * On success return 0 else return ret_code negative value.
 */
int relayd_add_stream(struct lttcomm_sock *sock, const char *channel_name,
		const char *pathname, uint64_t *stream_id)
{
	int ret;
	struct lttcomm_relayd_add_stream msg;
	struct lttcomm_relayd_status_stream reply;

	/* Code flow error. Safety net. */
	assert(sock);
	assert(channel_name);
	assert(pathname);

	DBG("Relayd adding stream for channel name %s", channel_name);

	strncpy(msg.channel_name, channel_name, sizeof(msg.channel_name));
	strncpy(msg.pathname, pathname, sizeof(msg.pathname));

	/* Send command */
	ret = send_command(sock, RELAYD_ADD_STREAM, (void *) &msg, sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Waiting for reply */
	ret = recv_reply(sock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	/* Back to host bytes order. */
	reply.handle = be64toh(reply.handle);
	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code != LTTNG_OK) {
		ret = -1;
		ERR("Relayd add stream replied error %d", reply.ret_code);
	} else {
		/* Success */
		ret = 0;
		*stream_id = reply.handle;
	}

	DBG("Relayd stream added successfully with handle %" PRIu64,
		reply.handle);

error:
	return ret;
}
Esempio n. 6
0
/*
 * Inform the relay that all the streams for the current channel has been sent.
 *
 * On success return 0 else return ret_code negative value.
 */
int relayd_streams_sent(struct lttcomm_relayd_sock *rsock)
{
	int ret;
	struct lttcomm_relayd_generic_reply reply;

	/* Code flow error. Safety net. */
	assert(rsock);

	DBG("Relayd sending streams sent.");

	/* This feature was introduced in 2.4, ignore it for earlier versions. */
	if (rsock->minor < 4) {
		ret = 0;
		goto end;
	}

	/* Send command */
	ret = send_command(rsock, RELAYD_STREAMS_SENT, NULL, 0, 0);
	if (ret < 0) {
		goto error;
	}

	/* Waiting for reply */
	ret = recv_reply(rsock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	/* Back to host bytes order. */
	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code != LTTNG_OK) {
		ret = -1;
		ERR("Relayd streams sent replied error %d", reply.ret_code);
		goto error;
	} else {
		/* Success */
		ret = 0;
	}

	DBG("Relayd streams sent success");

error:
end:
	return ret;
}
Esempio n. 7
0
/*
 * Check for data availability for a given stream id.
 *
 * Return 0 if NOT pending, 1 if so and a negative value on error.
 */
int relayd_data_pending(struct lttcomm_relayd_sock *rsock, uint64_t stream_id,
		uint64_t last_net_seq_num)
{
	int ret;
	struct lttcomm_relayd_data_pending msg;
	struct lttcomm_relayd_generic_reply reply;

	/* Code flow error. Safety net. */
	assert(rsock);

	DBG("Relayd data pending for stream id %" PRIu64, stream_id);

	memset(&msg, 0, sizeof(msg));
	msg.stream_id = htobe64(stream_id);
	msg.last_net_seq_num = htobe64(last_net_seq_num);

	/* Send command */
	ret = send_command(rsock, RELAYD_DATA_PENDING, (void *) &msg,
			sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(rsock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code >= LTTNG_OK) {
		ERR("Relayd data pending replied error %d", reply.ret_code);
	}

	/* At this point, the ret code is either 1 or 0 */
	ret = reply.ret_code;

	DBG("Relayd data is %s pending for stream id %" PRIu64,
			ret == 1 ? "" : "NOT", stream_id);

error:
	return ret;
}
Esempio n. 8
0
/*
 * Send close stream command to the relayd.
 */
int relayd_send_close_stream(struct lttcomm_relayd_sock *rsock, uint64_t stream_id,
		uint64_t last_net_seq_num)
{
	int ret;
	struct lttcomm_relayd_close_stream msg;
	struct lttcomm_relayd_generic_reply reply;

	/* Code flow error. Safety net. */
	assert(rsock);

	DBG("Relayd closing stream id %" PRIu64, stream_id);

	memset(&msg, 0, sizeof(msg));
	msg.stream_id = htobe64(stream_id);
	msg.last_net_seq_num = htobe64(last_net_seq_num);

	/* Send command */
	ret = send_command(rsock, RELAYD_CLOSE_STREAM, (void *) &msg, sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(rsock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code != LTTNG_OK) {
		ret = -1;
		ERR("Relayd close stream replied error %d", reply.ret_code);
	} else {
		/* Success */
		ret = 0;
	}

	DBG("Relayd close stream id %" PRIu64 " successfully", stream_id);

error:
	return ret;
}
Esempio n. 9
0
/*
 * End a data pending command for a specific session id.
 *
 * Return 0 on success and set is_data_inflight to 0 if no data is being
 * streamed or 1 if it is the case.
 */
int relayd_end_data_pending(struct lttcomm_relayd_sock *rsock, uint64_t id,
		unsigned int *is_data_inflight)
{
	int ret, recv_ret;
	struct lttcomm_relayd_end_data_pending msg;
	struct lttcomm_relayd_generic_reply reply;

	/* Code flow error. Safety net. */
	assert(rsock);

	DBG("Relayd end data pending");

	memset(&msg, 0, sizeof(msg));
	msg.session_id = htobe64(id);

	/* Send command */
	ret = send_command(rsock, RELAYD_END_DATA_PENDING, &msg, sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(rsock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	recv_ret = be32toh(reply.ret_code);
	if (recv_ret < 0) {
		ret = recv_ret;
		goto error;
	}

	*is_data_inflight = recv_ret;

	DBG("Relayd end data pending is data inflight: %d", recv_ret);

	return 0;

error:
	return ret;
}
Esempio n. 10
0
/*
 * Check on the relayd side for a quiescent state on the control socket.
 */
int relayd_quiescent_control(struct lttcomm_relayd_sock *rsock,
		uint64_t metadata_stream_id)
{
	int ret;
	struct lttcomm_relayd_quiescent_control msg;
	struct lttcomm_relayd_generic_reply reply;

	/* Code flow error. Safety net. */
	assert(rsock);

	DBG("Relayd checking quiescent control state");

	memset(&msg, 0, sizeof(msg));
	msg.stream_id = htobe64(metadata_stream_id);

	/* Send command */
	ret = send_command(rsock, RELAYD_QUIESCENT_CONTROL, &msg, sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(rsock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code != LTTNG_OK) {
		ret = -1;
		ERR("Relayd quiescent control replied error %d", reply.ret_code);
		goto error;
	}

	/* Control socket is quiescent */
	return 0;

error:
	return ret;
}
Esempio n. 11
0
/*
 * Begin a data pending command for a specific session id.
 */
int relayd_begin_data_pending(struct lttcomm_relayd_sock *rsock, uint64_t id)
{
	int ret;
	struct lttcomm_relayd_begin_data_pending msg;
	struct lttcomm_relayd_generic_reply reply;

	/* Code flow error. Safety net. */
	assert(rsock);

	DBG("Relayd begin data pending");

	memset(&msg, 0, sizeof(msg));
	msg.session_id = htobe64(id);

	/* Send command */
	ret = send_command(rsock, RELAYD_BEGIN_DATA_PENDING, &msg, sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(rsock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code != LTTNG_OK) {
		ret = -1;
		ERR("Relayd begin data pending replied error %d", reply.ret_code);
		goto error;
	}

	return 0;

error:
	return ret;
}
Esempio n. 12
0
/*
 * Send a RELAYD_CREATE_SESSION command to the relayd with the given socket and
 * set session_id of the relayd if we have a successful reply from the relayd.
 *
 * On success, return 0 else a negative value which is either an errno error or
 * a lttng error code from the relayd.
 */
int relayd_create_session(struct lttcomm_sock *sock, uint64_t *session_id)
{
	int ret;
	struct lttcomm_relayd_status_session reply;

	assert(sock);
	assert(session_id);

	DBG("Relayd create session");

	/* Send command */
	ret = send_command(sock, RELAYD_CREATE_SESSION, NULL, 0, 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(sock, (void *) &reply, sizeof(reply));
	if (ret < 0) {
		goto error;
	}

	reply.session_id = be64toh(reply.session_id);
	reply.ret_code = be32toh(reply.ret_code);

	/* Return session id or negative ret code. */
	if (reply.ret_code != LTTNG_OK) {
		ret = -1;
		ERR("Relayd create session replied error %d", reply.ret_code);
		goto error;
	} else {
		ret = 0;
		*session_id = reply.session_id;
	}

	DBG("Relayd session created with id %" PRIu64, reply.session_id);

error:
	return ret;
}
Esempio n. 13
0
File: nield.c Progetto: yumkam/nield
/*
 * main function
 */
int main(int argc, char *argv[])
{
    int sock = -1, ret;
    unsigned groups; 

    /* set option */
    ret = set_options(argc, argv);
    if(ret < 0)
        close_exit(sock, 0, ret);

    /* open log file */
    ret = open_log(log_file);
    if(ret < 0)
        close_exit(sock, 0, ret);

    /* open debug file */
    if(log_opts & L_DEBUG) {
        ret = open_dbg(dbg_file);
        if(ret < 0)
            close_exit(sock, 0, ret);
    }

    /* create lock file */
    ret = open_lock();
    if(ret < 0)
        close_exit(sock, 0, ret);

    /* set signal handlers */
    ret = set_signal_handlers();
    if(ret < 0)
        close_exit(sock, 0, ret);

    /* initizlize daemon */
    ret = init_daemon();
    if(ret < 0)
        close_exit(sock, 0, ret);

    rec_log("info: nield %s started(PID: %ld)", VERSION, (long)getpid());

    /* write pid to lock file */
    ret = write_lock();
    if(ret < 0)
        close_exit(sock, 0, ret);

    /* open netlink socket to create list */
    groups = 0;
    sock = open_netlink_socket(groups, NETLINK_ROUTE);
    if(sock < 0)
        close_exit(sock, 1, ret);

    /* request interface list */
    ret = send_request(sock, RTM_GETLINK, AF_UNSPEC);
    if(ret < 0)
        close_exit(sock, 1, ret);

    /* receive interface list */
    ret = recv_reply(sock, RTM_GETLINK);
    if(ret != 0)
        close_exit(sock, 1, ret);

    /* request bridge interface list */
    ret = send_request(sock, RTM_GETLINK, AF_BRIDGE);
    if(ret < 0)
        close_exit(sock, 1, ret);

    /* receive bridge interface list */
    ret = recv_reply(sock, RTM_GETLINK);
    if(ret != 0)
        close_exit(sock, 1, ret);

    /* request neighbor cache list */
    ret = send_request(sock, RTM_GETNEIGH, AF_UNSPEC);
    if(ret < 0)
        close_exit(sock, 1, ret);

    /* receive & create interface list */
    ret = recv_reply(sock, RTM_GETNEIGH);
    if(ret != 0)
        close_exit(sock, 1, ret);

    /* close socket */
    close(sock);

    /* set rtnetlink multicast groups */
    groups = set_rtnetlink_groups();
    sock = open_netlink_socket(groups, NETLINK_ROUTE);
    if(sock < 0)
        close_exit(sock, 1, ret);

    /* recevie events */
    ret = recv_events(sock);

    close_exit(sock, 1, ret);

    return(0);
}
Esempio n. 14
0
/*
 * Check version numbers on the relayd.
 * If major versions are compatible, we assign minor_to_use to the
 * minor version of the procotol we are going to use for this session.
 *
 * Return 0 if compatible else negative value.
 */
int relayd_version_check(struct lttcomm_relayd_sock *rsock)
{
	int ret;
	struct lttcomm_relayd_version msg;

	/* Code flow error. Safety net. */
	assert(rsock);

	DBG("Relayd version check for major.minor %u.%u", rsock->major,
			rsock->minor);

	memset(&msg, 0, sizeof(msg));
	/* Prepare network byte order before transmission. */
	msg.major = htobe32(rsock->major);
	msg.minor = htobe32(rsock->minor);

	/* Send command */
	ret = send_command(rsock, RELAYD_VERSION, (void *) &msg, sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(rsock, (void *) &msg, sizeof(msg));
	if (ret < 0) {
		goto error;
	}

	/* Set back to host bytes order */
	msg.major = be32toh(msg.major);
	msg.minor = be32toh(msg.minor);

	/*
	 * Only validate the major version. If the other side is higher,
	 * communication is not possible. Only major version equal can talk to each
	 * other. If the minor version differs, the lowest version is used by both
	 * sides.
	 */
	if (msg.major != rsock->major) {
		/* Not compatible */
		ret = -1;
		DBG2("Relayd version is NOT compatible. Relayd version %u != %u (us)",
				msg.major, rsock->major);
		goto error;
	}

	/*
	 * If the relayd's minor version is higher, it will adapt to our version so
	 * we can continue to use the latest relayd communication data structure.
	 * If the received minor version is higher, the relayd should adapt to us.
	 */
	if (rsock->minor > msg.minor) {
		rsock->minor = msg.minor;
	}

	/* Version number compatible */
	DBG2("Relayd version is compatible, using protocol version %u.%u",
			rsock->major, rsock->minor);
	ret = 0;

error:
	return ret;
}
Esempio n. 15
0
/*
 * Check version numbers on the relayd.
 *
 * Return 0 if compatible else negative value.
 */
int relayd_version_check(struct lttcomm_sock *sock, uint32_t major,
		uint32_t minor)
{
	int ret;
	struct lttcomm_relayd_version msg;

	/* Code flow error. Safety net. */
	assert(sock);

	DBG("Relayd version check for major.minor %u.%u", major, minor);

	/* Prepare network byte order before transmission. */
	msg.major = htobe32(major);
	msg.minor = htobe32(minor);

	/* Send command */
	ret = send_command(sock, RELAYD_VERSION, (void *) &msg, sizeof(msg), 0);
	if (ret < 0) {
		goto error;
	}

	/* Receive response */
	ret = recv_reply(sock, (void *) &msg, sizeof(msg));
	if (ret < 0) {
		goto error;
	}

	/* Set back to host bytes order */
	msg.major = be32toh(msg.major);
	msg.minor = be32toh(msg.minor);

	/*
	 * Only validate the major version. If the other side is higher,
	 * communication is not possible. Only major version equal can talk to each
	 * other. If the minor version differs, the lowest version is used by both
	 * sides.
	 *
	 * For now, before 2.1.0 stable release, we don't have to check the minor
	 * because this new mechanism with the relayd will only be available with
	 * 2.1 and NOT 2.0.x.
	 */
	if (msg.major == major) {
		/* Compatible */
		ret = 0;
		DBG2("Relayd version is compatible");
		goto error;
	}

	/*
	 * After 2.1.0 release, for the 2.2 release, at this point will have to
	 * check the minor version in order for the session daemon to know which
	 * structure to use to communicate with the relayd. If the relayd's minor
	 * version is higher, it will adapt to our version so we can continue to
	 * use the latest relayd communication data structure.
	 */

	/* Version number not compatible */
	DBG2("Relayd version is NOT compatible. Relayd version %u != %u (us)",
			msg.major, major);
	ret = -1;

error:
	return ret;
}