Blame lib/ipmi_lanp6.c

Packit d14fb6
/*
Packit d14fb6
 * Copyright (c) 2016 Pentair Technical Products. All right reserved
Packit d14fb6
 *
Packit d14fb6
 * Redistribution and use in source and binary forms, with or without
Packit d14fb6
 * modification, are permitted provided that the following conditions
Packit d14fb6
 * are met:
Packit d14fb6
 *
Packit d14fb6
 * Redistribution of source code must retain the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer.
Packit d14fb6
 *
Packit d14fb6
 * Redistribution in binary form must reproduce the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer in the
Packit d14fb6
 * documentation and/or other materials provided with the distribution.
Packit d14fb6
 *
Packit d14fb6
 * Neither the name of Pentair Technical Products or the names of
Packit d14fb6
 * contributors may be used to endorse or promote products derived
Packit d14fb6
 * from this software without specific prior written permission.
Packit d14fb6
 *
Packit d14fb6
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit d14fb6
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit d14fb6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
Packit d14fb6
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
Packit d14fb6
 * PENTAIR TECHNICAL SOLUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit d14fb6
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
Packit d14fb6
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Packit d14fb6
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit d14fb6
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit d14fb6
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
Packit d14fb6
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit d14fb6
 * POSSIBILITY OF SUCH DAMAGE.
Packit d14fb6
 */
Packit d14fb6
Packit d14fb6
#include <ipmitool/helper.h>
Packit d14fb6
#include <ipmitool/ipmi_cc.h>
Packit d14fb6
#include <ipmitool/ipmi_cfgp.h>
Packit d14fb6
#include <ipmitool/ipmi_lanp.h>
Packit d14fb6
#include <ipmitool/ipmi_lanp6.h>
Packit d14fb6
#include <ipmitool/log.h>
Packit d14fb6
Packit d14fb6
#include <errno.h>
Packit d14fb6
#include <stdio.h>
Packit d14fb6
#include <string.h>
Packit d14fb6
#include <arpa/inet.h>
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * LAN6 command values.
Packit d14fb6
 */
