<commit_before>/*
 * Linux WiMax
 * Messaging interface implementation
 *
 *
 * Copyright (C) 2007-2008 Intel Corporation. All rights reserved.
 * <NAME> <<EMAIL>>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * \defgroup the_messaging_interface The message interface
 *
 * This is a payload agnostic message interface for communication
 * between the WiMAX kernel drivers and user space applications.
 *
 * It writes messages (wimax_msg_write()) by sending them to the WiMAX
 * kernel stack, which passes it to the driver using the \e
 * wimax_dev->op_msg_from_user() call.
 *
 * To write messages to the driver:
 *
 * @code
 *  wimaxll_msg_write(wmx, PIPE_NAME, buf, buf_size);
 * @endcode
 *
 * where \a buf points to where the message is stored. \e PIPE_NAME
 * can be NULL. It is passed verbatim to the receiver.
 *
 * To wait for a message from the driver:
 *
 * @code
 *  void *msg;
 *  ...
 *  size = wimaxll_msg_read(wmx, PIPE_NAME, &msg);
 * @endcode
 *
 * Note this call is synchronous and blocking, and won't timeout. You
 * can put it on a thread to emulate asynchrony (see \ref
 * multithreading), but still it is quite difficult to integrate it in
 * an event loop. Read on for mainloop integration options.
 *
 * In \e msg you get a pointer to a dynamically allocated (by \e
 * libwimaxll) area with the message payload. When the application is
 * done processing the message, call:
 *
 * @code
 *  wimaxll_msg_free(msg);
 * @endcode
 *
 * All functions return negative \a errno codes on error.
 *
 * To integrate message reception into a mainloop, \ref callbacks
 * "callbacks" and select() should be used. The file descriptor
 * associated to the default \e message \e pipe can be obtained with
 * wimaxll_recv_fd(). When there is activity on the file descriptor,
 * wimaxll_recv() should be called:
 *
 * \code
 * wimax_recv(wmx);
 * \endcode
 *
 * this will, as explained in \ref receiving, for each received
 * notification, execute its callback.
 *
 * The callback for reception of messages from the WiMAX kernel stack
 * can be set with wimaxll_set_cb_msg_to_user()). For detailed
 * information on the message reception callback, see the definition
 * of \ref wimaxll_msg_to_user_cb_f.
 */
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <linux/types.h>
#include <netlink/msg.h>
#include <netlink/genl/genl.h>
#include <wimaxll.h>
#include "internal.h"
#define D_LOCAL 0
#include "debug.h"



/**
 * WIMAX_GNL_MSG_FROM_USER: policy specification
 *
 * \ingroup the_messaging_interface
 * \internal
 *
 * Authoritative reference for this is at the kernel code,
 * drivers/net/wimax/op-msg.c.
 */
static
struct nla_policy wimaxll_gnl_msg_from_user_policy[WIMAX_GNL_ATTR_MAX + 1] = {
	[WIMAX_GNL_MSG_DATA] = {
		.type = NLA_UNSPEC,
	},
	[WIMAX_GNL_MSG_IFIDX] = {
		.type = NLA_U32,
	},
	[WIMAX_GNL_MSG_PIPE_NAME] = {
		.type = NLA_STRING,
	},
};


/**
 * Callback to process an WIMAX_GNL_OP_MSG_TO_USER from the kernel
 *
 * \internal
 * \ingroup the_messaging_interface
 *
 * \param wmx WiMAX device handle
 * \param mch Pointer to \c struct wimaxll_mc_handle
 * \param msg Pointer to netlink message
 * \return \c enum nl_cb_action
 *
 * wimaxll_recv() calls libnl's nl_recvmsgs() to receive messages;
 * when a valid message is received, wimax_gnl__cb() that selects a
 * callback to run for each type of message and it will call this
 * function to actually do it. If no message handling callback is set,
 * this is not called.
 *
 * This "netlink" callback will just de-marshall the arguments and
 * call the callback set by the user with wimaxll_set_cb_msg_to_user().
 */
