/*
 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
 * Copyright (c) 2017-2018 The strace developers.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
 */

#include "defs.h"
#include "netlink.h"
#include "netlink_sock_diag.h"
#include "nlattr.h"
#include "print_fields.h"

#include <linux/sock_diag.h>
#include <linux/netlink_diag.h>

#include "xlat/netlink_diag_attrs.h"
#include "xlat/netlink_diag_show.h"
#include "xlat/netlink_socket_flags.h"
#include "xlat/netlink_states.h"

DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_req)
{
	struct netlink_diag_req req = { .sdiag_family = family };
	const size_t offset = sizeof(req.sdiag_family);

	PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
	tprints(", ");
	if (len >= sizeof(req)) {
		if (!umoven_or_printaddr(tcp, addr + offset,
					 sizeof(req) - offset,
					 (char *) &req + offset)) {
			if (NDIAG_PROTO_ALL == req.sdiag_protocol)
				tprintf("%s=%s",
					"sdiag_protocol", "NDIAG_PROTO_ALL");
			else
				PRINT_FIELD_XVAL("", req, sdiag_protocol,
						 netlink_protocols,
						 "NETLINK_???");
			PRINT_FIELD_U(", ", req, ndiag_ino);
			PRINT_FIELD_FLAGS(", ", req, ndiag_show,
					  netlink_diag_show, "NDIAG_SHOW_???");
			PRINT_FIELD_COOKIE(", ", req, ndiag_cookie);
		}
	} else
		tprints("...");
	tprints("}");
}

static bool
print_group(struct tcb *const tcp,
	    void *const elem_buf,
	    const size_t elem_size,
	    void *const opaque_data)
{
	if (elem_size < sizeof(kernel_ulong_t))
		tprintf("%#0*x", (int) elem_size * 2 + 2,
			*(unsigned int *) elem_buf);
	else
		tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
			*(kernel_ulong_t *) elem_buf);

	return true;
}

static bool
decode_netlink_diag_groups(struct tcb *const tcp,
			   const kernel_ulong_t addr,
			   const unsigned int len,
			   const void *const opaque_data)
{
	kernel_ulong_t buf;
	const size_t nmemb = len / current_wordsize;

	if (!nmemb)
		return false;

	print_array(tcp, addr, nmemb, &buf, current_wordsize,
		    umoven_or_printaddr, print_group, 0);

	return true;
}

static bool
decode_netlink_diag_ring(struct tcb *const tcp,
			 const kernel_ulong_t addr,
			 const unsigned int len,
			 const void *const opaque_data)
{
	struct netlink_diag_ring ndr;

	if (len < sizeof(ndr))
		return false;
	if (umove_or_printaddr(tcp, addr, &ndr))
		return true;

	PRINT_FIELD_U("{", ndr, ndr_block_size);
	PRINT_FIELD_U(", ", ndr, ndr_block_nr);
	PRINT_FIELD_U(", ", ndr, ndr_frame_size);
	PRINT_FIELD_U(", ", ndr, ndr_frame_nr);
	tprints("}");

	return true;
}

static bool
decode_netlink_diag_flags(struct tcb *const tcp,
			  const kernel_ulong_t addr,
			  const unsigned int len,
			  const void *const opaque_data)
{
	uint32_t flags;

	if (len < sizeof(flags))
		return false;
	if (umove_or_printaddr(tcp, addr, &flags))
		return true;

	printflags(netlink_socket_flags, flags, "NDIAG_FLAG_???");

	return true;
}

static const nla_decoder_t netlink_diag_msg_nla_decoders[] = {
	[NETLINK_DIAG_MEMINFO]	= decode_nla_meminfo,
	[NETLINK_DIAG_GROUPS]	= decode_netlink_diag_groups,
	[NETLINK_DIAG_RX_RING]	= decode_netlink_diag_ring,
	[NETLINK_DIAG_TX_RING]	= decode_netlink_diag_ring,
	[NETLINK_DIAG_FLAGS]	= decode_netlink_diag_flags
};

DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_msg)
{
	struct netlink_diag_msg msg = { .ndiag_family = family };
	size_t offset = sizeof(msg.ndiag_family);
	bool decode_nla = false;

	PRINT_FIELD_XVAL("{", msg, ndiag_family, addrfams, "AF_???");
	tprints(", ");
	if (len >= sizeof(msg)) {
		if (!umoven_or_printaddr(tcp, addr + offset,
					 sizeof(msg) - offset,
					 (char *) &msg + offset)) {
			PRINT_FIELD_XVAL("", msg, ndiag_type,
					 socktypes, "SOCK_???");
			PRINT_FIELD_XVAL(", ", msg, ndiag_protocol,
					 netlink_protocols, "NETLINK_???");
			PRINT_FIELD_XVAL(", ", msg, ndiag_state,
					 netlink_states, "NETLINK_???");
			PRINT_FIELD_U(", ", msg, ndiag_portid);
			PRINT_FIELD_U(", ", msg, ndiag_dst_portid);
			PRINT_FIELD_U(", ", msg, ndiag_dst_group);
			PRINT_FIELD_U(", ", msg, ndiag_ino);
			PRINT_FIELD_COOKIE(", ", msg, ndiag_cookie);
			decode_nla = true;
		}
	} else
		tprints("...");
	tprints("}");

	offset = NLMSG_ALIGN(sizeof(msg));
	if (decode_nla && len > offset) {
		tprints(", ");
		decode_nlattr(tcp, addr + offset, len - offset,
			      netlink_diag_attrs, "NETLINK_DIAG_???",
			      netlink_diag_msg_nla_decoders,
			      ARRAY_SIZE(netlink_diag_msg_nla_decoders), NULL);
	}
}