Packit d14fb6
enum {
Packit d14fb6
	LANP_CMD_SAVE,
Packit d14fb6
	LANP_CMD_SET,
Packit d14fb6
	LANP_CMD_PRINT,
Packit d14fb6
	LANP_CMD_LOCK,
Packit d14fb6
	LANP_CMD_COMMIT,
Packit d14fb6
	LANP_CMD_DISCARD,
Packit d14fb6
	LANP_CMD_HELP,
Packit d14fb6
	LANP_CMD_ANY = 0xFF
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Generic LAN configuration parameters.
Packit d14fb6
 */
Packit d14fb6
const struct ipmi_lanp generic_lanp6[] = {
Packit d14fb6
	{ 0,	"Set In Progress", 1 },
Packit d14fb6
	{ 50,	"IPv6/IPv4 Support", 1 },
Packit d14fb6
	{ 51,	"IPv6/IPv4 Addressing Enables", 1 },
Packit d14fb6
	{ 52,	"IPv6 Header Traffic Class", 1 },
Packit d14fb6
	{ 53,	"IPv6 Header Static Hop Limit", 1 },
Packit d14fb6
	{ 54,	"IPv6 Header Flow Label", 3 },
Packit d14fb6
	{ 55,	"IPv6 Status", 3 },
Packit d14fb6
	{ 56,	"IPv6 Static Address", 20 },
Packit d14fb6
	{ 57,	"IPv6 DHCPv6 Static DUID Storage Length", 1 },
Packit d14fb6
	{ 58,	"IPv6 DHCPv6 Static DUID", 18 },
Packit d14fb6
	{ 59,	"IPv6 Dynamic Address", 20 },
Packit d14fb6
	{ 60,	"IPv6 DHCPv6 Dynamic DUID Storage Length", 1 },
Packit d14fb6
	{ 61,	"IPv6 DHCPv6 Dynamic DUID", 18 },
Packit d14fb6
	{ 62,	"IPv6 DHCPv6 Timing Configuration Support", 1 },
Packit d14fb6
	{ 63,	"IPv6 DHCPv6 Timing Configuration", 18 },
Packit d14fb6
	{ 64,	"IPv6 Router Address Configuration Control", 1 },
Packit d14fb6
	{ 65,	"IPv6 Static Router 1 IP Address", 16 },
Packit d14fb6
	{ 66,	"IPv6 Static Router 1 MAC Address", 6 },
Packit d14fb6
	{ 67,	"IPv6 Static Router 1 Prefix Length", 1 },
Packit d14fb6
	{ 68,	"IPv6 Static Router 1 Prefix Value", 16 },
Packit d14fb6
	{ 69,	"IPv6 Static Router 2 IP Address", 16 },
Packit d14fb6
	{ 70,	"IPv6 Static Router 2 MAC Address", 6 },
Packit d14fb6
	{ 71,	"IPv6 Static Router 2 Prefix Length", 1 },
Packit d14fb6
	{ 72,	"IPv6 Static Router 2 Prefix Value", 16 },
Packit d14fb6
	{ 73,	"IPv6 Number of Dynamic Router Info Sets", 1 },
Packit d14fb6
	{ 74,	"IPv6 Dynamic Router Info IP Address", 17 },
Packit d14fb6
	{ 75,	"IPv6 Dynamic Router Info MAC Address", 7 },
Packit d14fb6
	{ 76,	"IPv6 Dynamic Router Info Prefix Length", 2 },
Packit d14fb6
	{ 77,	"IPv6 Dynamic Router Info Prefix Value", 17 },
Packit d14fb6
	{ 78,	"IPv6 Dynamic Router Received Hop Limit", 1 },
Packit d14fb6
	{ 79,	"IPv6 ND/SLAAC Timing Configuration Support", 1 },
Packit d14fb6
	{ 80,	"IPv6 ND/SLAAC Timing Configuration", 18 },
Packit d14fb6
	{ 0,	NULL, 0 }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Set/Get LAN Configuration Parameters
Packit d14fb6
 * command-specific completion codes.
Packit d14fb6
 */
Packit d14fb6
const struct valstr lanp_cc_vals[] = {
Packit d14fb6
	{ 0x80, "Parameter not supported" },
Packit d14fb6
	{ 0x81, "Set already in progress" },
Packit d14fb6
	{ 0x82, "Parameter is read-only" },
Packit d14fb6
	{ 0x83, "Write-only parameter" },
Packit d14fb6
	{ 0x00, NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * IPv6/IPv4 Addressing Enables.
Packit d14fb6
 */
Packit d14fb6
const struct valstr ip6_enable_vals[] = {
Packit d14fb6
	{ 0, "ipv4" },
Packit d14fb6
	{ 1, "ipv6" },
Packit d14fb6
	{ 2, "both" },
Packit d14fb6
	{ 0xFF, NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Enable/Disable a static address.
Packit d14fb6
 */
Packit d14fb6
const struct valstr ip6_addr_enable_vals[] = {
Packit d14fb6
	{ 0x00, "disable" },
Packit d14fb6
	{ 0x80, "enable" },
Packit d14fb6
	{ 0xFF, NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * IPv6 address source values.
Packit d14fb6
 */
Packit d14fb6
const struct valstr ip6_addr_sources[] = {
Packit d14fb6
	{ 0, "static" },
Packit d14fb6
	{ 1, "SLAAC" },
Packit d14fb6
	{ 2, "DHCPv6" },
Packit d14fb6
	{ 0, NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * IPv6 address status values.
Packit d14fb6
 */
Packit d14fb6
const struct valstr ip6_addr_statuses[] = {
Packit d14fb6
	{ 0, "active" },
Packit d14fb6
	{ 1, "disabled" },
Packit d14fb6
	{ 2, "pending" },
Packit d14fb6
	{ 3, "failed" },
Packit d14fb6
	{ 4, "deprecated" },
Packit d14fb6
	{ 5, "invalid" },
Packit d14fb6
	{ 0xFF, NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * DHCPv6 DUID type values.
Packit d14fb6
 */
Packit d14fb6
const struct valstr ip6_duid_types[] = {
Packit d14fb6
	{ 0, "unknown" },
Packit d14fb6
	{ 1, "DUID-LLT" },
Packit d14fb6
	{ 2, "DUID-EN" },
Packit d14fb6
	{ 3, "DUID-LL" },
Packit d14fb6
	{ 0xFF, NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Timing Configuration support values.
Packit d14fb6
 */
Packit d14fb6
const struct valstr ip6_cfg_sup_vals[] = {
Packit d14fb6
	{ 0, "not supported" },
Packit d14fb6
	{ 1, "global" },
Packit d14fb6
	{ 2, "per interface" },
Packit d14fb6
	{ 0xFF, NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Router Address Configuration Control values.
Packit d14fb6
 */
Packit d14fb6
const struct valstr ip6_rtr_configs[] = {
Packit d14fb6
	{ 1, "static" },
Packit d14fb6
	{ 2, "dynamic" },
Packit d14fb6
	{ 3, "both" },
Packit d14fb6
	{ 0xFF, NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
Packit d14fb6
const struct valstr ip6_command_vals[] = {
Packit d14fb6
	{ LANP_CMD_SET,		"set" },
Packit d14fb6
	{ LANP_CMD_SAVE,	"save" },
Packit d14fb6
	{ LANP_CMD_PRINT,	"print" },
Packit d14fb6
	{ LANP_CMD_LOCK,	"lock" },
Packit d14fb6
	{ LANP_CMD_COMMIT,	"commit" },
Packit d14fb6
	{ LANP_CMD_DISCARD,	"discard" },
Packit d14fb6
	{ LANP_CMD_HELP,	"help" },
Packit d14fb6
	{ LANP_CMD_ANY,		NULL }
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
static const struct ipmi_cfgp lan_cfgp[] = {
Packit d14fb6
	{ .name = "support", .format = NULL, .size = 1,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_SUPPORT
Packit d14fb6
	},
Packit d14fb6
	{ .name = "enables", .format = "{ipv4|ipv6|both}", .size = 1,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_ENABLES
Packit d14fb6
	},
Packit d14fb6
	{ .name = "traffic_class", .format = "<value>", .size = 1,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_TRAFFIC_CLASS
Packit d14fb6
	},
Packit d14fb6
	{ .name = "static_hops", .format = "<value>", .size = 1,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_STATIC_HOPS
Packit d14fb6
	},
Packit d14fb6
	{ .name = "flow_label", .format = "<value>", .size = 3,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_FLOW_LABEL
Packit d14fb6
	},
Packit d14fb6
	{ .name = "status", .format = NULL, .size = 3,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_STATUS
Packit d14fb6
	},
Packit d14fb6
	{ .name = "static_addr",
Packit d14fb6
		.format = "{enable|disable} <addr> <pfx_len>", .size = 20,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_STATIC_ADDR
Packit d14fb6
	},
Packit d14fb6
	{ .name = "static_duid_stg", .format = NULL, .size = 1,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_STATIC_DUID_STG
Packit d14fb6
	},
Packit d14fb6
	{ .name = "static_duid", .format = "<data>", .size = 18,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 1, .first_set = 0, .has_blocks = 1, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_STATIC_DUID
Packit d14fb6
	},
Packit d14fb6
	{ .name = "dynamic_addr", .format = NULL, .size = 20,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_DYNAMIC_ADDR
Packit d14fb6
	},
Packit d14fb6
	{ .name = "dynamic_duid_stg", .format = NULL, .size = 1,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_DYNAMIC_DUID_STG
Packit d14fb6
	},
Packit d14fb6
	{ .name = "dynamic_duid", .format = "<data>", .size = 18,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 1, .first_set = 0, .has_blocks = 1, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_DYNAMIC_DUID
Packit d14fb6
	},
Packit d14fb6
	{ .name = "dhcp6_cfg_sup", .format = NULL, .size = 1,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_DHCP6_CFG_SUP
Packit d14fb6
	},
Packit d14fb6
	{ .name = "dhcp6_cfg", .format = "<data> <data>", .size = 36,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_DHCP6_CFG
Packit d14fb6
	},
Packit d14fb6
	{ .name = "rtr_cfg", .format = "{static|dynamic|both}", .size = 1,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_ROUTER_CFG
Packit d14fb6
	},
Packit d14fb6
	{ .name = "static_rtr",
Packit d14fb6
		.format = "<addr> <macaddr> <prefix> <prefix_len>", .size = 43,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 1, .first_set = 1, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_STATIC_RTR1_ADDR
Packit d14fb6
	},
Packit d14fb6
	{ .name = "num_dynamic_rtrs", .format = NULL, .size = 1,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_NUM_DYNAMIC_RTRS
Packit d14fb6
	},
Packit d14fb6
	{ .name = "dynamic_rtr", .format = NULL, .size = 43,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_DYNAMIC_RTR_ADDR
Packit d14fb6
	},
Packit d14fb6
	{ .name = "dynamic_hops", .format = NULL, .size = 1,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_DYNAMIC_HOPS
Packit d14fb6
	},
Packit d14fb6
	{ .name = "ndslaac_cfg_sup", .format = NULL, .size = 1,
Packit d14fb6
		.access = CFGP_RDONLY,
Packit d14fb6
		.is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_NDSLAAC_CFG_SUP
Packit d14fb6
	},
Packit d14fb6
	{ .name = "ndslaac_cfg", .format = "<data>", .size = 18,
Packit d14fb6
		.access = CFGP_RDWR,
Packit d14fb6
		.is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
Packit d14fb6
		.specific = IPMI_LANP_IP6_NDSLAAC_CFG
Packit d14fb6
	}
Packit d14fb6
};
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Lookup LAN parameter descriptor by parameter selector.
Packit d14fb6
 */
Packit d14fb6
const struct ipmi_lanp *
Packit d14fb6
lookup_lanp(int param)
Packit d14fb6
{
Packit d14fb6
	const struct ipmi_lanp *p = generic_lanp6;
Packit d14fb6
Packit d14fb6
	while (p->name) {
Packit d14fb6
		if (p->selector == param) {
Packit d14fb6
			return p;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		p++;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return NULL;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Print request error.
Packit d14fb6
 */
Packit d14fb6
static int
Packit d14fb6
ipmi_lanp_err(const struct ipmi_rs *rsp, const struct ipmi_lanp *p,
Packit d14fb6
		const char *action, int quiet)
Packit d14fb6
{
Packit d14fb6
	const char *reason;
Packit d14fb6
	char cc_msg[10];
Packit d14fb6
	int log_level = LOG_ERR;
Packit d14fb6
	int err;
Packit d14fb6
Packit d14fb6
	if (rsp == NULL) {
Packit d14fb6
		reason = "No response";
Packit d14fb6
		err = -1;
Packit d14fb6
	} else {
Packit d14fb6
		err = rsp->ccode;
Packit d14fb6
		if (quiet == 1
Packit d14fb6
			&& (rsp->ccode == 0x80
Packit d14fb6
			|| rsp->ccode == IPMI_CC_PARAM_OUT_OF_RANGE
Packit d14fb6
			|| rsp->ccode == IPMI_CC_INV_DATA_FIELD_IN_REQ)) {
Packit d14fb6
			/* be quiet */
Packit d14fb6
			return err;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (rsp->ccode >= 0xC0) {
Packit d14fb6
			/* browse for generic completion codes */
Packit d14fb6
			reason = val2str(rsp->ccode, completion_code_vals);
Packit d14fb6
		} else {
Packit d14fb6
			/* browse for command-specific completion codes first */
Packit d14fb6
			reason = val2str(rsp->ccode, lanp_cc_vals);
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (reason == NULL) {
Packit d14fb6
			/* print completion code value */
Packit d14fb6
			snprintf(cc_msg, sizeof(cc_msg), "CC=%02x", rsp->ccode);
Packit d14fb6
			reason = cc_msg;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (rsp->ccode == IPMI_CC_OK) {
Packit d14fb6
			log_level = LOG_DEBUG;
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	lprintf(log_level, "Failed to %s %s: %s", action, p->name, reason);
Packit d14fb6
	return err;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Get dynamic OEM LAN configuration parameter from BMC.
Packit d14fb6
 * Dynamic in this context is when the base for OEM LAN parameters
Packit d14fb6
 * is not known apriori.
Packit d14fb6
 */
Packit d14fb6
int
Packit d14fb6
ipmi_get_dynamic_oem_lanp(void *priv, const struct ipmi_lanp *param,
Packit d14fb6
		int oem_base, int set_selector, int block_selector,
Packit d14fb6
		void *data, int quiet)
Packit d14fb6
{
Packit d14fb6
	struct ipmi_lanp_priv *lp = priv;
Packit d14fb6
	struct ipmi_rs *rsp;
Packit d14fb6
	struct ipmi_rq req;
Packit d14fb6
	uint8_t req_data[4];
Packit d14fb6
	int length;
Packit d14fb6
Packit d14fb6
	if (!priv || !param || !data) {
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
	req_data[0] = lp->channel;
Packit d14fb6
	req_data[1] = param->selector + oem_base;
Packit d14fb6
	req_data[2] = set_selector;
Packit d14fb6
	req_data[3] = block_selector;
Packit d14fb6
Packit d14fb6
	memset(&req, 0, sizeof(req));
Packit d14fb6
	req.msg.netfn    = IPMI_NETFN_TRANSPORT;
Packit d14fb6
	req.msg.cmd      = 2;
Packit d14fb6
	req.msg.data     = req_data;
Packit d14fb6
	req.msg.data_len = 4;
Packit d14fb6
Packit d14fb6
	lprintf(LOG_INFO, "Getting parameter '%s' set %d block %d",
Packit d14fb6
		param->name, set_selector, block_selector);
Packit d14fb6
Packit d14fb6
	rsp = lp->intf->sendrecv(lp->intf, &req;;
Packit d14fb6
	if (rsp == NULL || rsp->ccode) {
Packit d14fb6
		return ipmi_lanp_err(rsp, param, "get", quiet);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	memset(data, 0, param->size);
Packit d14fb6
Packit d14fb6
	if (rsp->data_len - 1 < param->size) {
Packit d14fb6
		length = rsp->data_len - 1;
Packit d14fb6
	} else {
Packit d14fb6
		length = param->size;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	if (length) {
Packit d14fb6
		memcpy(data, rsp->data + 1, length);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Get generic LAN configuration parameter.
Packit d14fb6
 */
Packit d14fb6
int
Packit d14fb6
ipmi_get_lanp(void *priv, int param_selector, int set_selector,
Packit d14fb6
		int block_selector, void *data, int quiet)
Packit d14fb6
{
Packit d14fb6
	return ipmi_get_dynamic_oem_lanp(priv, lookup_lanp(param_selector), 0,
Packit d14fb6
			set_selector, block_selector, data, quiet);
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Set dynamic OEM LAN configuration parameter to BMC.
Packit d14fb6
 * Dynamic in this context is when the base for OEM LAN parameters
Packit d14fb6
 * is not known apriori.
Packit d14fb6
 */
Packit d14fb6
int
Packit d14fb6
ipmi_set_dynamic_oem_lanp(void *priv, const struct ipmi_lanp *param,
Packit d14fb6
		int base, const void *data)
Packit d14fb6
{
Packit d14fb6
	struct ipmi_lanp_priv *lp = priv;
Packit d14fb6
	struct ipmi_rs *rsp;
Packit d14fb6
	struct ipmi_rq req;
Packit d14fb6
	uint8_t req_data[32];
Packit d14fb6
Packit d14fb6
	if (!priv || !param || !data) {
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
	/* fill the first two bytes */
Packit d14fb6
	req_data[0] = lp->channel;
Packit d14fb6
	req_data[1] = param->selector + base;
Packit d14fb6
Packit d14fb6
	/* fill the rest data */
Packit d14fb6
	memcpy(&req_data[2], data, param->size);
Packit d14fb6
Packit d14fb6
	/* fill request */
Packit d14fb6
	memset(&req, 0, sizeof(req));
Packit d14fb6
	req.msg.netfn    = IPMI_NETFN_TRANSPORT;
Packit d14fb6
	req.msg.cmd      = 1;
Packit d14fb6
	req.msg.data     = req_data;
Packit d14fb6
	req.msg.data_len = param->size + 2;
Packit d14fb6
Packit d14fb6
	lprintf(LOG_INFO, "Setting parameter '%s'", param->name);
Packit d14fb6
Packit d14fb6
	rsp = lp->intf->sendrecv(lp->intf, &req;;
Packit d14fb6
	if (rsp == NULL || rsp->ccode) {
Packit d14fb6
		return ipmi_lanp_err(rsp, param, "set", 0);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Set generic LAN configuration parameter.
Packit d14fb6
 */
Packit d14fb6
int
Packit d14fb6
ipmi_set_lanp(void *priv, int param_selector, const void *data)
Packit d14fb6
{
Packit d14fb6
	return ipmi_set_dynamic_oem_lanp(priv, lookup_lanp(param_selector),
Packit d14fb6
		0, data);
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_parse_cfgp(const struct ipmi_cfgp *p, int set, int block,
Packit d14fb6
		int argc, const char *argv[], unsigned char *data)
Packit d14fb6
{
Packit d14fb6
	unsigned int v;
Packit d14fb6
Packit d14fb6
	if (argc == 0) {
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	switch(p->specific) {
Packit d14fb6
	case IPMI_LANP_IP6_ENABLES:
Packit d14fb6
		data[0] = str2val(argv[0], ip6_enable_vals);
Packit d14fb6
		if (data[0] == 0xFF) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_FLOW_LABEL:
Packit d14fb6
		if (str2uint(argv[0], &v)) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		data[0] = (v >> 16) & 0x0F;
Packit d14fb6
		data[1] = (v >> 8) & 0xFF;
Packit d14fb6
		data[2] = v & 0xFF;
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATUS:
Packit d14fb6
		if (argc < 3) {
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (str2uchar(argv[0], &data[0])
Packit d14fb6
				|| str2uchar(argv[1], &data[1])
Packit d14fb6
				|| str2uchar(argv[2], &data[2])) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_ADDR:
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_ADDR:
Packit d14fb6
		if (argc < 3) {
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		data[0] = set;
Packit d14fb6
		if (p->specific == IPMI_LANP_IP6_STATIC_ADDR) {
Packit d14fb6
			data[1] = str2val(argv[0], ip6_addr_enable_vals);
Packit d14fb6
		} else {
Packit d14fb6
			data[1] = str2val(argv[0], ip6_addr_sources);
Packit d14fb6
		}
Packit d14fb6
		if (data[1] == 0xFF) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (inet_pton(AF_INET6, argv[1], &data[2]) != 1) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (str2uchar(argv[2], &data[18])) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (argc >= 4) {
Packit d14fb6
			data[19] = str2val(argv[3], ip6_addr_statuses);
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_DUID:
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_DUID:
Packit d14fb6
	case IPMI_LANP_IP6_NDSLAAC_CFG:
Packit d14fb6
		data[0] = set;
Packit d14fb6
		data[1] = block;
Packit d14fb6
		if (ipmi_parse_hex(argv[0], &data[2], 16) < 0) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_DHCP6_CFG:
Packit d14fb6
		data[0] = set;
Packit d14fb6
		data[1] = 0;
Packit d14fb6
		data[18] = set;
Packit d14fb6
		data[19] = 1;
Packit d14fb6
Packit d14fb6
		if (ipmi_parse_hex(argv[0], &data[2], 16) < 0
Packit d14fb6
			|| (argc > 1 &&
Packit d14fb6
			    ipmi_parse_hex(argv[1], &data[20], 6) < 0)) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_ROUTER_CFG:
Packit d14fb6
		data[0] = str2val(argv[0], ip6_rtr_configs);
Packit d14fb6
		if (data[0] == 0xFF) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
Packit d14fb6
		if (set > 2) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
Packit d14fb6
		if (argc < 4) {
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		/*
Packit d14fb6
		 * Data is stored in the following way:
Packit d14fb6
		 *  0: <set> <addr1>...<addr16>
Packit d14fb6
		 * 17: <set> <mac1>...<mac6>
Packit d14fb6
		 * 24: <set> <pfxlen>
Packit d14fb6
		 * 26: <set> <pfx1>...<pfx16>
Packit d14fb6
		 */
Packit d14fb6
		data[0] = data[17] = data[24] = data[26] = set;
Packit d14fb6
Packit d14fb6
		if (inet_pton(AF_INET6, argv[0], &data[1]) != 1
Packit d14fb6
				|| str2mac(argv[1], &data[18])
Packit d14fb6
				|| inet_pton(AF_INET6, argv[2], &data[27]) != 1
Packit d14fb6
				|| str2uchar(argv[3], &data[25])) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	default:
Packit d14fb6
		if (str2uchar(argv[0], &data[0])) {
Packit d14fb6
			lprintf(LOG_ERR, "invalid value");
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_set_cfgp(void *priv, const struct ipmi_cfgp *p, const unsigned char *data)
Packit d14fb6
{
Packit d14fb6
	int ret;
Packit d14fb6
	int param = p->specific;
Packit d14fb6
	int off = 0;
Packit d14fb6
Packit d14fb6
	switch(param) {
Packit d14fb6
	case IPMI_LANP_IP6_DHCP6_CFG:
Packit d14fb6
		ret = ipmi_set_lanp(priv, param, &data[0]);
Packit d14fb6
		if (ret == 0) {
Packit d14fb6
			ret = ipmi_set_lanp(priv, param, &data[18]);
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
Packit d14fb6
		if (data[0] == 2) {
Packit d14fb6
			param = IPMI_LANP_IP6_STATIC_RTR2_ADDR;
Packit d14fb6
		}
Packit d14fb6
		off = 1;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
Packit d14fb6
		ret = ipmi_set_lanp(priv, param, &data[0 + off]);
Packit d14fb6
		if (ret == 0) {
Packit d14fb6
			ret = ipmi_set_lanp(priv, param + 1, &data[17 + off]);
Packit d14fb6
		}
Packit d14fb6
		if (ret == 0) {
Packit d14fb6
			ret = ipmi_set_lanp(priv, param + 2, &data[24 + off]);
Packit d14fb6
		}
Packit d14fb6
		if (ret == 0) {
Packit d14fb6
			ret = ipmi_set_lanp(priv, param + 3, &data[26 + off]);
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
Packit d14fb6
	default:
Packit d14fb6
		ret = ipmi_set_lanp(priv, param, data);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return ret;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_get_cfgp(void *priv, const struct ipmi_cfgp *p,
Packit d14fb6
		int set, int block,  unsigned char *data, int quiet)
Packit d14fb6
{
Packit d14fb6
	int ret;
Packit d14fb6
	int param = p->specific;
Packit d14fb6
	int off = 0;
Packit d14fb6
Packit d14fb6
	switch(param) {
Packit d14fb6
	case IPMI_LANP_IP6_DHCP6_CFG:
Packit d14fb6
		ret = ipmi_get_lanp(priv, param, set, 0, &data[0], quiet);
Packit d14fb6
		if (ret == 0) {
Packit d14fb6
			ret = ipmi_get_lanp(priv, param, set,
Packit d14fb6
				1, &data[18], quiet);
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
Packit d14fb6
		if (set > 2) {
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (set == 2) {
Packit d14fb6
			param = IPMI_LANP_IP6_STATIC_RTR2_ADDR;
Packit d14fb6
		}
Packit d14fb6
		set = 0;
Packit d14fb6
		off = 1;
Packit d14fb6
		data[0] = data[17] = data[24] = data[26] = set;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
Packit d14fb6
		ret = ipmi_get_lanp(priv, param, set, block,
Packit d14fb6
			&data[0 + off], quiet);
Packit d14fb6
		if (ret == 0) {
Packit d14fb6
			ret = ipmi_get_lanp(priv, param + 1, set, block,
Packit d14fb6
				&data[17 + off], 0);
Packit d14fb6
		}
Packit d14fb6
		if (ret == 0) {
Packit d14fb6
			ret = ipmi_get_lanp(priv, param + 2, set, block,
Packit d14fb6
				&data[24 + off], 0);
Packit d14fb6
		}
Packit d14fb6
		if (ret == 0) {
Packit d14fb6
			ret = ipmi_get_lanp(priv, param + 3, set, block,
Packit d14fb6
				&data[26 + off], 0);
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	default:
Packit d14fb6
		ret = ipmi_get_lanp(priv, param, set, block, data, quiet);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return ret;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_save_cfgp(const struct ipmi_cfgp *p, const unsigned char *data, FILE *file)
Packit d14fb6
{
Packit d14fb6
	char addr[INET6_ADDRSTRLEN];
Packit d14fb6
	char pfx[INET6_ADDRSTRLEN];
Packit d14fb6
	const char *src;
Packit d14fb6
Packit d14fb6
	switch(p->specific) {
Packit d14fb6
	case IPMI_LANP_IP6_ENABLES:
Packit d14fb6
		fputs(val2str(data[0], ip6_enable_vals), file);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_FLOW_LABEL:
Packit d14fb6
		fprintf(file, "0x%xd", (data[0] << 16 ) | (data[1] << 8) | data[2]);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATUS:
Packit d14fb6
		fprintf(file, "%d %d %d", data[0], data[1], data[2]);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_ADDR:
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_ADDR:
Packit d14fb6
		if (p->specific == IPMI_LANP_IP6_STATIC_ADDR) {
Packit d14fb6
			src = val2str(data[1], ip6_addr_enable_vals);
Packit d14fb6
		} else {
Packit d14fb6
			src = val2str(data[1], ip6_addr_sources);
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		fprintf(file, "%s %s %d %s", src,
Packit d14fb6
				inet_ntop(AF_INET6, &data[2], addr, sizeof(addr)),
Packit d14fb6
				data[18], val2str(data[19], ip6_addr_statuses));
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_DUID:
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_DUID:
Packit d14fb6
	case IPMI_LANP_IP6_NDSLAAC_CFG:
Packit d14fb6
		fprintf(file, "%s", buf2str(&data[2], 16));
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_DHCP6_CFG:
Packit d14fb6
		fprintf(file, "%s", buf2str(&data[2], 16));
Packit d14fb6
		fprintf(file, " %s", buf2str(&data[20], 6));
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_ROUTER_CFG:
Packit d14fb6
		fputs(val2str(data[0], ip6_rtr_configs), file);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
Packit d14fb6
		fprintf(file, "%s %s %s %d",
Packit d14fb6
				inet_ntop(AF_INET6, &data[1], addr, sizeof(addr)),
Packit d14fb6
				mac2str(&data[18]),
Packit d14fb6
				inet_ntop(AF_INET6, &data[27], pfx, sizeof(pfx)), data[25]);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	default:
Packit d14fb6
		fprintf(file, "%d", data[0]);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_print_cfgp(const struct ipmi_cfgp *p,
Packit d14fb6
		int set, int block, const unsigned char *data, FILE *file)
Packit d14fb6
{
Packit d14fb6
	char addr[INET6_ADDRSTRLEN];
Packit d14fb6
	char pfx[INET6_ADDRSTRLEN];
Packit d14fb6
	const char *pname;
Packit d14fb6
	const struct ipmi_lanp *lanp = lookup_lanp(p->specific);
Packit d14fb6
Packit d14fb6
	if (!lanp || !p || !file || !data || !lanp->name) {
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
	pname = lanp->name;
Packit d14fb6
Packit d14fb6
	switch(p->specific) {
Packit d14fb6
	case IPMI_LANP_IP6_SUPPORT:
Packit d14fb6
		fprintf(file, "%s:\n"
Packit d14fb6
				"    IPv6 only: %s\n"
Packit d14fb6
				"    IPv4 and IPv6: %s\n"
Packit d14fb6
				"    IPv6 Destination Addresses for LAN alerting: %s\n",
Packit d14fb6
				pname,
Packit d14fb6
				data[0] & 1 ? "yes" : "no",
Packit d14fb6
				data[0] & 2 ? "yes" : "no",
Packit d14fb6
				data[0] & 4 ? "yes" : "no");
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_ENABLES:
Packit d14fb6
		fprintf(file, "%s: %s\n",
Packit d14fb6
				pname, val2str(data[0], ip6_enable_vals));
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_FLOW_LABEL:
Packit d14fb6
		fprintf(file, "%s: %d\n",
Packit d14fb6
				pname, (data[0] << 16 ) | (data[1] << 8) | data[2]);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATUS:
Packit d14fb6
		fprintf(file, "%s:\n"
Packit d14fb6
				"    Static address max:  %d\n"
Packit d14fb6
				"    Dynamic address max: %d\n"
Packit d14fb6
				"    DHCPv6 support:      %s\n"
Packit d14fb6
				"    SLAAC support:       %s\n",
Packit d14fb6
				pname,
Packit d14fb6
				data[0], data[1],
Packit d14fb6
				(data[2] & 1) ? "yes" : "no",
Packit d14fb6
				(data[2] & 2) ? "yes" : "no");
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_ADDR:
Packit d14fb6
		fprintf(file, "%s %d:\n"
Packit d14fb6
				"    Enabled:        %s\n"
Packit d14fb6
				"    Address:        %s/%d\n"
Packit d14fb6
				"    Status:         %s\n",
Packit d14fb6
				pname, set,
Packit d14fb6
				(data[1] & 0x80) ? "yes" : "no",
Packit d14fb6
				inet_ntop(AF_INET6, &data[2], addr, sizeof(addr)),
Packit d14fb6
				data[18], val2str(data[19] & 0xF, ip6_addr_statuses));
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_ADDR:
Packit d14fb6
		fprintf(file, "%s %d:\n"
Packit d14fb6
				"    Source/Type:    %s\n"
Packit d14fb6
				"    Address:        %s/%d\n"
Packit d14fb6
				"    Status:         %s\n",
Packit d14fb6
				pname, set,
Packit d14fb6
				val2str(data[1] & 0xF, ip6_addr_sources),
Packit d14fb6
				inet_ntop(AF_INET6, &data[2], addr, sizeof(addr)),
Packit d14fb6
				data[18], val2str(data[19] & 0xF, ip6_addr_statuses));
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_DUID:
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_DUID:
Packit d14fb6
		if (block == 0) {
Packit d14fb6
			fprintf(file, "%s %d:\n"
Packit d14fb6
				"    Length:   %d\n"
Packit d14fb6
				"    Type:     %s\n",
Packit d14fb6
				pname, set, data[2],
Packit d14fb6
				val2str((data[3] << 8) + data[4], ip6_duid_types));
Packit d14fb6
		}
Packit d14fb6
		fprintf(file, "    %s\n", buf2str(&data[2], 16));
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_DHCP6_CFG_SUP:
Packit d14fb6
	case IPMI_LANP_IP6_NDSLAAC_CFG_SUP:
Packit d14fb6
		fprintf(file, "%s: %s\n",
Packit d14fb6
				pname, val2str(data[0], ip6_cfg_sup_vals));
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_DHCP6_CFG:
Packit d14fb6
		fprintf(file, "%s %d:\n", pname, set);
Packit d14fb6
Packit d14fb6
		fprintf(file,
Packit d14fb6
				"    SOL_MAX_DELAY:   %d\n"
Packit d14fb6
				"    SOL_TIMEOUT:     %d\n"
Packit d14fb6
				"    SOL_MAX_RT:      %d\n"
Packit d14fb6
				"    REQ_TIMEOUT:     %d\n"
Packit d14fb6
				"    REQ_MAX_RT:      %d\n"
Packit d14fb6
				"    REQ_MAX_RC:      %d\n"
Packit d14fb6
				"    CNF_MAX_DELAY:   %d\n"
Packit d14fb6
				"    CNF_TIMEOUT:     %d\n"
Packit d14fb6
				"    CNF_MAX_RT:      %d\n"
Packit d14fb6
				"    CNF_MAX_RD:      %d\n"
Packit d14fb6
				"    REN_TIMEOUT:     %d\n"
Packit d14fb6
				"    REN_MAX_RT:      %d\n"
Packit d14fb6
				"    REB_TIMEOUT:     %d\n"
Packit d14fb6
				"    REB_MAX_RT:      %d\n"
Packit d14fb6
				"    INF_MAX_DELAY:   %d\n"
Packit d14fb6
				"    INF_TIMEOUT:     %d\n"
Packit d14fb6
				"    INF_MAX_RT:      %d\n"
Packit d14fb6
				"    REL_TIMEOUT:     %d\n"
Packit d14fb6
				"    REL_MAX_RC:      %d\n"
Packit d14fb6
				"    DEC_TIMEOUT:     %d\n"
Packit d14fb6
				"    DEC_MAX_RC:      %d\n"
Packit d14fb6
				"    HOP_COUNT_LIMIT: %d\n",
Packit d14fb6
				data[2], data[3], data[4], data[5],
Packit d14fb6
				data[6], data[7], data[8], data[9],
Packit d14fb6
				data[10], data[11], data[12], data[13],
Packit d14fb6
				data[14], data[15], data[16], data[17],
Packit d14fb6
				data[20], data[21], data[22], data[23],
Packit d14fb6
				data[24], data[25]);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_ROUTER_CFG:
Packit d14fb6
		fprintf(file, "%s:\n"
Packit d14fb6
				"    Enable static router address:  %s\n"
Packit d14fb6
				"    Enable dynamic router address: %s\n",
Packit d14fb6
				pname,
Packit d14fb6
				(data[0] & 1) ? "yes" : "no",
Packit d14fb6
				(data[0] & 2) ? "yes" : "no");
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
Packit d14fb6
	case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
Packit d14fb6
		if (p->specific == IPMI_LANP_IP6_STATIC_RTR1_ADDR) {
Packit d14fb6
			pname = "IPv6 Static Router";
Packit d14fb6
		} else {
Packit d14fb6
			pname = "IPv6 Dynamic Router";
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		fprintf(file, "%s %d:\n"
Packit d14fb6
				"    Address: %s\n"
Packit d14fb6
				"    MAC:     %s\n"
Packit d14fb6
				"    Prefix:  %s/%d\n",
Packit d14fb6
				pname, set,
Packit d14fb6
				inet_ntop(AF_INET6, &data[1], addr, sizeof(addr)),
Packit d14fb6
				mac2str(&data[18]),
Packit d14fb6
				inet_ntop(AF_INET6, &data[27], pfx, sizeof(pfx)), data[25]);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case IPMI_LANP_IP6_NDSLAAC_CFG:
Packit d14fb6
		fprintf(file, "%s %d:\n"
Packit d14fb6
				"    MAX_RTR_SOLICITATION_DELAY: %d\n"
Packit d14fb6
				"    RTR_SOLICITATION_INTERVAL:  %d\n"
Packit d14fb6
				"    MAX_RTR_SOLICITATIONS:      %d\n"
Packit d14fb6
				"    DupAddrDetectTransmits:     %d\n"
Packit d14fb6
				"    MAX_MULTICAST_SOLICIT:      %d\n"
Packit d14fb6
				"    MAX_UNICAST_SOLICIT:        %d\n"
Packit d14fb6
				"    MAX_ANYCAST_DELAY_TIME:     %d\n"
Packit d14fb6
				"    MAX_NEIGHBOR_ADVERTISEMENT: %d\n"
Packit d14fb6
				"    REACHABLE_TIME:             %d\n"
Packit d14fb6
				"    RETRANS_TIMER:              %d\n"
Packit d14fb6
				"    DELAY_FIRST_PROBE_TIME:     %d\n"
Packit d14fb6
				"    MAX_RANDOM_FACTOR:          %d\n"
Packit d14fb6
				"    MIN_RANDOM_FACTOR:          %d\n",
Packit d14fb6
				pname, set,
Packit d14fb6
				data[2], data[3], data[4], data[5],
Packit d14fb6
				data[6], data[7], data[8], data[9],
Packit d14fb6
				data[10], data[11], data[12], data[13],
Packit d14fb6
				data[14]);
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	default:
Packit d14fb6
		fprintf(file, "%s: %d\n", pname, data[0]);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_ip6_cfgp(void *priv, const struct ipmi_cfgp *p,
Packit d14fb6
		const struct ipmi_cfgp_action *action, unsigned char *data)
Packit d14fb6
{
Packit d14fb6
	switch (action->type) {
Packit d14fb6
	case CFGP_PARSE:
Packit d14fb6
		return lanp_parse_cfgp(p, action->set, action->block,
Packit d14fb6
				action->argc, action->argv, data);
Packit d14fb6
Packit d14fb6
	case CFGP_GET:
Packit d14fb6
		return lanp_get_cfgp(priv, p, action->set, action->block,
Packit d14fb6
				data, action->quiet);
Packit d14fb6
Packit d14fb6
	case CFGP_SET:
Packit d14fb6
		return lanp_set_cfgp(priv, p, data);
Packit d14fb6
Packit d14fb6
	case CFGP_SAVE:
Packit d14fb6
		return lanp_save_cfgp(p, data, action->file);
Packit d14fb6
Packit d14fb6
	case CFGP_PRINT:
Packit d14fb6
		return lanp_print_cfgp(p, action->set, action->block,
Packit d14fb6
				data, action->file);
Packit d14fb6
Packit d14fb6
	default:
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static void lanp_print_usage(int cmd)
Packit d14fb6
{
Packit d14fb6
	if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_HELP) {
Packit d14fb6
		printf("  help [command]\n");
Packit d14fb6
	}
Packit d14fb6
	if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_SAVE) {
Packit d14fb6
		printf("  save <channel> [<parameter> [<set_sel> [<block_sel>]]]\n");
Packit d14fb6
	}
Packit d14fb6
	if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_SET) {
Packit d14fb6
		printf("  set <channel> [nolock] <parameter> [<set_sel> [<block_sel>]] <values...>\n");
Packit d14fb6
	}
Packit d14fb6
	if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_PRINT) {
Packit d14fb6
		printf("  print <channel> [<parameter> [<set_sel> [<block_sel>]]]\n");
Packit d14fb6
	}
Packit d14fb6
	if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_LOCK) {
Packit d14fb6
		printf("  lock <channel>\n");
Packit d14fb6
	}
Packit d14fb6
	if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_COMMIT) {
Packit d14fb6
		printf("  commit <channel>\n");
Packit d14fb6
	}
Packit d14fb6
	if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_DISCARD) {
Packit d14fb6
		printf("  discard <channel>\n");
Packit d14fb6
	}
Packit d14fb6
	if (cmd == LANP_CMD_SAVE
Packit d14fb6
		|| cmd == LANP_CMD_PRINT
Packit d14fb6
		|| cmd == LANP_CMD_SET) {
Packit d14fb6
		printf("\n   available parameters:\n");
Packit d14fb6
		/* 'save' shall use 'write' filter, since it outputs a block
Packit d14fb6
		 * of 'set's */
Packit d14fb6
		ipmi_cfgp_usage(lan_cfgp,
Packit d14fb6
			sizeof(lan_cfgp)/sizeof(lan_cfgp[0]),
Packit d14fb6
			cmd != LANP_CMD_PRINT);
Packit d14fb6
	}
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_lock(struct ipmi_lanp_priv *lp)
Packit d14fb6
{
Packit d14fb6
	unsigned char byte = 1;
Packit d14fb6
Packit d14fb6
	return ipmi_set_lanp(lp, 0, &byte);
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_discard(struct ipmi_lanp_priv *lp)
Packit d14fb6
{
Packit d14fb6
	unsigned char byte = 0;
Packit d14fb6
Packit d14fb6
	return ipmi_set_lanp(lp, 0, &byte);
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static int
Packit d14fb6
lanp_commit(struct ipmi_lanp_priv *lp)
Packit d14fb6
{
Packit d14fb6
	unsigned char byte = 2;
Packit d14fb6
	int ret;
Packit d14fb6
Packit d14fb6
	ret = ipmi_set_lanp(lp, 0, &byte);
Packit d14fb6
	if (ret == 0) {
Packit d14fb6
		ret = lanp_discard(lp);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return ret;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int
Packit d14fb6
ipmi_lan6_main(struct ipmi_intf *intf, int argc, char **argv)
Packit d14fb6
{
Packit d14fb6
	struct ipmi_cfgp_ctx ctx;
Packit d14fb6
	struct ipmi_cfgp_sel sel;
Packit d14fb6
	struct ipmi_lanp_priv lp;
Packit d14fb6
	int cmd;
Packit d14fb6
	int chan;
Packit d14fb6
	int nolock = 0;
Packit d14fb6
	int ret;
Packit d14fb6
Packit d14fb6
	if (argc == 0) {
Packit d14fb6
		lanp_print_usage(LANP_CMD_ANY);
Packit d14fb6
		return 0;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	cmd = str2val(argv[0], ip6_command_vals);
Packit d14fb6
	if (cmd == LANP_CMD_ANY) {
Packit d14fb6
		lanp_print_usage(cmd);
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	if (cmd == LANP_CMD_HELP) {
Packit d14fb6
		if (argc == 1) {
Packit d14fb6
			cmd = LANP_CMD_ANY;
Packit d14fb6
		} else {
Packit d14fb6
			cmd = str2val(argv[1], ip6_command_vals);
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		lanp_print_usage(cmd);
Packit d14fb6
		return 0;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/*
Packit d14fb6
	 * the rest commands expect channel number
Packit d14fb6
	 * with the exception of 'get' and 'print'
Packit d14fb6
	 */
Packit d14fb6
	if (argc == 1) {
Packit d14fb6
		if (cmd == LANP_CMD_SAVE || cmd == LANP_CMD_PRINT) {
Packit d14fb6
			chan = find_lan_channel(intf, 1);
Packit d14fb6
			if (chan == 0) {
Packit d14fb6
				lprintf(LOG_ERR, "No LAN channel found");
Packit d14fb6
				return -1;
Packit d14fb6
			}
Packit d14fb6
		} else {
Packit d14fb6
			lanp_print_usage(cmd);
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		argc -= 1;
Packit d14fb6
		argv += 1;
Packit d14fb6
	} else {
Packit d14fb6
		if (str2int(argv[1], &chan) != 0) {
Packit d14fb6
			lprintf(LOG_ERR, "Invalid channel: %s", argv[1]);
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		argc -= 2;
Packit d14fb6
		argv += 2;
Packit d14fb6
Packit d14fb6
		if (cmd == LANP_CMD_SET) {
Packit d14fb6
			if (argc && !strcasecmp(argv[0], "nolock")) {
Packit d14fb6
				nolock = 1;
Packit d14fb6
Packit d14fb6
				argc -= 1;
Packit d14fb6
				argv += 1;
Packit d14fb6
			}
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	lp.intf = intf;
Packit d14fb6
	lp.channel = chan;
Packit d14fb6
Packit d14fb6
	/*
Packit d14fb6
	 * lock/commit/discard commands do not require parsing
Packit d14fb6
	 * of parameter selection
Packit d14fb6
	 */
Packit d14fb6
Packit d14fb6
	switch (cmd) {
Packit d14fb6
	case LANP_CMD_LOCK:
Packit d14fb6
		lprintf(LOG_NOTICE, "Lock parameter(s)...");
Packit d14fb6
		return lanp_lock(&lp);
Packit d14fb6
Packit d14fb6
	case LANP_CMD_COMMIT:
Packit d14fb6
		lprintf(LOG_NOTICE, "Commit parameter(s)...");
Packit d14fb6
		return lanp_commit(&lp);
Packit d14fb6
Packit d14fb6
	case LANP_CMD_DISCARD:
Packit d14fb6
		lprintf(LOG_NOTICE, "Discard parameter(s)...");
Packit d14fb6
		return lanp_discard(&lp);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/*
Packit d14fb6
	 * initialize configuration context and parse parameter selection
Packit d14fb6
	 */
Packit d14fb6
Packit d14fb6
	ipmi_cfgp_init(&ctx, lan_cfgp,
Packit d14fb6
		sizeof(lan_cfgp)/sizeof(lan_cfgp[0]), "lan6 set nolock",
Packit d14fb6
		lanp_ip6_cfgp, &lp);
Packit d14fb6
Packit d14fb6
	ret = ipmi_cfgp_parse_sel(&ctx, argc, (const char **)argv, &sel;;
Packit d14fb6
	if (ret == -1) {
Packit d14fb6
		lanp_print_usage(cmd);
Packit d14fb6
		ipmi_cfgp_uninit(&ctx;;
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	argc -= ret;
Packit d14fb6
	argv += ret;
Packit d14fb6
Packit d14fb6
	/*
Packit d14fb6
	 * handle the rest commands
Packit d14fb6
	 */
Packit d14fb6
Packit d14fb6
	switch (cmd) {
Packit d14fb6
	case LANP_CMD_SAVE:
Packit d14fb6
	case LANP_CMD_PRINT:
Packit d14fb6
		lprintf(LOG_NOTICE, "Getting parameter(s)...");
Packit d14fb6
Packit d14fb6
		ret = ipmi_cfgp_get(&ctx, &sel;;
Packit d14fb6
		if (ret != 0) {
Packit d14fb6
			break;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (cmd == LANP_CMD_SAVE) {
Packit d14fb6
			static char cmd[20];
Packit d14fb6
			FILE *out = stdout;
Packit d14fb6
			snprintf(cmd, sizeof(cmd) - 1, "lan6 set %d nolock",
Packit d14fb6
				lp.channel);
Packit d14fb6
			cmd[sizeof(cmd) - 1] = '\0';
Packit d14fb6
			ctx.cmdname = cmd;
Packit d14fb6
			fprintf(out, "lan6 lock %d\n", lp.channel);
Packit d14fb6
			ret = ipmi_cfgp_save(&ctx, &sel, out);
Packit d14fb6
			fprintf(out, "lan6 commit %d\nlan6 discard %d\nexit\n",
Packit d14fb6
				lp.channel, lp.channel);
Packit d14fb6
		} else {
Packit d14fb6
			ret = ipmi_cfgp_print(&ctx, &sel, stdout);
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
Packit d14fb6
	case LANP_CMD_SET:
Packit d14fb6
		ret = ipmi_cfgp_parse_data(&ctx, &sel, argc,
Packit d14fb6
			(const char **)argv);
Packit d14fb6
		if (ret != 0) {
Packit d14fb6
			break;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		lprintf(LOG_NOTICE, "Setting parameter(s)...");
Packit d14fb6
Packit d14fb6
		if (!nolock) {
Packit d14fb6
			ret = lanp_lock(&lp);
Packit d14fb6
			if (ret != 0) {
Packit d14fb6
				break;
Packit d14fb6
			}
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		ret = ipmi_cfgp_set(&ctx, &sel;;
Packit d14fb6
		if (!nolock) {
Packit d14fb6
			if (ret == 0) {
Packit d14fb6
				ret = lanp_commit(&lp);
Packit d14fb6
			} else {
Packit d14fb6
				lanp_discard(&lp);
Packit d14fb6
			}
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/*
Packit d14fb6
	 * free allocated memory
Packit d14fb6
	 */
Packit d14fb6
	ipmi_cfgp_uninit(&ctx;;
Packit d14fb6
Packit d14fb6
	return ret;
Packit d14fb6
}