int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *wmx,
				   struct nl_msg *msg)
{
	size_t size;
	ssize_t result;
	struct nlmsghdr *nl_hdr;
	struct genlmsghdr *gnl_hdr;
	struct nlattr *tb[WIMAX_GNL_ATTR_MAX+1];
	struct wimaxll_gnl_cb_context *ctx = wmx->msg_to_user_context;
	const char *pipe_name;
	void *data;

	d_fnstart(7, wmx, "(wmx %p msg %p)\n", wmx, msg);
	nl_hdr = nlmsg_hdr(msg);
	gnl_hdr = nlmsg_data(nl_hdr);

	assert(gnl_hdr->cmd == WIMAX_GNL_OP_MSG_TO_USER);

	/* Parse the attributes */
	result = genlmsg_parse(nl_hdr, 0, tb, WIMAX_GNL_ATTR_MAX,
			       wimaxll_gnl_msg_from_user_policy);
	if (result < 0) {
		wimaxll_msg(wmx, "E: %s: genlmsg_parse() failed: %d\n",
			  __func__, result);
		wimaxll_cb_maybe_set_result(ctx, result);
		result = NL_SKIP;
		goto error_parse;
	}
	/* Find if the message is for the interface wmx represents */
	if (tb[WIMAX_GNL_MSG_IFIDX] == NULL) {
		wimaxll_msg(wmx, "E: %s: cannot find IFIDX attribute\n",
			    __func__);
		wimaxll_cb_maybe_set_result(ctx, -ENODEV);
		result = NL_SKIP;
		goto error_no_attrs;

	}
	if (wmx->ifidx != nla_get_u32(tb[WIMAX_GNL_MSG_IFIDX])) {
		result = NL_OK;
		goto error_not_for_us;
	}
	/* Extract marshalled arguments */
	if (tb[WIMAX_GNL_MSG_DATA] == NULL) {
		wimaxll_msg(wmx, "E: %s: cannot find MSG_DATA attribute\n",
			  __func__);
		wimaxll_cb_maybe_set_result(ctx, -ENXIO);
		result = NL_SKIP;<commit_msg>wimaxll_gnl_handle_message_to_user: return NL_SKIP on incorrect interface index<commit_after>/*
 * Linux WiMax
 * Messaging interface implementation
 *
 *
 * Copyright (C) 2007-2008 Intel Corporation. All rights reserved.
 * <NAME> <<EMAIL>>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * \defgroup the_messaging_interface The message interface
 *
 * This is a payload agnostic message interface for communication
 * between the WiMAX kernel drivers and user space applications.
 *
 * It writes messages (wimax_msg_write()) by sending them to the WiMAX
 * kernel stack, which passes it to the driver using the \e
 * wimax_dev->op_msg_from_user() call.
 *
 * To write messages to the driver:
 *
 * @code
 *  wimaxll_msg_write(wmx, PIPE_NAME, buf, buf_size);
 * @endcode
 *
 * where \a buf points to where the message is stored. \e PIPE_NAME
 * can be NULL. It is passed verbatim to the receiver.
 *
 * To wait for a message from the driver:
 *
 * @code
 *  void *msg;
 *  ...
 *  size = wimaxll_msg_read(wmx, PIPE_NAME, &msg);
 * @endcode
 *
 * Note this call is synchronous and blocking, and won't timeout. You
 * can put it on a thread to emulate asynchrony (see \ref
 * multithreading), but still it is quite difficult to integrate it in
 * an event loop. Read on for mainloop integration options.
 *
 * In \e msg you get a pointer to a dynamically allocated (by \e
 * libwimaxll) area with the message payload. When the application is
 * done processing the message, call:
 *
 * @code
 *  wimaxll_msg_free(msg);
 * @endcode
 *
 * All functions return negative \a errno codes on error.
 *
 * To integrate message reception into a mainloop, \ref callbacks
 * "callbacks" and select() should be used. The file descriptor
 * associated to the default \e message \e pipe can be obtained with
 * wimaxll_recv_fd(). When there is activity on the file descriptor,
 * wimaxll_recv() should be called:
 *
 * \code
 * wimax_recv(wmx);
 * \endcode
 *
 * this will, as explained in \ref receiving, for each received
 * notification, execute its callback.
 *
 * The callback for reception of messages from the WiMAX kernel stack
 * can be set with wimaxll_set_cb_msg_to_user()). For detailed
 * information on the message reception callback, see the definition
 * of \ref wimaxll_msg_to_user_cb_f.
 */
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <linux/types.h>
#include <netlink/msg.h>
#include <netlink/genl/genl.h>
#include <wimaxll.h>
#include "internal.h"
#define D_LOCAL 0
#include "debug.h"



/**
 * WIMAX_GNL_MSG_FROM_USER: policy specification
 *
 * \ingroup the_messaging_interface
 * \internal
 *
 * Authoritative reference for this is at the kernel code,
 * drivers/net/wimax/op-msg.c.
 */
static
struct nla_policy wimaxll_gnl_msg_from_user_policy[WIMAX_GNL_ATTR_MAX + 1] = {
	[WIMAX_GNL_MSG_DATA] = {
		.type = NLA_UNSPEC,
	},
	[WIMAX_GNL_MSG_IFIDX] = {
		.type = NLA_U32,
	},
	[WIMAX_GNL_MSG_PIPE_NAME] = {
		.type = NLA_STRING,
	},
};


/**
 * Callback to process an WIMAX_GNL_OP_MSG_TO_USER from the kernel
 *
 * \internal
 * \ingroup the_messaging_interface
 *
 * \param wmx WiMAX device handle
 * \param mch Pointer to \c struct wimaxll_mc_handle
 * \param msg Pointer to netlink message
 * \return \c enum nl_cb_action
 *
 * wimaxll_recv() calls libnl's nl_recvmsgs() to receive messages;
 * when a valid message is received, wimax_gnl__cb() that selects a
 * callback to run for each type of message and it will call this
 * function to actually do it. If no message handling callback is set,
 * this is not called.
 *
 * This "netlink" callback will just de-marshall the arguments and
 * call the callback set by the user with wimaxll_set_cb_msg_to_user().
 */
int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *wmx,
				   struct nl_msg *msg)
{
	size_t size;
	ssize_t result;
	struct nlmsghdr *nl_hdr;
	struct genlmsghdr *gnl_hdr;
	struct nlattr *tb[WIMAX_GNL_ATTR_MAX+1];
	struct wimaxll_gnl_cb_context *ctx = wmx->msg_to_user_context;
	const char *pipe_name;
	void *data;

