|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* iSCSI host helpers
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* Copyright (C) 2008 Mike Christie
|
|
Packit |
eace71 |
* Copyright (C) 2008 Red Hat, Inc. All rights reserved.
|
|
Packit |
eace71 |
* maintained by open-iscsi@@googlegroups.com
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
eace71 |
* it under the terms of the GNU General Public License as published
|
|
Packit |
eace71 |
* by the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
eace71 |
* (at your option) any later version.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
eace71 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
eace71 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
eace71 |
* General Public License for more details.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* See the file COPYING included with this distribution for more details.
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
#include <stdlib.h>
|
|
Packit |
eace71 |
#include <stdio.h>
|
|
Packit |
eace71 |
#include <errno.h>
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "list.h"
|
|
Packit |
eace71 |
#include "iscsi_util.h"
|
|
Packit |
eace71 |
#include "log.h"
|
|
Packit |
eace71 |
#include "iscsi_sysfs.h"
|
|
Packit |
eace71 |
#include "version.h"
|
|
Packit |
eace71 |
#include "iscsi_settings.h"
|
|
Packit |
eace71 |
#include "mgmt_ipc.h"
|
|
Packit |
eace71 |
#include "host.h"
|
|
Packit |
eace71 |
#include "session_info.h"
|
|
Packit |
eace71 |
#include "transport.h"
|
|
Packit |
eace71 |
#include "initiator.h"
|
|
Packit |
eace71 |
#include "iface.h"
|
|
Packit |
eace71 |
#include "iscsi_err.h"
|
|
Packit |
eace71 |
#include "iscsi_netlink.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
struct _host_info_print_tree_arg {
|
|
Packit |
eace71 |
unsigned int flags;
|
|
Packit |
eace71 |
struct iscsi_session **ses;
|
|
Packit |
eace71 |
uint32_t se_count;
|
|
Packit |
eace71 |
};
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int match_host_to_session(uint32_t host_no, struct iscsi_session *se)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
uint32_t sid = 0;
|
|
Packit |
eace71 |
uint32_t info_host_no;
|
|
Packit |
eace71 |
int rc;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
sid = iscsi_session_sid_get(se);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
info_host_no = iscsi_sysfs_get_host_no_from_sid(sid, &rc);
|
|
Packit |
eace71 |
if (rc) {
|
|
Packit |
eace71 |
log_error("could not get host_no for session%d err %d.",
|
|
Packit |
eace71 |
sid, rc);
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return host_no == info_host_no;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void print_host_info(struct iface_rec *iface, char *prefix)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
if (strlen(iface->transport_name))
|
|
Packit |
eace71 |
printf("%sTransport: %s\n", prefix,
|
|
Packit |
eace71 |
iface->transport_name);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sTransport: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strlen(iface->iname))
|
|
Packit |
eace71 |
printf("%sInitiatorname: %s\n", prefix,
|
|
Packit |
eace71 |
iface->iname);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sInitiatorname: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!strlen(iface->ipaddress))
|
|
Packit |
eace71 |
printf("%sIPaddress: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else if (strchr(iface->ipaddress, '.'))
|
|
Packit |
eace71 |
printf("%sIPaddress: %s\n", prefix, iface->ipaddress);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sIPaddress: [%s]\n", prefix, iface->ipaddress);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strlen(iface->hwaddress))
|
|
Packit |
eace71 |
printf("%sHWaddress: %s\n", prefix, iface->hwaddress);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sHWaddress: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strlen(iface->netdev))
|
|
Packit |
eace71 |
printf("%sNetdev: %s\n", prefix, iface->netdev);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sNetdev: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int host_info_print_flat(void *data, struct host_info *hinfo)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iface_rec *iface = &hinfo->iface;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strlen(iface->transport_name))
|
|
Packit |
eace71 |
printf("%s: ", iface->transport_name);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%s: ", UNKNOWN_VALUE);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
printf("[%u] ", hinfo->host_no);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!strlen(iface->ipaddress))
|
|
Packit |
eace71 |
printf("%s,", UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else if (strchr(iface->ipaddress, '.'))
|
|
Packit |
eace71 |
printf("%s,", iface->ipaddress);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("[%s],", iface->ipaddress);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strlen(iface->hwaddress))
|
|
Packit |
eace71 |
printf("[%s],", iface->hwaddress);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("[%s],", UNKNOWN_VALUE);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strlen(iface->netdev))
|
|
Packit |
eace71 |
printf("%s ", iface->netdev);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%s ", UNKNOWN_VALUE);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (strlen(iface->iname))
|
|
Packit |
eace71 |
printf("%s\n", iface->iname);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%s\n", UNKNOWN_VALUE);
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int print_host_iface(void *data, struct iface_rec *iface)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
char *prefix = data;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
printf("%s**********\n", prefix);
|
|
Packit |
eace71 |
printf("%sInterface:\n", prefix);
|
|
Packit |
eace71 |
printf("%s**********\n", prefix);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
printf("%sKernel Name: %s\n", prefix, iface->name);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!strlen(iface->ipaddress))
|
|
Packit |
eace71 |
printf("%sIPaddress: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else if (strchr(iface->ipaddress, '.')) {
|
|
Packit |
eace71 |
printf("%sIPaddress: %s\n", prefix, iface->ipaddress);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!strlen(iface->gateway))
|
|
Packit |
eace71 |
printf("%sGateway: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sGateway: %s\n", prefix, iface->gateway);
|
|
Packit |
eace71 |
if (!strlen(iface->subnet_mask))
|
|
Packit |
eace71 |
printf("%sSubnet: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sSubnet: %s\n", prefix, iface->subnet_mask);
|
|
Packit |
eace71 |
if (!strlen(iface->bootproto))
|
|
Packit |
eace71 |
printf("%sBootProto: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sBootProto: %s\n", prefix, iface->bootproto);
|
|
Packit |
eace71 |
} else {
|
|
Packit |
eace71 |
printf("%sIPaddress: [%s]\n", prefix, iface->ipaddress);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!strlen(iface->ipv6_autocfg))
|
|
Packit |
eace71 |
printf("%sIPaddress Autocfg: %s\n", prefix,
|
|
Packit |
eace71 |
UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sIPaddress Autocfg: %s\n", prefix,
|
|
Packit |
eace71 |
iface->ipv6_autocfg);
|
|
Packit |
eace71 |
if (!strlen(iface->ipv6_linklocal))
|
|
Packit |
eace71 |
printf("%sLink Local Address: %s\n", prefix,
|
|
Packit |
eace71 |
UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sLink Local Address: [%s]\n", prefix,
|
|
Packit |
eace71 |
iface->ipv6_linklocal);
|
|
Packit |
eace71 |
if (!strlen(iface->linklocal_autocfg))
|
|
Packit |
eace71 |
printf("%sLink Local Autocfg: %s\n", prefix,
|
|
Packit |
eace71 |
UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sLink Local Autocfg: %s\n", prefix,
|
|
Packit |
eace71 |
iface->linklocal_autocfg);
|
|
Packit |
eace71 |
if (!strlen(iface->ipv6_router))
|
|
Packit |
eace71 |
printf("%sRouter Address: %s\n", prefix,
|
|
Packit |
eace71 |
UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sRouter Address: [%s]\n", prefix,
|
|
Packit |
eace71 |
iface->ipv6_router);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!strlen(iface->port_state))
|
|
Packit |
eace71 |
printf("%sPort State: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sPort State: %s\n", prefix, iface->port_state);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!strlen(iface->port_speed))
|
|
Packit |
eace71 |
printf("%sPort Speed: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sPort Speed: %s\n", prefix, iface->port_speed);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!iface->port)
|
|
Packit |
eace71 |
printf("%sPort: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sPort: %u\n", prefix, iface->port);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!iface->mtu)
|
|
Packit |
eace71 |
printf("%sMTU: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sMTU: %u\n", prefix, iface->mtu);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (iface->vlan_id == UINT16_MAX)
|
|
Packit |
eace71 |
printf("%sVLAN ID: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sVLAN ID: %u\n", prefix, iface->vlan_id);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (iface->vlan_priority == UINT8_MAX)
|
|
Packit |
eace71 |
printf("%sVLAN priority: %s\n", prefix, UNKNOWN_VALUE);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("%sVLAN priority: %u\n", prefix, iface->vlan_priority);
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void print_host_ifaces(struct host_info *hinfo, char *prefix)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int nr_found = 0;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
iscsi_sysfs_for_each_iface_on_host(prefix, hinfo->host_no, &nr_found,
|
|
Packit |
eace71 |
print_host_iface);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int host_info_print_tree(void *data, struct host_info *hinfo)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
unsigned int session_info_flags = 0;
|
|
Packit |
eace71 |
struct _host_info_print_tree_arg *arg = data;
|
|
Packit |
eace71 |
struct iscsi_session **ses = NULL;
|
|
Packit |
eace71 |
struct iscsi_session **matched_ses = NULL;
|
|
Packit |
eace71 |
uint32_t se_count = 0;
|
|
Packit |
eace71 |
uint32_t matched_se_count = 0;
|
|
Packit |
eace71 |
uint32_t i = 0;
|
|
Packit |
eace71 |
char state[SCSI_MAX_STATE_VALUE];
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (arg == NULL)
|
|
Packit |
eace71 |
return -EINVAL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
session_info_flags = arg->flags;
|
|
Packit |
eace71 |
ses = arg->ses;
|
|
Packit |
eace71 |
se_count = arg->se_count;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
printf("Host Number: %u\n", hinfo->host_no);
|
|
Packit |
eace71 |
if (!iscsi_sysfs_get_host_state(state, hinfo->host_no))
|
|
Packit |
eace71 |
printf("\tState: %s\n", state);
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
printf("\tState: Unknown\n");
|
|
Packit |
eace71 |
print_host_info(&hinfo->iface, "\t");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
print_host_ifaces(hinfo, "\t");
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if ((!session_info_flags) || (!se_count))
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
matched_ses = calloc(se_count, sizeof(struct iscsi_session *));
|
|
Packit |
eace71 |
if (matched_ses == NULL)
|
|
Packit |
eace71 |
return -ENOMEM;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
for (i = 0; i < se_count; ++i)
|
|
Packit |
eace71 |
if (match_host_to_session(hinfo->host_no, ses[i]))
|
|
Packit |
eace71 |
matched_ses[matched_se_count++] = ses[i];
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!matched_se_count)
|
|
Packit |
eace71 |
goto out;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
printf("\t*********\n");
|
|
Packit |
eace71 |
printf("\tSessions:\n");
|
|
Packit |
eace71 |
printf("\t*********\n");
|
|
Packit |
eace71 |
session_info_print_tree(matched_ses, matched_se_count, "\t",
|
|
Packit |
eace71 |
session_info_flags, 0/* don't show password */);
|
|
Packit |
eace71 |
out:
|
|
Packit |
eace71 |
free(matched_ses);
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int host_info_print(int info_level, uint32_t host_no,
|
|
Packit |
eace71 |
struct iscsi_session **ses, uint32_t se_count)
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int num_found = 0, err = 0;
|
|
Packit |
eace71 |
char *version;
|
|
Packit |
eace71 |
unsigned int flags = 0;
|
|
Packit |
eace71 |
struct _host_info_print_tree_arg arg;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
switch (info_level) {
|
|
Packit |
eace71 |
case 0:
|
|
Packit |
eace71 |
case -1:
|
|
Packit |
eace71 |
err = iscsi_sysfs_for_each_host(NULL, &num_found,
|
|
Packit |
eace71 |
host_info_print_flat);
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
case 4:
|
|
Packit |
eace71 |
version = iscsi_sysfs_get_iscsi_kernel_version();
|
|
Packit |
eace71 |
if (version) {
|
|
Packit |
eace71 |
printf("iSCSI Transport Class version %s\n",
|
|
Packit |
eace71 |
version);
|
|
Packit |
eace71 |
printf("version %s\n", ISCSI_VERSION_STR);
|
|
Packit |
eace71 |
free(version);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
flags |= SESSION_INFO_SCSI_DEVS;
|
|
Packit |
eace71 |
/* fall through */
|
|
Packit |
eace71 |
case 3:
|
|
Packit |
eace71 |
flags |= SESSION_INFO_ISCSI_PARAMS;
|
|
Packit |
eace71 |
/* fall through */
|
|
Packit |
eace71 |
case 2:
|
|
Packit |
eace71 |
flags |= SESSION_INFO_ISCSI_STATE | SESSION_INFO_IFACE;
|
|
Packit |
eace71 |
/* fall through */
|
|
Packit |
eace71 |
case 1:
|
|
Packit |
eace71 |
arg.flags = flags;
|
|
Packit |
eace71 |
arg.ses = ses;
|
|
Packit |
eace71 |
arg.se_count = se_count;
|
|
Packit |
eace71 |
if (host_no != -1) {
|
|
Packit |
eace71 |
struct host_info hinfo;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
memset(&hinfo, 0, sizeof(struct host_info));
|
|
Packit |
eace71 |
hinfo.host_no = host_no;
|
|
Packit |
eace71 |
iscsi_sysfs_get_hostinfo_by_host_no(&hinfo);
|
|
Packit |
eace71 |
host_info_print_tree(&arg, &hinfo);
|
|
Packit |
eace71 |
num_found = 1;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
transport_probe_for_offload();
|
|
Packit |
eace71 |
err = iscsi_sysfs_for_each_host(&arg, &num_found,
|
|
Packit |
eace71 |
host_info_print_tree);
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
default:
|
|
Packit |
eace71 |
log_error("Invalid info level %d. Try 0 - 4.", info_level);
|
|
Packit |
eace71 |
return ISCSI_ERR_INVAL;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (err) {
|
|
Packit |
eace71 |
log_error("Can not get list of iSCSI hosts: %s",
|
|
Packit |
eace71 |
iscsi_err_to_str(err));
|
|
Packit |
eace71 |
return err;
|
|
Packit |
eace71 |
} else if (!num_found) {
|
|
Packit |
eace71 |
log_error("No iSCSI hosts.");
|
|
Packit |
eace71 |
return ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int chap_fill_param_uint(struct iovec *iov, int param,
|
|
Packit |
eace71 |
uint32_t param_val, int param_len)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iscsi_param_info *param_info;
|
|
Packit |
eace71 |
struct nlattr *attr;
|
|
Packit |
eace71 |
int len;
|
|
Packit |
eace71 |
uint8_t val8 = 0;
|
|
Packit |
eace71 |
uint16_t val16 = 0;
|
|
Packit |
eace71 |
uint32_t val32 = 0;
|
|
Packit |
eace71 |
char *val = NULL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
len = sizeof(struct iscsi_param_info) + param_len;
|
|
Packit |
eace71 |
iov->iov_base = iscsi_nla_alloc(param, len);
|
|
Packit |
eace71 |
if (!iov->iov_base)
|
|
Packit |
eace71 |
return 1;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
attr = iov->iov_base;
|
|
Packit |
eace71 |
iov->iov_len = NLA_ALIGN(attr->nla_len);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
param_info = (struct iscsi_param_info *)ISCSI_NLA_DATA(attr);
|
|
Packit |
eace71 |
param_info->param = param;
|
|
Packit |
eace71 |
param_info->len = param_len;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
switch (param_len) {
|
|
Packit |
eace71 |
case 1:
|
|
Packit |
eace71 |
val8 = (uint8_t)param_val;
|
|
Packit |
eace71 |
val = (char *)&val;;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
case 2:
|
|
Packit |
eace71 |
val16 = (uint16_t)param_val;
|
|
Packit |
eace71 |
val = (char *)&val16;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
case 4:
|
|
Packit |
eace71 |
val32 = (uint32_t)param_val;
|
|
Packit |
eace71 |
val = (char *)&val32;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
default:
|
|
Packit |
eace71 |
goto free;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
memcpy(param_info->value, val, param_len);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
free:
|
|
Packit |
eace71 |
free(iov->iov_base);
|
|
Packit |
eace71 |
iov->iov_base = NULL;
|
|
Packit |
eace71 |
iov->iov_len = 0;
|
|
Packit |
eace71 |
return 1;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int chap_fill_param_str(struct iovec *iov, int param, char *param_val,
|
|
Packit |
eace71 |
int param_len)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iscsi_param_info *param_info;
|
|
Packit |
eace71 |
struct nlattr *attr;
|
|
Packit |
eace71 |
int len;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
len = sizeof(struct iscsi_param_info) + param_len;
|
|
Packit |
eace71 |
iov->iov_base = iscsi_nla_alloc(param, len);
|
|
Packit |
eace71 |
if (!iov->iov_base)
|
|
Packit |
eace71 |
return 1;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
attr = iov->iov_base;
|
|
Packit |
eace71 |
iov->iov_len = NLA_ALIGN(attr->nla_len);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
param_info = (struct iscsi_param_info *)ISCSI_NLA_DATA(attr);
|
|
Packit |
eace71 |
param_info->param = param;
|
|
Packit |
eace71 |
param_info->len = param_len;
|
|
Packit |
eace71 |
memcpy(param_info->value, param_val, param_len);
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int chap_build_config(struct iscsi_chap_rec *crec, struct iovec *iovs)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iovec *iov = NULL;
|
|
Packit |
eace71 |
int count = 0;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* start at 2, because 0 is for nlmsghdr and 1 for event */
|
|
Packit |
eace71 |
iov = iovs + 2;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!chap_fill_param_uint(&iov[count], ISCSI_CHAP_PARAM_INDEX,
|
|
Packit |
eace71 |
crec->chap_tbl_idx,
|
|
Packit |
eace71 |
sizeof(crec->chap_tbl_idx)))
|
|
Packit |
eace71 |
count++;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!chap_fill_param_uint(&iov[count], ISCSI_CHAP_PARAM_CHAP_TYPE,
|
|
Packit |
eace71 |
crec->chap_type, sizeof(crec->chap_type)))
|
|
Packit |
eace71 |
count++;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!chap_fill_param_str(&iov[count], ISCSI_CHAP_PARAM_USERNAME,
|
|
Packit |
eace71 |
crec->username, strlen(crec->username)))
|
|
Packit |
eace71 |
count++;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!chap_fill_param_str(&iov[count], ISCSI_CHAP_PARAM_PASSWORD,
|
|
Packit |
eace71 |
(char *)crec->password,
|
|
Packit |
eace71 |
strlen((char *)crec->password)))
|
|
Packit |
eace71 |
count++;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!chap_fill_param_uint(&iov[count], ISCSI_CHAP_PARAM_PASSWORD_LEN,
|
|
Packit |
eace71 |
crec->password_length,
|
|
Packit |
eace71 |
sizeof(crec->password_length)))
|
|
Packit |
eace71 |
count++;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return count;
|
|
Packit |
eace71 |
}
|