	d_fnstart(7, wmx, "(wmx %p msg %p)\n", wmx, msg);
	nl_hdr = nlmsg_hdr(msg);
	gnl_hdr = nlmsg_data(nl_hdr);

	assert(gnl_hdr->cmd == WIMAX_GNL_OP_MSG_TO_USER);

	/* Parse the attributes */
	result = genlmsg_parse(nl_hdr, 0, tb, WIMAX_GNL_ATTR_MAX,
			       wimaxll_gnl_msg_from_user_policy);
	if (result < 0) {
		wimaxll_msg(wmx, "E: %s: genlmsg_parse() failed: %d\n",
			  __func__, result);
		wimaxll_cb_maybe_set_result(ctx, result);
		result = NL_SKIP;
		goto error_parse;
	}
	/* Find if the message is for the interface wmx represents */
	if (tb[WIMAX_GNL_MSG_IFIDX] == NULL) {
		wimaxll_msg(wmx, "E: %s: cannot find IFIDX attribute\n",
			    __func__);
		wimaxll_cb_maybe_set_result(ctx, -ENODEV);
		result = NL_SKIP;
		goto error_no_attrs;

	}
	if (wmx->ifidx != nla_get_u32(tb[WIMAX_GNL_MSG_IFIDX])) {
		result = NL_SKIP;
		goto error_no_attrs;
	}
	/* Extract marshalled arguments */
	if (tb[WIMAX_GNL_MSG_DATA] == NULL) {
		wimaxll_msg(wmx, "E: %s: cannot find MSG_DATA attribute\n",
			  __func__);
		wimaxll_cb_maybe_set_result(ctx, -ENXIO);
		result = NL_SKIP;
{'fraction_non_alphanumeric': 0.08774436090225564, 'fraction_numerical': 0.002706766917293233, 'mean_word_length': 4.067047619047619, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4761931', 'n_tokens_mistral': 4592, 'n_tokens_neox': 4382, 'n_words': 1559}